diff --git a/cadquery/occ_impl/shapes.py b/cadquery/occ_impl/shapes.py index 4adcacf48..cbba68d76 100644 --- a/cadquery/occ_impl/shapes.py +++ b/cadquery/occ_impl/shapes.py @@ -112,6 +112,7 @@ from math import pi, sqrt from functools import reduce +import warnings TOLERANCE = 1e-6 DEG2RAD = 2 * pi / 360. @@ -809,13 +810,26 @@ def assembleEdges(cls, listOfEdges): """ Attempts to build a wire that consists of the edges in the provided list :param cls: - :param listOfEdges: a list of Edge objects + :param listOfEdges: a list of Edge objects. The edges are not to be consecutive. :return: a wire with the edges assembled + :BRepBuilderAPI_MakeWire::Error() values + :BRepBuilderAPI_WireDone = 0 + :BRepBuilderAPI_EmptyWire = 1 + :BRepBuilderAPI_DisconnectedWire = 2 + :BRepBuilderAPI_NonManifoldWire = 3 """ wire_builder = BRepBuilderAPI_MakeWire() - for edge in listOfEdges: - wire_builder.Add(edge.wrapped) - + + edges_list = TopTools_ListOfShape() + for e in listOfEdges: + edges_list.Append(e.wrapped) + wire_builder.Add(edges_list) + if wire_builder.Error()!=0: + w1 = 'BRepBuilderAPI_MakeWire::IsDone(): returns true if this algorithm contains a valid wire. IsDone returns false if: there are no edges in the wire, or the last edge which you tried to add was not connectable = '+ str(wire_builder.IsDone()) + w2 = 'BRepBuilderAPI_MakeWire::Error(): returns the construction status. BRepBuilderAPI_WireDone if the wire is built, or another value of the BRepBuilderAPI_WireError enumeration indicating why the construction failed = ' + str(wire_builder.Error()) + warnings.warn(w1) + warnings.warn(w2) + return cls(wire_builder.Wire()) @classmethod diff --git a/tests/__init__.py b/tests/__init__.py index bae4439d7..2c0ca15d2 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -59,4 +59,5 @@ def assertTupleAlmostEquals(self, expected, actual, places): 'TestImporters', 'TestJupyter', 'TestWorkplanes', + 'TestAssembleEdges', ] diff --git a/tests/test_cadquery.py b/tests/test_cadquery.py index 64b852372..01562c6e9 100644 --- a/tests/test_cadquery.py +++ b/tests/test_cadquery.py @@ -2139,3 +2139,40 @@ def testSlot2D(self): point = result.faces(">Z").edges(">X").first().val().startPoint().toTuple() self.assertTupleAlmostEquals(point, (0.707106781, 1.414213562, 1.0), decimal_places) + def test_assembleEdges(self): + + # Plate with 5 sides and 2 bumps, one side is not co-planar with the other sides + # Passes an open wire to assembleEdges so that IsDone is true but Error returns 2 to test the warning functionality. + edge_points = [[-7.,-7.,0.], [-3.,-10.,3.], [7.,-7.,0.], [7.,7.,0.], [-7.,7.,0.]] + edge_wire = Workplane('XY').polyline([(-7.,-7.), (7.,-7.), (7.,7.), (-7.,7.)]) + edge_wire = edge_wire.add(Workplane('YZ').workplane().transformed(offset=Vector(0, 0, -7), rotate=Vector(0, 45, 0)).spline([(-7.,0.), (3,-3), (7.,0.)])) + edge_wire = [o.vals()[0] for o in edge_wire.all()] + edge_wire = Wire.assembleEdges(edge_wire) + + # Embossed star, need to change optional parameters to obtain nice looking result. + r1=3. + r2=10. + fn=6 + edge_points = [[r1*math.cos(i * math.pi/fn), r1*math.sin(i * math.pi/fn)] if i%2==0 else [r2*math.cos(i * math.pi/fn), r2*math.sin(i * math.pi/fn)] for i in range(2*fn+1)] + edge_wire = Workplane('XY').polyline(edge_points) + edge_wire = [o.vals()[0] for o in edge_wire.all()] + edge_wire = Wire.assembleEdges(edge_wire) + + # Points on hexagonal pattern coordinates, use of pushpoints. + r1 = 1. + fn = 6 + edge_points = [[r1*math.cos(i * 2*math.pi/fn), r1*math.sin(i * 2*math.pi/fn)] for i in range(fn+1)] + surface_points = [[0.25,0,0.75], [-0.25,0,0.75], [0,0.25,0.75], [0,-0.25,0.75], [0,0,2]] + edge_wire = Workplane('XY').polyline(edge_points) + edge_wire = [o.vals()[0] for o in edge_wire.all()] + edge_wire = Wire.assembleEdges(edge_wire) + + # Gyroïd, all edges are splines on different workplanes. + edge_points = [[[3.54, 3.54], [1.77, 0.0], [3.54, -3.54]], [[-3.54, -3.54], [0.0, -1.77], [3.54, -3.54]], [[-3.54, -3.54], [0.0, -1.77], [3.54, -3.54]], [[-3.54, -3.54], [-1.77, 0.0], [-3.54, 3.54]], [[3.54, 3.54], [0.0, 1.77], [-3.54, 3.54]], [[3.54, 3.54], [0.0, 1.77], [-3.54, 3.54]]] + plane_list = ['XZ', 'XY', 'YZ', 'XZ', 'YZ', 'XY'] + offset_list = [-3.54, 3.54, 3.54, 3.54, -3.54, -3.54] + edge_wire = Workplane(plane_list[0]).workplane(offset=-offset_list[0]).spline(edge_points[0]) + for i in range(len(edge_points)-1): + edge_wire = edge_wire.add(Workplane(plane_list[i+1]).workplane(offset=-offset_list[i+1]).spline(edge_points[i+1])) + edge_wire = [o.vals()[0] for o in edge_wire.all()] + edge_wire = Wire.assembleEdges(edge_wire)