Merge branch 'master' into adam-urbanczyk-brepfeat-prism
This commit is contained in:
@ -2278,7 +2278,8 @@ class Workplane(CQ):
|
||||
newS = newS.clean()
|
||||
return newS
|
||||
|
||||
def sweep(self, path, sweepAlongWires=False, makeSolid=True, isFrenet=False, combine=True, clean=True):
|
||||
def sweep(self, path, sweepAlongWires=False, makeSolid=True, isFrenet=False,
|
||||
combine=True, clean=True, transition='right'):
|
||||
"""
|
||||
Use all un-extruded wires in the parent chain to create a swept solid.
|
||||
|
||||
@ -2288,10 +2289,14 @@ class Workplane(CQ):
|
||||
True to create only one solid swept along path with shape following the list of wires on the chain
|
||||
: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
|
||||
:param transition:
|
||||
handling of profile orientation at C1 path discontinuities.
|
||||
Possible values are {'transformed','round', 'right'} (default: 'right').
|
||||
:return: a CQ object with the resulting solid selected.
|
||||
"""
|
||||
|
||||
r = self._sweep(path.wire(), sweepAlongWires, makeSolid, isFrenet) # returns a Solid (or a compound if there were multiple)
|
||||
r = self._sweep(path.wire(), sweepAlongWires, makeSolid, isFrenet,
|
||||
transition) # returns a Solid (or a compound if there were multiple)
|
||||
if combine:
|
||||
newS = self._combineWithBase(r)
|
||||
else:
|
||||
@ -2644,7 +2649,8 @@ class Workplane(CQ):
|
||||
|
||||
return Compound.makeCompound(toFuse)
|
||||
|
||||
def _sweep(self, path, sweepAlongWires=False, makeSolid=True, isFrenet=False):
|
||||
def _sweep(self, path, sweepAlongWires=False, makeSolid=True,
|
||||
isFrenet=False, transition='right'):
|
||||
"""
|
||||
Makes a swept solid from an existing set of pending wires.
|
||||
|
||||
@ -2652,7 +2658,7 @@ class Workplane(CQ):
|
||||
:param boolean sweepAlongWires:
|
||||
False to create multiple swept from wires on the chain along path
|
||||
True to create only one solid swept along path with shape following the list of wires on the chain
|
||||
:return:a FreeCAD solid, suitable for boolean operations
|
||||
:return:a solid, suitable for boolean operations
|
||||
"""
|
||||
|
||||
# group wires together into faces based on which ones are inside the others
|
||||
@ -2665,7 +2671,8 @@ class Workplane(CQ):
|
||||
toFuse = []
|
||||
if not sweepAlongWires:
|
||||
for ws in wireSets:
|
||||
thisObj = Solid.sweep(ws[0], ws[1:], path.val(), makeSolid, isFrenet)
|
||||
thisObj = Solid.sweep(ws[0], ws[1:], path.val(), makeSolid,
|
||||
isFrenet, transition)
|
||||
toFuse.append(thisObj)
|
||||
else:
|
||||
section = []
|
||||
|
||||
@ -16,7 +16,10 @@ from OCC.Core.BRepBuilderAPI import (BRepBuilderAPI_MakeVertex,
|
||||
BRepBuilderAPI_MakeWire,
|
||||
BRepBuilderAPI_Copy,
|
||||
BRepBuilderAPI_GTransform,
|
||||
BRepBuilderAPI_Transform)
|
||||
BRepBuilderAPI_Transform,
|
||||
BRepBuilderAPI_Transformed,
|
||||
BRepBuilderAPI_RightCorner,
|
||||
BRepBuilderAPI_RoundCorner)
|
||||
# properties used to store mass calculation result
|
||||
from OCC.Core.GProp import GProp_GProps
|
||||
from OCC.Core.BRepGProp import BRepGProp_Face, \
|
||||
@ -114,6 +117,7 @@ from OCC.Core.Addons import (text_to_brep,
|
||||
from OCC.Core.BRepFeat import BRepFeat_MakePrism, BRepFeat_MakeDPrism
|
||||
|
||||
from math import pi, sqrt
|
||||
from functools import reduce
|
||||
|
||||
TOLERANCE = 1e-6
|
||||
DEG2RAD = 2 * pi / 360.
|
||||
@ -194,7 +198,7 @@ class Shape(object):
|
||||
"""Experimental clean using ShapeUpgrade"""
|
||||
|
||||
upgrader = ShapeUpgrade_UnifySameDomain(
|
||||
self.wrapped, True, True, False)
|
||||
self.wrapped, True, True, True)
|
||||
upgrader.Build()
|
||||
|
||||
return self.cast(upgrader.Shape())
|
||||
@ -1070,7 +1074,6 @@ class Mixin3D(object):
|
||||
|
||||
# make a edge --> faces mapping
|
||||
edge_face_map = TopTools_IndexedDataMapOfShapeListOfShape()
|
||||
|
||||
topexp_MapShapesAndAncestors(self.wrapped,
|
||||
ta.TopAbs_EDGE,
|
||||
ta.TopAbs_FACE,
|
||||
@ -1383,32 +1386,47 @@ class Solid(Shape, Mixin3D):
|
||||
|
||||
return cls(revol_builder.Shape())
|
||||
|
||||
_transModeDict = {'transformed' : BRepBuilderAPI_Transformed,
|
||||
'round' : BRepBuilderAPI_RoundCorner,
|
||||
'right' : BRepBuilderAPI_RightCorner}
|
||||
|
||||
@classmethod
|
||||
def sweep(cls, outerWire, innerWires, path, makeSolid=True, isFrenet=False):
|
||||
def sweep(cls, outerWire, innerWires, path, makeSolid=True, isFrenet=False,
|
||||
transitionMode='transformed'):
|
||||
"""
|
||||
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
|
||||
:param boolean makeSolid: return Solid or Shell (defualt True)
|
||||
:param boolean isFrenet: Frenet mode (default False)
|
||||
:param transitionMode:
|
||||
handling of profile orientation at C1 path discontinuities.
|
||||
Possible values are {'transformed','round', 'right'} (default: 'right').
|
||||
:return: a Solid object
|
||||
"""
|
||||
if path.ShapeType() == 'Edge':
|
||||
path = Wire.assembleEdges([path, ])
|
||||
|
||||
if makeSolid:
|
||||
face = Face.makeFromWires(outerWire, innerWires)
|
||||
builder = BRepOffsetAPI_MakePipe(path.wrapped, face.wrapped)
|
||||
rv = cls(builder.Shape())
|
||||
else:
|
||||
shapes = []
|
||||
for w in [outerWire]+innerWires:
|
||||
builder = BRepOffsetAPI_MakePipeShell(path.wrapped)
|
||||
builder.SetMode(isFrenet)
|
||||
builder.SetTransitionMode(cls._transModeDict[transitionMode])
|
||||
builder.Add(w.wrapped)
|
||||
|
||||
builder.Build()
|
||||
if makeSolid:
|
||||
builder.MakeSolid()
|
||||
|
||||
shapes.append(cls(builder.Shape()))
|
||||
|
||||
rv = Compound.makeCompound(shapes)
|
||||
rv,inner_shapes = shapes[0],shapes[1:]
|
||||
|
||||
if inner_shapes:
|
||||
inner_shapes = reduce(lambda a,b: a.fuse(b),inner_shapes)
|
||||
rv = rv.cut(inner_shapes)
|
||||
|
||||
return rv
|
||||
|
||||
@ -1435,8 +1453,6 @@ class Solid(Shape, Mixin3D):
|
||||
if makeSolid:
|
||||
builder.MakeSolid()
|
||||
|
||||
|
||||
|
||||
return cls(builder.Shape())
|
||||
|
||||
def dprism(self, basis, profiles, depth=None, taper=0, thruAll=True,
|
||||
|
||||
@ -438,10 +438,34 @@ class TestCadQuery(BaseTest):
|
||||
path = Workplane("XZ").polyline(pts)
|
||||
|
||||
# Test defaults
|
||||
result = Workplane("XY").circle(0.1).sweep(path)
|
||||
result = Workplane("XY").circle(0.1).sweep(path,transition='transformed')
|
||||
self.assertEqual(5, result.faces().size())
|
||||
self.assertEqual(7, result.edges().size())
|
||||
|
||||
# Polyline path and one inner profiles
|
||||
path = Workplane("XZ").polyline(pts)
|
||||
|
||||
# Test defaults
|
||||
result = Workplane("XY").circle(0.2).circle(0.1).sweep(path,transition='transformed')
|
||||
self.assertEqual(8, result.faces().size())
|
||||
self.assertEqual(14, result.edges().size())
|
||||
|
||||
# Polyline path and different transition settings
|
||||
for t in ('transformed','right','round'):
|
||||
path = Workplane("XZ").polyline(pts)
|
||||
|
||||
result = Workplane("XY").circle(0.2).rect(0.2,0.1).rect(0.1,0.2)\
|
||||
.sweep(path,transition=t)
|
||||
self.assertTrue(result.solids().val().isValid())
|
||||
|
||||
# Polyline path and multiple inner profiles
|
||||
path = Workplane("XZ").polyline(pts)
|
||||
|
||||
# Test defaults
|
||||
result = Workplane("XY").circle(0.2).rect(0.2,0.1).rect(0.1,0.2)\
|
||||
.circle(0.1).sweep(path)
|
||||
self.assertTrue(result.solids().val().isValid())
|
||||
|
||||
# Arc path
|
||||
path = Workplane("XZ").threePointArc((1.0, 1.5), (0.0, 1.0))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user