diff --git a/cadquery/freecad_impl/geom.py b/cadquery/freecad_impl/geom.py index b73a721..9b560b3 100644 --- a/cadquery/freecad_impl/geom.py +++ b/cadquery/freecad_impl/geom.py @@ -73,12 +73,12 @@ class Vector(object): if len(args) == 3: fV = FreeCAD.Base.Vector(args[0],args[1],args[2]) elif len(args) == 1: - if type(args[0]) is tuple: - fV = FreeCAD.Base.Vector(args[0][0],args[0][1],args[0][2]) - elif type(args[0] is FreeCAD.Base.Vector): - fV = args[0] - elif type(args[0] is Vector): + if isinstance(args[0], Vector): fV = args[0].wrapped + elif isinstance(args[0], tuple): + fV = FreeCAD.Base.Vector(args[0][0],args[0][1],args[0][2]) + elif isinstance(args[0], FreeCAD.Base.Vector): + fV = args[0] else: fV = args[0] else: @@ -251,10 +251,10 @@ class Plane: #origin, xDir, normal 'XY' : Plane(Vector(origin),Vector((1,0,0)),Vector((0,0,1))), 'YZ' : Plane(Vector(origin),Vector((0,1,0)),Vector((1,0,0))), - 'ZX': Plane(Vector(origin), Vector((0, 0, 1)), Vector((0, 1, 0))), + 'ZX': Plane(origin, (0, 0, 1), (0, 1, 0)), 'XZ' : Plane(Vector(origin),Vector((1,0,0)),Vector((0,-1,0))), - 'YX': Plane(Vector(origin), Vector((0, 1, 0)), Vector((0, 0, -1))), - 'ZY': Plane(Vector(origin), Vector((0, 0, 1)), Vector((-1, 0, 0))), + 'YX': Plane(origin, (0, 1, 0), (0, 0, -1)), + 'ZY': Plane(origin, (0, 0, 1), (-1, 0, 0)), 'front': Plane(Vector(origin),Vector((1,0,0)),Vector((0,0,1))), 'back': Plane(Vector(origin),Vector((-1,0,0)),Vector((0,0,-1))), 'left': Plane(Vector(origin),Vector((0,0,1)),Vector((-1,0,0))), @@ -276,10 +276,28 @@ class Plane: def YZ(cls,origin=(0,0,0),xDir=Vector(1,0,0)): return Plane.named('YZ',origin) + @classmethod + def ZX(cls, origin=(0, 0, 0), xDir=Vector(0, 0, 1)): + plane = Plane.named('ZX', origin) + plane._setPlaneDir(xDir) + return plane + @classmethod def XZ(cls,origin=(0,0,0),xDir=Vector(1,0,0)): return Plane.named('XZ',origin) + @classmethod + def YX(cls, origin=(0, 0, 0), xDir=Vector(0, 1, 0)): + plane = Plane.named('YX', origin) + plane._setPlaneDir(xDir) + return plane + + @classmethod + def ZY(cls, origin=(0, 0, 0), xDir=Vector(0, 0, 1)): + plane = Plane.named('ZY', origin) + plane._setPlaneDir(xDir) + return plane + @classmethod def front(cls,origin=(0,0,0),xDir=Vector(1,0,0)): return Plane.named('front',origin) @@ -319,9 +337,14 @@ class Plane: :return: a plane in the global space, with the xDirection of the plane in the specified direction. """ - self.xDir = xDir.normalize() - self.yDir = normal.cross(self.xDir).normalize() + normal = Vector(normal) + if (normal.Length == 0.0): + raise ValueError('normal should be non null') self.zDir = normal.normalize() + xDir = Vector(xDir) + if (xDir.Length == 0.0): + raise ValueError('xDir should be non null') + self._setPlaneDir(xDir) #stupid freeCAD!!!!! multiply has a bug that changes the original also! self.invZDir = self.zDir.multiply(-1.0) @@ -337,7 +360,7 @@ class Plane: :return: void """ - self.origin = originVector + self.origin = Vector(originVector) self._calcTransforms() def setOrigin2d(self,x,y): @@ -359,7 +382,6 @@ class Plane: """ self.setOrigin3d(self.toWorldCoords((x,y))) - def isWireInside(self,baseWire,testWire): """ Determine if testWire is inside baseWire, after both wires are projected into the current plane @@ -514,6 +536,12 @@ class Plane: return resultWires + def _setPlaneDir(self, xDir): + """Set the vectors parallel to the plane, i.e. xDir and yDir""" + if (self.zDir.dot(xDir) > 1e-5): + raise ValueError('xDir must be parralel to the plane') + self.xDir = xDir.normalize() + self.yDir = self.zDir.cross(self.xDir).normalize() def _calcTransforms(self): """ diff --git a/tests/TestWorkplanes.py b/tests/TestWorkplanes.py index 54f908e..838b953 100644 --- a/tests/TestWorkplanes.py +++ b/tests/TestWorkplanes.py @@ -7,6 +7,13 @@ from cadquery import * from tests import BaseTest,toTuple +xAxis_ = Vector(1, 0, 0) +yAxis_ = Vector(0, 1, 0) +zAxis_ = Vector(0, 0, 1) +xInvAxis_ = Vector(-1, 0, 0) +yInvAxis_ = Vector(0, -1, 0) +zInvAxis_ = Vector(0, 0, -1) + class TestWorkplanes(BaseTest): def testYZPlaneOrigins(self): @@ -40,8 +47,6 @@ class TestWorkplanes(BaseTest): #origin is always (0,0,0) in local coordinates self.assertTupleAlmostEquals((0,0,0), p.toLocalCoords(p.origin).toTuple() ,2 ) - - def testPlaneBasics(self): p = Plane.XY() #local to world @@ -81,4 +86,40 @@ class TestWorkplanes(BaseTest): p = Plane.XZ(origin=(2,0,2)) r = p.toWorldCoords((1.0,1.0)).toTuple() self.assertTupleAlmostEquals((3.0,0.0,3.0),r ,2 ) - self.assertTupleAlmostEquals((10.0,10.0), p.toLocalCoords(Vector(12.0,0.0,12.0)).toTuple() ,2 ) \ No newline at end of file + self.assertTupleAlmostEquals((10.0,10.0), p.toLocalCoords(Vector(12.0,0.0,12.0)).toTuple() ,2 ) + + def testXYPlaneBasics(self): + p = Plane.named('XY') + self.assertTupleAlmostEquals(p.zDir.toTuple(), zAxis_.toTuple(), 4) + self.assertTupleAlmostEquals(p.xDir.toTuple(), xAxis_.toTuple(), 4) + self.assertTupleAlmostEquals(p.yDir.toTuple(), yAxis_.toTuple(), 4) + + def testYZPlaneBasics(self): + p = Plane.named('YZ') + self.assertTupleAlmostEquals(p.zDir.toTuple(), xAxis_.toTuple(), 4) + self.assertTupleAlmostEquals(p.xDir.toTuple(), yAxis_.toTuple(), 4) + self.assertTupleAlmostEquals(p.yDir.toTuple(), zAxis_.toTuple(), 4) + + def testZXPlaneBasics(self): + p = Plane.named('ZX') + self.assertTupleAlmostEquals(p.zDir.toTuple(), yAxis_.toTuple(), 4) + self.assertTupleAlmostEquals(p.xDir.toTuple(), zAxis_.toTuple(), 4) + self.assertTupleAlmostEquals(p.yDir.toTuple(), xAxis_.toTuple(), 4) + + def testXZPlaneBasics(self): + p = Plane.named('XZ') + self.assertTupleAlmostEquals(p.zDir.toTuple(), yInvAxis_.toTuple(), 4) + self.assertTupleAlmostEquals(p.xDir.toTuple(), xAxis_.toTuple(), 4) + self.assertTupleAlmostEquals(p.yDir.toTuple(), zAxis_.toTuple(), 4) + + def testYXPlaneBasics(self): + p = Plane.named('YX') + self.assertTupleAlmostEquals(p.zDir.toTuple(), zInvAxis_.toTuple(), 4) + self.assertTupleAlmostEquals(p.xDir.toTuple(), yAxis_.toTuple(), 4) + self.assertTupleAlmostEquals(p.yDir.toTuple(), xAxis_.toTuple(), 4) + + def testZYPlaneBasics(self): + p = Plane.named('ZY') + self.assertTupleAlmostEquals(p.zDir.toTuple(), xInvAxis_.toTuple(), 4) + self.assertTupleAlmostEquals(p.xDir.toTuple(), zAxis_.toTuple(), 4) + self.assertTupleAlmostEquals(p.yDir.toTuple(), yAxis_.toTuple(), 4)