diff --git a/src/Mod/Path/PathScripts/PathProfileEdges.py b/src/Mod/Path/PathScripts/PathProfileEdges.py index 515e0de5dd..26ee36d541 100644 --- a/src/Mod/Path/PathScripts/PathProfileEdges.py +++ b/src/Mod/Path/PathScripts/PathProfileEdges.py @@ -34,7 +34,6 @@ import PySide # lazily loaded modules from lazy_loader.lazy_loader import LazyLoader -Draft = LazyLoader('Draft', globals(), 'Draft') Part = LazyLoader('Part', globals(), 'Part') DraftGeomUtils = LazyLoader('DraftGeomUtils', globals(), 'DraftGeomUtils') @@ -51,6 +50,7 @@ __title__ = "Path Profile Edges Operation" __author__ = "sliptonic (Brad Collette)" __url__ = "http://www.freecadweb.org" __doc__ = "Path Profile operation based on edges." +__contributors__ = "russ4262 (Russell Johnson)" class ObjectProfile(PathProfileBase.ObjectProfile): @@ -69,8 +69,10 @@ class ObjectProfile(PathProfileBase.ObjectProfile): '''areaOpShapes(obj) ... returns envelope for all wires formed by the base edges.''' PathLog.track() - self.tmpGrp = FreeCAD.ActiveDocument.addObject('App::DocumentObjectGroup', 'tmpDebugGrp') - tmpGrpNm = self.tmpGrp.Name + inaccessible = translate('PathProfileEdges', 'The selected edge(s) are inaccessible. If multiple, re-ordering selection might work.') + if PathLog.getLevel(PathLog.thisModule()) == 4: + self.tmpGrp = FreeCAD.ActiveDocument.addObject('App::DocumentObjectGroup', 'tmpDebugGrp') + tmpGrpNm = self.tmpGrp.Name self.JOB = PathUtils.findParentJob(obj) self.offsetExtra = abs(obj.OffsetExtra.Value) @@ -104,7 +106,7 @@ class ObjectProfile(PathProfileBase.ObjectProfile): # f = Part.makeFace(wire, 'Part::FaceMakerSimple') # if planar error, Comment out previous line, uncomment the next two (origWire, flatWire) = self._flattenWire(obj, wire, obj.FinalDepth.Value) - f = origWire.Shape.Wires[0] + f = origWire.Wires[0] if f is not False: # shift the compound to the bottom of the base object for proper sectioning zShift = zMin - f.BoundBox.ZMin @@ -113,7 +115,7 @@ class ObjectProfile(PathProfileBase.ObjectProfile): env = PathUtils.getEnvelope(base.Shape, subshape=f, depthparams=self.depthparams) shapes.append((env, False)) else: - PathLog.error(translate('PathProfileEdges', 'The selected edge(s) are inaccessible.')) + PathLog.error(inaccessible) else: if self.JOB.GeometryTolerance.Value == 0.0: msg = self.JOB.Label + '.GeometryTolerance = 0.0.' @@ -121,76 +123,64 @@ class ObjectProfile(PathProfileBase.ObjectProfile): PathLog.error(msg) else: cutWireObjs = False - (origWire, flatWire) = self._flattenWire(obj, wire, obj.FinalDepth.Value) - cutShp = self._getCutAreaCrossSection(obj, base, origWire, flatWire) - if cutShp is not False: - cutWireObjs = self._extractPathWire(obj, base, flatWire, cutShp) + flattened = self._flattenWire(obj, wire, obj.FinalDepth.Value) + if flattened: + (origWire, flatWire) = flattened + if PathLog.getLevel(PathLog.thisModule()) == 4: + os = FreeCAD.ActiveDocument.addObject('Part::Feature', 'tmpFlatWire') + os.Shape = flatWire + os.purgeTouched() + self.tmpGrp.addObject(os) + cutShp = self._getCutAreaCrossSection(obj, base, origWire, flatWire) + if cutShp is not False: + cutWireObjs = self._extractPathWire(obj, base, flatWire, cutShp) - if cutWireObjs is not False: - for cW in cutWireObjs: - shapes.append((cW, False)) - self.profileEdgesIsOpen = True + if cutWireObjs is not False: + for cW in cutWireObjs: + shapes.append((cW, False)) + self.profileEdgesIsOpen = True + else: + PathLog.error(inaccessible) else: - PathLog.error(translate('PathProfileEdges', 'The selected edge(s) are inaccessible.')) + PathLog.error(inaccessible) # Delete the temporary objects - if PathLog.getLevel(PathLog.thisModule()) != 4: - for to in self.tmpGrp.Group: - FreeCAD.ActiveDocument.removeObject(to.Name) - FreeCAD.ActiveDocument.removeObject(tmpGrpNm) - else: + if PathLog.getLevel(PathLog.thisModule()) == 4: if FreeCAD.GuiUp: import FreeCADGui FreeCADGui.ActiveDocument.getObject(tmpGrpNm).Visibility = False - + self.tmpGrp.purgeTouched() + return shapes def _flattenWire(self, obj, wire, trgtDep): '''_flattenWire(obj, wire)... Return a flattened version of the wire''' PathLog.debug('_flattenWire()') wBB = wire.BoundBox - tmpGrp = self.tmpGrp - - OW = FreeCAD.ActiveDocument.addObject('Part::Feature', 'tmpOriginalWire') - OW.Shape = wire - OW.purgeTouched() - tmpGrp.addObject(OW) if wBB.ZLength > 0.0: PathLog.debug('Wire is not horizontally co-planar. Flattening it.') # Extrude non-horizontal wire extFwdLen = wBB.ZLength * 2.2 - mbbEXT = self._extrudeObject(OW, extFwdLen, False) + mbbEXT = wire.extrude(FreeCAD.Vector(0, 0, extFwdLen)) # Create cross-section of shape and translate sliceZ = wire.BoundBox.ZMin + (extFwdLen / 2) - crsectFaceShp = self._makeCrossSection(mbbEXT.Shape, sliceZ, trgtDep) + crsectFaceShp = self._makeCrossSection(mbbEXT, sliceZ, trgtDep) if crsectFaceShp is not False: - # srtWire = Part.Wire(Part.__sortEdges__(crsectFaceShp.Edges)) - FW = FreeCAD.ActiveDocument.addObject('Part::Feature', 'tmpFlattenedWire') - FW.Shape = crsectFaceShp # srtWire - FW.recompute() - FW.purgeTouched() - tmpGrp.addObject(FW) - - return (OW, FW) + return (wire, crsectFaceShp) else: return False else: srtWire = Part.Wire(Part.__sortEdges__(wire.Edges)) srtWire.translate(FreeCAD.Vector(0, 0, trgtDep - srtWire.BoundBox.ZMin)) - FW = FreeCAD.ActiveDocument.addObject('Part::Feature', 'tmpOriginalWireSorted') - FW.Shape = srtWire - FW.purgeTouched() - tmpGrp.addObject(FW) - return (OW, FW) + return (wire, srtWire) # Open-edges methods - def _getCutAreaCrossSection(self, obj, base, origWire, flatWireObj): + def _getCutAreaCrossSection(self, obj, base, origWire, flatWire): PathLog.debug('_getCutAreaCrossSection()') - tmpGrp = self.tmpGrp FCAD = FreeCAD.ActiveDocument tolerance = self.JOB.GeometryTolerance.Value toolDiam = 2 * self.radius # self.radius defined in PathAreaOp or PathProfileBase modules @@ -198,16 +188,16 @@ class ObjectProfile(PathProfileBase.ObjectProfile): bbBfr = (self.ofstRadius * 2) * 1.25 if bbBfr < minBfr: bbBfr = minBfr - fwBB = flatWireObj.Shape.BoundBox - wBB = origWire.Shape.BoundBox + fwBB = flatWire.BoundBox + wBB = origWire.BoundBox minArea = (self.ofstRadius - tolerance)**2 * math.pi - useWire = origWire.Shape.Wires[0] + useWire = origWire.Wires[0] numOrigEdges = len(useWire.Edges) sdv = wBB.ZMax fdv = obj.FinalDepth.Value extLenFwd = sdv - fdv - WIRE = flatWireObj.Shape.Wires[0] + WIRE = flatWire.Wires[0] numEdges = len(WIRE.Edges) # Identify first/last edges and first/last vertex on wire @@ -242,15 +232,24 @@ class ObjectProfile(PathProfileBase.ObjectProfile): # Create intersection tags for determining which side of wire to cut (begInt, begExt, iTAG, eTAG) = self._makeIntersectionTags(useWire, numOrigEdges, fdv) + if not begInt or not begExt: + return False self.iTAG = iTAG self.eTAG = eTAG # Create extended wire boundbox, and extrude extBndbox = self._makeExtendedBoundBox(wBB, bbBfr, fdv) - extBndboxEXT = self._extrudeObject(extBndbox, extLenFwd) # (objToExt, extFwdLen) + extBndboxEXT = extBndbox.extrude(FreeCAD.Vector(0, 0, extLenFwd)) # Cut model(selected edges) from extended edges boundbox - cutArea = extBndboxEXT.Shape.cut(base.Shape) + cutArea = extBndboxEXT.cut(base.Shape) + if PathLog.getLevel(PathLog.thisModule()) == 4: + CA = FCAD.addObject('Part::Feature', 'tmpCutArea') + CA.Shape = cutArea + CA.recompute() + CA.purgeTouched() + self.tmpGrp.addObject(CA) + # Get top and bottom faces of cut area (CA), and combine faces when necessary topFc = list() @@ -270,8 +269,8 @@ class ObjectProfile(PathProfileBase.ObjectProfile): topComp.translate(FreeCAD.Vector(0, 0, fdv - topComp.BoundBox.ZMin)) # Translate face to final depth if len(botFc) > 1: PathLog.debug('len(botFc) > 1') - bndboxFace = Part.Face(extBndbox.Shape.Wires[0]) - tmpFace = Part.Face(extBndbox.Shape.Wires[0]) + bndboxFace = Part.Face(extBndbox.Wires[0]) + tmpFace = Part.Face(extBndbox.Wires[0]) for f in botFc: Q = tmpFace.cut(cutArea.Faces[f]) tmpFace = Q @@ -280,38 +279,20 @@ class ObjectProfile(PathProfileBase.ObjectProfile): botComp = Part.makeCompound([cutArea.Faces[f] for f in botFc]) # Part.makeCompound([CA.Shape.Faces[f] for f in botFc]) botComp.translate(FreeCAD.Vector(0, 0, fdv - botComp.BoundBox.ZMin)) # Translate face to final depth - # Convert compound shapes to FC objects for use in multicommon operation - TP = FCAD.addObject('Part::Feature', 'tmpTopCompound') - TP.Shape = topComp - TP.recompute() - TP.purgeTouched() - tmpGrp.addObject(TP) - BT = FCAD.addObject('Part::Feature', 'tmpBotCompound') - BT.Shape = botComp - BT.recompute() - BT.purgeTouched() - tmpGrp.addObject(BT) - # Make common of the two - comFC = FCAD.addObject('Part::MultiCommon', 'tmpCommonTopBotFaces') - comFC.Shapes = [TP, BT] - comFC.recompute() - TP.purgeTouched() - BT.purgeTouched() - comFC.purgeTouched() - tmpGrp.addObject(comFC) + comFC = topComp.common(botComp) # Determine with which set of intersection tags the model intersects (cmnIntArea, cmnExtArea) = self._checkTagIntersection(iTAG, eTAG, 'QRY', comFC) if cmnExtArea > cmnIntArea: PathLog.debug('Cutting on Ext side.') self.cutSide = 'E' - self.cutSideTags = eTAG.Shape + self.cutSideTags = eTAG tagCOM = begExt.CenterOfMass else: PathLog.debug('Cutting on Int side.') self.cutSide = 'I' - self.cutSideTags = iTAG.Shape + self.cutSideTags = iTAG tagCOM = begInt.CenterOfMass # Make two beginning style(oriented) 'L' shape stops @@ -331,9 +312,9 @@ class ObjectProfile(PathProfileBase.ObjectProfile): pathStops.translate(FreeCAD.Vector(0, 0, fdv - pathStops.BoundBox.ZMin)) # Identify closed wire in cross-section that corresponds to user-selected edge(s) - workShp = comFC.Shape + workShp = comFC fcShp = workShp - wire = origWire.Shape # flatWireObj.Shape + wire = origWire WS = workShp.Wires lenWS = len(WS) if lenWS < 3: @@ -354,7 +335,6 @@ class ObjectProfile(PathProfileBase.ObjectProfile): if wi is None: PathLog.error('The cut area cross-section wire does not coincide with selected edge. Wires[] index is None.') - tmpGrp.purgeTouched() return False else: PathLog.debug('Cross-section Wires[] index is {}.'.format(wi)) @@ -368,13 +348,8 @@ class ObjectProfile(PathProfileBase.ObjectProfile): if wi > 0: # and isInterior is False: PathLog.debug('Multiple wires in cut area. First choice is not 0. Testing.') testArea = fcShp.cut(base.Shape) - # testArea = fcShp - TA = FreeCAD.ActiveDocument.addObject('Part::Feature','tmpCutFaceTest') - TA.Shape = testArea - TA.purgeTouched() - tmpGrp.addObject(TA) - isReady = self._checkTagIntersection(iTAG, eTAG, self.cutSide, TA) + isReady = self._checkTagIntersection(iTAG, eTAG, self.cutSide, testArea) PathLog.debug('isReady {}.'.format(isReady)) if isReady is False: @@ -395,38 +370,18 @@ class ObjectProfile(PathProfileBase.ObjectProfile): # Add path stops at ends of wire cutShp = workShp.cut(pathStops) - - CF = FreeCAD.ActiveDocument.addObject('Part::Feature','tmpCutFace') - CF.Shape = cutShp - CF.recompute() - CF.purgeTouched() - tmpGrp.addObject(CF) - - tmpGrp.purgeTouched() - return cutShp # CF.Shape + return cutShp def _checkTagIntersection(self, iTAG, eTAG, cutSide, tstObj): # Identify intersection of Common area and Interior Tags - intCmn = FreeCAD.ActiveDocument.addObject('Part::MultiCommon', 'tmpCmnIntTags') - intCmn.Shapes = [tstObj, iTAG] - intCmn.recompute() - tstObj.purgeTouched() - iTAG.purgeTouched() - intCmn.purgeTouched() - self.tmpGrp.addObject(intCmn) + intCmn = tstObj.common(iTAG) # Identify intersection of Common area and Exterior Tags - extCmn = FreeCAD.ActiveDocument.addObject('Part::MultiCommon', 'tmpCmnExtTags') - extCmn.Shapes = [tstObj, eTAG] - extCmn.recompute() - tstObj.purgeTouched() - eTAG.purgeTouched() - extCmn.purgeTouched() - self.tmpGrp.addObject(extCmn) + extCmn = tstObj.common(eTAG) # Calculate common intersection (solid model side, or the non-cut side) area with tags, to determine physical cut side - cmnIntArea = intCmn.Shape.Area - cmnExtArea = extCmn.Shape.Area + cmnIntArea = intCmn.Area + cmnExtArea = extCmn.Area if cutSide == 'QRY': return (cmnIntArea, cmnExtArea) @@ -440,16 +395,15 @@ class ObjectProfile(PathProfileBase.ObjectProfile): return True return False - def _extractPathWire(self, obj, base, fWire, cutShp): + def _extractPathWire(self, obj, base, flatWire, cutShp): PathLog.debug('_extractPathWire()') subLoops = list() rtnWIRES = list() osWrIdxs = list() subDistFactor = 1.0 # Raise to include sub wires at greater distance from original - tmpGrp = self.tmpGrp fdv = obj.FinalDepth.Value - wire = fWire.Shape + wire = flatWire lstVrtIdx = len(wire.Vertexes) - 1 lstVrt = wire.Vertexes[lstVrtIdx] frstVrt = wire.Vertexes[0] @@ -468,14 +422,14 @@ class ObjectProfile(PathProfileBase.ObjectProfile): osArea = ofstShp.Area except Exception as ee: PathLog.error('No area to offset shape returned.') - tmpGrp.purgeTouched() return False - os = FreeCAD.ActiveDocument.addObject('Part::Feature', 'tmpOffsetShape') - os.Shape = ofstShp - os.recompute() - os.purgeTouched() - tmpGrp.addObject(os) + if PathLog.getLevel(PathLog.thisModule()) == 4: + os = FreeCAD.ActiveDocument.addObject('Part::Feature', 'tmpOffsetShape') + os.Shape = ofstShp + os.recompute() + os.purgeTouched() + self.tmpGrp.addObject(os) numOSWires = len(ofstShp.Wires) for w in range(0, numOSWires): @@ -491,10 +445,12 @@ class ObjectProfile(PathProfileBase.ObjectProfile): min0 = N[4] min0i = n (w0, vi0, pnt0, vrt0, d0) = NEAR0[0] # min0i - near0 = Draft.makeWire([cent0, pnt0], placement=pl, closed=False, face=False, support=None) - near0.recompute() - near0.purgeTouched() - tmpGrp.addObject(near0) + if PathLog.getLevel(PathLog.thisModule()) == 4: + near0 = FreeCAD.ActiveDocument.addObject('Part::Feature', 'tmpNear0') + near0.Shape = Part.makeLine(cent0, pnt0) + near0.recompute() + near0.purgeTouched() + self.tmpGrp.addObject(near0) NEAR1 = self._findNearestVertex(ofstShp, cent1) min1i = 0 @@ -505,24 +461,23 @@ class ObjectProfile(PathProfileBase.ObjectProfile): min1 = N[4] min1i = n (w1, vi1, pnt1, vrt1, d1) = NEAR1[0] # min1i - near1 = Draft.makeWire([cent1, pnt1], placement=pl, closed=False, face=False, support=None) - near1.recompute() - near1.purgeTouched() - tmpGrp.addObject(near1) + if PathLog.getLevel(PathLog.thisModule()) == 4: + near1 = FreeCAD.ActiveDocument.addObject('Part::Feature', 'tmpNear1') + near1.Shape = Part.makeLine(cent1, pnt1) + near1.recompute() + near1.purgeTouched() + self.tmpGrp.addObject(near1) if w0 != w1: - PathLog.debug('w0 is {}.'.format(w0)) - PathLog.debug('w1 is {}.'.format(w1)) - PathLog.warning('Offset wire endpoint indexes are not equal: {}, {}'.format(w0, w1)) + PathLog.warning('Offset wire endpoint indexes are not equal - w0, w1: {}, {}'.format(w0, w1)) - ''' - PathLog.debug('min0i is {}.'.format(min0i)) - PathLog.debug('min1i is {}.'.format(min1i)) - PathLog.debug('NEAR0[{}] is {}.'.format(w0, NEAR0[w0])) - PathLog.debug('NEAR1[{}] is {}.'.format(w1, NEAR1[w1])) - PathLog.debug('NEAR0 is {}.'.format(NEAR0)) - PathLog.debug('NEAR1 is {}.'.format(NEAR1)) - ''' + if PathLog.getLevel(PathLog.thisModule()) == 4: + PathLog.debug('min0i is {}.'.format(min0i)) + PathLog.debug('min1i is {}.'.format(min1i)) + PathLog.debug('NEAR0[{}] is {}.'.format(w0, NEAR0[w0])) + PathLog.debug('NEAR1[{}] is {}.'.format(w1, NEAR1[w1])) + PathLog.debug('NEAR0 is {}.'.format(NEAR0)) + PathLog.debug('NEAR1 is {}.'.format(NEAR1)) mainWire = ofstShp.Wires[w0] @@ -553,7 +508,6 @@ class ObjectProfile(PathProfileBase.ObjectProfile): # Eif # Break offset loop into two wires - one of which is the desired profile path wire. - # (edgeIdxs0, edgeIdxs1) = self._separateWireAtVertexes(mainWire, ofstShp.Vertexes[vi0], ofstShp.Vertexes[vi1]) (edgeIdxs0, edgeIdxs1) = self._separateWireAtVertexes(mainWire, mainWire.Vertexes[vi0], mainWire.Vertexes[vi1]) edgs0 = list() edgs1 = list() @@ -573,7 +527,6 @@ class ObjectProfile(PathProfileBase.ObjectProfile): rtnWIRES.append(part1) rtnWIRES.extend(subLoops) - tmpGrp.purgeTouched() return rtnWIRES def _extractFaceOffset(self, obj, fcShape, isHole): @@ -608,13 +561,7 @@ class ObjectProfile(PathProfileBase.ObjectProfile): area.add(fcShape) # obj.Shape to use for extracting offset area.setParams(**areaParams) # set parameters - # Save parameters for debugging - # obj.AreaParams = str(area.getParams()) - # PathLog.debug("Area with params: {}".format(area.getParams())) - - offsetShape = area.getShape() - - return offsetShape + return area.getShape() def _findNearestVertex(self, shape, point): PathLog.debug('_findNearestVertex()') @@ -795,29 +742,17 @@ class ObjectProfile(PathProfileBase.ObjectProfile): return False def _makeExtendedBoundBox(self, wBB, bbBfr, zDep): - pl = FreeCAD.Placement() - pl.Rotation = FreeCAD.Rotation(FreeCAD.Vector(0, 0, 1), 0) - pl.Base = FreeCAD.Vector(0, 0, 0) - p1 = FreeCAD.Vector(wBB.XMin - bbBfr, wBB.YMin - bbBfr, zDep) p2 = FreeCAD.Vector(wBB.XMax + bbBfr, wBB.YMin - bbBfr, zDep) p3 = FreeCAD.Vector(wBB.XMax + bbBfr, wBB.YMax + bbBfr, zDep) p4 = FreeCAD.Vector(wBB.XMin - bbBfr, wBB.YMax + bbBfr, zDep) - bb = Draft.makeWire([p1, p2, p3, p4], placement=pl, closed=True, face=False, support=None) - bb.Label = 'ProfileEdges_BoundBox' - bb.recompute() - bb.purgeTouched() - self.tmpGrp.addObject(bb) - return bb + L1 = Part.makeLine(p1, p2) + L2 = Part.makeLine(p2, p3) + L3 = Part.makeLine(p3, p4) + L4 = Part.makeLine(p4, p1) - def _makeSimpleCircle(self, rad, plcmnt, isFace=False, label='SimpleCircle'): - C = Draft.makeCircle(rad, placement=plcmnt, face=isFace) - C.Label = 'tmp' + label - C.recompute() - C.purgeTouched() - self.tmpGrp.addObject(C) - return C + return Part.Face(Part.Wire([L1, L2, L3, L4])) def _makeIntersectionTags(self, useWire, numOrigEdges, fdv): # Create circular probe tags around perimiter of wire @@ -825,8 +760,8 @@ class ObjectProfile(PathProfileBase.ObjectProfile): intTags = list() tagRad = (self.radius / 2) tagCnt = 0 - begInt = None - begExt = None + begInt = False + begExt = False for e in range(0, numOrigEdges): E = useWire.Edges[e] LE = E.Length @@ -846,31 +781,22 @@ class ObjectProfile(PathProfileBase.ObjectProfile): cp1 = E.valueAt(E.getParameterByLength(0)) cp2 = E.valueAt(E.getParameterByLength(aspc)) (intTObj, extTObj) = self._makeOffsetCircleTag(cp1, cp2, tagRad, fdv, 'BeginEdge[{}]_'.format(e)) - if intTObj is not False: - begInt = intTObj.Shape - begExt = extTObj.Shape + if intTObj and extTObj: + begInt = intTObj + begExt = extTObj else: d = i * mid cp1 = E.valueAt(E.getParameterByLength(d - spc)) cp2 = E.valueAt(E.getParameterByLength(d + spc)) (intTObj, extTObj) = self._makeOffsetCircleTag(cp1, cp2, tagRad, fdv, 'Edge[{}]_'.format(e)) - if intTObj is not False: + if intTObj and extTObj: tagCnt += nt intTags.append(intTObj) extTags.append(extTObj) tagArea = math.pi * tagRad**2 * tagCnt - # FreeCAD object required for Part::MultiCommon usage - intTagsComp = Part.makeCompound([T.Shape for T in intTags]) - iTAG = FreeCAD.ActiveDocument.addObject('Part::Feature', 'tmpInteriorTags') - iTAG.Shape = intTagsComp - iTAG.purgeTouched() - self.tmpGrp.addObject(iTAG) - # FreeCAD object required for Part::MultiCommon usage - extTagsComp = Part.makeCompound([T.Shape for T in extTags]) - eTAG = FreeCAD.ActiveDocument.addObject('Part::Feature', 'tmpExteriorTags') - eTAG.Shape = extTagsComp - eTAG.purgeTouched() - self.tmpGrp.addObject(eTAG) + iTAG = Part.makeCompound(intTags) + eTAG = Part.makeCompound(extTags) + return (begInt, begExt, iTAG, eTAG) def _makeOffsetCircleTag(self, p1, p2, cutterRad, depth, lbl, reverse=False): @@ -890,32 +816,19 @@ class ObjectProfile(PathProfileBase.ObjectProfile): pl = FreeCAD.Placement() pl.Rotation = FreeCAD.Rotation(FreeCAD.Vector(0, 0, 1), 0) # make exterior tag - adjlbl = lbl + 'Ext' - pl.Base = extPnt.add(FreeCAD.Vector(0, 0, depth)) - extTag = self._makeSimpleCircle((cutterRad / 2), pl, True, adjlbl) + eCntr = extPnt.add(FreeCAD.Vector(0, 0, depth)) + ecw = Part.Wire(Part.makeCircle((cutterRad / 2), eCntr).Edges[0]) + extTag = Part.Face(ecw) # make interior tag - adjlbl = lbl + 'Int' perpI = FreeCAD.Vector(-1 * toMid.y, toMid.x, 0.0).multiply(cutFactor) # interior tag intPnt = pb.add(toMid.add(perpI)) - pl.Base = intPnt.add(FreeCAD.Vector(0, 0, depth)) - intTag = self._makeSimpleCircle((cutterRad / 2), pl, True, adjlbl) + iCntr = intPnt.add(FreeCAD.Vector(0, 0, depth)) + icw = Part.Wire(Part.makeCircle((cutterRad / 2), iCntr).Edges[0]) + intTag = Part.Face(icw) return (intTag, extTag) - def _extrudeObject(self, objToExt, extFwdLen, solid=True): - # Extrude non-horizontal wire - E = FreeCAD.ActiveDocument.addObject('Part::Extrusion', 'tmpExtrusion') - E.Base = objToExt - E.DirMode = 'Custom' - E.Dir = FreeCAD.Vector(0, 0, 1) - E.LengthFwd = extFwdLen - E.Solid = solid - E.recompute() - E.purgeTouched() - self.tmpGrp.addObject(E) - return E - def _makeStop(self, sType, pA, pB, lbl): rad = self.radius ofstRad = self.ofstRadius @@ -953,7 +866,13 @@ class ObjectProfile(PathProfileBase.ObjectProfile): p5 = self._makePerp2DVector(p3, p4, -1 * (1 + extra)) # E4 p6 = self._makePerp2DVector(p4, p5, -1 * (ofstRad + extra)) # E5 p7 = E # E6 - S = Draft.makeWire([p1, p2, p3, p4, p5, p6, p7], placement=pl, closed=True, face=True) + L1 = Part.makeLine(p1, p2) + L2 = Part.makeLine(p2, p3) + L3 = Part.makeLine(p3, p4) + L4 = Part.makeLine(p4, p5) + L5 = Part.makeLine(p5, p6) + L6 = Part.makeLine(p6, p7) + wire = Part.Wire([L1, L2, L3, L4, L5, L6]) else: # 'L' stop shape and edge legend # : @@ -973,13 +892,22 @@ class ObjectProfile(PathProfileBase.ObjectProfile): p4 = self._makePerp2DVector(p2, p3, -1 * (0.5 + abs(self.offsetExtra))) # FIRST POINT p5 = self._makePerp2DVector(p3, p4, -1 * (0.25 + abs(self.offsetExtra))) # E1 SECOND p6 = p1 # E4 - S = Draft.makeWire([p1, p2, p3, p4, p5, p6], placement=pl, closed=True, face=True) + L1 = Part.makeLine(p1, p2) + L2 = Part.makeLine(p2, p3) + L3 = Part.makeLine(p3, p4) + L4 = Part.makeLine(p4, p5) + L5 = Part.makeLine(p5, p6) + wire = Part.Wire([L1, L2, L3, L4, L5]) # Eif - S.Label = 'tmp' + lbl - S.recompute() - S.purgeTouched() - self.tmpGrp.addObject(S) - return S.Shape + face = Part.Face(wire) + if PathLog.getLevel(PathLog.thisModule()) == 4: + os = FreeCAD.ActiveDocument.addObject('Part::Feature', 'tmp' + lbl) + os.Shape = face + os.recompute() + os.purgeTouched() + self.tmpGrp.addObject(os) + + return face def _makePerp2DVector(self, v1, v2, dist): p1 = FreeCAD.Vector(v1.x, v1.y, 0.0)