Arch: Renamed Role property to IfcRole

This commit is contained in:
Yorik van Havre
2018-05-11 12:01:55 -03:00
parent 03908877fc
commit 63794fcefd
15 changed files with 112 additions and 49 deletions

View File

@@ -25,12 +25,51 @@ __title__="FreeCAD Arch Component"
__author__ = "Yorik van Havre"
__url__ = "http://www.freecadweb.org"
# Possible roles for IFC objects
Roles = ['Undefined','Beam','Chimney','Column','Covering','Curtain Wall',
'Door','Foundation','Furniture','Hydro Equipment','Electric Equipment',
'Member','Plate','Railing','Ramp','Ramp Flight','Rebar','Pile','Roof','Shading Device','Slab','Space',
'Stair','Stair Flight','Tendon','Wall','Wall Layer','Window','Pipe Segment','Curtain Wall',
'Pipe Fitting','Reinforcing Bar']
# IFC types
IFCTYPES = ["IfcActuator", "IfcAirTerminal", "IfcAirTerminalBox", "IfcAirToAirHeatRecovery",
"IfcAlarm", "IfcAnnotation", "IfcAudioVisualAppliance", "IfcBeam", "IfcBeamStandardCase",
"IfcBoiler", "IfcBuilding", "IfcBuildingElement", "IfcBuildingElementPart", "IfcBuildingElementProxy",
"IfcBuildingStorey", "IfcBurner", "IfcCableCarrierFitting", "IfcCableCarrierSegment",
"IfcCableFitting", "IfcCableSegment", "IfcChiller", "IfcChimney", "IfcCivilElement",
"IfcCoil", "IfcColumn", "IfcColumnStandardCase", "IfcCommunicationsAppliance", "IfcCompressor",
"IfcCondenser", "IfcController", "IfcCooledBeam", "IfcCoolingTower", "IfcCovering",
"IfcCurtainWall", "IfcDamper", "IfcDiscreteAccessory", "IfcDistributionChamberElement",
"IfcDistributionControlElement", "IfcDistributionElement", "IfcDistributionFlowElement",
"IfcDistributionPort", "IfcDoor", "IfcDoorStandardCase", "IfcDuctFitting", "IfcDuctSegment",
"IfcDuctSilencer", "IfcElectricAppliance", "IfcElectricDistributionBoard", "IfcElectricFlowStorageDevice",
"IfcElectricGenerator", "IfcElectricMotor", "IfcElectricTimeControl",
"IfcElementAssembly", "IfcElementComponent", "IfcEnergyConversionDevice", "IfcEngine",
"IfcEvaporativeCooler", "IfcEvaporator", "IfcExternalSpatialElement", "IfcExternalSpatialStructureElement",
"IfcFan", "IfcFastener", "IfcFeatureElement", "IfcFeatureElementAddition", "IfcFeatureElementSubtraction",
"IfcFilter", "IfcFireSuppressionTerminal", "IfcFlowController", "IfcFlowFitting", "IfcFlowInstrument",
"IfcFlowMeter", "IfcFlowMovingDevice", "IfcFlowSegment", "IfcFlowStorageDevice", "IfcFlowTerminal",
"IfcFlowTreatmentDevice", "IfcFooting", "IfcFurnishingElement", "IfcFurniture", "IfcGeographicElement",
"IfcGrid", "IfcHeatExchanger", "IfcHumidifier", "IfcInterceptor", "IfcJunctionBox", "IfcLamp",
"IfcLightFixture", "IfcMechanicalFastener", "IfcMedicalDevice", "IfcMember", "IfcMemberStandardCase",
"IfcMotorConnection", "IfcOpeningElement", "IfcOpeningStandardCase", "IfcOutlet", "IfcPile",
"IfcPipeFitting", "IfcPipeSegment", "IfcPlate", "IfcPlateStandardCase", "IfcPort",
"IfcProjectionElement", "IfcProtectiveDevice", "IfcProtectiveDeviceTrippingUnit",
"IfcProxy", "IfcPump", "IfcRailing", "IfcRamp", "IfcRampFlight", "IfcReinforcingBar",
"IfcReinforcingElement", "IfcReinforcingMesh", "IfcRoof", "IfcSanitaryTerminal",
"IfcSensor", "IfcShadingDevice", "IfcSite", "IfcSlab", "IfcSlabElementedCase", "IfcSlabStandardCase",
"IfcSolarDevice", "IfcSpace", "IfcSpaceHeater", "IfcSpatialElement", "IfcSpatialStructureElement",
"IfcSpatialZone", "IfcStackTerminal", "IfcStair", "IfcStairFlight", "IfcStructuralAction",
"IfcStructuralActivity", "IfcStructuralConnection", "IfcStructuralCurveAction",
"IfcStructuralCurveConnection", "IfcStructuralCurveMember", "IfcStructuralCurveMemberVarying",
"IfcStructuralCurveReaction", "IfcStructuralItem", "IfcStructuralLinearAction",
"IfcStructuralMember", "IfcStructuralPlanarAction", "IfcStructuralPointAction",
"IfcStructuralPointConnection", "IfcStructuralPointReaction", "IfcStructuralReaction",
"IfcStructuralSurfaceAction", "IfcStructuralSurfaceConnection", "IfcStructuralSurfaceMember",
"IfcStructuralSurfaceMemberVarying", "IfcStructuralSurfaceReaction", "IfcSurfaceFeature",
"IfcSwitchingDevice", "IfcSystemFurnitureElement", "IfcTank", "IfcTendon", "IfcTendonAnchor",
"IfcTransformer", "IfcTransportElement", "IfcTubeBundle", "IfcUnitaryControlElement",
"IfcUnitaryEquipment", "IfcValve", "IfcVibrationIsolator", "IfcVirtualElement", "IfcVoidingFeature",
"IfcWall", "IfcWallElementedCase", "IfcWallStandardCase", "IfcWasteTerminal", "IfcWindow",
"IfcWindowStandardCase"]
# Possible roles for FreeCAD BIM objects
IfcRoles = ['Undefined']+[''.join(map(lambda x: x if x.islower() else " "+x, t[3:]))[1:] for t in IFCTYPES]
import FreeCAD,Draft,ArchCommands,math
from FreeCAD import Vector
@@ -318,7 +357,7 @@ class Component:
obj.addProperty("App::PropertyString","Tag","Component",QT_TRANSLATE_NOOP("App::Property","An optional tag for this component"))
obj.addProperty("App::PropertyMap","IfcAttributes","Component",QT_TRANSLATE_NOOP("App::Property","Custom IFC properties and attributes"))
obj.addProperty("App::PropertyLink","Material","Component",QT_TRANSLATE_NOOP("App::Property","A material for this object"))
obj.addProperty("App::PropertyEnumeration","Role","Component",QT_TRANSLATE_NOOP("App::Property","The role of this object"))
obj.addProperty("App::PropertyEnumeration","IfcRole","Component",QT_TRANSLATE_NOOP("App::Property","The role of this object"))
obj.addProperty("App::PropertyBool","MoveWithHost","Component",QT_TRANSLATE_NOOP("App::Property","Specifies if this object must move together when its host is moved"))
obj.addProperty("App::PropertyLink","IfcProperties","Component",QT_TRANSLATE_NOOP("App::Property","Custom IFC properties and attributes"))
obj.addProperty("App::PropertyArea","VerticalArea","Component",QT_TRANSLATE_NOOP("App::Property","The area of all vertical faces of this object"))
@@ -330,7 +369,7 @@ class Component:
self.Type = "Component"
self.Subvolume = None
self.MoveWithHost = False
obj.Role = Roles
obj.IfcRole = IfcRoles
obj.setEditorMode("VerticalArea",1)
obj.setEditorMode("HorizontalArea",1)
obj.setEditorMode("PerimeterLength",1)

View File

@@ -266,7 +266,7 @@ class _Equipment(ArchComponent.Component):
obj.addProperty("App::PropertyVectorList","SnapPoints","Arch",QT_TRANSLATE_NOOP("App::Property","Additional snap points for this equipment"))
obj.addProperty("App::PropertyFloat","EquipmentPower","Arch",QT_TRANSLATE_NOOP("App::Property","The electric power needed by this equipment in Watts"))
self.Type = "Equipment"
obj.Role = "Furniture"
obj.IfcRole = "Furniture"
obj.Proxy = self
obj.setEditorMode("VerticalArea",2)
obj.setEditorMode("HorizontalArea",2)

View File

@@ -106,7 +106,7 @@ class _Frame(ArchComponent.Component):
obj.addProperty("App::PropertyBool","Fuse","Arch",QT_TRANSLATE_NOOP("App::Property","If true, geometry is fused, otherwise a compound"))
self.Type = "Frame"
obj.Align = True
obj.Role = "Railing"
obj.IfcRole = "Railing"
obj.Edges = ["All edges","Vertical edges","Horizontal edges","Bottom horizontal edges","Top horizontal edges"]
def execute(self,obj):

View File

@@ -369,7 +369,7 @@ class _Panel(ArchComponent.Component):
obj.addProperty("App::PropertyVector","Normal","Arch",QT_TRANSLATE_NOOP("App::Property","The normal extrusion direction of this object (keep (0,0,0) for automatic normal)"))
obj.Sheets = 1
self.Type = "Panel"
obj.Role = "Plate"
obj.IfcRole = "Plate"
obj.WaveType = ["Curved","Trapezoidal","Spikes"]
obj.FaceMaker = ["None","Simple","Cheese","Bullseye"]
obj.setEditorMode("VerticalArea",2)

View File

@@ -185,7 +185,7 @@ class _ArchPipe(ArchComponent.Component):
ArchComponent.Component.__init__(self,obj)
self.Type = "Pipe"
obj.Role = "Pipe Segment"
obj.IfcRole = "Pipe Segment"
obj.addProperty("App::PropertyLength", "Diameter", "Arch", QT_TRANSLATE_NOOP("App::Property","The diameter of this pipe, if not based on a profile"))
obj.addProperty("App::PropertyLength", "Length", "Arch", QT_TRANSLATE_NOOP("App::Property","The length of this pipe, if not based on an edge"))
obj.addProperty("App::PropertyLink", "Profile", "Arch", QT_TRANSLATE_NOOP("App::Property","An optional closed profile to base this pipe on"))
@@ -299,7 +299,7 @@ class _ArchPipeConnector(ArchComponent.Component):
ArchComponent.Component.__init__(self,obj)
self.Type = "PipeConnector"
obj.Role = "Pipe Fitting"
obj.IfcRole = "Pipe Fitting"
obj.addProperty("App::PropertyLength", "Radius", "Arch", QT_TRANSLATE_NOOP("App::Property","The curvature radius of this connector"))
obj.addProperty("App::PropertyLinkList", "Pipes", "Arch", QT_TRANSLATE_NOOP("App::Property","The pipes linked by this connector"))
obj.addProperty("App::PropertyEnumeration", "ConnectorType", "Arch", QT_TRANSLATE_NOOP("App::Property","The type of this connector"))

View File

@@ -61,7 +61,6 @@ class _Precast(ArchComponent.Component):
obj.addProperty("App::PropertyDistance","Height","Arch",QT_TRANSLATE_NOOP("App::Property","The height of this element"))
obj.addProperty("App::PropertyVectorList","Nodes","Arch",QT_TRANSLATE_NOOP("App::Property","The structural nodes of this element"))
self.Type = "Precast"
obj.Role = ["Beam","Column","Panel","Slab","Stairs"]
def execute(self,obj):
@@ -80,7 +79,7 @@ class _PrecastBeam(_Precast):
obj.addProperty("App::PropertyDistance","DentLength","Arch",QT_TRANSLATE_NOOP("App::Property","The dent length of this element"))
obj.addProperty("App::PropertyDistance","DentHeight","Arch",QT_TRANSLATE_NOOP("App::Property","The dent height of this element"))
obj.addProperty("App::PropertyStringList","Dents","Arch",QT_TRANSLATE_NOOP("App::Property","The dents of this element"))
obj.Role = ["Beam"]
obj.IfcRole = "Beam"
def execute(self,obj):
@@ -183,7 +182,7 @@ class _PrecastIbeam(_Precast):
_Precast.__init__(self,obj)
obj.addProperty("App::PropertyDistance","Chamfer","Arch",QT_TRANSLATE_NOOP("App::Property","The chamfer length of this element"))
obj.addProperty("App::PropertyDistance","BeamBase","Arch",QT_TRANSLATE_NOOP("App::Property","The base length of this element"))
obj.Role = ["Beam"]
obj.IfcRole = "Beam"
def execute(self,obj):
@@ -238,7 +237,7 @@ class _PrecastPillar(_Precast):
obj.addProperty("App::PropertyDistance","GrooveSpacing","Arch",QT_TRANSLATE_NOOP("App::Property","The spacing between the grooves of this element"))
obj.addProperty("App::PropertyInteger","GrooveNumber","Arch",QT_TRANSLATE_NOOP("App::Property","The number of grooves of this element"))
obj.addProperty("App::PropertyStringList","Dents","Arch",QT_TRANSLATE_NOOP("App::Property","The dents of this element"))
obj.Role = ["Column"]
obj.IfcRole = "Column"
def execute(self,obj):
@@ -357,7 +356,7 @@ class _PrecastPanel(_Precast):
obj.addProperty("App::PropertyDistance","Chamfer","Arch",QT_TRANSLATE_NOOP("App::Property","The size of the chamfer of this element"))
obj.addProperty("App::PropertyDistance","DentWidth","Arch",QT_TRANSLATE_NOOP("App::Property","The dent width of this element"))
obj.addProperty("App::PropertyDistance","DentHeight","Arch",QT_TRANSLATE_NOOP("App::Property","The dent height of this element"))
obj.Role = ["Plate"]
obj.IfcRole = "Plate"
def execute(self,obj):
@@ -455,7 +454,7 @@ class _PrecastSlab(_Precast):
obj.addProperty("App::PropertyDistance","HoleMajor","Arch",QT_TRANSLATE_NOOP("App::Property","The major radius of the holes of this element"))
obj.addProperty("App::PropertyDistance","HoleMinor","Arch",QT_TRANSLATE_NOOP("App::Property","The minor radius of the holes of this element"))
obj.addProperty("App::PropertyDistance","HoleSpacing","Arch",QT_TRANSLATE_NOOP("App::Property","The spacing between the holes of this element"))
obj.Role = ["Slab"]
obj.IfcRole = "Slab"
obj.SlabType = ["Champagne","Hat"]
def execute(self,obj):
@@ -546,7 +545,7 @@ class _PrecastStairs(_Precast):
obj.addProperty("App::PropertyInteger","RiserNumber","Arch",QT_TRANSLATE_NOOP("App::Property","The number of risers in this element"))
obj.addProperty("App::PropertyDistance","Riser","Arch",QT_TRANSLATE_NOOP("App::Property","The riser height of this element"))
obj.addProperty("App::PropertyDistance","Tread","Arch",QT_TRANSLATE_NOOP("App::Property","The tread depth of this element"))
obj.Role = ["Stairs"]
obj.IfcRole = "Stairs"
def execute(self,obj):

View File

@@ -170,7 +170,7 @@ class _Rebar(ArchComponent.Component):
obj.addProperty("App::PropertyDistance", "Length", "Arch", QT_TRANSLATE_NOOP("App::Property","Length of a single rebar"))
obj.addProperty("App::PropertyDistance", "TotalLength", "Arch", QT_TRANSLATE_NOOP("App::Property","Total length of all rebars"))
self.Type = "Rebar"
obj.Role = "Reinforcing Bar"
obj.IfcRole = "Reinforcing Bar"
obj.setEditorMode("Spacing", 1)
obj.setEditorMode("Length", 1)
obj.setEditorMode("TotalLength", 1)

View File

@@ -182,7 +182,7 @@ class _Roof(ArchComponent.Component):
obj.addProperty("App::PropertyLength","BorderLength","Arch", QT_TRANSLATE_NOOP("App::Property","The total length of borders of this roof"))
obj.addProperty("App::PropertyBool","Flip","Arch",QT_TRANSLATE_NOOP("App::Property","Flip the roof direction if going the wrong way"))
self.Type = "Roof"
obj.Role = "Roof"
obj.IfcRole = "Roof"
obj.Proxy = self
obj.setEditorMode("RidgeLength",1)
obj.setEditorMode("BorderLength",1)

View File

@@ -156,13 +156,19 @@ class _ArchSchedule:
if Draft.getType(o).upper() == args[1].upper():
ok = False
elif args[0].upper() == "ROLE":
if hasattr(o,"Role"):
if hasattr(o,"IfcRole"):
if o.IfcRole.upper() != args[1].upper():
ok = False
elif hasattr(o,"Role"):
if o.Role.upper() != args[1].upper():
ok = False
else:
ok = False
elif args[0].upper() == "!ROLE":
if hasattr(o,"Role"):
if o.IfcRole.upper() == args[1].upper():
ok = False
elif hasattr(o,"Role"):
if o.Role.upper() == args[1].upper():
ok = False
if ok:

View File

@@ -266,7 +266,7 @@ class _Space(ArchComponent.Component):
self.Type = "Space"
obj.SpaceType = SpaceTypes
obj.Conditioning = ConditioningTypes
obj.Role = "Space"
obj.IfcRole = "Space"
obj.setEditorMode("HorizontalArea",2)
def execute(self,obj):

View File

@@ -141,7 +141,7 @@ class _Stairs(ArchComponent.Component):
obj.setEditorMode("RiserHeight",1)
obj.setEditorMode("BlondelRatio",1)
self.Type = "Stairs"
obj.Role = "Stair"
obj.IfcRole = "Stair"
def execute(self,obj):

View File

@@ -95,7 +95,7 @@ def makeStructure(baseobj=None,length=None,width=None,height=None,name="Structur
# gets wrong
obj.Length = p.GetFloat("StructureLength",100)
if obj.Height > obj.Length:
obj.Role = "Column"
obj.IfcRole = "Column"
return obj
def makeStructuralSystem(objects=[],axes=[],name="StructuralSystem"):
@@ -460,7 +460,7 @@ class _Structure(ArchComponent.Component):
obj.addProperty("App::PropertyEnumeration","FaceMaker","Arch",QT_TRANSLATE_NOOP("App::Property","The facemaker type to use to build the profile of this object"))
self.Type = "Structure"
obj.FaceMaker = ["None","Simple","Cheese","Bullseye"]
obj.Role = "Beam"
obj.IfcRole = "Beam"
def execute(self,obj):
"creates the structure shape"
@@ -514,6 +514,10 @@ class _Structure(ArchComponent.Component):
def getExtrusionData(self,obj):
"""returns (shape,extrusion vector,placement) or None"""
if hasattr(obj,"IfcRole"):
role = obj.IfcRole
else:
role = obj.Role
import Part,DraftGeomUtils
data = ArchComponent.Component.getExtrusionData(self,obj)
if data:
@@ -572,7 +576,7 @@ class _Structure(ArchComponent.Component):
baseface = Part.Face(w)
base,placement = self.rebase(baseface)
elif length and width and height:
if (length > height) and (obj.Role != "Slab"):
if (length > height) and (role != "Slab"):
h2 = height/2 or 0.5
w2 = width/2 or 0.5
v1 = Vector(0,-w2,-h2)
@@ -598,7 +602,7 @@ class _Structure(ArchComponent.Component):
if not normal.Length:
normal = Vector(0,0,1)
extrusion = normal
if (length > height) and (obj.Role != "Slab"):
if (length > height) and (role != "Slab"):
if length:
extrusion = normal.multiply(length)
else:
@@ -608,6 +612,12 @@ class _Structure(ArchComponent.Component):
return None
def onChanged(self,obj,prop):
if hasattr(obj,"IfcRole"):
role = obj.IfcRole
elif hasattr(obj,"Role"):
role = obj.Role
else:
role = None
self.hideSubobjects(obj,prop)
if prop in ["Shape","ResetNodes","NodesOffset"]:
# ResetNodes is not a property but it allows us to use this function to force reset the nodes
@@ -616,7 +626,7 @@ class _Structure(ArchComponent.Component):
if extdata:
nodes = extdata[0]
nodes.Placement = nodes.Placement.multiply(extdata[2])
if obj.Role not in ["Slab"]:
if role not in ["Slab"]:
if obj.Tool:
nodes = obj.Tool.Shape
elif extdata[1].Length > 0:
@@ -698,9 +708,13 @@ class _ViewProviderStructure(ArchComponent.ViewProviderComponent):
self.coords.point.set1Value(len(p),p[0][0],p[0][1],p[0][2])
self.lineset.coordIndex.setValues(0,len(p)+2,range(len(p)+1)+[-1])
self.faceset.coordIndex.setValues(0,len(p)+1,range(len(p))+[-1])
elif prop == "Role":
elif prop in ["Role","IfcRole"]:
if hasattr(obj.ViewObject,"NodeType"):
if obj.Role == "Slab":
if hasattr(obj,"IfcRole"):
role = obj.IfcRole
else:
role = obj.Role
if role == "Slab":
obj.ViewObject.NodeType = "Area"
else:
obj.ViewObject.NodeType = "Linear"

View File

@@ -476,7 +476,7 @@ class _Wall(ArchComponent.Component):
obj.Align = ['Left','Right','Center']
self.Type = "Wall"
obj.Role = "Wall"
obj.IfcRole = "Wall"
def execute(self,obj):
"builds the wall shape"

View File

@@ -55,7 +55,8 @@ WindowPartTypes = ["Frame","Solid panel","Glass panel","Louvre"]
AllowedHosts = ["Wall","Structure","Roof"]
WindowPresets = ["Fixed", "Open 1-pane", "Open 2-pane", "Sash 2-pane",
"Sliding 2-pane", "Simple door", "Glass door", "Sliding 4-pane"]
WindowOpeningModes = ["None","Arc 90","Arc 90 inv","Arc 45","Arc 45 inv","Arc 180","Arc 180 inv","Triangle","Triangle inv","Sliding","Sliding inv"]
WindowOpeningModes = ["None","Arc 90","Arc 90 inv","Arc 45","Arc 45 inv","Arc 180",
"Arc 180 inv","Triangle","Triangle inv","Sliding","Sliding inv"]
def makeWindow(baseobj=None,width=None,height=None,parts=None,name="Window"):
@@ -803,7 +804,7 @@ class _Window(ArchComponent.Component):
obj.setEditorMode("HorizontalArea",2)
obj.setEditorMode("PerimeterLength",2)
self.Type = "Window"
obj.Role = "Window"
obj.IfcRole = "Window"
obj.Proxy = self
obj.MoveWithHost = True

View File

@@ -676,16 +676,20 @@ def insert(filename,docname,skip=[],only=[],root=None):
baseobj.ViewObject.hide()
# setting role
try:
r = ptype[3:]
tr = dict((v,k) for k, v in translationtable.iteritems())
if r in tr.keys():
r = tr[r]
# remove the "StandardCase"
if "StandardCase" in r:
r = r[:-12]
obj.Role = r
if hasattr(obj,"IfcRole"):
obj.IfcRole = ptype[3:]
else:
# pre-0.18 objects, only support a small subset of types
r = ptype[3:]
tr = dict((v,k) for k, v in translationtable.iteritems())
if r in tr.keys():
r = tr[r]
# remove the "StandardCase"
if "StandardCase" in r:
r = r[:-12]
obj.Role = r
except:
pass
print("Unable to give IFC role ",ptype," to object ",obj.Label)
# setting uid
if hasattr(obj,"IfcAttributes"):
a = obj.IfcAttributes
@@ -1115,7 +1119,9 @@ def export(exportList,filename):
obj.IfcAttributes = d
# setting the IFC type + name conversions
if hasattr(obj,"Role"):
if hasattr(obj,"IfcRole"):
ifctype = obj.IfcRole.replace(" ","")
elif hasattr(obj,"Role"):
ifctype = obj.Role.replace(" ","")
else:
ifctype = Draft.getType(obj)
@@ -1127,10 +1133,8 @@ def export(exportList,filename):
if ifctype == "IfcGroup":
groups[obj.Name] = [o.Name for o in obj.Group]
continue
ifctypes = []
for v in typesmap.values():
ifctypes.extend(v)
if ifctype not in ifctypes:
from ArchComponent import IFCTYPES
if ifctype not in IFCTYPES:
ifctype = "IfcBuildingElementProxy"
# getting the "Force BREP" flag