Export Arch Structure as Ifc Brep if not a simple extrusion

This commit is contained in:
alafr
2020-02-16 13:13:43 +01:00
committed by Yorik van Havre
parent 6ae04900b9
commit ac0268c904
3 changed files with 71 additions and 58 deletions

View File

@@ -318,7 +318,7 @@ class Component(ArchIFC.IfcProduct):
def getExtrusionData(self,obj):
"returns (shape,extrusion vector,placement) or None"
"returns (shape,extrusion vector or path,placement) or None"
if hasattr(obj,"CloneOf"):
if obj.CloneOf:
if hasattr(obj.CloneOf,"Proxy"):

View File

@@ -669,14 +669,14 @@ class _Structure(ArchComponent.Component):
else:
pli = pla[-1].copy()
shi.Placement = pli.multiply(shi.Placement)
extv = pla[0].Rotation.multVec(evi)
if obj.Tool:
if not isinstance(evi, FreeCAD.Vector):
try:
shi = obj.Tool.Shape.copy().makePipe(shi)
shi = evi.makePipe(shi)
except Part.OCCError:
FreeCAD.Console.PrintError(translate("Arch","Error: The base shape couldn't be extruded along this tool object")+"\n")
return
else:
extv = pla[0].Rotation.multVec(evi)
shi = shi.extrude(extv)
base.append(shi)
if len(base) == 1:
@@ -807,23 +807,31 @@ class _Structure(ArchComponent.Component):
baseface = Part.Face(Part.makePolygon([v1,v2,v3,v4,v1]))
base,placement = self.rebase(baseface)
if base and placement:
if obj.Normal.Length:
normal = Vector(obj.Normal)
if isinstance(placement,list):
normal = placement[0].inverse().Rotation.multVec(normal)
else:
normal = placement.inverse().Rotation.multVec(normal)
if not normal:
normal = Vector(0,0,1)
if not normal.Length:
normal = Vector(0,0,1)
extrusion = normal
if (length > height) and (IfcType != "Slab"):
if length:
extrusion = normal.multiply(length)
if obj.Tool:
if obj.Tool.Shape:
edges = obj.Tool.Shape.Edges
if len(edges) == 1 and DraftGeomUtils.geomType(edges[0]) == "Line":
extrusion = DraftGeomUtils.vec(edges[0])
else:
extrusion = obj.Tool.Shape.copy()
else:
if height:
extrusion = normal.multiply(height)
if obj.Normal.Length:
normal = Vector(obj.Normal)
if isinstance(placement,list):
normal = placement[0].inverse().Rotation.multVec(normal)
else:
normal = placement.inverse().Rotation.multVec(normal)
if not normal:
normal = Vector(0,0,1)
if not normal.Length:
normal = Vector(0,0,1)
extrusion = normal
if (length > height) and (IfcType != "Slab"):
if length:
extrusion = normal.multiply(length)
else:
if height:
extrusion = normal.multiply(height)
return (base,extrusion,placement)
return None

View File

@@ -1812,44 +1812,49 @@ def getRepresentation(ifcfile,context,obj,forcebrep=False,subtraction=False,tess
pl = extdata[2]
if not isinstance(pl,list):
pl = [pl]
for i in range(len(p)):
pi = p[i]
pi.scale(preferences['SCALE_FACTOR'])
if i < len(ev):
evi = FreeCAD.Vector(ev[i])
else:
evi = FreeCAD.Vector(ev[-1])
evi.multiply(preferences['SCALE_FACTOR'])
if i < len(pl):
pli = pl[i].copy()
else:
pli = pl[-1].copy()
pli.Base = pli.Base.multiply(preferences['SCALE_FACTOR'])
pstr = str([v.Point for v in p[i].Vertexes])
if pstr in profiledefs:
profile = profiledefs[pstr]
shapetype = "reusing profile"
else:
profile = getProfile(ifcfile,pi)
if profile:
profiledefs[pstr] = profile
if profile and not(DraftVecUtils.isNull(evi)):
#ev = pl.Rotation.inverted().multVec(evi)
#print("evi:",evi)
if not tostore:
# add the object placement to the profile placement. Otherwise it'll be done later at map insert
pl2 = obj.getGlobalPlacement()
pl2.Base = pl2.Base.multiply(preferences['SCALE_FACTOR'])
pli = pl2.multiply(pli)
xvc = ifcbin.createIfcDirection(tuple(pli.Rotation.multVec(FreeCAD.Vector(1,0,0))))
zvc = ifcbin.createIfcDirection(tuple(pli.Rotation.multVec(FreeCAD.Vector(0,0,1))))
ovc = ifcbin.createIfcCartesianPoint(tuple(pli.Base))
lpl = ifcbin.createIfcAxis2Placement3D(ovc,zvc,xvc)
edir = ifcbin.createIfcDirection(tuple(FreeCAD.Vector(evi).normalize()))
shape = ifcfile.createIfcExtrudedAreaSolid(profile,lpl,edir,evi.Length)
shapes.append(shape)
solidType = "SweptSolid"
shapetype = "extrusion"
simpleExtrusion = True
for evi in ev:
if not isinstance(evi, FreeCAD.Vector):
simpleExtrusion = False
if simpleExtrusion:
for i in range(len(p)):
pi = p[i]
pi.scale(preferences['SCALE_FACTOR'])
if i < len(ev):
evi = FreeCAD.Vector(ev[i])
else:
evi = FreeCAD.Vector(ev[-1])
evi.multiply(preferences['SCALE_FACTOR'])
if i < len(pl):
pli = pl[i].copy()
else:
pli = pl[-1].copy()
pli.Base = pli.Base.multiply(preferences['SCALE_FACTOR'])
pstr = str([v.Point for v in p[i].Vertexes])
if pstr in profiledefs:
profile = profiledefs[pstr]
shapetype = "reusing profile"
else:
profile = getProfile(ifcfile,pi)
if profile:
profiledefs[pstr] = profile
if profile and not(DraftVecUtils.isNull(evi)):
#ev = pl.Rotation.inverted().multVec(evi)
#print("evi:",evi)
if not tostore:
# add the object placement to the profile placement. Otherwise it'll be done later at map insert
pl2 = obj.getGlobalPlacement()
pl2.Base = pl2.Base.multiply(preferences['SCALE_FACTOR'])
pli = pl2.multiply(pli)
xvc = ifcbin.createIfcDirection(tuple(pli.Rotation.multVec(FreeCAD.Vector(1,0,0))))
zvc = ifcbin.createIfcDirection(tuple(pli.Rotation.multVec(FreeCAD.Vector(0,0,1))))
ovc = ifcbin.createIfcCartesianPoint(tuple(pli.Base))
lpl = ifcbin.createIfcAxis2Placement3D(ovc,zvc,xvc)
edir = ifcbin.createIfcDirection(tuple(FreeCAD.Vector(evi).normalize()))
shape = ifcfile.createIfcExtrudedAreaSolid(profile,lpl,edir,evi.Length)
shapes.append(shape)
solidType = "SweptSolid"
shapetype = "extrusion"
if not shapes: