diff --git a/cadquery/cq.py b/cadquery/cq.py index 59a1180..7293813 100644 --- a/cadquery/cq.py +++ b/cadquery/cq.py @@ -742,6 +742,19 @@ class CQ(object): return self.newObject([o.rotate(axisStartPoint, axisEndPoint, angleDegrees) for o in self.objects]) + def mirror(self, mirrorPlane="XY", basePointVector=(0, 0, 0)): + """ + Mirror a single CQ object. This operation is the same as in the FreeCAD PartWB's mirroring + + :param mirrorPlane: the plane to mirror about + :type mirrorPlane: string, one of "XY", "YX", "XZ", "ZX", "YZ", "ZY" the planes + :param basePointVector: the base point to mirror about + :type basePointVector: tuple + """ + newS = self.newObject([self.objects[0].mirror(mirrorPlane, basePointVector)]) + return newS.first() + + def translate(self, vec): """ Returns a copy of all of the items on the stack moved by the specified translation vector. diff --git a/cadquery/freecad_impl/shapes.py b/cadquery/freecad_impl/shapes.py index 76af1c1..12d410b 100644 --- a/cadquery/freecad_impl/shapes.py +++ b/cadquery/freecad_impl/shapes.py @@ -185,8 +185,22 @@ class Shape(object): return self.wrapped.isValid() def BoundingBox(self): + self.wrapped.tessellate(0.000001) return BoundBox(self.wrapped.BoundBox) + def mirror(self, mirrorPlane="XY", basePointVector=(0, 0, 0)): + if mirrorPlane == "XY" or mirrorPlane== "YX": + mirrorPlaneNormalVector = FreeCAD.Base.Vector(0, 0, 1) + elif mirrorPlane == "XZ" or mirrorPlane == "ZX": + mirrorPlaneNormalVector = FreeCAD.Base.Vector(0, 1, 0) + elif mirrorPlane == "YZ" or mirrorPlane == "ZY": + mirrorPlaneNormalVector = FreeCAD.Base.Vector(1, 0, 0) + + if type(basePointVector) == tuple: + basePointVector = Vector(basePointVector) + + return Shape.cast(self.wrapped.mirror(basePointVector.wrapped, mirrorPlaneNormalVector)) + def Center(self): # A Part.Shape object doesn't have the CenterOfMass function, but it's wrapped Solid(s) does if isinstance(self.wrapped, FreeCADPart.Shape):