Merge pull request #8187 from paullee0/ArchStructure_1_Select-ArchSketch-Edges

[ArchStructure] ArchSketch Feature : Select Edges to build shape
This commit is contained in:
Yorik van Havre
2023-01-17 09:28:43 +01:00
committed by GitHub

View File

@@ -707,6 +707,17 @@ class _Structure(ArchComponent.Component):
if not "FaceMaker" in pl:
obj.addProperty("App::PropertyEnumeration","FaceMaker","Structure",QT_TRANSLATE_NOOP("App::Property","The facemaker type to use to build the profile of this object"))
obj.FaceMaker = ["None","Simple","Cheese","Bullseye"]
if not "ArchSketchEdges" in pl: # PropertyStringList
obj.addProperty("App::PropertyStringList","ArchSketchEdges","Structure",QT_TRANSLATE_NOOP("App::Property","Selected edges (or group of edges) of the base ArchSketch, to use in creating the shape of this Arch Structure (instead of using all the Base shape's edges by default). Input are index numbers of edges or groups."))
else:
# test if the property was added but as IntegerList, then update;
type = obj.getTypeIdOfProperty('ArchSketchEdges')
if type == "App::PropertyIntegerList":
oldIntValue = obj.ArchSketchEdges
newStrValue = [str(x) for x in oldIntValue]
obj.removeProperty("ArchSketchEdges")
obj.addProperty("App::PropertyStringList","ArchSketchEdges","Structure",QT_TRANSLATE_NOOP("App::Property","Selected edges (or group of edges) of the base ArchSketch, to use in creating the shape of this Arch Structure (instead of using all the Base shape's edges by default). Input are index numbers of edges or groups."))
obj.ArchSketchEdges = newStrValue
self.Type = "Structure"
def onDocumentRestored(self,obj):
@@ -723,10 +734,10 @@ class _Structure(ArchComponent.Component):
if self.clone(obj):
return
import Part, DraftGeomUtils
base = None
pl = obj.Placement
extdata = self.getExtrusionData(obj)
if extdata:
sh = extdata[0]
if not isinstance(sh,list):
@@ -827,15 +838,34 @@ class _Structure(ArchComponent.Component):
else:
baseface = obj.Base.Shape.copy()
elif obj.Base.Shape.Wires:
if hasattr(obj,"FaceMaker"):
if obj.FaceMaker != "None":
try:
baseface = Part.makeFace(obj.Base.Shape.Wires,"Part::FaceMaker"+str(obj.FaceMaker))
except Exception:
FreeCAD.Console.PrintError(translate("Arch","Facemaker returned an error")+"\n")
return None
# ArchSketch feature :
# Get base shape wires, and faceMaker, for Structure (slab. etc.) from Base Objects if they store and provide by getStructureBaseShapeWires()
# (thickness, normal/extrusion, length, width, baseface maybe for later) of structure (slab etc.)
structureBaseShapeWires = None
baseShapeWires = None #baseSlabWires / baseSlabOpeningWires = None
faceMaker = None
if hasattr(obj.Base, 'Proxy'):
if hasattr(obj.Base.Proxy, 'getStructureBaseShapeWires'):
structureBaseShapeWires = obj.Base.Proxy.getStructureBaseShapeWires(obj.Base, archsketchEdges=obj.ArchSketchEdges)
# provide selected edges, or groups, in obj.ArchSketchEdges for processing in getStructureBaseShapeWires() (getSortedClusters) as override
# returned a {dict} ( or a [list] )
# get slab wires; use original wires if structureBaseShapeWires() provided none
if structureBaseShapeWires: # would be false (none) if both base ArchSketch and obj do not have the edges stored / inputed by user
# if structureBaseShapeWires is {dict}
baseShapeWires = structureBaseShapeWires.get('slabWires')
faceMaker = structureBaseShapeWires.get('faceMaker')
if not baseShapeWires:
baseShapeWires = obj.Base.Shape.Wires
if faceMaker or (obj.FaceMaker != "None"):
if not faceMaker:
faceMaker = obj.FaceMaker
try:
baseface = Part.makeFace(baseShapeWires,"Part::FaceMaker"+str(faceMaker))
except Exception:
FreeCAD.Console.PrintError(translate("Arch","Facemaker returned an error")+"\n")
# Not returning even Part.makeFace fails, fall back to 'non-Part.makeFace' method
if not baseface:
for w in obj.Base.Shape.Wires:
for w in baseShapeWires:
if not w.isClosed():
p0 = w.OrderedVertexes[0].Point
p1 = w.OrderedVertexes[-1].Point
@@ -844,9 +874,11 @@ class _Structure(ArchComponent.Component):
w.add(e)
w.fix(0.1,0,1) # fixes self-intersecting wires
f = Part.Face(w)
# check if it is 1st face (f) created from w in baseShapeWires; if not, fuse()
if baseface:
baseface = baseface.fuse(f)
else:
# TODO use Part.Shape() rather than shape.copy() ... ?
baseface = f.copy()
elif length and width and height:
if (length > height) and (IfcType != "Slab"):
@@ -894,14 +926,14 @@ class _Structure(ArchComponent.Component):
if obj.Normal.Length:
normal = Vector(obj.Normal).normalize()
else:
normal = baseface.Faces[0].normalAt(0, 0)
normal = baseface.Faces[0].normalAt(0, 0) ## TODO to use ArchSketch's 'normal' for consistency
base = None
placement = None
inverse_placement = None
if len(baseface.Faces) > 1:
base = []
placement = []
hint = baseface.Faces[0].normalAt(0, 0)
hint = baseface.Faces[0].normalAt(0, 0) ## TODO anything to do ?
for f in baseface.Faces:
bf, pf = self.rebase(f, hint)
base.append(bf)
@@ -1128,7 +1160,7 @@ class _ViewProviderStructure(ArchComponent.ViewProviderComponent):
else:
ArchComponent.ViewProviderComponent.onChanged(self,vobj,prop)
def setEdit(self, vobj, mode):
def setEdit(self,vobj,mode):
if mode != 0:
return None