Skip to content

Commit

Permalink
Arch: IFC browser - fixes #1384
Browse files Browse the repository at this point in the history
Arch -> Utilities -> IFC Explorer
This opens a browser window that displays the contents of an IFC file
in a more readable manner than a text editor.
  • Loading branch information
yorikvanhavre committed Feb 7, 2014
1 parent 70091e5 commit 4e722e2
Show file tree
Hide file tree
Showing 7 changed files with 213 additions and 12 deletions.
15 changes: 15 additions & 0 deletions src/Mod/Arch/ArchCommands.py
Expand Up @@ -925,6 +925,20 @@ def Activated(self):
FreeCADGui.Selection.addSelection(i[0])


class _CommandIfcExplorer:
"the Arch Ifc Explorer command definition"
def GetResources(self):
return {'Pixmap' : 'IFC',
'MenuText': QtCore.QT_TRANSLATE_NOOP("Arch_IfcExplorer","Ifc Explorer"),
'ToolTip': QtCore.QT_TRANSLATE_NOOP("Arch_Check","Explore the contents of an Ifc file")}

def Activated(self):
if hasattr(self,"dialog"):
del self.dialog
import importIFC
self.dialog = importIFC.explore()


class _CommandFixture:
# OBSOLETE - To be removed
"the Arch Fixture command definition"
Expand Down Expand Up @@ -958,4 +972,5 @@ def Activated(self):
FreeCADGui.addCommand('Arch_RemoveShape',_CommandRemoveShape())
FreeCADGui.addCommand('Arch_CloseHoles',_CommandCloseHoles())
FreeCADGui.addCommand('Arch_Check',_CommandCheck())
FreeCADGui.addCommand('Arch_IfcExplorer',_CommandIfcExplorer())
#FreeCADGui.addCommand('Arch_Fixture',_CommandFixture())
8 changes: 4 additions & 4 deletions src/Mod/Arch/Arch_rc.py

Large diffs are not rendered by default.

9 changes: 4 additions & 5 deletions src/Mod/Arch/InitGui.py
Expand Up @@ -74,10 +74,10 @@ def Initialize(self):
"Arch_Window","Arch_Roof","Arch_Axis",
"Arch_SectionPlane","Arch_Space","Arch_Stairs",
"Arch_Frame","Arch_Add","Arch_Remove"]
self.meshtools = ["Arch_SplitMesh","Arch_MeshToShape",
self.utilities = ["Arch_SplitMesh","Arch_MeshToShape",
"Arch_SelectNonSolidMeshes","Arch_RemoveShape",
"Arch_CloseHoles","Arch_MergeWalls"]
self.calctools = ["Arch_Check"]
"Arch_CloseHoles","Arch_MergeWalls","Arch_Check",
"Arch_IfcExplorer"]

# draft tools
self.drafttools = ["Draft_Line","Draft_Wire","Draft_Circle","Draft_Arc","Draft_Ellipse",
Expand All @@ -103,8 +103,7 @@ def Initialize(self):
self.appendToolbar(translate("arch","Arch tools"),self.archtools)
self.appendToolbar(translate("arch","Draft tools"),self.drafttools)
self.appendToolbar(translate("arch","Draft mod tools"),self.draftmodtools)
self.appendMenu([translate("arch","&Architecture"),translate("arch","Conversion Tools")],self.meshtools)
self.appendMenu([translate("arch","&Architecture"),translate("arch","Calculation Tools")],self.calctools)
self.appendMenu([translate("arch","&Architecture"),translate("arch","Utilities")],self.utilities)
self.appendMenu(translate("arch","&Architecture"),self.archtools)
self.appendMenu(translate("arch","&Draft"),self.drafttools+self.draftmodtools+self.extramodtools)
self.appendMenu([translate("arch","&Draft"),translate("arch","Context Tools")],self.draftcontexttools)
Expand Down
1 change: 1 addition & 0 deletions src/Mod/Arch/Resources/Arch.qrc
Expand Up @@ -40,6 +40,7 @@
<file>icons/Arch_Rebar_Tree.svg</file>
<file>icons/Arch_Frame.svg</file>
<file>icons/Arch_Frame_Tree.svg</file>
<file>icons/IFC.svg</file>
<file>ui/archprefs-base.ui</file>
<file>ui/archprefs-import.ui</file>
<file>ui/ParametersWindowDouble.svg</file>
Expand Down
83 changes: 83 additions & 0 deletions src/Mod/Arch/Resources/icons/IFC.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
89 changes: 87 additions & 2 deletions src/Mod/Arch/ifcReader.py
Expand Up @@ -145,6 +145,14 @@ def getAttributes(self, name):
attrs.reverse()
return attrs

def capitalize(self, name):
"returns a capitalized version of a type"
if name.upper() in self.data.upper():
i1 = self.data.upper().index(name.upper())
i2 = i1 + len(name)
name = self.data[i1:i2]
return name

class IfcFile:
"""
Parses an ifc file given by filename, entities can be retrieved by name and id
Expand Down Expand Up @@ -291,6 +299,9 @@ def __init__(self,ent,doc=None):
def __repr__(self):
return str(self.id) + ' : ' + self.type + ' ' + str(self.attributes)

def getProperties(self):
return self.doc.find('IFCRELDEFINESBYPROPERTIES','RelatedObjects',self)

def getProperty(self,propName):
"finds the value of the given property or quantity in this object, if exists"
propsets = self.doc.find('IFCRELDEFINESBYPROPERTIES','RelatedObjects',self)
Expand Down Expand Up @@ -322,8 +333,7 @@ def getAttribute(self,attr):

class IfcDocument:
"an object representing an IFC document"
def __init__(self,filename,schema="IFC2X3_TC1.exp",debug=False):
DEBUG = debug
def __init__(self,filename,schema="IFC2X3_TC1.exp"):
f = IfcFile(filename,schema)
self.filename = filename
self.data = f.entById
Expand Down Expand Up @@ -441,6 +451,81 @@ def find(self,pat1,pat2=None,pat3=None):
obs.extend(self.getEnt(l))
return obs
return None

def explorer(filename,schema="IFC2X3_TC1.exp"):
"returns a PySide dialog showing the contents of an IFC file"
from PySide import QtCore,QtGui
ifc = IfcDocument(filename,schema)
schema = IfcSchema(schema)
tree = QtGui.QTreeWidget()
tree.setColumnCount(3)
tree.setWordWrap(True)
tree.header().setDefaultSectionSize(60)
tree.header().resizeSection(0,60)
tree.header().resizeSection(1,30)
tree.header().setStretchLastSection(True)
tree.headerItem().setText(0, "ID")
tree.headerItem().setText(1, "")
tree.headerItem().setText(2, "Item and Properties")
bold = QtGui.QFont()
bold.setWeight(75)
bold.setBold(True)

for i in range(1,len(ifc.Entities)):
e = ifc.Entities[i]
item = QtGui.QTreeWidgetItem(tree)
item.setText(0,str(e.id))
if e.type in ["IFCWALL","IFCWALLSTANDARDCASE"]:
item.setIcon(1,QtGui.QIcon(":icons/Arch_Wall_Tree.svg"))
elif e.type in ["IFCCOLUMN","IFCBEAM","IFCSLAB","IFCFOOTING"]:
item.setIcon(1,QtGui.QIcon(":icons/Arch_Structure_Tree.svg"))
elif e.type in ["IFCSITE"]:
item.setIcon(1,QtGui.QIcon(":icons/Arch_Site_Tree.svg"))
elif e.type in ["IFCBUILDING"]:
item.setIcon(1,QtGui.QIcon(":icons/Arch_Building_Tree.svg"))
elif e.type in ["IFCSTOREY"]:
item.setIcon(1,QtGui.QIcon(":icons/Arch_Floor_Tree.svg"))
elif e.type in ["IFCWINDOW"]:
item.setIcon(1,QtGui.QIcon(":icons/Arch_Window_Tree.svg"))
elif e.type in ["IFCROOF"]:
item.setIcon(1,QtGui.QIcon(":icons/Arch_Roof_Tree.svg"))
elif e.type in ["IFCEXTRUDEDAREASOLID","IFCCLOSEDSHELL"]:
item.setIcon(1,QtGui.QIcon(":icons/Tree_Part.svg"))
elif e.type in ["IFCFACE"]:
item.setIcon(1,QtGui.QIcon(":icons/Draft_SwitchMode.svg"))
elif e.type in ["IFCARBITRARYCLOSEDPROFILEDEF","IFCPOLYLOOP"]:
item.setIcon(1,QtGui.QIcon(":icons/Draft_Draft.svg"))
item.setText(2,str(schema.capitalize(e.type)))
item.setFont(2,bold);
for a in e.attributes.keys():
if hasattr(e,a):
if not a.upper() in ["ID", "GLOBALID"]:
v = getattr(e,a)
if isinstance(v,IfcEntity):
t = "Entity #" + str(v.id) + ": " + str(v.type)
elif isinstance(v,list):
t = ""
else:
t = str(v)
t = " " + str(a) + " : " + str(t)
item = QtGui.QTreeWidgetItem(tree)
item.setText(2,str(t))
if isinstance(v,list):
for vi in v:
if isinstance(vi,IfcEntity):
t = "Entity #" + str(vi.id) + ": " + str(vi.type)
else:
t = vi
t = " " + str(t)
item = QtGui.QTreeWidgetItem(tree)
item.setText(2,str(t))
d = QtGui.QDialog()
d.setObjectName("IfcExplorer")
d.setWindowTitle("Ifc Explorer")
d.resize(640, 480)
layout = QtGui.QVBoxLayout(d)
layout.addWidget(tree)
return d

if __name__ == "__main__":
print __doc__
Expand Down
20 changes: 19 additions & 1 deletion src/Mod/Arch/importIFC.py
Expand Up @@ -353,7 +353,8 @@ def read(filename):
schema=getSchema()
if schema:
if DEBUG: print "opening",filename,"..."
ifc = ifcReader.IfcDocument(filename,schema=schema,debug=DEBUG)
ifcReader.DEBUG = DEBUG
ifc = ifcReader.IfcDocument(filename,schema=schema)
else:
FreeCAD.Console.PrintWarning(translate("Arch","IFC Schema not found, IFC import disabled.\n"))
return None
Expand Down Expand Up @@ -995,3 +996,20 @@ def export(exportList,filename):
print "IFC export: object type ", otype, " is not supported yet."

ifc.write()


def explore(filename=None):
"explore the contents of an ifc file in a Qt dialog"
if not filename:
from PySide import QtGui
filename = QtGui.QFileDialog.getOpenFileName(QtGui.qApp.activeWindow(),'IFC files','*.ifc')
if filename:
filename = filename[0]
if filename:
import ifcReader
getConfig()
schema=getSchema()
ifcReader.DEBUG = DEBUG
d = ifcReader.explorer(filename,schema)
d.show()
return d

0 comments on commit 4e722e2

Please sign in to comment.