Updated to work with 0.13
- This is _totally_ experimental, and I haven't done exhaustive tests - 88 unit tests do pass though, and I added a new import test. - 0.12 and 0.13 seem to structure stuff a bit differently, probably due to changes in the FreeCAD lib wrappers. - Not tested on windows (but should work) or 0.12. Need some help there.
This commit is contained in:
		@ -2,7 +2,7 @@
 | 
			
		||||
    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
 | 
			
		||||
@ -15,14 +15,25 @@
 | 
			
		||||
 | 
			
		||||
    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/>
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    An exporter should provide functionality to accept a shape, and return
 | 
			
		||||
    a string containing the model content.
 | 
			
		||||
"""
 | 
			
		||||
import cadquery
 | 
			
		||||
 | 
			
		||||
import FreeCAD,tempfile,os,StringIO
 | 
			
		||||
from FreeCAD import Drawing
 | 
			
		||||
from .verutil import fc_import
 | 
			
		||||
FreeCAD = fc_import("FreeCAD")
 | 
			
		||||
import tempfile,os,StringIO
 | 
			
		||||
 | 
			
		||||
Drawing = fc_import("FreeCAD.Drawing")
 | 
			
		||||
#_FCVER = freecad_version()
 | 
			
		||||
#if _FCVER>=(0,13):
 | 
			
		||||
    #import Drawing as FreeCADDrawing #It's in FreeCAD lib path
 | 
			
		||||
#elif _FCVER>=(0,12):
 | 
			
		||||
    #import FreeCAD.Drawing as FreeCADDrawing
 | 
			
		||||
#else:
 | 
			
		||||
    #raise RuntimeError, "Invalid freecad version: %s" % str(".".join(_FCVER))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
try:
 | 
			
		||||
    import xml.etree.cElementTree as ET
 | 
			
		||||
@ -35,7 +46,7 @@ class ExportTypes:
 | 
			
		||||
    AMF = "AMF"
 | 
			
		||||
    SVG = "SVG"
 | 
			
		||||
    TJS = "TJS"
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
class UNITS:
 | 
			
		||||
    MM = "mm"
 | 
			
		||||
    IN = "in"
 | 
			
		||||
@ -45,7 +56,7 @@ def toString(shape,exportType,tolerance=0.1):
 | 
			
		||||
	s= StringIO.StringIO()
 | 
			
		||||
	exportShape(shape,exportType,s,tolerance)
 | 
			
		||||
	return s.getvalue()
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
def exportShape(shape,exportType,fileLike,tolerance=0.1):
 | 
			
		||||
    """
 | 
			
		||||
        :param shape:  the shape to export. it can be a shape object, or a cadquery object. If a cadquery
 | 
			
		||||
@ -54,13 +65,13 @@ def exportShape(shape,exportType,fileLike,tolerance=0.1):
 | 
			
		||||
        :param tolerance: the tolerance, in model units
 | 
			
		||||
        :param fileLike: a file like object to which the content will be written.
 | 
			
		||||
        The object should be already open and ready to write. The caller is responsible
 | 
			
		||||
        for closing the object 
 | 
			
		||||
        for closing the object
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    if isinstance(shape,cadquery.CQ):
 | 
			
		||||
        shape = shape.val()
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
    if exportType == ExportTypes.TJS:
 | 
			
		||||
        #tessellate the model
 | 
			
		||||
        tess = shape.tessellate(tolerance)
 | 
			
		||||
@ -78,9 +89,9 @@ def exportShape(shape,exportType,fileLike,tolerance=0.1):
 | 
			
		||||
        fileLike.write(getSVG(shape.wrapped))
 | 
			
		||||
    elif exportType == ExportTypes.AMF:
 | 
			
		||||
        tess = shape.tessellate(tolerance)
 | 
			
		||||
        aw = AmfWriter(tess).writeAmf(fileLike)        
 | 
			
		||||
        aw = AmfWriter(tess).writeAmf(fileLike)
 | 
			
		||||
    else:
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        #all these types required writing to a file and then
 | 
			
		||||
        #re-reading. this is due to the fact that FreeCAD writes these
 | 
			
		||||
        (h, outFileName) = tempfile.mkstemp()
 | 
			
		||||
@ -130,8 +141,8 @@ def guessUnitOfMeasure(shape):
 | 
			
		||||
    if sum(dimList) < 10:
 | 
			
		||||
        return UNITS.IN
 | 
			
		||||
 | 
			
		||||
    return UNITS.MM    
 | 
			
		||||
    
 | 
			
		||||
    return UNITS.MM
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class AmfWriter(object):
 | 
			
		||||
    def __init__(self,tessellation):
 | 
			
		||||
@ -172,7 +183,7 @@ class AmfWriter(object):
 | 
			
		||||
        ET.ElementTree(amf).write(outFile,encoding='ISO-8859-1')
 | 
			
		||||
 | 
			
		||||
"""
 | 
			
		||||
    Objects that represent 
 | 
			
		||||
    Objects that represent
 | 
			
		||||
    three.js JSON object notation
 | 
			
		||||
    https://github.com/mrdoob/three.js/wiki/JSON-Model-format-3.0
 | 
			
		||||
"""
 | 
			
		||||
@ -183,21 +194,21 @@ class JsonMesh(object):
 | 
			
		||||
        self.faces = [];
 | 
			
		||||
        self.nVertices = 0;
 | 
			
		||||
        self.nFaces = 0;
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
    def addVertex(self,x,y,z):
 | 
			
		||||
        self.nVertices += 1;
 | 
			
		||||
        self.vertices.extend([x,y,z]);
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
    #add triangle composed of the three provided vertex indices
 | 
			
		||||
    def addTriangleFace(self, i,j,k):
 | 
			
		||||
        #first position means justa simple triangle
 | 
			
		||||
        self.nFaces += 1;
 | 
			
		||||
        self.faces.extend([0,int(i),int(j),int(k)]);
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    """
 | 
			
		||||
        Get a json model from this model.
 | 
			
		||||
        For now we'll forget about colors, vertex normals, and all that stuff
 | 
			
		||||
    """    
 | 
			
		||||
    """
 | 
			
		||||
    def toJson(self):
 | 
			
		||||
        return JSON_TEMPLATE % {
 | 
			
		||||
            'vertices' : str(self.vertices),
 | 
			
		||||
@ -249,7 +260,7 @@ def getSVG(shape,opts=None):
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    d = {'width':800,'height':240,'marginLeft':200,'marginTop':20}
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    if opts:
 | 
			
		||||
        d.update(opts)
 | 
			
		||||
 | 
			
		||||
@ -314,14 +325,14 @@ def exportSVG(shape, fileName):
 | 
			
		||||
        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.val().wrapped)
 | 
			
		||||
    f = open(fileName,'w')
 | 
			
		||||
    f.write(svg)
 | 
			
		||||
    f.close()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
JSON_TEMPLATE= """\
 | 
			
		||||
{
 | 
			
		||||
    "metadata" :
 | 
			
		||||
@ -336,9 +347,9 @@ JSON_TEMPLATE= """\
 | 
			
		||||
        "materials"     : 1,
 | 
			
		||||
        "morphTargets"  : 0
 | 
			
		||||
    },
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    "scale" : 1.0,
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    "materials": [    {
 | 
			
		||||
    "DbgColor" : 15658734,
 | 
			
		||||
    "DbgIndex" : 0,
 | 
			
		||||
 | 
			
		||||
@ -2,7 +2,7 @@
 | 
			
		||||
    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
 | 
			
		||||
@ -18,8 +18,10 @@
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
import math,sys
 | 
			
		||||
import FreeCAD
 | 
			
		||||
import FreeCAD.Part
 | 
			
		||||
#import FreeCAD
 | 
			
		||||
from .verutil import fc_import
 | 
			
		||||
FreeCAD = fc_import("FreeCAD")
 | 
			
		||||
#Turns out we don't need the Part module here.
 | 
			
		||||
 | 
			
		||||
def sortWiresByBuildOrder(wireList,plane,result=[]):
 | 
			
		||||
    """
 | 
			
		||||
@ -187,8 +189,8 @@ class Vector(object):
 | 
			
		||||
 | 
			
		||||
class Matrix:
 | 
			
		||||
    """
 | 
			
		||||
        A 3d , 4x4 transformation matrix.        
 | 
			
		||||
        
 | 
			
		||||
        A 3d , 4x4 transformation matrix.
 | 
			
		||||
 | 
			
		||||
        Used to move geometry in space.
 | 
			
		||||
    """
 | 
			
		||||
    def __init__(self,matrix=None):
 | 
			
		||||
@ -196,14 +198,14 @@ class Matrix:
 | 
			
		||||
            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.
 | 
			
		||||
@ -321,7 +323,7 @@ class Plane:
 | 
			
		||||
 | 
			
		||||
        self.setOrigin3d(origin)
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
    def setOrigin3d(self,originVector):
 | 
			
		||||
        """
 | 
			
		||||
            Move the origin of the plane, leaving its orientation and xDirection unchanged.
 | 
			
		||||
@ -427,7 +429,7 @@ class Plane:
 | 
			
		||||
            v = Vector(tuplePoint[0],tuplePoint[1],tuplePoint[2])
 | 
			
		||||
        return Vector(self.rG.multiply(v.wrapped))
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
    def rotated(self,rotate=(0,0,0)):
 | 
			
		||||
        """
 | 
			
		||||
        returns a copy of this plane, rotated about the specified axes, as measured from horizontal
 | 
			
		||||
@ -445,7 +447,7 @@ class Plane:
 | 
			
		||||
        """
 | 
			
		||||
 | 
			
		||||
        if rotate.__class__.__name__ != 'Vector':
 | 
			
		||||
            rotate = Vector(rotate)		
 | 
			
		||||
            rotate = Vector(rotate)
 | 
			
		||||
        #convert to radians
 | 
			
		||||
        rotate = rotate.multiply(math.pi / 180.0 )
 | 
			
		||||
 | 
			
		||||
@ -473,13 +475,13 @@ class Plane:
 | 
			
		||||
        #compute rotation matrix ( global --> local --> rotate  --> global )
 | 
			
		||||
        #rm = self.plane.fG.multiply(matrix).multiply(self.plane.rG)
 | 
			
		||||
        rm = self.computeTransform(rotationMatrix)
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        #There might be a better way, but to do this rotation takes 3 steps
 | 
			
		||||
        #transform geometry to local coordinates
 | 
			
		||||
        #then rotate about x
 | 
			
		||||
        #then transform back to global coordiante
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        resultWires = []
 | 
			
		||||
        for w in listOfShapes:
 | 
			
		||||
            mirrored = w.transformGeometry(rotationMatrix.wrapped)
 | 
			
		||||
@ -487,7 +489,7 @@ class Plane:
 | 
			
		||||
 | 
			
		||||
        return resultWires
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
    def _calcTransforms(self):
 | 
			
		||||
        """
 | 
			
		||||
            Computes transformation martrices to convert betwene local and global coordinates
 | 
			
		||||
@ -507,12 +509,12 @@ 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)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -2,7 +2,7 @@
 | 
			
		||||
	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
 | 
			
		||||
@ -43,13 +43,15 @@
 | 
			
		||||
 | 
			
		||||
        5. allow changing interfaces when we'd like.  there are  few cases where the freecad api is not
 | 
			
		||||
           very userfriendly: we like to change those when necesary. As an example, in the freecad api,
 | 
			
		||||
           all factory methods are on the 'Part' object, but it is very useful to know what kind of 
 | 
			
		||||
           object each one returns, so these are better grouped by the type of object they return. 
 | 
			
		||||
           all factory methods are on the 'Part' object, but it is very useful to know what kind of
 | 
			
		||||
           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,BoundBox
 | 
			
		||||
import FreeCAD
 | 
			
		||||
import FreeCAD.Part
 | 
			
		||||
 | 
			
		||||
from .verutil import fc_import
 | 
			
		||||
FreeCADPart = fc_import("FreeCAD.Part")
 | 
			
		||||
 | 
			
		||||
class Shape(object):
 | 
			
		||||
    """
 | 
			
		||||
@ -269,7 +271,7 @@ 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.
 | 
			
		||||
 | 
			
		||||
@ -316,9 +318,9 @@ class Edge(Shape):
 | 
			
		||||
        #self.endPoint = None
 | 
			
		||||
 | 
			
		||||
        self.edgetypes= {
 | 
			
		||||
            FreeCAD.Part.Line : 'LINE',
 | 
			
		||||
            FreeCAD.Part.ArcOfCircle : 'ARC',
 | 
			
		||||
            FreeCAD.Part.Circle : 'CIRCLE'
 | 
			
		||||
            FreeCADPart.Line : 'LINE',
 | 
			
		||||
            FreeCADPart.ArcOfCircle : 'ARC',
 | 
			
		||||
            FreeCADPart.Circle : 'CIRCLE'
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    def geomType(self):
 | 
			
		||||
@ -368,7 +370,7 @@ class Edge(Shape):
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def makeCircle(cls,radius,pnt=(0,0,0),dir=(0,0,1),angle1=360.0,angle2=360):
 | 
			
		||||
        return Edge(FreeCAD.Part.makeCircle(radius,toVector(pnt),toVector(dir),angle1,angle2))
 | 
			
		||||
        return Edge(FreeCADPart.makeCircle(radius,toVector(pnt),toVector(dir),angle1,angle2))
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def makeSpline(cls,listOfVector):
 | 
			
		||||
@ -380,7 +382,7 @@ class Edge(Shape):
 | 
			
		||||
        """
 | 
			
		||||
        vecs = [v.wrapped for v in listOfVector]
 | 
			
		||||
 | 
			
		||||
        spline = FreeCAD.Part.BSplineCurve()
 | 
			
		||||
        spline = FreeCADPart.BSplineCurve()
 | 
			
		||||
        spline.interpolate(vecs,False)
 | 
			
		||||
        return Edge(spline.toShape())
 | 
			
		||||
 | 
			
		||||
@ -394,7 +396,7 @@ class Edge(Shape):
 | 
			
		||||
        :param v3: end vector
 | 
			
		||||
        :return: an edge object through the three points
 | 
			
		||||
        """
 | 
			
		||||
        arc = FreeCAD.Part.Arc(v1.wrapped,v2.wrapped,v3.wrapped)
 | 
			
		||||
        arc = FreeCADPart.Arc(v1.wrapped,v2.wrapped,v3.wrapped)
 | 
			
		||||
        e = Edge(arc.toShape())
 | 
			
		||||
        return e #arcane and undocumented, this creates an Edge object
 | 
			
		||||
 | 
			
		||||
@ -406,7 +408,7 @@ class Edge(Shape):
 | 
			
		||||
            :param v2: Vector that represents the second point
 | 
			
		||||
            :return: A linear edge between the two provided points
 | 
			
		||||
        """
 | 
			
		||||
        return Edge(FreeCAD.Part.makeLine(v1.toTuple(),v2.toTuple() ))
 | 
			
		||||
        return Edge(FreeCADPart.makeLine(v1.toTuple(),v2.toTuple() ))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Wire(Shape):
 | 
			
		||||
@ -425,7 +427,7 @@ class Wire(Shape):
 | 
			
		||||
        :param listOfWires:
 | 
			
		||||
        :return:
 | 
			
		||||
        """
 | 
			
		||||
        return Shape.cast(FreeCAD.Part.Wire([w.wrapped for w in listOfWires]))
 | 
			
		||||
        return Shape.cast(FreeCADPart.Wire([w.wrapped for w in listOfWires]))
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def assembleEdges(cls,listOfEdges):
 | 
			
		||||
@ -437,7 +439,7 @@ class Wire(Shape):
 | 
			
		||||
        """
 | 
			
		||||
        fCEdges = [a.wrapped for a in listOfEdges]
 | 
			
		||||
 | 
			
		||||
        wa = Wire( FreeCAD.Part.Wire(fCEdges) )
 | 
			
		||||
        wa = Wire( FreeCADPart.Wire(fCEdges) )
 | 
			
		||||
        return wa
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
@ -449,13 +451,13 @@ class Wire(Shape):
 | 
			
		||||
            :param normal: vector representing the direction of the plane the circle should lie in
 | 
			
		||||
            :return:
 | 
			
		||||
        """
 | 
			
		||||
        w = Wire(FreeCAD.Part.Wire([FreeCAD.Part.makeCircle(radius,center.wrapped,normal.wrapped)]))
 | 
			
		||||
        w = Wire(FreeCADPart.Wire([FreeCADPart.makeCircle(radius,center.wrapped,normal.wrapped)]))
 | 
			
		||||
        return w
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def makePolygon(cls,listOfVertices,forConstruction=False):
 | 
			
		||||
        #convert list of tuples into Vectors.
 | 
			
		||||
        w = Wire(FreeCAD.Part.makePolygon([i.wrapped for i in listOfVertices]))
 | 
			
		||||
        w = Wire(FreeCADPart.makePolygon([i.wrapped for i in listOfVertices]))
 | 
			
		||||
        w.forConstruction = forConstruction
 | 
			
		||||
        return w
 | 
			
		||||
 | 
			
		||||
@ -466,7 +468,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(FreeCAD.Part.makeHelix(pitch,height,radius,angle))
 | 
			
		||||
        return Wire(FreeCADPart.makeHelix(pitch,height,radius,angle))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Face(Shape):
 | 
			
		||||
@ -478,9 +480,9 @@ class Face(Shape):
 | 
			
		||||
 | 
			
		||||
        self.facetypes = {
 | 
			
		||||
            #TODO: bezier,bspline etc
 | 
			
		||||
            FreeCAD.Part.Plane : 'PLANE',
 | 
			
		||||
            FreeCAD.Part.Sphere : 'SPHERE',
 | 
			
		||||
            FreeCAD.Part.Cone : 'CONE'
 | 
			
		||||
            FreeCADPart.Plane : 'PLANE',
 | 
			
		||||
            FreeCADPart.Sphere : 'SPHERE',
 | 
			
		||||
            FreeCADPart.Cone : 'CONE'
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    def geomType(self):
 | 
			
		||||
@ -506,7 +508,7 @@ class Face(Shape):
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def makePlane(cls,length,width,basePnt=None,dir=None):
 | 
			
		||||
        return Face(FreeCAD.Part.makePlan(length,width,toVector(basePnt),toVector(dir)))
 | 
			
		||||
        return Face(FreeCADPart.makePlan(length,width,toVector(basePnt),toVector(dir)))
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def makeRuledSurface(cls,edgeOrWire1,edgeOrWire2,dist=None):
 | 
			
		||||
@ -515,7 +517,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(FreeCAD.Part.makeRuledSurface(edgeOrWire1.obj,edgeOrWire2.obj,dist))
 | 
			
		||||
        return Shape.cast(FreeCADPart.makeRuledSurface(edgeOrWire1.obj,edgeOrWire2.obj,dist))
 | 
			
		||||
 | 
			
		||||
    def cut(self,faceToCut):
 | 
			
		||||
        "Remove a face from another one"
 | 
			
		||||
@ -541,7 +543,7 @@ class Shell(Shape):
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def makeShell(cls,listOfFaces):
 | 
			
		||||
        return Shell(FreeCAD.Part.makeShell([i.obj for i in listOfFaces]))
 | 
			
		||||
        return Shell(FreeCADPart.makeShell([i.obj for i in listOfFaces]))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Solid(Shape):
 | 
			
		||||
@ -568,7 +570,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(FreeCAD.Part.makeBox(length,width,height,pnt.wrapped,dir.wrapped))
 | 
			
		||||
        return Shape.cast(FreeCADPart.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):
 | 
			
		||||
@ -577,7 +579,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(FreeCAD.Part.makeCone(radius1,radius2,height,pnt.wrapped,dir.wrapped,angleDegrees))
 | 
			
		||||
        return Shape.cast(FreeCADPart.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):
 | 
			
		||||
@ -586,7 +588,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(FreeCAD.Part.makeCylinder(radius,height,pnt.wrapped,dir.wrapped,angleDegrees))
 | 
			
		||||
        return Shape.cast(FreeCADPart.makeCylinder(radius,height,pnt.wrapped,dir.wrapped,angleDegrees))
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def makeTorus(cls,radius1,radius2,pnt=None,dir=None,angleDegrees1=None,angleDegrees2=None):
 | 
			
		||||
@ -596,7 +598,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(FreeCAD.Part.makeTorus(radius1,radius2,pnt,dir,angleDegrees1,angleDegrees2))
 | 
			
		||||
        return Shape.cast(FreeCADPart.makeTorus(radius1,radius2,pnt,dir,angleDegrees1,angleDegrees2))
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def sweep(cls,profileWire,pathWire):
 | 
			
		||||
@ -615,11 +617,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 FreeCAD.Part.
 | 
			
		||||
            wants to make an infinitely thin shell for a real FreeCADPart.
 | 
			
		||||
        """
 | 
			
		||||
        #the True flag requests building a solid instead of a shell.
 | 
			
		||||
 | 
			
		||||
        return Shape.cast(FreeCAD.Part.makeLoft([i.wrapped for i in listOfWire],True))
 | 
			
		||||
        return Shape.cast(FreeCADPart.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):
 | 
			
		||||
@ -629,7 +631,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(FreeCAD.Part.makeWedge(xmin,ymin,zmin,z2min,x2min,xmax,ymax,zmax,z2max,x2max,pnt,dir))
 | 
			
		||||
        return Shape.cast(FreeCADPart.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):
 | 
			
		||||
@ -638,7 +640,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(FreeCAD.Part.makeSphere(radius,pnt,angleDegrees1,angleDegrees2,angleDegrees3))
 | 
			
		||||
        return Solid(FreeCADPart.makeSphere(radius,pnt,angleDegrees1,angleDegrees2,angleDegrees3))
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def extrudeLinearWithRotation(cls,outerWire,innerWires,vecCenter, vecNormal,angleDegrees):
 | 
			
		||||
@ -679,12 +681,12 @@ class Solid(Shape):
 | 
			
		||||
        #make a ruled surface for each set of wires
 | 
			
		||||
        sides = []
 | 
			
		||||
        for w1,w2 in zip(startWires,endWires):
 | 
			
		||||
            rs = FreeCAD.Part.makeRuledSurface(w1,w2)
 | 
			
		||||
            rs = FreeCADPart.makeRuledSurface(w1,w2)
 | 
			
		||||
            sides.append(rs)
 | 
			
		||||
 | 
			
		||||
        #make faces for the top and bottom
 | 
			
		||||
        startFace = FreeCAD.Part.Face(startWires)
 | 
			
		||||
        endFace = FreeCAD.Part.Face(endWires)
 | 
			
		||||
        startFace = FreeCADPart.Face(startWires)
 | 
			
		||||
        endFace = FreeCADPart.Face(endWires)
 | 
			
		||||
 | 
			
		||||
        #collect all the faces from the sides
 | 
			
		||||
        faceList = [ startFace]
 | 
			
		||||
@ -692,8 +694,8 @@ class Solid(Shape):
 | 
			
		||||
            faceList.extend(s.Faces)
 | 
			
		||||
        faceList.append(endFace)
 | 
			
		||||
 | 
			
		||||
        shell = FreeCAD.Part.makeShell(faceList)
 | 
			
		||||
        solid = FreeCAD.Part.makeSolid(shell)
 | 
			
		||||
        shell = FreeCADPart.makeShell(faceList)
 | 
			
		||||
        solid = FreeCADPart.makeSolid(shell)
 | 
			
		||||
        return Shape.cast(solid)
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
@ -730,7 +732,7 @@ class Solid(Shape):
 | 
			
		||||
        for w in innerWires:
 | 
			
		||||
            freeCADWires.append(w.wrapped)
 | 
			
		||||
 | 
			
		||||
        f = FreeCAD.Part.Face(freeCADWires)
 | 
			
		||||
        f = FreeCADPart.Face(freeCADWires)
 | 
			
		||||
        result = f.extrude(vecNormal.wrapped)
 | 
			
		||||
 | 
			
		||||
        return Shape.cast(result)
 | 
			
		||||
@ -794,11 +796,11 @@ class Compound(Shape):
 | 
			
		||||
        Create a compound out of a list of shapes
 | 
			
		||||
        """
 | 
			
		||||
        solids = [s.wrapped for s in listOfShapes]
 | 
			
		||||
        c = FreeCAD.Part.Compound(solids)
 | 
			
		||||
        c = FreeCADPart.Compound(solids)
 | 
			
		||||
        return Shape.cast( c)
 | 
			
		||||
 | 
			
		||||
    def fuse(self,toJoin):
 | 
			
		||||
        return Shape.cast(self.wrapped.fuse(toJoin.wrapped))
 | 
			
		||||
 | 
			
		||||
    def tessellate(self,tolerance):
 | 
			
		||||
        return self.wrapped.tessellate(tolerance)
 | 
			
		||||
        return self.wrapped.tessellate(tolerance)
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										113
									
								
								cadquery/freecad_impl/verutil.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										113
									
								
								cadquery/freecad_impl/verutil.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,113 @@
 | 
			
		||||
"""
 | 
			
		||||
    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.
 | 
			
		||||
 | 
			
		||||
    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/>
 | 
			
		||||
 | 
			
		||||
    An exporter should provide functionality to accept a shape, and return
 | 
			
		||||
    a string containing the model content.
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
import re
 | 
			
		||||
from importlib import import_module
 | 
			
		||||
import os
 | 
			
		||||
import sys
 | 
			
		||||
 | 
			
		||||
MEMO_VERSION = None
 | 
			
		||||
SUBMODULES = None
 | 
			
		||||
_PATH = None
 | 
			
		||||
 | 
			
		||||
def _figure_out_version(freecadversion):
 | 
			
		||||
    """Break this out for testability."""
 | 
			
		||||
    return tuple(
 | 
			
		||||
            ((int(re.sub("([0-9]*).*", "\\1", part) or 0))
 | 
			
		||||
                for part in freecadversion[:3]))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def _fc_path():
 | 
			
		||||
    """Find FreeCAD"""
 | 
			
		||||
    global _PATH
 | 
			
		||||
    if _PATH:
 | 
			
		||||
        return _PATH
 | 
			
		||||
    if sys.platform.startswith('linux'):
 | 
			
		||||
        #Make some dangerous assumptions...
 | 
			
		||||
        for _PATH in [
 | 
			
		||||
                os.path.join(os.path.expanduser("~"), "lib/freecad/lib"),
 | 
			
		||||
                "/usr/local/lib/freecad/lib",
 | 
			
		||||
                "/usr/lib/freecad/lib",
 | 
			
		||||
                ]:
 | 
			
		||||
            if os.path.exists(_PATH):
 | 
			
		||||
                return _PATH
 | 
			
		||||
 | 
			
		||||
    elif sys.platform.startswith('win'):
 | 
			
		||||
        for _PATH in [
 | 
			
		||||
                "c:/apps/FreeCAD0.12/bin",
 | 
			
		||||
                "c:/apps/FreeCAD0.13/bin",
 | 
			
		||||
                ]:
 | 
			
		||||
            if os.path.exists(_PATH):
 | 
			
		||||
                return _PATH
 | 
			
		||||
 | 
			
		||||
def freecad_version():
 | 
			
		||||
    """Determine the freecad version and return it as a simple
 | 
			
		||||
    comparable tuple"""
 | 
			
		||||
    #If we cannot find freecad, we append it to the path if possible
 | 
			
		||||
    _pthtmp = _fc_path()
 | 
			
		||||
    if not _pthtmp in sys.path:
 | 
			
		||||
        sys.path.append(_pthtmp)
 | 
			
		||||
    import FreeCAD
 | 
			
		||||
    global MEMO_VERSION
 | 
			
		||||
    if not MEMO_VERSION:
 | 
			
		||||
        MEMO_VERSION = _figure_out_version(FreeCAD.Version())
 | 
			
		||||
    return MEMO_VERSION
 | 
			
		||||
 | 
			
		||||
def _find_submodules():
 | 
			
		||||
    """Find the list of allowable submodules in fc13"""
 | 
			
		||||
    global SUBMODULES
 | 
			
		||||
    searchpath = _fc_path()
 | 
			
		||||
    if not SUBMODULES:
 | 
			
		||||
        SUBMODULES = [
 | 
			
		||||
                re.sub("(.*)\\.(py|so)","\\1", filename)
 | 
			
		||||
                for filename in os.listdir(searchpath)
 | 
			
		||||
                if (
 | 
			
		||||
                    filename.endswith(".so") or
 | 
			
		||||
                    filename.endswith(".py") or
 | 
			
		||||
                    filename.endswith(".dll") )] #Yes, complex. Sorry.
 | 
			
		||||
    return SUBMODULES
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def fc_import(modulename):
 | 
			
		||||
    """Intelligent import of freecad components.
 | 
			
		||||
    If we are in 0.12, we can import FreeCAD.Drawing
 | 
			
		||||
    If we are in 0.13, we need to set sys.path and import Drawing as toplevel.
 | 
			
		||||
    This may or may not be a FreeCAD bug though.
 | 
			
		||||
    This is ludicrously complex and feels awful. Kinda like a lot of OCC.
 | 
			
		||||
    """
 | 
			
		||||
    #Note that this also sets the path as a side effect.
 | 
			
		||||
 | 
			
		||||
    _fcver = freecad_version()
 | 
			
		||||
 | 
			
		||||
    if _fcver >= (0, 13):
 | 
			
		||||
        if modulename in _find_submodules():
 | 
			
		||||
            return import_module(modulename)
 | 
			
		||||
        elif re.sub("^FreeCAD\\.", "", modulename) in _find_submodules():
 | 
			
		||||
            return import_module(re.sub("^FreeCAD\\.", "", modulename))
 | 
			
		||||
        else:
 | 
			
		||||
            raise ImportError, "Module %s not found/allowed in %s" % (
 | 
			
		||||
                    modulename, _PATH)
 | 
			
		||||
    elif _fcver >= (0, 12):
 | 
			
		||||
        return import_module(modulename)
 | 
			
		||||
    else:
 | 
			
		||||
        raise RuntimeError, "Invalid freecad version: %s" % \
 | 
			
		||||
                str(".".join(_fcver))
 | 
			
		||||
 | 
			
		||||
__ALL__ = ['fc_import', 'freecad_version']
 | 
			
		||||
							
								
								
									
										4
									
								
								setup.py
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								setup.py
									
									
									
									
									
								
							@ -1,4 +1,4 @@
 | 
			
		||||
from distutils.core import setup
 | 
			
		||||
from setuptools import setup
 | 
			
		||||
 | 
			
		||||
setup(
 | 
			
		||||
    name='cadquery',
 | 
			
		||||
@ -37,4 +37,4 @@ setup(
 | 
			
		||||
        'Topic :: Internet',
 | 
			
		||||
        'Topic :: Scientific/Engineering'
 | 
			
		||||
    ]
 | 
			
		||||
)
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@ -3,9 +3,15 @@ import sys
 | 
			
		||||
 | 
			
		||||
import unittest
 | 
			
		||||
from tests import BaseTest
 | 
			
		||||
import FreeCAD
 | 
			
		||||
 | 
			
		||||
from cadquery.freecad_impl.verutil import fc_import
 | 
			
		||||
FreeCAD = fc_import("FreeCAD")
 | 
			
		||||
if not hasattr(FreeCAD, 'Part'):
 | 
			
		||||
    FreeCAD.Part = fc_import("FreeCAD.Part")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
from cadquery import *
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
class TestCadObjects(BaseTest):
 | 
			
		||||
 | 
			
		||||
    def testVectorConstructors(self):
 | 
			
		||||
@ -57,6 +63,6 @@ class TestCadObjects(BaseTest):
 | 
			
		||||
    def testVertices(self):
 | 
			
		||||
        e = Shape.cast(FreeCAD.Part.makeLine((0,0,0),(1,1,0)))
 | 
			
		||||
        self.assertEquals(2,len(e.Vertices()))
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
if __name__ == '__main__':
 | 
			
		||||
    unittest.main()		
 | 
			
		||||
    unittest.main()
 | 
			
		||||
 | 
			
		||||
@ -11,7 +11,11 @@ from cadquery import exporters
 | 
			
		||||
from tests import BaseTest,writeStringToFile,makeUnitCube,readFileAsString,makeUnitSquareWire,makeCube
 | 
			
		||||
 | 
			
		||||
#where unit test output will be saved
 | 
			
		||||
OUTDIR = "c:/temp"
 | 
			
		||||
import sys
 | 
			
		||||
if sys.platform.startswith("win"):
 | 
			
		||||
    OUTDIR = "c:/temp"
 | 
			
		||||
else:
 | 
			
		||||
    OUTDIR = "/tmp"
 | 
			
		||||
SUMMARY_FILE = os.path.join(OUTDIR,"testSummary.html")
 | 
			
		||||
 | 
			
		||||
SUMMARY_TEMPLATE="""<html>
 | 
			
		||||
@ -422,13 +426,14 @@ class TestCadQuery(BaseTest):
 | 
			
		||||
 | 
			
		||||
    def testBasicLines(self):
 | 
			
		||||
        "Make a triangluar boss"
 | 
			
		||||
        global OUTDIR
 | 
			
		||||
        s = Workplane(Plane.XY())
 | 
			
		||||
 | 
			
		||||
        #TODO:  extrude() should imply wire() if not done already
 | 
			
		||||
        #most users dont understand what a wire is, they are just drawing
 | 
			
		||||
 | 
			
		||||
        r = s.lineTo(1.0,0).lineTo(0,1.0).close().wire().extrude(0.25)
 | 
			
		||||
        r.val().exportStep('c:/temp/testBasicLinesStep1.STEP')
 | 
			
		||||
        r.val().exportStep(os.path.join(OUTDIR, 'testBasicLinesStep1.STEP'))
 | 
			
		||||
 | 
			
		||||
        self.assertEqual(0,s.faces().size()) #no faces on the original workplane
 | 
			
		||||
        self.assertEqual(5,r.faces().size() ) # 5 faces on newly created object
 | 
			
		||||
@ -436,12 +441,12 @@ class TestCadQuery(BaseTest):
 | 
			
		||||
        #now add a circle through a side face
 | 
			
		||||
        r.faces("+XY").workplane().circle(0.08).cutThruAll()
 | 
			
		||||
        self.assertEqual(6,r.faces().size())
 | 
			
		||||
        r.val().exportStep('c:/temp/testBasicLinesXY.STEP')
 | 
			
		||||
        r.val().exportStep(os.path.join(OUTDIR, 'testBasicLinesXY.STEP'))
 | 
			
		||||
 | 
			
		||||
        #now add a circle through a top
 | 
			
		||||
        r.faces("+Z").workplane().circle(0.08).cutThruAll()
 | 
			
		||||
        self.assertEqual(9,r.faces().size())
 | 
			
		||||
        r.val().exportStep('c:/temp/testBasicLinesZ.STEP')
 | 
			
		||||
        r.val().exportStep(os.path.join(OUTDIR, 'testBasicLinesZ.STEP'))
 | 
			
		||||
 | 
			
		||||
        self.saveModel(r)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										30
									
								
								tests/TestImports.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								tests/TestImports.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,30 @@
 | 
			
		||||
"""
 | 
			
		||||
    Tests basic workplane functionality
 | 
			
		||||
"""
 | 
			
		||||
#core modules
 | 
			
		||||
 | 
			
		||||
#my modules
 | 
			
		||||
from cadquery.freecad_impl import verutil
 | 
			
		||||
from tests import BaseTest
 | 
			
		||||
 | 
			
		||||
class TestVersionsForImport(BaseTest):
 | 
			
		||||
    """Test version checks."""
 | 
			
		||||
 | 
			
		||||
    def test_013_version(self):
 | 
			
		||||
        """Make sure various 0.13 Version calls work correctly"""
 | 
			
		||||
        self.assertEquals(verutil._figure_out_version(
 | 
			
		||||
            ['0', '13', '2055 (Git)',
 | 
			
		||||
                'git://git.code.sf.net/p/free-cad/code',
 | 
			
		||||
                '2013/04/18 13:48:49', 'master',
 | 
			
		||||
                '3511a807a30cf41909aaf12a1efe1db6c53db577']),
 | 
			
		||||
            (0,13,2055))
 | 
			
		||||
        self.assertEquals(verutil._figure_out_version(
 | 
			
		||||
            ['0', '13', '12345']),
 | 
			
		||||
            (0,13,12345))
 | 
			
		||||
        self.assertEquals(verutil._figure_out_version(
 | 
			
		||||
            ['0', '13', 'SOMETAGTHATBREAKSSTUFF']),
 | 
			
		||||
            (0,13,0))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,12 +1,13 @@
 | 
			
		||||
from cadquery import *
 | 
			
		||||
import unittest
 | 
			
		||||
import sys
 | 
			
		||||
FREECAD_LIB = "c:/apps/FreeCAD0.12/bin";
 | 
			
		||||
sys.path.append(FREECAD_LIB);
 | 
			
		||||
import FreeCAD
 | 
			
		||||
import os
 | 
			
		||||
 | 
			
		||||
P = FreeCAD.Part
 | 
			
		||||
V = FreeCAD.Base.Vector
 | 
			
		||||
from cadquery.freecad_impl.verutil import fc_import
 | 
			
		||||
FreeCAD = fc_import("FreeCAD")
 | 
			
		||||
 | 
			
		||||
P = fc_import("FreeCAD.Part")
 | 
			
		||||
V = fc_import("FreeCAD").Base.Vector
 | 
			
		||||
 | 
			
		||||
def readFileAsString(fileName):
 | 
			
		||||
    f= open(fileName,'r')
 | 
			
		||||
@ -18,7 +19,7 @@ def writeStringToFile(strToWrite,fileName):
 | 
			
		||||
    f = open(fileName,'w')
 | 
			
		||||
    f.write(strToWrite)
 | 
			
		||||
    f.close()
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def makeUnitSquareWire():
 | 
			
		||||
    return Solid.cast(P.makePolygon([V(0,0,0),V(1,0,0),V(1,1,0),V(0,1,0),V(0,0,0)]))
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user