the test cases pass now at least

This commit is contained in:
Dave Cowden 2013-04-16 22:29:06 -04:00
parent 3f7d38cdeb
commit 26cd0a443d
17 changed files with 1576 additions and 133 deletions

File diff suppressed because it is too large Load Diff

8
cadquery/README.txt Normal file
View File

@ -0,0 +1,8 @@
***
Core CadQuery implementation.
No files should depend on or import FreeCAD , pythonOCC, or other CAD Kernel libraries!!!
Dependencies should be on the classes provided by implementation packages, which in turn
can depend on CAD libraries.
***

View File

@ -19,20 +19,20 @@
#these items point to the freecad implementation
from .freecad_impl.geom import Plane,BoundBox,Vector
from .freecad_impl.shapes import Shape,Vertex,Edge,Wire,Solid,Shell,Compound
from .freecad_impl.exporters import SvgExporter, AmfExporter, JsonExporter
from .freecad_impl.geom import Plane,BoundBox,Vector,Matrix,sortWiresByBuildOrder
from .freecad_impl.shapes import Shape,Vertex,Edge,Face,Wire,Solid,Shell,Compound
from .freecad_impl import exporters
#these items are the common implementation
from .CQ import CQ
from .workplane import Workplane
from . import plugins
#the order of these matter
from . import selectors
from .CQ import CQ,CQContext,Workplane
__all__ = [
'CQ','Workplane','plugins','selectors','Plane','BoundBox',
'Shape','Vertex','Edge','Wire','Solid','Shell','Compound',
'SvgExporter','AmfExporter','JsonExporter',
'CQ','Workplane','plugins','selectors','Plane','BoundBox','Matrix','Vector','sortWiresByBuildOrder',
'Shape','Vertex','Edge','Wire','Solid','Shell','Compound','exporters',
'plugins'
]

View File

@ -0,0 +1,3 @@
It is ok for files in this directory to import FreeCAD, FreeCAD.Base, and FreeCAD.Part.
Other modules should _not_ depend on FreeCAD

View File

@ -17,6 +17,9 @@
License along with this library; If not, see <http://www.gnu.org/licenses/>
"""
import FreeCAD
from FreeCAD import Drawing
try:
import xml.etree.cElementTree as ET
except ImportError:
@ -54,15 +57,8 @@ def guessUnitOfMeasure(shape):
return UNITS.MM
class Exporter(object):
def export(self):
"""
return a string representing the model exported in the specified format
"""
raise NotImplementedError()
class AmfExporter(Exporter):
class AmfExporter(object):
def __init__(self,tessellation):
self.units = "mm"
@ -105,7 +101,7 @@ class AmfExporter(Exporter):
three.js JSON object notation
https://github.com/mrdoob/three.js/wiki/JSON-Model-format-3.0
"""
class JsonExporter(Exporter):
class JsonExporter(object):
def __init__(self):
self.vertices = [];
@ -135,10 +131,6 @@ class JsonExporter(Exporter):
'nFaces' : self.nFaces
};
class SvgExporter(Exporter):
def export(self):
pass
def getPaths(freeCadSVG):
"""
@ -240,11 +232,15 @@ def getSVG(shape,opts=None):
#)
return svg
def exportSVG(shape, fileName):
"""
accept a cadquery shape, and export it to the provided file
TODO: should use file-like objects, not a fileName, and/or be able to return a string instead
export a view of a part to svg
"""
svg = getSVG(shape)
svg = getSVG(shape.val().wrapped)
f = open(fileName,'w')
f.write(svg)
f.close()

View File

@ -1,20 +1,20 @@
"""
Copyright (C) 2011-2013 Parametric Products Intellectual Holdings, LLC
Copyright (C) 2011-2013 Parametric Products Intellectual Holdings, LLC
This file is part of CadQuery.
CadQuery is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This file is part of CadQuery.
CadQuery is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
CadQuery is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
CadQuery is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; If not, see <http://www.gnu.org/licenses/>
You should have received a copy of the GNU Lesser General Public
License along with this library; If not, see <http://www.gnu.org/licenses/>
"""
import math,sys
@ -48,33 +48,6 @@ def sortWiresByBuildOrder(wireList,plane,result=[]):
return result
def sortWiresByBuildOrderOld(wireList,plane,result=[]):
"""
Tries to determine how wires should be combined into faces.
Assume:
The wires make up one or more faces, which could have 'holes'
Outer wires are listed ahead of inner wires
there are no wires inside wires inside wires ( IE, islands -- we can deal with that later on )
none of the wires are construction wires
Compute:
one or more sets of wires, with the outer wire listed first, and inner ones
Returns, list of lists.
"""
outerWire = wireList.pop(0)
remainingWires = list(wireList)
childWires = []
for w in wireList:
if plane.isWireInside(outerWire,w):
childWires.append(remainingWires.pop(0))
else:
#doesnt match, assume this wire is a new outer
result.append([outerWire] + childWires)
return sortWiresByBuildOrder(remainingWires,plane,result)
result.append([outerWire] + childWires)
return result
class Vector(object):
"""
Create a 3-dimensional vector
@ -212,6 +185,25 @@ class Vector(object):
def __eq__(self,other):
return self.wrapped.__eq__(other)
class Matrix:
"""
A 3d , 4x4 transformation matrix.
Used to move geometry in space.
"""
def __init__(self,matrix=None):
if matrix == None:
self.wrapped = FreeCAD.Base.Matrix()
else:
self.wrapped = matrix
def rotateX(self,angle):
self.wrapped.rotateX(angle)
def rotateY(self,angle):
self.wrapped.rotateY(angle)
class Plane:
"""
A 2d coordinate system in space, with the x-y axes on the a plane, and a particular point as the origin.
@ -329,6 +321,7 @@ class Plane:
self.setOrigin3d(origin)
def setOrigin3d(self,originVector):
"""
Move the origin of the plane, leaving its orientation and xDirection unchanged.
@ -417,6 +410,7 @@ class Plane:
else:
raise ValueError("Dont know how to convert type %s to local coordinates" % str(type(obj)))
def toWorldCoords(self, tuplePoint):
"""
Convert a point in local coordinates to global coordinates.
@ -433,6 +427,7 @@ class Plane:
v = Vector(tuplePoint[0],tuplePoint[1],tuplePoint[2])
return Vector(self.rG.multiply(v.wrapped))
def rotated(self,rotate=Vector(0,0,0)):
"""
returns a copy of this plane, rotated about the specified axes, as measured from horizontal
@ -453,7 +448,7 @@ class Plane:
rotate = rotate.multiply(math.pi / 180.0 )
#compute rotation matrix
m = Base.Matrix()
m = FreeCAD.Base.Matrix()
m.rotateX(rotate.x)
m.rotateY(rotate.y)
m.rotateZ(rotate.z)
@ -473,7 +468,7 @@ class Plane:
#ok i will be really honest-- i cannot understand exactly why this works
#something bout the order of the transaltion and the rotation.
# the double-inverting is strange, and i dont understand it.
r = Base.Matrix()
r = FreeCAD.Base.Matrix()
#forward transform must rotate and adjust for origin
(r.A11, r.A12, r.A13 ) = (self.xDir.x, self.xDir.y, self.xDir.z )
@ -484,7 +479,14 @@ class Plane:
(invR.A14,invR.A24,invR.A34) = (self.origin.x,self.origin.y,self.origin.z)
( self.rG,self.fG ) = ( invR,invR.inverse() )
def computeTransform(self,tMatrix):
"""
Computes the 2-d projection of the supplied matrix
"""
rm = self.fG.multiply(tMatrix.wrapped).multiply(self.rG)
return Matrix(rm)
class BoundBox(object):
"A BoundingBox for an object or set of objects. Wraps the FreeCAD one"

View File

@ -47,7 +47,7 @@
object each one returns, so these are better grouped by the type of object they return.
(who would know that Part.makeCircle() returns an Edge, but Part.makePolygon() returns a Wire ?
"""
from cadquery import Vector
from cadquery import Vector,BoundBox
import FreeCAD
import FreeCAD.Part
@ -65,7 +65,7 @@ class Shape(object):
def cast(cls,obj,forConstruction = False):
"Returns the right type of wrapper, given a FreeCAD object"
s = obj.ShapeType
if type(obj) == Base.Vector:
if type(obj) == FreeCAD.Base.Vector:
return Vector(obj)
tr = None
@ -99,7 +99,9 @@ class Shape(object):
tr.forConstruction = forConstruction
return tr
#TODO: all these should move into the exporters folder.
#we dont need a bunch of exporting code stored in here!
#
def exportStl(self,fileName):
self.wrapped.exportStl(fileName)
@ -254,6 +256,7 @@ class Shape(object):
def transformShape(self,tMatrix):
"""
tMatrix is a matrix object.
returns a copy of the ojbect, transformed by the provided matrix,
with all objects keeping their type
"""
@ -265,6 +268,8 @@ class Shape(object):
def transformGeometry(self,tMatrix):
"""
tMatrix is a matrix object.
returns a copy of the object, but with geometry transformed insetad of just
rotated.
@ -311,9 +316,9 @@ class Edge(Shape):
#self.endPoint = None
self.edgetypes= {
Part.Line : 'LINE',
Part.ArcOfCircle : 'ARC',
Part.Circle : 'CIRCLE'
FreeCAD.Part.Line : 'LINE',
FreeCAD.Part.ArcOfCircle : 'ARC',
FreeCAD.Part.Circle : 'CIRCLE'
}
def geomType(self):
@ -363,7 +368,7 @@ class Edge(Shape):
@classmethod
def makeCircle(cls,radius,pnt=(0,0,0),dir=(0,0,1),angle1=360.0,angle2=360):
return Edge(Part.makeCircle(radius,toVector(pnt),toVector(dir),angle1,angle2))
return Edge(FreeCAD.Part.makeCircle(radius,toVector(pnt),toVector(dir),angle1,angle2))
@classmethod
def makeSpline(cls,listOfVector):
@ -375,7 +380,7 @@ class Edge(Shape):
"""
vecs = [v.wrapped for v in listOfVector]
spline = Part.BSplineCurve()
spline = FreeCAD.Part.BSplineCurve()
spline.interpolate(vecs,False)
return Edge(spline.toShape())
@ -389,7 +394,7 @@ class Edge(Shape):
:param v3: end vector
:return: an edge object through the three points
"""
arc = Part.Arc(v1.wrapped,v2.wrapped,v3.wrapped)
arc = FreeCAD.Part.Arc(v1.wrapped,v2.wrapped,v3.wrapped)
e = Edge(arc.toShape())
return e #arcane and undocumented, this creates an Edge object
@ -401,7 +406,7 @@ class Edge(Shape):
:param v2: Vector that represents the second point
:return: A linear edge between the two provided points
"""
return Edge(Part.makeLine(v1.toTuple(),v2.toTuple() ))
return Edge(FreeCAD.Part.makeLine(v1.toTuple(),v2.toTuple() ))
class Wire(Shape):
@ -420,7 +425,7 @@ class Wire(Shape):
:param listOfWires:
:return:
"""
return Shape.cast(Part.Wire([w.wrapped for w in listOfWires]))
return Shape.cast(FreeCAD.Part.Wire([w.wrapped for w in listOfWires]))
@classmethod
def assembleEdges(cls,listOfEdges):
@ -432,7 +437,7 @@ class Wire(Shape):
"""
fCEdges = [a.wrapped for a in listOfEdges]
wa = Wire( Part.Wire(fCEdges) )
wa = Wire( FreeCAD.Part.Wire(fCEdges) )
return wa
@classmethod
@ -444,13 +449,13 @@ class Wire(Shape):
:param normal: vector representing the direction of the plane the circle should lie in
:return:
"""
w = Wire(Part.Wire([Part.makeCircle(radius,center.wrapped,normal.wrapped)]))
w = Wire(FreeCAD.Part.Wire([FreeCAD.Part.makeCircle(radius,center.wrapped,normal.wrapped)]))
return w
@classmethod
def makePolygon(cls,listOfVertices,forConstruction=False):
#convert list of tuples into Vectors.
w = Wire(Part.makePolygon([i.wrapped for i in listOfVertices]))
w = Wire(FreeCAD.Part.makePolygon([i.wrapped for i in listOfVertices]))
w.forConstruction = forConstruction
return w
@ -461,7 +466,7 @@ class Wire(Shape):
By default a cylindrical surface is used to create the helix. If
the fourth parameter is set (the apex given in degree) a conical surface is used instead'
"""
return Wire(Part.makeHelix(pitch,height,radius,angle))
return Wire(FreeCAD.Part.makeHelix(pitch,height,radius,angle))
class Face(Shape):
@ -473,9 +478,9 @@ class Face(Shape):
self.facetypes = {
#TODO: bezier,bspline etc
Part.Plane : 'PLANE',
Part.Sphere : 'SPHERE',
Part.Cone : 'CONE'
FreeCAD.Part.Plane : 'PLANE',
FreeCAD.Part.Sphere : 'SPHERE',
FreeCAD.Part.Cone : 'CONE'
}
def geomType(self):
@ -501,7 +506,7 @@ class Face(Shape):
@classmethod
def makePlane(cls,length,width,basePnt=None,dir=None):
return Face(Part.makePlan(length,width,toVector(basePnt),toVector(dir)))
return Face(FreeCAD.Part.makePlan(length,width,toVector(basePnt),toVector(dir)))
@classmethod
def makeRuledSurface(cls,edgeOrWire1,edgeOrWire2,dist=None):
@ -510,7 +515,7 @@ class Face(Shape):
Create a ruled surface out of two edges or wires. If wires are used then
these must have the same
"""
return Shape.cast(Part.makeRuledSurface(edgeOrWire1.obj,edgeOrWire2.obj,dist))
return Shape.cast(FreeCAD.Part.makeRuledSurface(edgeOrWire1.obj,edgeOrWire2.obj,dist))
def cut(self,faceToCut):
"Remove a face from another one"
@ -536,7 +541,7 @@ class Shell(Shape):
@classmethod
def makeShell(cls,listOfFaces):
return Shell(Part.makeShell([i.obj for i in listOfFaces]))
return Shell(FreeCAD.Part.makeShell([i.obj for i in listOfFaces]))
class Solid(Shape):
@ -563,7 +568,7 @@ class Solid(Shape):
makeBox(length,width,height,[pnt,dir]) -- Make a box located\nin pnt with the d
imensions (length,width,height)\nBy default pnt=Vector(0,0,0) and dir=Vector(0,0,1)'
"""
return Shape.cast(Part.makeBox(length,width,height,pnt.wrapped,dir.wrapped))
return Shape.cast(FreeCAD.Part.makeBox(length,width,height,pnt.wrapped,dir.wrapped))
@classmethod
def makeCone(cls,radius1,radius2,height,pnt=Vector(0,0,0),dir=Vector(0,0,1),angleDegrees=360):
@ -572,7 +577,7 @@ class Solid(Shape):
Make a cone with given radii and height\nBy default pnt=Vector(0,0,0),
dir=Vector(0,0,1) and angle=360'
"""
return Shape.cast(Part.makeCone(radius1,radius2,height,pnt.wrapped,dir.wrapped,angleDegrees))
return Shape.cast(FreeCAD.Part.makeCone(radius1,radius2,height,pnt.wrapped,dir.wrapped,angleDegrees))
@classmethod
def makeCylinder(cls,radius,height,pnt=Vector(0,0,0),dir=Vector(0,0,1),angleDegrees=360):
@ -581,7 +586,7 @@ class Solid(Shape):
Make a cylinder with a given radius and height
By default pnt=Vector(0,0,0),dir=Vector(0,0,1) and angle=360'
"""
return Shape.cast(Part.makeCylinder(radius,height,pnt.wrapped,dir.wrapped,angleDegrees))
return Shape.cast(FreeCAD.Part.makeCylinder(radius,height,pnt.wrapped,dir.wrapped,angleDegrees))
@classmethod
def makeTorus(cls,radius1,radius2,pnt=None,dir=None,angleDegrees1=None,angleDegrees2=None):
@ -591,7 +596,7 @@ class Solid(Shape):
By default pnt=Vector(0,0,0),dir=Vector(0,0,1),angle1=0
,angle1=360 and angle=360'
"""
return Shape.cast(Part.makeTorus(radius1,radius2,pnt,dir,angleDegrees1,angleDegrees2))
return Shape.cast(FreeCAD.Part.makeTorus(radius1,radius2,pnt,dir,angleDegrees1,angleDegrees2))
@classmethod
def sweep(cls,profileWire,pathWire):
@ -610,11 +615,11 @@ class Solid(Shape):
"""
makes a loft from a list of wires
The wires will be converted into faces when possible-- it is presumed that nobody ever actually
wants to make an infinitely thin shell for a real part.
wants to make an infinitely thin shell for a real FreeCAD.Part.
"""
#the True flag requests building a solid instead of a shell.
return Shape.cast(Part.makeLoft([i.wrapped for i in listOfWire],True))
return Shape.cast(FreeCAD.Part.makeLoft([i.wrapped for i in listOfWire],True))
@classmethod
def makeWedge(cls,xmin,ymin,zmin,z2min,x2min,xmax,ymax,zmax,z2max,x2max,pnt=None,dir=None):
@ -624,7 +629,7 @@ class Solid(Shape):
Make a wedge located in pnt\nBy default pnt=Vector(0,0,0) and dir=Vec
tor(0,0,1)'
"""
return Shape.cast(Part.makeWedge(xmin,ymin,zmin,z2min,x2min,xmax,ymax,zmax,z2max,x2max,pnt,dir))
return Shape.cast(FreeCAD.Part.makeWedge(xmin,ymin,zmin,z2min,x2min,xmax,ymax,zmax,z2max,x2max,pnt,dir))
@classmethod
def makeSphere(cls,radius,pnt=None,angleDegrees1=None,angleDegrees2=None,angleDegrees3=None):
@ -633,7 +638,7 @@ class Solid(Shape):
Make a sphere with a giv
en radius\nBy default pnt=Vector(0,0,0), dir=Vector(0,0,1), angle1=0, angle2=90 and angle3=360'
"""
return Solid(Part.makeSphere(radius,pnt,angleDegrees1,angleDegrees2,angleDegrees3))
return Solid(FreeCAD.Part.makeSphere(radius,pnt,angleDegrees1,angleDegrees2,angleDegrees3))
@classmethod
def extrudeLinearWithRotation(cls,outerWire,innerWires,vecCenter, vecNormal,angleDegrees):
@ -674,12 +679,12 @@ class Solid(Shape):
#make a ruled surface for each set of wires
sides = []
for w1,w2 in zip(startWires,endWires):
rs = Part.makeRuledSurface(w1,w2)
rs = FreeCAD.Part.makeRuledSurface(w1,w2)
sides.append(rs)
#make faces for the top and bottom
startFace = Part.Face(startWires)
endFace = Part.Face(endWires)
startFace = FreeCAD.Part.Face(startWires)
endFace = FreeCAD.Part.Face(endWires)
#collect all the faces from the sides
faceList = [ startFace]
@ -687,8 +692,8 @@ class Solid(Shape):
faceList.extend(s.Faces)
faceList.append(endFace)
shell = Part.makeShell(faceList)
solid = Part.makeSolid(shell)
shell = FreeCAD.Part.makeShell(faceList)
solid = FreeCAD.Part.makeSolid(shell)
return Shape.cast(solid)
@classmethod
@ -725,7 +730,7 @@ class Solid(Shape):
for w in innerWires:
freeCADWires.append(w.wrapped)
f = Part.Face(freeCADWires)
f = FreeCAD.Part.Face(freeCADWires)
result = f.extrude(vecNormal.wrapped)
return Shape.cast(result)
@ -789,7 +794,7 @@ class Compound(Shape):
Create a compound out of a list of shapes
"""
solids = [s.wrapped for s in listOfShapes]
c = Part.Compound(solids)
c = FreeCAD.Part.Compound(solids)
return Shape.cast( c)
def fuse(self,toJoin):

View File

@ -19,6 +19,7 @@
import re
import math
from cadquery import Vector,Edge,Vertex,Face,Solid,Shell,Compound
class Selector(object):
"""

View File

@ -18,8 +18,8 @@
"""
import math
from . import CQ
from cadquery import Vector
from cadquery import Vector,CQ,CQContext,Plane,Wire
class Workplane(CQ):
"""

16
runtests.py Normal file
View File

@ -0,0 +1,16 @@
import sys
from tests import *
import cadquery
import unittest
#if you are on python 2.7, you can use -m uniitest discover.
#but this is required for python 2.6.6 on windows. FreeCAD0.12 will not load
#on py 2.7.x on win
suite = unittest.TestSuite()
suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestCadObjects.TestCadObjects))
suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestWorkplanes.TestWorkplanes))
suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestCQSelectors.TestCQSelectors))
suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestCadQuery.TestCadQuery))
unittest.TextTestRunner().run(suite)

1
tests/README.txt Normal file
View File

@ -0,0 +1 @@
It is OK for tests to import implementations like FreeCAD directly.

View File

@ -13,8 +13,9 @@ import unittest,sys
import os.path
#my modules
from TestBase import *
from tests import BaseTest,makeUnitCube,makeUnitSquareWire
from cadquery import *
from cadquery import selectors
class TestCQSelectors(BaseTest):
@ -122,8 +123,8 @@ class TestCQSelectors(BaseTest):
#faces parallel to Z axis
self.assertEqual(2, c.faces("|Z").size())
#TODO: provide short names for ParallelDirSelector
self.assertEqual(2, c.faces(ParallelDirSelector(Vector((0,0,1)))).size()) #same thing as above
self.assertEqual(2, c.faces(ParallelDirSelector(Vector((0,0,-1)))).size()) #same thing as above
self.assertEqual(2, c.faces(selectors.ParallelDirSelector(Vector((0,0,1)))).size()) #same thing as above
self.assertEqual(2, c.faces(selectors.ParallelDirSelector(Vector((0,0,-1)))).size()) #same thing as above
#just for fun, vertices on faces parallel to z
self.assertEqual(8, c.faces("|Z").vertices().size())
@ -164,17 +165,17 @@ class TestCQSelectors(BaseTest):
#nearest vertex to origin is (0,0,0)
t = Vector(0.1,0.1,0.1)
v = c.vertices(NearestToPointSelector(t)).vals()[0]
v = c.vertices(selectors.NearestToPointSelector(t)).vals()[0]
self.assertTupleAlmostEquals((0.0,0.0,0.0),(v.X,v.Y,v.Z),3)
t = Vector(0.1,0.1,0.2)
#nearest edge is the vertical side edge, 0,0,0 -> 0,0,1
e = c.edges(NearestToPointSelector(t)).vals()[0]
v = c.edges(NearestToPointSelector(t)).vertices().vals()
e = c.edges(selectors.NearestToPointSelector(t)).vals()[0]
v = c.edges(selectors.NearestToPointSelector(t)).vertices().vals()
self.assertEqual(2,len(v))
#nearest solid is myself
s = c.solids(NearestToPointSelector(t)).vals()
s = c.solids(selectors.NearestToPointSelector(t)).vals()
self.assertEqual(1,len(s))
def testFaceCount(self):

View File

@ -1,11 +1,11 @@
#system modules
import sys
#my modules
import from cadquery import *
import unittest
from tests import BaseTest
import FreeCAD
from cadquery import *
class TestCadObjects(BaseTest):
def testVectorConstructors(self):
@ -56,4 +56,7 @@ class TestCadObjects(BaseTest):
def testVertices(self):
e = Shape.cast(FreeCAD.Part.makeLine((0,0,0),(1,1,0)))
self.assertEquals(2,len(e.Vertices()))
self.assertEquals(2,len(e.Vertices()))
if __name__ == '__main__':
unittest.main()

View File

@ -7,6 +7,8 @@ import math,sys,os.path,time
#my modules
from cadquery import *
from cadquery import exporters
from tests import BaseTest,writeStringToFile,makeUnitCube,readFileAsString,makeUnitSquareWire,makeCube
#where unit test output will be saved
OUTDIR = "c:/temp"
@ -739,16 +741,6 @@ class TestCadQuery(BaseTest):
self.saveModel(s3)
def testTwistedGear3(self):
pts = plugins.make_gear(14.5,10,2.5) #make involutes
s = Workplane("XY").polyline(pts).twistExtrude(4.0,8.0)
#s2 = s.faces(">Z").workplane().transformed(rotate=Vector(0,0,8)).polyline(pts).twistExtrude(4.0,-8.0,combine=False)
#s3 = s.union(s2)
#s.val().exportStl("c:\\temp\\pleasework3.stl")
#s3.val().exportStl("c:\\temp\\pleasework5.stl")
self.saveModel(s)
def testEnclosure(self):
"""
Builds an electronics enclosure

View File

@ -3,7 +3,7 @@ __author__ = 'dcowden'
from cadquery import *
import unittest,sys
import MakeTestObjects
from tests import MakeTestObjects
import SVGexporter
class TestCadQuery(unittest.TestCase):

View File

@ -5,9 +5,9 @@
#my modules
from cadquery import *
from tests import BaseTest,toTuple
class TestPlane(BaseTest):
class TestWorkplanes(BaseTest):
def testYZPlaneOrigins(self):
#xy plane-- with origin at x=0.25

View File

@ -32,7 +32,7 @@ def makeCube(size):
def toTuple(v):
"convert a vector or a vertex to a 3-tuple: x,y,z"
pnt = v
if type(v) == Base.Vector:
if type(v) == FreeCAD.Base.Vector:
return (v.Point.x,v.Point.y,v.Point.z)
elif type(v) == Vector:
return v.toTuple()
@ -45,3 +45,5 @@ class BaseTest(unittest.TestCase):
def assertTupleAlmostEquals(self,expected,actual,places):
for i,j in zip(actual,expected):
self.assertAlmostEquals(i,j,places)
__all__ = [ 'TestCadObjects','TestCadQuery','TestCQSelectors','TestWorkplanes']