mirror of
https://github.com/gumyr/build123d.git
synced 2025-12-05 18:20:46 -08:00
Eliminating copying exploration methods in higher order classes
Some checks are pending
benchmarks / benchmarks (macos-14, 3.12) (push) Waiting to run
benchmarks / benchmarks (macos-15-intel, 3.12) (push) Waiting to run
benchmarks / benchmarks (ubuntu-latest, 3.12) (push) Waiting to run
benchmarks / benchmarks (windows-latest, 3.12) (push) Waiting to run
Upload coverage reports to Codecov / run (push) Waiting to run
pylint / lint (3.10) (push) Waiting to run
Run type checker / typecheck (3.10) (push) Waiting to run
Run type checker / typecheck (3.13) (push) Waiting to run
Wheel building and publishing / Build wheel on ubuntu-latest (push) Waiting to run
Wheel building and publishing / upload_pypi (push) Blocked by required conditions
tests / tests (macos-14, 3.10) (push) Waiting to run
tests / tests (macos-14, 3.13) (push) Waiting to run
tests / tests (macos-15-intel, 3.10) (push) Waiting to run
tests / tests (macos-15-intel, 3.13) (push) Waiting to run
tests / tests (ubuntu-latest, 3.10) (push) Waiting to run
tests / tests (ubuntu-latest, 3.13) (push) Waiting to run
tests / tests (windows-latest, 3.10) (push) Waiting to run
tests / tests (windows-latest, 3.13) (push) Waiting to run
Some checks are pending
benchmarks / benchmarks (macos-14, 3.12) (push) Waiting to run
benchmarks / benchmarks (macos-15-intel, 3.12) (push) Waiting to run
benchmarks / benchmarks (ubuntu-latest, 3.12) (push) Waiting to run
benchmarks / benchmarks (windows-latest, 3.12) (push) Waiting to run
Upload coverage reports to Codecov / run (push) Waiting to run
pylint / lint (3.10) (push) Waiting to run
Run type checker / typecheck (3.10) (push) Waiting to run
Run type checker / typecheck (3.13) (push) Waiting to run
Wheel building and publishing / Build wheel on ubuntu-latest (push) Waiting to run
Wheel building and publishing / upload_pypi (push) Blocked by required conditions
tests / tests (macos-14, 3.10) (push) Waiting to run
tests / tests (macos-14, 3.13) (push) Waiting to run
tests / tests (macos-15-intel, 3.10) (push) Waiting to run
tests / tests (macos-15-intel, 3.13) (push) Waiting to run
tests / tests (ubuntu-latest, 3.10) (push) Waiting to run
tests / tests (ubuntu-latest, 3.13) (push) Waiting to run
tests / tests (windows-latest, 3.10) (push) Waiting to run
tests / tests (windows-latest, 3.13) (push) Waiting to run
This commit is contained in:
parent
3871345dcd
commit
726a72a20b
5 changed files with 93 additions and 82 deletions
|
|
@ -600,7 +600,7 @@ class Compound(Mixin3D[TopoDS_Compound]):
|
||||||
"""Return the Compound"""
|
"""Return the Compound"""
|
||||||
shape_list = self.compounds()
|
shape_list = self.compounds()
|
||||||
entity_count = len(shape_list)
|
entity_count = len(shape_list)
|
||||||
if entity_count != 1:
|
if entity_count > 1:
|
||||||
warnings.warn(
|
warnings.warn(
|
||||||
f"Found {entity_count} compounds, returning first",
|
f"Found {entity_count} compounds, returning first",
|
||||||
stacklevel=2,
|
stacklevel=2,
|
||||||
|
|
|
||||||
|
|
@ -556,7 +556,7 @@ class Mixin1D(Shape[TOPODS]):
|
||||||
|
|
||||||
A curvature comb is a set of short line segments (“teeth”) erected
|
A curvature comb is a set of short line segments (“teeth”) erected
|
||||||
perpendicular to the curve that visualize the signed curvature κ(u).
|
perpendicular to the curve that visualize the signed curvature κ(u).
|
||||||
Tooth length is proportional to \|κ\| and the direction encodes the sign
|
Tooth length is proportional to |κ| and the direction encodes the sign
|
||||||
(left normal for κ>0, right normal for κ<0). This is useful for inspecting
|
(left normal for κ>0, right normal for κ<0). This is useful for inspecting
|
||||||
fairness and continuity (C0/C1/C2) of edges and wires.
|
fairness and continuity (C0/C1/C2) of edges and wires.
|
||||||
|
|
||||||
|
|
@ -684,30 +684,30 @@ class Mixin1D(Shape[TOPODS]):
|
||||||
|
|
||||||
return derivative
|
return derivative
|
||||||
|
|
||||||
def edge(self) -> Edge | None:
|
# def edge(self) -> Edge | None:
|
||||||
"""Return the Edge"""
|
# """Return the Edge"""
|
||||||
return Shape.get_single_shape(self, "Edge")
|
# return Shape.get_single_shape(self, "Edge")
|
||||||
|
|
||||||
def edges(self) -> ShapeList[Edge]:
|
# def edges(self) -> ShapeList[Edge]:
|
||||||
"""edges - all the edges in this Shape"""
|
# """edges - all the edges in this Shape"""
|
||||||
if isinstance(self, Wire) and self.wrapped is not None:
|
# if isinstance(self, Wire) and self.wrapped is not None:
|
||||||
# The WireExplorer is a tool to explore the edges of a wire in a connection order.
|
# # The WireExplorer is a tool to explore the edges of a wire in a connection order.
|
||||||
explorer = BRepTools_WireExplorer(self.wrapped)
|
# explorer = BRepTools_WireExplorer(self.wrapped)
|
||||||
|
|
||||||
edge_list: ShapeList[Edge] = ShapeList()
|
# edge_list: ShapeList[Edge] = ShapeList()
|
||||||
while explorer.More():
|
# while explorer.More():
|
||||||
next_edge = Edge(explorer.Current())
|
# next_edge = Edge(explorer.Current())
|
||||||
next_edge.topo_parent = (
|
# next_edge.topo_parent = (
|
||||||
self if self.topo_parent is None else self.topo_parent
|
# self if self.topo_parent is None else self.topo_parent
|
||||||
)
|
# )
|
||||||
edge_list.append(next_edge)
|
# edge_list.append(next_edge)
|
||||||
explorer.Next()
|
# explorer.Next()
|
||||||
return edge_list
|
# return edge_list
|
||||||
|
|
||||||
edge_list = Shape.get_shape_list(self, "Edge")
|
# edge_list = Shape.get_shape_list(self, "Edge")
|
||||||
return edge_list.filter_by(
|
# return edge_list.filter_by(
|
||||||
lambda e: BRep_Tool.Degenerated_s(e.wrapped), reverse=True
|
# lambda e: BRep_Tool.Degenerated_s(e.wrapped), reverse=True
|
||||||
)
|
# )
|
||||||
|
|
||||||
def end_point(self) -> Vector:
|
def end_point(self) -> Vector:
|
||||||
"""The end point of this edge.
|
"""The end point of this edge.
|
||||||
|
|
@ -1431,21 +1431,21 @@ class Mixin1D(Shape[TOPODS]):
|
||||||
"""
|
"""
|
||||||
return self.derivative_at(position, 1, position_mode).normalized()
|
return self.derivative_at(position, 1, position_mode).normalized()
|
||||||
|
|
||||||
def vertex(self) -> Vertex | None:
|
# def vertex(self) -> Vertex | None:
|
||||||
"""Return the Vertex"""
|
# """Return the Vertex"""
|
||||||
return Shape.get_single_shape(self, "Vertex")
|
# return Shape.get_single_shape(self, "Vertex")
|
||||||
|
|
||||||
def vertices(self) -> ShapeList[Vertex]:
|
# def vertices(self) -> ShapeList[Vertex]:
|
||||||
"""vertices - all the vertices in this Shape"""
|
# """vertices - all the vertices in this Shape"""
|
||||||
return Shape.get_shape_list(self, "Vertex")
|
# return Shape.get_shape_list(self, "Vertex")
|
||||||
|
|
||||||
def wire(self) -> Wire | None:
|
# def wire(self) -> Wire | None:
|
||||||
"""Return the Wire"""
|
# """Return the Wire"""
|
||||||
return Shape.get_single_shape(self, "Wire")
|
# return Shape.get_single_shape(self, "Wire")
|
||||||
|
|
||||||
def wires(self) -> ShapeList[Wire]:
|
# def wires(self) -> ShapeList[Wire]:
|
||||||
"""wires - all the wires in this Shape"""
|
# """wires - all the wires in this Shape"""
|
||||||
return Shape.get_shape_list(self, "Wire")
|
# return Shape.get_shape_list(self, "Wire")
|
||||||
|
|
||||||
|
|
||||||
class Edge(Mixin1D[TopoDS_Edge]):
|
class Edge(Mixin1D[TopoDS_Edge]):
|
||||||
|
|
@ -3561,6 +3561,21 @@ class Wire(Mixin1D[TopoDS_Wire]):
|
||||||
|
|
||||||
return return_value
|
return return_value
|
||||||
|
|
||||||
|
def edges(self) -> ShapeList[Edge]:
|
||||||
|
"""edges - all the edges in this Shape"""
|
||||||
|
# The WireExplorer is a tool to explore the edges of a wire in a connection order.
|
||||||
|
explorer = BRepTools_WireExplorer(self.wrapped)
|
||||||
|
|
||||||
|
edge_list: ShapeList[Edge] = ShapeList()
|
||||||
|
while explorer.More():
|
||||||
|
next_edge = Edge(explorer.Current())
|
||||||
|
next_edge.topo_parent = (
|
||||||
|
self if self.topo_parent is None else self.topo_parent
|
||||||
|
)
|
||||||
|
edge_list.append(next_edge)
|
||||||
|
explorer.Next()
|
||||||
|
return edge_list
|
||||||
|
|
||||||
def fillet_2d(self, radius: float, vertices: Iterable[Vertex]) -> Wire:
|
def fillet_2d(self, radius: float, vertices: Iterable[Vertex]) -> Wire:
|
||||||
"""fillet_2d
|
"""fillet_2d
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -101,7 +101,7 @@ from OCP.BRepGProp import BRepGProp, BRepGProp_Face
|
||||||
from OCP.BRepIntCurveSurface import BRepIntCurveSurface_Inter
|
from OCP.BRepIntCurveSurface import BRepIntCurveSurface_Inter
|
||||||
from OCP.BRepMesh import BRepMesh_IncrementalMesh
|
from OCP.BRepMesh import BRepMesh_IncrementalMesh
|
||||||
from OCP.BRepPrimAPI import BRepPrimAPI_MakeHalfSpace
|
from OCP.BRepPrimAPI import BRepPrimAPI_MakeHalfSpace
|
||||||
from OCP.BRepTools import BRepTools
|
from OCP.BRepTools import BRepTools, BRepTools_WireExplorer
|
||||||
from OCP.gce import gce_MakeLin
|
from OCP.gce import gce_MakeLin
|
||||||
from OCP.Geom import Geom_Line
|
from OCP.Geom import Geom_Line
|
||||||
from OCP.GeomAPI import GeomAPI_ProjectPointOnSurf
|
from OCP.GeomAPI import GeomAPI_ProjectPointOnSurf
|
||||||
|
|
@ -839,7 +839,9 @@ class Shape(NodeMixin, Generic[TOPODS]):
|
||||||
with a warning if count != 1."""
|
with a warning if count != 1."""
|
||||||
shape_list = Shape.get_shape_list(shape, entity_type)
|
shape_list = Shape.get_shape_list(shape, entity_type)
|
||||||
entity_count = len(shape_list)
|
entity_count = len(shape_list)
|
||||||
if entity_count != 1:
|
if entity_count == 0:
|
||||||
|
return None
|
||||||
|
elif entity_count > 1:
|
||||||
warnings.warn(
|
warnings.warn(
|
||||||
f"Found {entity_count} {entity_type.lower()}s, returning first",
|
f"Found {entity_count} {entity_type.lower()}s, returning first",
|
||||||
stacklevel=3,
|
stacklevel=3,
|
||||||
|
|
@ -1185,13 +1187,14 @@ class Shape(NodeMixin, Generic[TOPODS]):
|
||||||
|
|
||||||
def edge(self) -> Edge | None:
|
def edge(self) -> Edge | None:
|
||||||
"""Return the Edge"""
|
"""Return the Edge"""
|
||||||
return None
|
return Shape.get_single_shape(self, "Edge")
|
||||||
|
|
||||||
# Note all sub-classes have vertices and vertex methods
|
|
||||||
|
|
||||||
def edges(self) -> ShapeList[Edge]:
|
def edges(self) -> ShapeList[Edge]:
|
||||||
"""edges - all the edges in this Shape - subclasses may override"""
|
"""edges - all the edges in this Shape - subclasses may override"""
|
||||||
return ShapeList()
|
edge_list = Shape.get_shape_list(self, "Edge")
|
||||||
|
return edge_list.filter_by(
|
||||||
|
lambda e: BRep_Tool.Degenerated_s(e.wrapped), reverse=True
|
||||||
|
)
|
||||||
|
|
||||||
def entities(self, topo_type: Shapes) -> list[TopoDS_Shape]:
|
def entities(self, topo_type: Shapes) -> list[TopoDS_Shape]:
|
||||||
"""Return all of the TopoDS sub entities of the given type"""
|
"""Return all of the TopoDS sub entities of the given type"""
|
||||||
|
|
@ -1201,11 +1204,11 @@ class Shape(NodeMixin, Generic[TOPODS]):
|
||||||
|
|
||||||
def face(self) -> Face | None:
|
def face(self) -> Face | None:
|
||||||
"""Return the Face"""
|
"""Return the Face"""
|
||||||
return None
|
return Shape.get_single_shape(self, "Face")
|
||||||
|
|
||||||
def faces(self) -> ShapeList[Face]:
|
def faces(self) -> ShapeList[Face]:
|
||||||
"""faces - all the faces in this Shape"""
|
"""faces - all the faces in this Shape"""
|
||||||
return ShapeList()
|
return Shape.get_shape_list(self, "Face")
|
||||||
|
|
||||||
def faces_intersected_by_axis(
|
def faces_intersected_by_axis(
|
||||||
self,
|
self,
|
||||||
|
|
@ -1724,11 +1727,11 @@ class Shape(NodeMixin, Generic[TOPODS]):
|
||||||
|
|
||||||
def shell(self) -> Shell | None:
|
def shell(self) -> Shell | None:
|
||||||
"""Return the Shell"""
|
"""Return the Shell"""
|
||||||
return None
|
return Shape.get_single_shape(self, "Shell")
|
||||||
|
|
||||||
def shells(self) -> ShapeList[Shell]:
|
def shells(self) -> ShapeList[Shell]:
|
||||||
"""shells - all the shells in this Shape"""
|
"""shells - all the shells in this Shape"""
|
||||||
return ShapeList()
|
return Shape.get_shape_list(self, "Shell")
|
||||||
|
|
||||||
def show_topology(
|
def show_topology(
|
||||||
self,
|
self,
|
||||||
|
|
@ -1782,11 +1785,11 @@ class Shape(NodeMixin, Generic[TOPODS]):
|
||||||
|
|
||||||
def solid(self) -> Solid | None:
|
def solid(self) -> Solid | None:
|
||||||
"""Return the Solid"""
|
"""Return the Solid"""
|
||||||
return None
|
return Shape.get_single_shape(self, "Solid")
|
||||||
|
|
||||||
def solids(self) -> ShapeList[Solid]:
|
def solids(self) -> ShapeList[Solid]:
|
||||||
"""solids - all the solids in this Shape"""
|
"""solids - all the solids in this Shape"""
|
||||||
return ShapeList()
|
return Shape.get_shape_list(self, "Solid")
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def split(
|
def split(
|
||||||
|
|
@ -2235,11 +2238,11 @@ class Shape(NodeMixin, Generic[TOPODS]):
|
||||||
|
|
||||||
def wire(self) -> Wire | None:
|
def wire(self) -> Wire | None:
|
||||||
"""Return the Wire"""
|
"""Return the Wire"""
|
||||||
return None
|
return Shape.get_single_shape(self, "Wire")
|
||||||
|
|
||||||
def wires(self) -> ShapeList[Wire]:
|
def wires(self) -> ShapeList[Wire]:
|
||||||
"""wires - all the wires in this Shape"""
|
"""wires - all the wires in this Shape"""
|
||||||
return ShapeList()
|
return Shape.get_shape_list(self, "Wire")
|
||||||
|
|
||||||
def _apply_transform(self, transformation: gp_Trsf) -> Self:
|
def _apply_transform(self, transformation: gp_Trsf) -> Self:
|
||||||
"""Private Apply Transform
|
"""Private Apply Transform
|
||||||
|
|
@ -2395,6 +2398,14 @@ class Shape(NodeMixin, Generic[TOPODS]):
|
||||||
|
|
||||||
return shape_to_html(self)._repr_html_()
|
return shape_to_html(self)._repr_html_()
|
||||||
|
|
||||||
|
def vertex(self) -> Vertex | None:
|
||||||
|
"""Return the Vertex"""
|
||||||
|
return Shape.get_single_shape(self, "Vertex")
|
||||||
|
|
||||||
|
def vertices(self) -> ShapeList[Vertex]:
|
||||||
|
"""vertices - all the vertices in this Shape"""
|
||||||
|
return Shape.get_shape_list(self, "Vertex")
|
||||||
|
|
||||||
|
|
||||||
class Comparable(ABC):
|
class Comparable(ABC):
|
||||||
"""Abstract base class that requires comparison methods"""
|
"""Abstract base class that requires comparison methods"""
|
||||||
|
|
|
||||||
|
|
@ -144,16 +144,6 @@ class Mixin3D(Shape[TOPODS]):
|
||||||
project_to_viewport = Mixin1D.project_to_viewport
|
project_to_viewport = Mixin1D.project_to_viewport
|
||||||
find_intersection_points = Mixin2D.find_intersection_points
|
find_intersection_points = Mixin2D.find_intersection_points
|
||||||
|
|
||||||
vertices = Mixin1D.vertices
|
|
||||||
vertex = Mixin1D.vertex
|
|
||||||
edges = Mixin1D.edges
|
|
||||||
edge = Mixin1D.edge
|
|
||||||
wires = Mixin1D.wires
|
|
||||||
wire = Mixin1D.wire
|
|
||||||
faces = Mixin2D.faces
|
|
||||||
face = Mixin2D.face
|
|
||||||
shells = Mixin2D.shells
|
|
||||||
shell = Mixin2D.shell
|
|
||||||
# ---- Properties ----
|
# ---- Properties ----
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|
@ -725,13 +715,13 @@ class Mixin3D(Shape[TOPODS]):
|
||||||
|
|
||||||
return offset_solid
|
return offset_solid
|
||||||
|
|
||||||
def solid(self) -> Solid | None:
|
# def solid(self) -> Solid | None:
|
||||||
"""Return the Solid"""
|
# """Return the Solid"""
|
||||||
return Shape.get_single_shape(self, "Solid")
|
# return Shape.get_single_shape(self, "Solid")
|
||||||
|
|
||||||
def solids(self) -> ShapeList[Solid]:
|
# def solids(self) -> ShapeList[Solid]:
|
||||||
"""solids - all the solids in this Shape"""
|
# """solids - all the solids in this Shape"""
|
||||||
return Shape.get_shape_list(self, "Solid")
|
# return Shape.get_shape_list(self, "Solid")
|
||||||
|
|
||||||
|
|
||||||
class Solid(Mixin3D[TopoDS_Solid]):
|
class Solid(Mixin3D[TopoDS_Solid]):
|
||||||
|
|
|
||||||
|
|
@ -174,11 +174,6 @@ class Mixin2D(ABC, Shape[TOPODS]):
|
||||||
|
|
||||||
project_to_viewport = Mixin1D.project_to_viewport
|
project_to_viewport = Mixin1D.project_to_viewport
|
||||||
|
|
||||||
vertices = Mixin1D.vertices
|
|
||||||
vertex = Mixin1D.vertex
|
|
||||||
edges = Mixin1D.edges
|
|
||||||
edge = Mixin1D.edge
|
|
||||||
wires = Mixin1D.wires
|
|
||||||
# ---- Properties ----
|
# ---- Properties ----
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|
@ -226,13 +221,13 @@ class Mixin2D(ABC, Shape[TOPODS]):
|
||||||
|
|
||||||
return new_surface
|
return new_surface
|
||||||
|
|
||||||
def face(self) -> Face | None:
|
# def face(self) -> Face | None:
|
||||||
"""Return the Face"""
|
# """Return the Face"""
|
||||||
return Shape.get_single_shape(self, "Face")
|
# return Shape.get_single_shape(self, "Face")
|
||||||
|
|
||||||
def faces(self) -> ShapeList[Face]:
|
# def faces(self) -> ShapeList[Face]:
|
||||||
"""faces - all the faces in this Shape"""
|
# """faces - all the faces in this Shape"""
|
||||||
return Shape.get_shape_list(self, "Face")
|
# return Shape.get_shape_list(self, "Face")
|
||||||
|
|
||||||
def find_intersection_points(
|
def find_intersection_points(
|
||||||
self, other: Axis, tolerance: float = TOLERANCE
|
self, other: Axis, tolerance: float = TOLERANCE
|
||||||
|
|
@ -412,13 +407,13 @@ class Mixin2D(ABC, Shape[TOPODS]):
|
||||||
"""Return a copy of self moved along the normal by amount"""
|
"""Return a copy of self moved along the normal by amount"""
|
||||||
return copy.deepcopy(self).moved(Location(self.normal_at() * amount))
|
return copy.deepcopy(self).moved(Location(self.normal_at() * amount))
|
||||||
|
|
||||||
def shell(self) -> Shell | None:
|
# def shell(self) -> Shell | None:
|
||||||
"""Return the Shell"""
|
# """Return the Shell"""
|
||||||
return Shape.get_single_shape(self, "Shell")
|
# return Shape.get_single_shape(self, "Shell")
|
||||||
|
|
||||||
def shells(self) -> ShapeList[Shell]:
|
# def shells(self) -> ShapeList[Shell]:
|
||||||
"""shells - all the shells in this Shape"""
|
# """shells - all the shells in this Shape"""
|
||||||
return Shape.get_shape_list(self, "Shell")
|
# return Shape.get_shape_list(self, "Shell")
|
||||||
|
|
||||||
def _wrap_edge(
|
def _wrap_edge(
|
||||||
self,
|
self,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue