Arch: Added IFC pref option to automatically export IFC objects as Standard Cases when possible

This commit is contained in:
Yorik van Havre
2019-05-08 21:58:04 -03:00
parent af0cb40682
commit 2876e82faa
3 changed files with 78 additions and 0 deletions

View File

@@ -678,6 +678,56 @@ class Component:
if obj.PerimeterLength.Value != self.flatarea.Faces[0].OuterWire.Length:
obj.PerimeterLength = self.flatarea.Faces[0].OuterWire.Length
def isStandardCase(self,obj):
# Standard Case has been set manually by the user
if obj.IfcType.endswith("Standard Case"):
return True
# Try to guess
import ArchIFC
if obj.IfcType + " Standard Case" in ArchIFC.IfcTypes:
# this type has a standard case
if obj.Additions or obj.Subtractions:
return False
if obj.Placement.Rotation.Axis.getAngle(FreeCAD.Vector(0,0,1)) > 0.01:
# reject rotated objects
return False
if obj.CloneOf:
return obj.CloneOf.Proxy.isStandardCase(obj.CloneOf)
if obj.IfcType == "Wall":
# rules:
# - vertically extruded
# - single baseline or no baseline
if (not obj.Base) or (len(obj.Base.Shape.Edges) == 1):
if hasattr(obj,"Normal"):
if obj.Normal in [FreeCAD.Vector(0,0,0),FreeCAD.Vector(0,0,1)]:
return True
elif obj.IfcType in ["Beam","Column","Slab"]:
# rules:
# - have a single-wire profile or no profile
# - extrusion direction is perpendicular to the profile
if obj.Base and (len(obj.Base.Shape.Wires) != 1):
return False
if not hasattr(obj,"Normal"):
return False
if hasattr(obj,"Tool") and obj.Tool:
return False
if obj.Normal == FreeCAD.Vector(0,0,0):
return True
elif len(obj.Base.Shape.Wires) == 1:
import DraftGeomUtils
n = DraftGeomUtils.getNormal(obj.Base.Shape)
if n:
if (n.getAngle(obj.Normal) < 0.01) or (abs(n.getAngle(obj.Normal)-3.14159) < 0.01):
return True
# TODO: Support windows and doors
# rules:
# - must have a rectangular shape
# - must have a host
# - must be parallel to the host plane
# - must have an IfcWindowType and IfcRelFillsElement (to be implemented in IFC exporter)
return False
class ViewProviderComponent:

View File

@@ -501,6 +501,22 @@
</property>
</widget>
</item>
<item>
<widget class="Gui::PrefCheckBox" name="checkBox_17">
<property name="toolTip">
<string>Some IFC types such as IfcWall or IfcBeam have special standard versions like IfcWallStandardCase or IfcBeamStandardCase. If this option is turned on, FreeCAD will automatically export such objects as standard cases when the necessary conditions are met.</string>
</property>
<property name="text">
<string>Auto-detet and export as standard cases when applicable</string>
</property>
<property name="prefEntry" stdset="0">
<cstring>getStandardCase</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Arch</cstring>
</property>
</widget>
</item>
</layout>
</widget>
</item>

View File

@@ -1568,6 +1568,7 @@ def export(exportList,filename):
email = s[1].strip(">")
global template
template = ifctemplate.replace("$version",version[0]+"."+version[1]+" build "+version[2])
getstd = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Arch").GetBool("getStandardType",False)
if hasattr(ifcopenshell,"schema_identifier"):
schema = ifcopenshell.schema_identifier
elif hasattr(ifcopenshell,"version") and (float(ifcopenshell.version[:3]) >= 0.6):
@@ -1755,6 +1756,9 @@ def export(exportList,filename):
# getting the representation
representation,placement,shapetype = getRepresentation(ifcfile,context,obj,forcebrep=(brepflag or FORCE_BREP))
if getstd:
if isStandardCase(obj,ifctype):
ifctype += "StandardCase"
if DEBUG: print(str(count).ljust(3)," : ", ifctype, " (",shapetype,") : ",name)
@@ -2378,6 +2382,14 @@ def export(exportList,filename):
del ifcbin
def isStandardCase(obj,ifctype):
if ifctype.endswith("StandardCase"):
return False # type is already standard case, return False so "StandardCase" is not added twice
if hasattr(obj,"Proxy") and hasattr(obj.Proxy,"isStandardCase"):
return obj.Proxy.isStandardCase(obj)
return False
def getIfcTypeFromObj(obj):
if (Draft.getType(obj) == "BuildingPart") and hasattr(obj,"IfcType") and (obj.IfcType == "Undefined"):