# 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 ```python 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:** ```python 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:** ```python 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:** ```python 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 ```python 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 ```python 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 ```python 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 ```python 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 ```python 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 ```python 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