Skip to content

Commit

Permalink
Refactored topology.py ready to split into multiple modules
Browse files Browse the repository at this point in the history
  • Loading branch information
gumyr committed Dec 9, 2024
1 parent 36a89ea commit d1de2a6
Show file tree
Hide file tree
Showing 14 changed files with 1,865 additions and 1,777 deletions.
19 changes: 13 additions & 6 deletions src/build123d/build_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -429,23 +429,30 @@ def _add_to_context(
if mode == Mode.ADD:
if self._obj is None:
if len(typed[self._shape]) == 1:
self._obj = typed[self._shape][0]
combined = typed[self._shape][0]
else:
self._obj = (
combined = (
typed[self._shape].pop().fuse(*typed[self._shape])
)
else:
self._obj = self._obj.fuse(*typed[self._shape])
combined = self._obj.fuse(*typed[self._shape])
elif mode == Mode.SUBTRACT:
if self._obj is None:
raise RuntimeError("Nothing to subtract from")
self._obj = self._obj.cut(*typed[self._shape])
combined = self._obj.cut(*typed[self._shape])
elif mode == Mode.INTERSECT:
if self._obj is None:
raise RuntimeError("Nothing to intersect with")
self._obj = self._obj.intersect(*typed[self._shape])
combined = self._obj.intersect(*typed[self._shape])
elif mode == Mode.REPLACE:
self._obj = Compound(list(typed[self._shape]))
combined = self._sub_class(list(typed[self._shape]))

# If the boolean operation created a list, convert back
self._obj = (
self._sub_class(combined)
if isinstance(combined, list)
else combined
)

if self._obj is not None and clean:
self._obj = self._obj.clean()
Expand Down
18 changes: 10 additions & 8 deletions src/build123d/drafting.py
Original file line number Diff line number Diff line change
Expand Up @@ -439,23 +439,25 @@ def __init__(
overage = shaft_length + draft.pad_around_text + label_length / 2
label_u_values = [0.5, -overage / path_length, 1 + overage / path_length]

# d_lines = Sketch(children=arrows[0])
d_lines = {}
# for arrow_pair in arrow_shapes:
for u_value in label_u_values:
d_line = Sketch()
for add_arrow, arrow_shape in zip(arrows, arrow_shapes):
if add_arrow:
d_line += arrow_shape
select_arrow_shapes = [
arrow_shape
for add_arrow, arrow_shape in zip(arrows, arrow_shapes)
if add_arrow
]
d_line = Sketch(select_arrow_shapes)
flip_label = path_obj.tangent_at(u_value).get_angle(Vector(1, 0, 0)) >= 180
loc = Draft._sketch_location(path_obj, u_value, flip_label)
placed_label = label_shape.located(loc)
self_intersection = d_line.intersect(placed_label).area
self_intersection = Sketch.intersect(d_line, placed_label).area
d_line += placed_label
bbox_size = d_line.bounding_box().size

# Minimize size while avoiding intersections
common_area = 0.0 if sketch is None else d_line.intersect(sketch).area
common_area = (
0.0 if sketch is None else Sketch.intersect(d_line, sketch).area
)
common_area += self_intersection
score = (d_line.area - 10 * common_area) / bbox_size.X
d_lines[d_line] = score
Expand Down
23 changes: 10 additions & 13 deletions src/build123d/exporters.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,17 +55,14 @@
from OCP.TopExp import TopExp_Explorer # type: ignore
from typing_extensions import Self

from build123d.build_enums import Unit
from build123d.geometry import TOLERANCE, Color
from build123d.build_enums import Unit, GeomType
from build123d.geometry import TOLERANCE, Color, Vector, VectorLike
from build123d.topology import (
BoundBox,
Compound,
Edge,
Wire,
GeomType,
Shape,
Vector,
VectorLike,
)
from build123d.build_common import UNITS_PER_METER

Expand Down Expand Up @@ -682,7 +679,7 @@ def _convert_line(self, edge: Edge, attribs: dict):

def _convert_circle(self, edge: Edge, attribs: dict):
"""Converts a Circle object into a DXF circle entity."""
curve = edge._geom_adaptor()
curve = edge.geom_adaptor()
circle = curve.Circle()
center = self._convert_point(circle.Location())
radius = circle.Radius()
Expand Down Expand Up @@ -710,7 +707,7 @@ def _convert_circle(self, edge: Edge, attribs: dict):

def _convert_ellipse(self, edge: Edge, attribs: dict):
"""Converts an Ellipse object into a DXF ellipse entity."""
geom = edge._geom_adaptor()
geom = edge.geom_adaptor()
ellipse = geom.Ellipse()
minor_radius = ellipse.MinorRadius()
major_radius = ellipse.MajorRadius()
Expand Down Expand Up @@ -743,7 +740,7 @@ def _convert_bspline(self, edge: Edge, attribs):

# This pulls the underlying Geom_BSplineCurve out of the Edge.
# The adaptor also supplies a parameter range for the curve.
adaptor = edge._geom_adaptor()
adaptor = edge.geom_adaptor()
curve = adaptor.Curve().Curve()
u1 = adaptor.FirstParameter()
u2 = adaptor.LastParameter()
Expand Down Expand Up @@ -1157,7 +1154,7 @@ def _path_point(self, pt: Union[gp_Pnt, Vector]) -> complex:
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

def _line_segment(self, edge: Edge, reverse: bool) -> PT.Line:
curve = edge._geom_adaptor()
curve = edge.geom_adaptor()
fp = curve.FirstParameter()
lp = curve.LastParameter()
(u0, u1) = (lp, fp) if reverse else (fp, lp)
Expand Down Expand Up @@ -1187,7 +1184,7 @@ def _line_element(self, edge: Edge) -> ET.Element:

def _circle_segments(self, edge: Edge, reverse: bool) -> list[PathSegment]:
# pylint: disable=too-many-locals
curve = edge._geom_adaptor()
curve = edge.geom_adaptor()
circle = curve.Circle()
radius = circle.Radius()
x_axis = circle.XAxis().Direction()
Expand Down Expand Up @@ -1215,7 +1212,7 @@ def _circle_segments(self, edge: Edge, reverse: bool) -> list[PathSegment]:
def _circle_element(self, edge: Edge) -> ET.Element:
"""Converts a Circle object into an SVG circle element."""
if edge.is_closed:
curve = edge._geom_adaptor()
curve = edge.geom_adaptor()
circle = curve.Circle()
radius = circle.Radius()
center = circle.Location()
Expand All @@ -1233,7 +1230,7 @@ def _circle_element(self, edge: Edge) -> ET.Element:

def _ellipse_segments(self, edge: Edge, reverse: bool) -> list[PathSegment]:
# pylint: disable=too-many-locals
curve = edge._geom_adaptor()
curve = edge.geom_adaptor()
ellipse = curve.Ellipse()
minor_radius = ellipse.MinorRadius()
major_radius = ellipse.MajorRadius()
Expand Down Expand Up @@ -1276,7 +1273,7 @@ def _bspline_segments(self, edge: Edge, reverse: bool) -> list[PathSegment]:

# This pulls the underlying Geom_BSplineCurve out of the Edge.
# The adaptor also supplies a parameter range for the curve.
adaptor = edge._geom_adaptor()
adaptor = edge.geom_adaptor()
spline = adaptor.Curve().Curve()
u1 = adaptor.FirstParameter()
u2 = adaptor.LastParameter()
Expand Down
2 changes: 1 addition & 1 deletion src/build123d/geometry.py
Original file line number Diff line number Diff line change
Expand Up @@ -963,7 +963,7 @@ def find_outside_box_2d(bb1: BoundBox, bb2: BoundBox) -> Optional[BoundBox]:
return result

@classmethod
def _from_topo_ds(
def from_topo_ds(
cls,
shape: TopoDS_Shape,
tolerance: float = None,
Expand Down
2 changes: 1 addition & 1 deletion src/build123d/importers.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ def import_brep(file_name: Union[PathLike, str, bytes]) -> Shape:
if shape.IsNull():
raise ValueError(f"Could not import {file_name}")

return Shape.cast(shape)
return Compound.cast(shape)


def import_step(filename: Union[PathLike, str, bytes]) -> Compound:
Expand Down
2 changes: 1 addition & 1 deletion src/build123d/objects_sketch.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
Vector,
VectorLike,
to_align_offset,
TOLERANCE,
)
from build123d.topology import (
Compound,
Expand All @@ -52,7 +53,6 @@
Sketch,
Wire,
tuplify,
TOLERANCE,
topo_explore_common_vertex,
)

Expand Down
13 changes: 11 additions & 2 deletions src/build123d/operations_generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -904,7 +904,7 @@ def scale(

def split(
objects: Union[SplitType, Iterable[SplitType]] = None,
bisect_by: Union[Plane, Face] = Plane.XZ,
bisect_by: Union[Plane, Face, Shell] = Plane.XZ,
keep: Keep = Keep.TOP,
mode: Mode = Mode.REPLACE,
):
Expand Down Expand Up @@ -937,7 +937,16 @@ def split(

new_objects = []
for obj in object_list:
new_objects.append(obj.split(bisect_by, keep))
bottom = None
if keep == Keep.BOTH:
top, bottom = obj.split(bisect_by, keep)
else:
top = obj.split(bisect_by, keep)
for subpart in [top, bottom]:
if isinstance(subpart, Iterable):
new_objects.extend(subpart)
elif subpart is not None:
new_objects.append(subpart)

if context is not None:
context._add_to_context(*new_objects, mode=mode)
Expand Down
9 changes: 7 additions & 2 deletions src/build123d/operations_part.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,10 @@ def extrude(
context._add_to_context(*new_solids, clean=clean, mode=mode)
else:
if len(new_solids) > 1:
new_solids = [new_solids.pop().fuse(*new_solids)]
fused_solids = new_solids.pop().fuse(*new_solids)
new_solids = (
fused_solids if isinstance(fused_solids, list) else [fused_solids]
)
if clean:
new_solids = [solid.clean() for solid in new_solids]

Expand Down Expand Up @@ -597,7 +600,9 @@ def thicken(
)
for direction in [1, -1] if both else [1]:
new_solids.append(
face.thicken(depth=amount, normal_override=face_normal * direction)
Solid.thicken(
face, depth=amount, normal_override=face_normal * direction
)
)

if context is not None:
Expand Down
3 changes: 1 addition & 2 deletions src/build123d/operations_sketch.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,8 @@
Sketch,
topo_explore_connected_edges,
topo_explore_common_vertex,
TOLERANCE,
)
from build123d.geometry import Vector
from build123d.geometry import Vector, TOLERANCE
from build123d.build_common import flatten_sequence, validate_inputs
from build123d.build_sketch import BuildSketch
from scipy.spatial import Voronoi
Expand Down
Loading

0 comments on commit d1de2a6

Please sign in to comment.