Files
2026-07-22 19:38:36 +08:00

12 KiB

Wire

Overview

Wire is the wire class in the SimpleCAD API, representing a 1D geometric path formed by connecting multiple edges. A wire can be open (different start and end points) or closed (forming a closed path). It wraps the OCP Wire object and adds tagging functionality.

Class Definition

class Wire(TaggedMixin):
    """线类,包装OCP的Wire,添加标签功能"""

Inheritance

  • Inherits from TaggedMixin, providing tag and metadata functionality

Usage

  • Represent continuous paths or contours
  • Form the boundary of faces (Face)
  • Define paths for sweep, extrude, and other operations
  • Create complex geometric contours

Constructor

__init__(wrapped)

Initializes a wire object.

Parameters:

  • wrapped (OCP TopoDS_Wire): A OCP wire object

Raises:

  • ValueError: When the input wire object is invalid

Example:

from simplecadapi import (
    make_rectangle_rwire, 
    make_circle_rwire, 
    make_polyline_rwire
)

# 通过 SimpleCAD 函数创建线
rectangle = make_rectangle_rwire(width=5, height=3)
circle = make_circle_rwire(center=(0, 0, 0), radius=2.0)
polyline = make_polyline_rwire(points=[(0, 0, 0), (1, 1, 0), (2, 0, 0)])

Main Properties

  • wrapped: The underlying OCP wire object
  • _tags: Tag set (inherited from TaggedMixin)
  • _metadata: Metadata dictionary (inherited from TaggedMixin)

Common Methods

get_edges()

Get all edges that make up the wire.

Returns:

  • List[Edge]: List of edge objects

Raises:

  • ValueError: When edge list retrieval fails

Example:

from simplecadapi import make_rectangle_rwire

rectangle = make_rectangle_rwire(width=4, height=3)
edges = rectangle.get_edges()

print(f"矩形由 {len(edges)} 条边组成")
for i, edge in enumerate(edges):
    print(f"边 {i}: 长度 {edge.get_length():.3f}")

is_closed()

Check if the wire is closed.

Returns:

  • bool: Returns True if the wire is closed, False otherwise

Raises:

  • ValueError: When closure check fails

Example:

from simplecadapi import make_rectangle_rwire, make_polyline_rwire

# 闭合线
rectangle = make_rectangle_rwire(width=5, height=3)
print(f"矩形是否闭合: {rectangle.is_closed()}")  # True

# 开放线
polyline = make_polyline_rwire(points=[(0, 0, 0), (1, 1, 0), (2, 0, 0)])
print(f"折线是否闭合: {polyline.is_closed()}")  # False

Tagging and Metadata

Use the functional public API apply_tag(shape, tag) and list_tags(shape) for tags. Use set_metadata(key, value) and get_metadata(key, default=None) for structured metadata.

Usage Examples

Creating Different Types of Wires

from simplecadapi import (
    make_rectangle_rwire,
    make_circle_rwire,
    make_polyline_rwire,
    make_spline_rwire
)

# 矩形线
rectangle = make_rectangle_rwire(width=10, height=6)
apply_tag(rectangle, "rectangle")
apply_tag(rectangle, "closed")

# 圆形线
circle = make_circle_rwire(center=(0, 0, 0), radius=3.0)
apply_tag(circle, "circle")
apply_tag(circle, "closed")

# 折线
polyline = make_polyline_rwire(points=[
    (0, 0, 0), (2, 0, 0), (2, 2, 0), (1, 3, 0), (0, 2, 0)
])
apply_tag(polyline, "polyline")
apply_tag(polyline, "open")

# 样条线:control_points 是 B-spline poles,不是采样点
spline = make_spline_rwire(
    control_points=[(0, 0, 0), (1, 2, 0), (3, 2, 0), (4, 0, 0)]
)
apply_tag(spline, "spline")
apply_tag(spline, "smooth")

# 分析线的属性
wires = [rectangle, circle, polyline, spline]
for wire in wires:
    edges = wire.get_edges()
    closed = wire.is_closed()
    tags = list_tags(wire)
    
    print(f"线类型: {tags}, 边数: {len(edges)}, 闭合: {closed}")

Creating Complex Contours

from simplecadapi import make_polyline_rwire

def create_complex_profile():
    """创建复杂的轮廓线"""
    
    # 定义轮廓点
    points = [
        (0, 0, 0),      # 起点
        (10, 0, 0),     # 底边
        (10, 2, 0),     # 右下
        (8, 2, 0),      # 内凹1
        (8, 4, 0),      # 
        (10, 4, 0),     # 右上
        (10, 6, 0),     # 顶边右
        (0, 6, 0),      # 顶边左
        (0, 4, 0),      # 左上
        (2, 4, 0),      # 内凹2
        (2, 2, 0),      # 
        (0, 2, 0),      # 左下
        (0, 0, 0)       # 闭合回起点
    ]
    
    profile = make_polyline_rwire(points=points)
    apply_tag(profile, "complex_profile")
    apply_tag(profile, "symmetric")
    
    # 添加几何信息
    edges = profile.get_edges()
    total_length = sum(edge.get_length() for edge in edges)
    
    profile.set_metadata("total_length", total_length)
    profile.set_metadata("point_count", len(points))
    profile.set_metadata("edge_count", len(edges))
    
    return profile

profile = create_complex_profile()
print(f"复杂轮廓: {list_tags(profile)}")
print(f"总长度: {profile.get_metadata('total_length'):.3f}")
print(f"边数: {profile.get_metadata('edge_count')}")

Wire Analysis and Processing

from simplecadapi import make_rectangle_rwire, make_circle_rwire

def analyze_wire_properties():
    """分析线的属性"""
    
    # 创建不同的线
    rectangle = make_rectangle_rwire(width=6, height=4)
    circle = make_circle_rwire(center=(0, 0, 0), radius=2.0)
    
    wires = [rectangle, circle]
    
    for i, wire in enumerate(wires):
        # 基本属性
        edges = wire.get_edges()
        is_closed = wire.is_closed()
        
        # 计算总长度
        total_length = sum(edge.get_length() for edge in edges)
        
        # 分析边
        edge_lengths = [edge.get_length() for edge in edges]
        min_edge_length = min(edge_lengths)
        max_edge_length = max(edge_lengths)
        avg_edge_length = sum(edge_lengths) / len(edge_lengths)
        
        # 添加标签和元数据
        apply_tag(wire, f"wire_{i}")
        apply_tag(wire, "analyzed")
        
        if is_closed:
            apply_tag(wire, "closed")
        else:
            apply_tag(wire, "open")
        
        wire.set_metadata("total_length", total_length)
        wire.set_metadata("edge_count", len(edges))
        wire.set_metadata("min_edge_length", min_edge_length)
        wire.set_metadata("max_edge_length", max_edge_length)
        wire.set_metadata("avg_edge_length", avg_edge_length)
        
        # 分类边
        for j, edge in enumerate(edges):
            apply_tag(edge, f"wire_{i}_edge_{j}")
            edge.set_metadata("parent_wire", i)
            edge.set_metadata("position_in_wire", j)
        
        print(f"线 {i}:")
        print(f"  总长度: {total_length:.3f}")
        print(f"  边数: {len(edges)}")
        print(f"  闭合: {is_closed}")
        print(f"  最短边: {min_edge_length:.3f}")
        print(f"  最长边: {max_edge_length:.3f}")
        print(f"  平均边长: {avg_edge_length:.3f}")
        print()

analyze_wire_properties()

Wire Transformation and Operations

from simplecadapi import make_rectangle_rwire, translate_shape, rotate_shape

def transform_wires():
    """变换线的操作"""
    
    # 创建基础矩形
    base_rect = make_rectangle_rwire(width=4, height=2)
    apply_tag(base_rect, "base")
    apply_tag(base_rect, "original")
    
    # 创建变换后的线
    translated_rect = translate_shape(base_rect, offset=(5, 0, 0))
    apply_tag(translated_rect, "translated")
    
    rotated_rect = rotate_shape(base_rect, axis=(0, 0, 1), angle=45)
    apply_tag(rotated_rect, "rotated")
    
    # 收集所有线
    all_wires = [base_rect, translated_rect, rotated_rect]
    
    # 分析变换结果
    for wire in all_wires:
        edges = wire.get_edges()
        total_length = sum(edge.get_length() for edge in edges)
        
        # 计算边界框(简化版)
        all_coords = []
        for edge in edges:
            start_coords = edge.get_start_vertex().get_coordinates()
            end_coords = edge.get_end_vertex().get_coordinates()
            all_coords.extend([start_coords, end_coords])
        
        if all_coords:
            min_x = min(coord[0] for coord in all_coords)
            max_x = max(coord[0] for coord in all_coords)
            min_y = min(coord[1] for coord in all_coords)
            max_y = max(coord[1] for coord in all_coords)
            
            wire.set_metadata("bbox_min", (min_x, min_y))
            wire.set_metadata("bbox_max", (max_x, max_y))
            wire.set_metadata("bbox_width", max_x - min_x)
            wire.set_metadata("bbox_height", max_y - min_y)
        
        wire.set_metadata("total_length", total_length)
        
        print(f"线标签: {list_tags(wire)}")
        print(f"  总长度: {total_length:.3f}")
        if wire.get_metadata("bbox_min"):
            print(f"  边界框: {wire.get_metadata('bbox_min')}{wire.get_metadata('bbox_max')}")
        print()

transform_wires()

Building Wire Sequences

from simplecadapi import make_segment_rwire

def create_wire_sequence():
    """创建线的序列"""
    
    # 创建连续的线段
    segments = []
    
    # 定义路径点
    waypoints = [
        (0, 0, 0),
        (2, 0, 0),
        (2, 2, 0),
        (0, 2, 0),
        (0, 4, 0),
        (4, 4, 0),
        (4, 0, 0),
        (6, 0, 0)
    ]
    
    # 创建连续的线段
    for i in range(len(waypoints) - 1):
        start = waypoints[i]
        end = waypoints[i + 1]
        
        segment = make_segment_rwire(start=start, end=end)
        apply_tag(segment, f"segment_{i}")
        apply_tag(segment, "path_segment")
        
        # 添加方向信息
        direction = (
            end[0] - start[0],
            end[1] - start[1],
            end[2] - start[2]
        )
        
        if direction[0] > 0:
            apply_tag(segment, "eastward")
        elif direction[0] < 0:
            apply_tag(segment, "westward")
        
        if direction[1] > 0:
            apply_tag(segment, "northward")
        elif direction[1] < 0:
            apply_tag(segment, "southward")
        
        segment.set_metadata("start_point", start)
        segment.set_metadata("end_point", end)
        segment.set_metadata("direction", direction)
        segment.set_metadata("sequence_index", i)
        
        segments.append(segment)
    
    # 分析序列
    total_path_length = sum(seg.get_edges(0).get_length() for seg in segments)
    
    print(f"路径段数: {len(segments)}")
    print(f"总路径长度: {total_path_length:.3f}")
    
    # 按方向分类
    eastward = [s for s in segments if "eastward" in list_tags(s)]
    northward = [s for s in segments if "northward" in list_tags(s)]
    
    print(f"向东段数: {len(eastward)}")
    print(f"向北段数: {len(northward)}")
    
    return segments

sequence = create_wire_sequence()

String Representation

from simplecadapi import make_rectangle_rwire

wire = make_rectangle_rwire(width=5, height=3)
apply_tag(wire, "example_rectangle")
wire.set_metadata("area", 15.0)

print(wire)

Output:

Wire:
  edge_count: 4
  closed: True
  edges:
    edge_0:
      length: 5.000
      vertices:
        start: (0.0, 0.0, 0.0)
        end: (5.0, 0.0, 0.0)
    edge_1:
      length: 3.000
      vertices:
        start: (5.0, 0.0, 0.0)
        end: (5.0, 3.0, 0.0)
    edge_2:
      length: 5.000
      vertices:
        start: (5.0, 3.0, 0.0)
        end: (0.0, 3.0, 0.0)
    edge_3:
      length: 3.000
      vertices:
        start: (0.0, 3.0, 0.0)
        end: (0.0, 0.0, 0.0)
  tags: [example_rectangle]
  metadata:
    area: 15.0

Relationships with Other Geometry

  • Edge (Edge): Components of a wire
  • Face (Face): Closed wires can define face boundaries
  • Solid (Solid): Can be created by sweeping or extruding wires

Notes

  • Wire edges must be continuous; endpoints of adjacent edges must coincide
  • The start and end points of a closed wire must coincide
  • Wire orientation affects certain operations (such as face normal direction)
  • Complex wires may contain self-intersections and require special handling
  • Wire length equals the sum of all edge lengths
  • When creating faces, outer boundary wires should be counterclockwise; inner boundary wires should be clockwise