Hey @shanmama - did you see some of the links and source code posted here?
Is there a particular type of data you are trying to extract? Is it geometry? Is it an attribute? Is it a property set? If you're interested, in an online meeting I can do a screenshare and teach a bit about IfcOpenShell-python. Would you participate?
Dear all,
Please Help....
I am a beginner in using python, IFC and BlenderBim add on. I am trying to do the following;
1. extract the quantities, material type of walls and floors and place them into a dictionary
2. extract the quantities of external walls and group them based on their cardinal orientation (south, north, west, etc) of each wall. I do not know if it's workable.
@polsonmila at first glance it looks as if you're getting an AttributeError because you're attempting to access quantity.lengthValue instead of quantity.LengthValue -- > the properties all use CamelCase
BTW: if you post code do not use a screen shot but copy the code and use code tags instead. It looks like in the post of vpajic. If you post a screen shot noone can copy and test your code.
#These are the imports I am using
import ifcopenshell
import ifcopenshell.util
from ifcopenshell.util.selector import Selector
from ifcopenshell import util
import ifcopenshell.util.pset
import ifcopenshell.util.element
import pandas as pd
# The IFC file I am using as attached
ifc = ifcopenshell.open('Duplex3.ifc')
selector = Selector()
# The walls and slab using the by_type function
walls = ifc.by_type('IfcWall')
slabs = ifc.by_type('IfcSlab')
# The iterations for the psets I did.
for wall in my_walls:
wall_details = wall.get_info()
for wall in walls:
pset_wall = ifcopenshell.util.element.get_psets(wall)
NOTE: I am trying to extract the quantities of Walls and Slabs and place them in a dataframe.
I want these to have their GUID.
I would also like to group all the Walls external walls based on their Cardinal points (south, north, etc)
once again thank you for your anticipated responses.
@vpajic said:
Also, you need to loop through each Wall in your Walls list before you try to access .isDefinedBy.
something like:
walls = [] # your list of walls
for wall in walls:
for definition in wall.IsDefinedBy:
NOTE: I am trying to extract the quantities of Walls and Slabs and place them in a dataframe.
I want these to have their GUID.
I would also like to group all the Walls external walls based on their Cardinal points (south, north, etc)
once again thank you for your anticipated responses.
@vpajic Thank you. I am relatively new to both Python and IfcOpenshell. I am now exploring my way through (as I go through the Wiki.osarch.org tutorials. I was able use the get_info and loop through (as shown below). But I as you suggested, I also observed that I could loop through the wall list from the wall.by_type function call. I will work on it so that I can try accessing the IsDefinedBy.
Well this is how far I have gone.
import ifcopenshell
import pandas as pd
m = ifcopenshell.open("data/Duplex_A.ifc")
#m = ifcopenshell.open("../data/231110AC-11-Smiley-West-04-07-2007.ifc")
walls = m.by_type('IfcWall')
#print (walls)
#count = 0
for wall in walls:
#count += 1
wall_details = wall.get_info()
#print(wall_details)
wall_details_edit = {str(key): str(value) for key, value in wall_details.items()}
#print(wall_details_edit)
wall_details_edit_df = pd.DataFrame(wall_details_edit, index = [0])
print(wall_details_edit_df)
#print(count)
@vpajic Thank you for your comment I still need help... @Moult and @bernd kindly assist.
I am relatively new to both Python and IfcOpenshell. I am now exploring my way through (as I go through the Wiki.osarch.org tutorials. I was able use the get_info and loop through (as shown below). But I as @vpajic suggested, I also observed that I could loop through the wall list from the wall.by_type function call. I will work on it so that I can try accessing the IsDefinedBy.
Well, this is how far I have gone.
I have been able to have the loop through to get the property set of one wall using the IsDefinedBy procedure. But I could not access the Quantities. Please, can someone help me to identify where I am getting things wrong?
'''I am trying to access all the propeties and quantities of the walls
using an IFC 2x3 file format but???? please help'''
ifc = ifcopenshell.open('Duplex3.ifc')
#the walls from the model
walls = ifc.by_type('IfcWall')
#the single wall I am considering since the loop for properties has no IsDefinedBy
wall_1 = walls[0]
a = wall_1.IsDefinedBy
print(a)
'''the for loop I used to track the inverse IsDefineBy as in the tutorials
all went well and I am still exploring'''
for i in a:
if i.is_a('IfcRelDefinesByProperties'):
a_property_set = i.RelatingPropertyDefinition
#print(a_property_set.Name) # Might return Pset_WallCommon
for property in a_property_set.HasProperties:
if property.is_a('IfcPropertySingleValue'):
#print(property.Name)
print(property.NominalValue.wrappedValue)
'''this is the point where I am stuck, I have tried many approaches but I couldn't get the Quantities of the wall following the tutorial'''
for i in a:
#if i.is_a('IfcRelDefinesByProperties'):
a_property_set = i.RelatingPropertyDefinition
if property.is_a('IfcElementQuantity'):
print(property.Name)
for quantity in property.Quantities:
print(quantity.Name)
if quantity.is_a('IfcQuantityLength'):
print(quantity.LengthValue)
@polsonmila - i would heartily recommend having a look at . Using the console in blender will allow you to explore the commands and structure of ifcopenshell more intuitively.
@Coen thank you for your follow-up question. I followed the YouTube video tutorial specified by @vpajic it has been helpful. Though, I will still need help.
I want to extract the data from the IFC 2x3 format and place them in a data frame.
1. I used the util.get_psets() function to get the property sets of all the walls in a particular building but I could not loop through the walls and place them into a data frame. I could only do that for one wall (as shown in the code below).
2. I want to extract the external walls within an IFC 2x3 specifying the cardinal orientation of the external faces of the walls with respect to the Project North (e.g. North-west, North-south, North). If you have any idea on how to extract these details, I will be grateful.
Code for question 1
`#The IFC 2x3 model
model_name = 'Duplex_A.ifc'
model = ifcopenshell.open(model_name)
The walls by_type
walls = model.by_type('IfcWall')
count = 0
Iterating through the walls
for wall in walls:
wall_sets_dict = {}
#count += 1
The util.get_psets function
wall_sets_fulldict = util.get_psets(wall, psets_only=True, qtos_only=False)
wall_sets_dict.update(wall_sets_fulldict) # I updated the dictionary
#print (wall_sets_dict)
#I tried to make the dictionary into an organised pattern but this gives me an error????
for wall_set in wall_sets_dict:
for outerKey, innerDict in wall_sets_dict.items():
for innerKey, values in innerDict.items():
wall_sets_dict[(outerKey, innerKey)] = values
#print(wall_sets_dict)
`
Question 2
????
NOTE: I added a note pad for further details and the IFC 2x3 file.
@Moult please pardon my miscommunication (I am a beginner). I meant a pandas data frame. I was able to use the util.get_psets for only one wall and derived a multi-index data frame (as shown in the code below)
#A sample of Pset from the util.get_pset. I placed it as a dictionary
nest_dict = {'Pset_WallCommon': {'Reference': 'Basic Wall:Interior - Partition (92mm Stud)', 'LoadBearing': False,
'ExtendToStructure': False, 'IsExternal': False, 'id': 4093},
'PSet_Revit_Constraints': {'Location Line': 2, 'Base Constraint': 'Level 1', 'Base Offset': 0.0,
'Base is Attached': False, 'Base Extension Distance': 0.0,
'Top Constraint': 'Up to level: Level 2',
'Unconnected Height': 2.795000000000196, 'Top Offset': -0.3050000000000001,
'Top is Attached': False, 'Top Extension Distance': 0.0, 'Room Bounding': True,
'Related to Mass': False, 'id': 4142},
'PSet_Revit_Other': {'InstallationDate': 'InstallationDate', 'SerialNumber': 'SerialNumber',
'WarrantyStartDate': 'WarrantyStartDate', 'BarCode': 'BarCode',
'AssetIdentifier': 'AssetIdentifier', 'TagNumber': 'TagNumber', 'id': 4144},
'PSet_Revit_Phasing': {'Phase Created': 'New Construction', 'id': 4146},
'PSet_Revit_Structural': {'Structural Usage': 0, 'id': 4148},
'PSet_Revit_Dimensions': {'Length': 3.791499999999996, 'Area': 10.01448500000069,
'Volume': 1.241796140000085, 'id': 4150},
'PSet_Revit_Type_Construction': {'Wrapping at Inserts': 0, 'Wrapping at Ends': 2, 'Width': 0.124,
'Function': 0, 'id': 4152},
'PSet_Revit_Type_Graphics': {'Coarse Scale Fill Color': 0, 'id': 4153},
'PSet_Revit_Type_Identity Data': {'Manufacturer': 'Manufacturer', 'Assembly Description': '',
'Assembly Code': '', 'id': 4154},
'PSet_Revit_Type_Other': {'AccessibilityPerformance': 'AccessibilityPerformance',
'CodePerformance': 'CodePerformance', 'Color': 'Color',
'Constituents': 'Constituents', 'Features': 'Features', 'Finish': 'Finish',
'Grade': 'Grade', 'Material': 'Material', 'ModelReference': 'ModelReference',
'NominalHeight': 'NominalHeight', 'NominalLength': 'NominalLength',
'NominalWidth': 'NominalWidth', 'ProductionYear': 'ProductionYear',
'Reference': 'Reference', 'Shape': 'Shape', 'Size': 'Size',
'SustainabilityPerformance': 'SustainabilityPerformance',
'WarrantyDescription': 'WarrantyDescription',
'WarrantyDurationLabor': 'WarrantyDurationLabor',
'WarrantyDurationParts': 'WarrantyDurationParts',
'WarrantyGuarantorLabor': 'WarrantyGuarantorLabor',
'WarrantyGuarantorParts': 'WarrantyGuarantorParts', 'ModelNumber': 'ModelNumber',
'ExpectedLife': 'ExpectedLife', 'ReplacementCost': 'ReplacementCost',
'AssetAccountingType': 'FIXED', 'id': 4155}}

#I used this code to generate a data frame
reformed_dict = {}
for outerKey, innerDict in nest_dict.items():
for innerKey, values in innerDict.items():
reformed_dict[(outerKey, innerKey)] = values
df1 = pd.DataFrame.from_dict(reformed_dict, orient='index').transpose()
df1.columns = pd.MultiIndex.from_tuples(df1.columns)
df1
# But I want to iterate not just one wall pset but all the walls.
Looks like you're overwriting your dictionary for each wall, maybe you want to create a list of dictionaries and flatten it at the end ? or a dict of dicts with the guid as a key ?
@Gorgious I will try your suggestion. Though I tried making a list and or dict of dict (but I got error!)....may be due to beginner level in python & ifcopenshell. I think flattening might change its default structure from the util.get_pset function output.
@Moult and @Gorgious I have been able to create a list of dictionaries (nested dictionaries) from the util.get_pset(). But I still get a runtime error if I iterate through the list.
`
I have the following as a list of nested dictionaries. I want to loop through it and create a multi index data frame. But I always get a runtime error.
Here is the sample list of nested dictionaies and the code I used.
sample_list_of_nestdict = [{'Pset_WallCommon': {'Reference': 'Basic Wall:Interior - Partition (92mm Stud)',
'LoadBearing': False, 'ExtendToStructure': False, 'IsExternal': False, 'id': 4093},
'PSet_Revit_Constraints': {'Location Line': 2, 'Base Constraint': 'Level 1',
'Base Offset': 0.0, 'Base is Attached': False, 'Base Extension Distance': 0.0,
'Top Constraint': 'Up to level: Level 2', 'Unconnected Height': 2.795000000000196,
'Top Offset': -0.3050000000000001, 'Top is Attached': False, 'Top Extension Distance': 0.0,
'Room Bounding': True, 'Related to Mass': False, 'id': 4142},
'PSet_Revit_Phasing': {'Phase Created': 'New Construction', 'id': 4146},
'PSet_Revit_Structural': {'Structural Usage': 0, 'id': 4148},
'PSet_Revit_Dimensions': {'Length': 3.791499999999996, 'Area': 10.01448500000069, 'Volume': 1.241796140000085, 'id': 4150}},
{'Pset_WallCommon': {'Reference': 'Basic Wall:Party Wall - CMU Residential Unit Dimising Wall',
'LoadBearing': False, 'ExtendToStructure': False, 'IsExternal': True, 'id': 4246},
'PSet_Revit_Constraints': {'Location Line': 0, 'Base Constraint': 'Level 1',
'Base Offset': 0.0, 'Base is Attached': False, 'Base Extension Distance': 0.0,
'Top Constraint': 'Up to level: Level 2', 'Unconnected Height': 2.795000000000196,
'Top Offset': -0.3050000000000002, 'Top is Attached': False, 'Top Extension Distance': 0.0,
'Room Bounding': True, 'Related to Mass': False, 'id': 4294},
'PSet_Revit_Phasing': {'Phase Created': 'New Construction', 'id': 4298},
'PSet_Revit_Structural': {'Structural Usage': 0, 'id': 4300},
'PSet_Revit_Dimensions': {'Length': 4.191499999999984, 'Area': 11.74179500000078, 'Volume': 5.788704935000469, 'id': 4302}}]
#The code below only works if I iterate for index[0]. I want to iterate all through the list of nested dictionary
Here is the code I used to iterate only the first index item into a dataframe. But I could not iterate for all.
reformed_dict = {}
#Iterating over the sample_list_of_nestdict
for outerKey, innerDict in sample_list_of_nestdict[0].items:
for innerKey, values in innerDict.items():
reformed_dict[(outerKey, innerKey)] = values
print(reformed_dict)
#the multi index pandas data frame
df2 = pd.DataFrame.from_dict(reformed_dict, orient='index').transpose()
df2.columns = pd.MultiIndex.from_tuples(df2.columns)
df2
reformed_dict = {}
#Iterating over the sample_list_of_nestdict
for outerKey, innerDict in sample_list_of_nestdict[0].items:
for innerKey, values in innerDict.items():
reformed_dict[(outerKey, innerKey)] = values
print(reformed_dict)
#the multi index pandas data frame
df2 = pd.DataFrame.from_dict(reformed_dict, orient='index').transpose()
df2.columns = pd.MultiIndex.from_tuples(df2.columns)
df2
Thank you all. @Moult , @Gorgious, @vpajic and @Coen. I have been able to solve the problem. I extracted the wall property set and I am working on them in pandas.
I am still trying to extract external walls coordinates in relation to the project north. If you have any suggestion, I will appreciate it.
Thanks.
Comments
Hey @shanmama - did you see some of the links and source code posted here?
Is there a particular type of data you are trying to extract? Is it geometry? Is it an attribute? Is it a property set? If you're interested, in an online meeting I can do a screenshare and teach a bit about IfcOpenShell-python. Would you participate?
Dear all,
Please Help....
I am a beginner in using python, IFC and BlenderBim add on. I am trying to do the following;
1. extract the quantities, material type of walls and floors and place them into a dictionary
2. extract the quantities of external walls and group them based on their cardinal orientation (south, north, west, etc) of each wall. I do not know if it's workable.
For the quantities I tried the sample code on https://thinkmoult.com/using-ifcopenshell-parse-ifc-files-python.html but I get an attribute error (as shown below). I just hope I am doing the right thing.

@polsonmila at first glance it looks as if you're getting an AttributeError because you're attempting to access quantity.lengthValue instead of quantity.LengthValue -- > the properties all use CamelCase
Also, you need to loop through each Wall in your Walls list before you try to access .isDefinedBy.
something like:
@vpajic Thank you for the response. I will try to do that and give you an update.
BTW: if you post code do not use a screen shot but copy the code and use code tags instead. It looks like in the post of vpajic. If you post a screen shot noone can copy and test your code.
cheers bernd
am grateful for the help
After reading through the https://wiki.osarch.org/index.php?title=IfcOpenShell_code_examples
I was able to at least use the sample code to extract the wall pset as dictionary.
NOTE: I am trying to extract the quantities of Walls and Slabs and place them in a dataframe.
I want these to have their GUID.
I would also like to group all the Walls external walls based on their Cardinal points (south, north, etc)
once again thank you for your anticipated responses.
NOTE: I am trying to extract the quantities of Walls and Slabs and place them in a dataframe.
I want these to have their GUID.
I would also like to group all the Walls external walls based on their Cardinal points (south, north, etc)
once again thank you for your anticipated responses.
@vpajic Thank you. I am relatively new to both Python and IfcOpenshell. I am now exploring my way through (as I go through the Wiki.osarch.org tutorials. I was able use the get_info and loop through (as shown below). But I as you suggested, I also observed that I could loop through the wall list from the wall.by_type function call. I will work on it so that I can try accessing the IsDefinedBy.
Well this is how far I have gone.
@vpajic Thank you for your comment I still need help...
@Moult and @bernd kindly assist.
I am relatively new to both Python and IfcOpenshell. I am now exploring my way through (as I go through the Wiki.osarch.org tutorials. I was able use the get_info and loop through (as shown below). But I as @vpajic suggested, I also observed that I could loop through the wall list from the wall.by_type function call. I will work on it so that I can try accessing the IsDefinedBy.
Well, this is how far I have gone.
I have been able to have the loop through to get the property set of one wall using the IsDefinedBy procedure. But I could not access the Quantities. Please, can someone help me to identify where I am getting things wrong?
@polsonmila - i would heartily recommend having a look at
. Using the console in blender will allow you to explore the commands and structure of ifcopenshell more intuitively.
In your last example, it seems to me you are trying to access
property.is_a('IfcElementQuantity'):
without having first defined 'property'@polsonmila
How has progress been? :-)
@Coen thank you for your follow-up question. I followed the YouTube video tutorial specified by @vpajic it has been helpful. Though, I will still need help.
@polsonmila have you considered using the util module? To get properties and quantities you can just do it in one line of code:
I want to extract the data from the IFC 2x3 format and place them in a data frame.
1. I used the util.get_psets() function to get the property sets of all the walls in a particular building but I could not loop through the walls and place them into a data frame. I could only do that for one wall (as shown in the code below).
2. I want to extract the external walls within an IFC 2x3 specifying the cardinal orientation of the external faces of the walls with respect to the Project North (e.g. North-west, North-south, North). If you have any idea on how to extract these details, I will be grateful.
Code for question 1
`#The IFC 2x3 model
model_name = 'Duplex_A.ifc'
model = ifcopenshell.open(model_name)
The walls by_type
walls = model.by_type('IfcWall')
count = 0
Iterating through the walls
for wall in walls:
wall_sets_dict = {}
#count += 1
The util.get_psets function
`
Question 2
????
NOTE: I added a note pad for further details and the IFC 2x3 file.
I've never seen a dataframe before, what's the structure you need in the end? Is is a dictionary? List? What should it look like?
@Moult please pardon my miscommunication (I am a beginner). I meant a pandas data frame. I was able to use the util.get_psets for only one wall and derived a multi-index data frame (as shown in the code below)
Looks like you're overwriting your dictionary for each wall, maybe you want to create a list of dictionaries and flatten it at the end ? or a dict of dicts with the guid as a key ?
@Gorgious I will try your suggestion. Though I tried making a list and or dict of dict (but I got error!)....may be due to beginner level in python & ifcopenshell. I think flattening might change its default structure from the util.get_pset function output.
@polsonmila if you manually type out a list / dict with sample data of the structure you're after for your data frame, perhaps we can help :)
@Moult and @Gorgious I have been able to create a list of dictionaries (nested dictionaries) from the util.get_pset(). But I still get a runtime error if I iterate through the list.
`
I have the following as a list of nested dictionaries. I want to loop through it and create a multi index data frame. But I always get a runtime error.
Here is the sample list of nested dictionaies and the code I used.
`
Here is the code I used to iterate only the first index item into a dataframe. But I could not iterate for all.
I quickly skimmed through the Pandas documentation and perhaps
pd.DataFrame.from_records(sample_list_of_nestdict)
might be what you're after.Thank you all. @Moult , @Gorgious, @vpajic and @Coen. I have been able to solve the problem. I extracted the wall property set and I am working on them in pandas.
I am still trying to extract external walls coordinates in relation to the project north. If you have any suggestion, I will appreciate it.
Thanks.