From 97c40204a43352d63a238f2987c9497d460144d2 Mon Sep 17 00:00:00 2001 From: paullee0 Date: Mon, 10 Feb 2020 01:01:32 +0800 Subject: [PATCH] [ArchWall, DraftGeomUtils] fix bug: ArchWall with Offset Attribute set and based on Sketch fails at some cases DraftGeomUtils.offsetWire() supports ArchWall Offset setting inherently now. Discussion: https://forum.freecadweb.org/viewtopic.php?f=23&t=42933 --- src/Mod/Arch/ArchWall.py | 30 +++++++++++++++++++----------- src/Mod/Draft/DraftGeomUtils.py | 15 +++++++++++++-- 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/src/Mod/Arch/ArchWall.py b/src/Mod/Arch/ArchWall.py index 07a3b663bd..831c83f49c 100644 --- a/src/Mod/Arch/ArchWall.py +++ b/src/Mod/Arch/ArchWall.py @@ -742,6 +742,7 @@ class _Wall(ArchComponent.Component): return base = self.processSubShapes(obj,base,pl) + self.applyShape(obj,base,pl) # count blocks @@ -1037,16 +1038,18 @@ class _Wall(ArchComponent.Component): layeroffset += abs(layers[i]) else: dvec.multiply(width) - if off: - dvec2 = DraftVecUtils.scaleTo(dvec,off) - wire = DraftGeomUtils.offsetWire(wire,dvec2) + # Now DraftGeomUtils.offsetWire() support similar effect as ArchWall Offset + # + #if off: + # dvec2 = DraftVecUtils.scaleTo(dvec,off) + # wire = DraftGeomUtils.offsetWire(wire,dvec2) - # Get the 'offseted' wire taking into account of width and align of each edge - w2 = DraftGeomUtils.offsetWire(wire,dvec,False,False,widths,None,aligns,normal) + # Get the 'offseted' wire taking into account of Width and Align of each edge, and overall Offset + w2 = DraftGeomUtils.offsetWire(wire,dvec,False,False,widths,None,aligns,normal,off) # Get the 'base' wire taking into account of width and align of each edge - w1 = DraftGeomUtils.offsetWire(wire,dvec,False,False,widths,"BasewireMode",aligns,normal) + w1 = DraftGeomUtils.offsetWire(wire,dvec,False,False,widths,"BasewireMode",aligns,normal,off) sh = DraftGeomUtils.bind(w1,w2) elif curAligns == "Right": @@ -1058,12 +1061,15 @@ class _Wall(ArchComponent.Component): layeroffset += abs(layers[i]) else: dvec.multiply(width) - if off: - dvec2 = DraftVecUtils.scaleTo(dvec,off) - wire = DraftGeomUtils.offsetWire(wire,dvec2) - w2 = DraftGeomUtils.offsetWire(wire,dvec,False,False,widths,None,aligns,normal) - w1 = DraftGeomUtils.offsetWire(wire,dvec,False,False,widths,"BasewireMode",aligns,normal) + # Now DraftGeomUtils.offsetWire() support similar effect as ArchWall Offset + # + #if off: + # dvec2 = DraftVecUtils.scaleTo(dvec,off) + # wire = DraftGeomUtils.offsetWire(wire,dvec2) + + w2 = DraftGeomUtils.offsetWire(wire,dvec,False,False,widths,None,aligns,normal,off) + w1 = DraftGeomUtils.offsetWire(wire,dvec,False,False,widths,"BasewireMode",aligns,normal,off) sh = DraftGeomUtils.bind(w1,w2) #elif obj.Align == "Center": @@ -1085,7 +1091,9 @@ class _Wall(ArchComponent.Component): del widths[0:edgeNum] del aligns[0:edgeNum] if sh: + sh.fix(0.1,0,1) # fixes self-intersecting wires + f = Part.Face(sh) if baseface: diff --git a/src/Mod/Draft/DraftGeomUtils.py b/src/Mod/Draft/DraftGeomUtils.py index 67865dd3a8..8537cfb5cb 100644 --- a/src/Mod/Draft/DraftGeomUtils.py +++ b/src/Mod/Draft/DraftGeomUtils.py @@ -1196,7 +1196,7 @@ def calculatePlacement(shape): return pla -def offsetWire(wire,dvec,bind=False,occ=False,widthList=None, offsetMode=None, alignList=[], normal=None): # offsetMode="BasewireMode" or None +def offsetWire(wire,dvec,bind=False,occ=False,widthList=None, offsetMode=None, alignList=[], normal=None, basewireOffset=0): # offsetMode="BasewireMode" or None ''' offsetWire(wire,vector,[bind]): offsets the given wire along the given vector. The vector will be applied at the first vertex of the wire. If bind @@ -1216,6 +1216,8 @@ def offsetWire(wire,dvec,bind=False,occ=False,widthList=None, offsetMode=None, a OffsetWire() is now aware of width and align per edge (Primarily for use with ArchWall based on Sketch object ) 'dvec' vector to offset is now derived (and can be ignored) in this function if widthList and alignList are provided - 'dvec' to be obsolete in future ? + + 'basewireOffset' corresponds to 'offset' in ArchWall which offset the basewire before creating the wall outline ''' # Accept 'wire' as a list of edges (use the list directly), or previously as a wire or a face (Draft Wire with MakeFace True or False supported) @@ -1379,6 +1381,8 @@ def offsetWire(wire,dvec,bind=False,occ=False,widthList=None, offsetMode=None, a nedge = offset(curredge,delta,trim=True) else: # if curAlign in ['Left', 'Right']: # elif curAlign == 'Center': # Both conditions same result.. + if basewireOffset: # ArchWall has an Offset properties for user to offset the basewire before creating the base profile of wall (not applicable to 'Center' align) + delta = DraftVecUtils.scaleTo(delta, delta.Length+basewireOffset) nedge = offset(curredge,delta,trim=True) if curOrientation == "Reversed": # TODO arc alway in counter-clockwise directinon ... ( not necessarily 'reversed') @@ -1396,13 +1400,20 @@ def offsetWire(wire,dvec,bind=False,occ=False,widthList=None, offsetMode=None, a elif offsetMode in ["BasewireMode"]: if not ( (curOrientation == firstOrientation) != (curDir == firstDir) ): if curAlign in ['Left', 'Right']: - nedge = curredge + if basewireOffset: # ArchWall has an Offset properties for user to offset the basewire before creating the base profile of wall (not applicable to 'Center' align) + delta = DraftVecUtils.scaleTo(delta, basewireOffset) + nedge = offset(curredge,delta,trim=True) + else: + nedge = curredge elif curAlign == 'Center': delta = delta.negative() nedge = offset(curredge,delta,trim=True) else: if curAlign in ['Left', 'Right']: + if basewireOffset: # ArchWall has an Offset properties for user to offset the basewire before creating the base profile of wall (not applicable to 'Center' align) + delta = DraftVecUtils.scaleTo(delta, delta.Length+basewireOffset) nedge = offset(curredge,delta,trim=True) + elif curAlign == 'Center': nedge = offset(curredge,delta,trim=True) if curOrientation == "Reversed":