Merge commit '37cf193c86d3e29ccf1938472b07bde9ce3be45c'

This commit is contained in:
Jeremy Mack Wright 2016-04-26 21:44:38 -04:00
commit e6c95401b9
5 changed files with 117 additions and 1 deletions

View File

@ -165,7 +165,7 @@ Installing -- FreeStanding Installation
Use these steps if you would like to write CadQuery scripts as a python API. In this case, FreeCAD is used only as a CAD kernel. Use these steps if you would like to write CadQuery scripts as a python API. In this case, FreeCAD is used only as a CAD kernel.
1. install FreeCAD, version 0.12 or greater for your platform. http://sourceforge.net/projects/free-cad/. 1. install FreeCAD, version 0.15 or greater for your platform. https://github.com/FreeCAD/FreeCAD/releases.
2. adjust your path if necessary. FreeCAD bundles a python interpreter, but you'll probably want to use your own, 2. adjust your path if necessary. FreeCAD bundles a python interpreter, but you'll probably want to use your own,
preferably one that has virtualenv available. To use FreeCAD from any python interpreter, just append the FreeCAD preferably one that has virtualenv available. To use FreeCAD from any python interpreter, just append the FreeCAD

View File

@ -2055,6 +2055,24 @@ class Workplane(CQ):
if clean: newS = newS.clean() if clean: newS = newS.clean()
return newS return newS
def sweep(self, path, makeSolid=True, isFrenet=False, combine=True, clean=True):
"""
Use all un-extruded wires in the parent chain to create a swept solid.
:param path: A wire along which the pending wires will be swept
:param boolean combine: True to combine the resulting solid with parent solids if found.
:param boolean clean: call :py:meth:`clean` afterwards to have a clean shape
:return: a CQ object with the resulting solid selected.
"""
r = self._sweep(path.wire(), makeSolid, isFrenet) # returns a Solid (or a compound if there were multiple)
if combine:
newS = self._combineWithBase(r)
else:
newS = self.newObject([r])
if clean: newS = newS.clean()
return newS
def _combineWithBase(self, obj): def _combineWithBase(self, obj):
""" """
Combines the provided object with the base solid, if one can be found. Combines the provided object with the base solid, if one can be found.
@ -2318,6 +2336,28 @@ class Workplane(CQ):
return Compound.makeCompound(toFuse) return Compound.makeCompound(toFuse)
def _sweep(self, path, makeSolid=True, isFrenet=False):
"""
Makes a swept solid from an existing set of pending wires.
:param path: A wire along which the pending wires will be swept
:return:a FreeCAD solid, suitable for boolean operations
"""
# group wires together into faces based on which ones are inside the others
# result is a list of lists
s = time.time()
wireSets = sortWiresByBuildOrder(list(self.ctx.pendingWires), self.plane, [])
# print "sorted wires in %d sec" % ( time.time() - s )
self.ctx.pendingWires = [] # now all of the wires have been used to create an extrusion
toFuse = []
for ws in wireSets:
thisObj = Solid.sweep(ws[0], ws[1:], path.val(), makeSolid, isFrenet)
toFuse.append(thisObj)
return Compound.makeCompound(toFuse)
def box(self, length, width, height, centered=(True, True, True), combine=True, clean=True): def box(self, length, width, height, centered=(True, True, True), combine=True, clean=True):
""" """
Return a 3d box with specified dimensions for each object on the stack. Return a 3d box with specified dimensions for each object on the stack.

View File

@ -905,6 +905,28 @@ class Solid(Shape):
return Shape.cast(result) return Shape.cast(result)
@classmethod
def sweep(cls, outerWire, innerWires, path, makeSolid=True, isFrenet=False):
"""
Attempt to sweep the list of wires into a prismatic solid along the provided path
:param outerWire: the outermost wire
:param innerWires: a list of inner wires
:param path: The wire to sweep the face resulting from the wires over
:return: a Solid object
"""
# FreeCAD allows this in one operation, but others might not
freeCADWires = [outerWire.wrapped]
for w in innerWires:
freeCADWires.append(w.wrapped)
# f = FreeCADPart.Face(freeCADWires)
wire = FreeCADPart.Wire([path.wrapped])
result = wire.makePipeShell(freeCADWires, makeSolid, isFrenet)
return Shape.cast(result)
def tessellate(self, tolerance): def tessellate(self, tolerance):
return self.wrapped.tessellate(tolerance) return self.wrapped.tessellate(tolerance)

View File

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 58 KiB

View File

@ -349,6 +349,60 @@ class TestCadQuery(BaseTest):
self.assertEqual(2, result.vertices().size()) self.assertEqual(2, result.vertices().size())
self.assertEqual(3, result.edges().size()) self.assertEqual(3, result.edges().size())
def testSweep(self):
"""
Tests the operation of sweeping a wire(s) along a path
"""
pts = [
(0, 1),
(1, 2),
(2, 4)
]
# Spline path
path = Workplane("XZ").spline(pts)
# Test defaults
result = Workplane("XY").circle(1.0).sweep(path)
self.assertEqual(3, result.faces().size())
self.assertEqual(3, result.edges().size())
# Test with makeSolid False
result = Workplane("XY").circle(1.0).sweep(path, makeSolid=False)
self.assertEqual(1, result.faces().size())
self.assertEqual(3, result.edges().size())
# Test with isFrenet True
result = Workplane("XY").circle(1.0).sweep(path, isFrenet=True)
self.assertEqual(3, result.faces().size())
self.assertEqual(3, result.edges().size())
# Test with makeSolid False and isFrenet True
result = Workplane("XY").circle(1.0).sweep(path, makeSolid=False, isFrenet=True)
self.assertEqual(1, result.faces().size())
self.assertEqual(3, result.edges().size())
# Test rectangle with defaults
result = Workplane("XY").rect(1.0, 1.0).sweep(path)
self.assertEqual(6, result.faces().size())
self.assertEqual(12, result.edges().size())
# Polyline path
path = Workplane("XZ").polyline(pts)
# Test defaults
result = Workplane("XY").circle(0.1).sweep(path)
self.assertEqual(5, result.faces().size())
self.assertEqual(7, result.edges().size())
# Arc path
path = Workplane("XZ").threePointArc((1.0, 1.5),(0.0, 1.0))
# Test defaults
result = Workplane("XY").circle(0.1).sweep(path)
self.assertEqual(3, result.faces().size())
self.assertEqual(3, result.edges().size())
def testTwistExtrude(self): def testTwistExtrude(self):
""" """
Tests extrusion while twisting through an angle. Tests extrusion while twisting through an angle.