1

I am trying to read the deepest level of quantities for objects in an ifc file, using IfcOpenShell in Python. So far I have:

import ifcopenshell

path = r'D:\ifcos_1\slab.ifc'
ifc_file = ifcopenshell.open(path)

geometries = ifc_file.by_type("IfcProduct")

for geometry in geometries:
    if geometry.is_a("IfcSlab"):
        print geometry
        test = geometry.IfcPhysicalQuantity()
        print test

I've studied the definitions

No matter which type of function I try to place for the test = geometry.X(), I get an error:

File "C:\Python27\lib\site-packages\ifcopenshell\entity_instance.py", line 48, in __getattr__
   "entity instance of type '%s' has no attribute '%s'" % (self.wrapped_data.is_a(), name))
AttributeError: entity instance of type 'IfcSlab' has no attribute 'IfcPhysicalQuantity'

Not sure how to solve this and would appreciate help.

EDIT:

Further work which gets the slab and further references:

for geometry in geometries:
    if geometry.is_a("IfcSlab"):
        print geometry
        definedBy = geometry.IsDefinedBy

        print definedBy[0]

        for each in definedBy:
            test = each.is_a()
            print test

As of this moment the obstacle is the compatibility with IFC4, which I will try to recompile with instructions from this forum post.

EDIT 2:

Further work using for now the IFC 2x3 standard, with a file that has quantity information (verified via the raw data). The following is the relevant code:

for geometry in geometries:
    if geometry.is_a("IfcSlab"):
        definedBy = geometry.IsDefinedBy

        for line in definedBy:
        test = line.is_a()
        # print test
        if line.is_a() == 'IfcRelDefinesByProperties' or line.is_a() == 'IfcRelDefinesByType':
            step1 = line.RelatingPropertyDefinition
            step2 = step1.is_a()
            print step2

There is an error no matter what I place after step1 = line., none of the following give a result:

line.IfcPropertySet
line.IfcElementQuantity
line.RelatingPropertyDefiniton

The output from this code is nevertheless:

IfcPropertySet
IfcPropertySet
IfcPropertySet
IfcPropertySet
IfcPropertySet
IfcPropertySet
IfcPropertySet
IfcPropertySet
IfcPropertySet
IfcPropertySet
IfcElementQuantity
IfcElementQuantity

Which means that I can access IfcElementQuantity but none of the Attributes work. I've looked at schema reference but can't find the correct one.

Loebl
  • 1,381
  • 11
  • 21
Yafim Simanovsky
  • 531
  • 7
  • 26

3 Answers3

5

When implementing this you should take care which version of IFC your import library works on - the version distributed by the IfcOpenShell-Website works with IFC2X3. For IFC4 you will probably need to compile a version yourself. (you can check your IFC version with ifcopenshell.schema_identifier)

I am putting links up to the buildingSMART IFC 4 definition even if I am talking about IFC2X3. Differences to IFC2X3 are marked in red on the buildingSMART web page. And the IFC4 definition is nicer to read (IMO).

Quantities aren't directly attached like an attribute. They are written as property sets and then related to the element or element type. So first you should ensure your IFC file contains quantities - otherwise you will not find any. Usually you start with a specific product - ifc_file.by_type('IfcSlab'). You can reach the property sets via inverse attributes - those are usually set up by the IFC library, they don't appear directly as attribute in the file.

I took you example file and shortened it to about a third (so it's still a valid IFC2X3 file):

ISO-10303-21;
HEADER;FILE_DESCRIPTION(('ViewDefinition [Custom, QuantityTakeOffAddOnView, SpaceBoundary2ndLevelAddOnView]','Option [Drawing Scale: 100.000000]','Option [Global Unique Identifiers (GUID): Keep existing]','Option [Elements to export: Visible elements (on all stories)]','Option [Partial Structure Display: Entire Model]','Option [IFC Domain: All]','Option [Structural Function: All Elements]','Option [Convert Grid elements: On]','Option [Convert IFC Annotations and ARCHICAD 2D elements: Off]','Option [Convert 2D symbols of Doors and Windows: Off]','Option [Explode Composite and Complex Profile elements into parts: On]','Option [Export geometries that Participates in Collision Detection only: Off]','Option [Elements in Solid Element Operations: Extruded/revolved]','Option [Elements with junctions: Extruded/revolved without junctions]','Option [Slabs with slanted edge(s): Extruded]','Option [Use legacy geometric methods as in Coordination View 1.0: Off]','Option [IFC Site Geometry: As boundary representation (BRep)]','Option [IFC Site Location: At Project Origin]','Option [Curtain Wall export mode: Container Element]','Option [Railing export mode: Single Element]','Option [Stair export mode: Container Element]','Option [Properties To Export: All properties]','Option [Space containment: On]','Option [IFC Domain For Space Containment: All]','Option [Bounding Box: Off]','Option [Geometry to type objects: Off]','Option [Element Properties: All]','Option [Property Type Element Parameter: On]','Option [Quantity Type Element Parameter: On]','Option [IFC Base Quantities: On]','Option [Window Door Lining and Panel Parameters: On]','Option [IFC Space boundaries: On]','Option [ARCHICAD Zone Categories as IFC Space classification data: On]','Option [Element Classifications: On]'),'2;1');
FILE_NAME('D:\\Side Projects\\Paragraph3\\The database\\IFC Files\\Local tests\\ifcos_1\\slab.ifc','2018-06-13T18:28:40',('Architect'),('Building Designer Office'),'The EXPRESS Data Manager Version 5.02.0100.09 : 26 Sep 2013','IFC file generated by GRAPHISOFT ARCHICAD-64 21.0.0 INT FULL Windows version (IFC2x3 add-on version: 3005 INT FULL).','The authorising person');
FILE_SCHEMA(('IFC2X3'));
ENDSEC;
DATA;
#1= IFCPERSON($,'Undefined',$,$,$,$,$,$);
#7= IFCPERSONANDORGANIZATION(#1,#10,$);
#10= IFCORGANIZATION('GS','GRAPHISOFT','GRAPHISOFT',$,$);
#11= IFCAPPLICATION(#10,'21.0.0','ARCHICAD-64','IFC2x3 add-on version: 3005 INT FULL');
#12= IFCOWNERHISTORY(#7,#11,$,.ADDED.,$,$,$,1528907320);
#13= IFCSIUNIT(*,.LENGTHUNIT.,.MILLI.,.METRE.);
#14= IFCSIUNIT(*,.AREAUNIT.,$,.SQUARE_METRE.);
#16= IFCSIUNIT(*,.PLANEANGLEUNIT.,$,.RADIAN.);
#17= IFCMEASUREWITHUNIT(IFCPLANEANGLEMEASURE(0.0174532925199),#16);
#18= IFCDIMENSIONALEXPONENTS(0,0,0,0,0,0,0);
#19= IFCCONVERSIONBASEDUNIT(#18,.PLANEANGLEUNIT.,'DEGREE',#17);
#29= IFCUNITASSIGNMENT((#13,#14,#19));
#31= IFCDIRECTION((1.,0.,0.));
#35= IFCDIRECTION((0.,0.,1.));
#37= IFCCARTESIANPOINT((0.,0.,0.));
#39= IFCAXIS2PLACEMENT3D(#37,#35,#31);
#40= IFCDIRECTION((0.,1.));
#42= IFCGEOMETRICREPRESENTATIONCONTEXT($,'Model',3,1.00000000000E-5,#39,#40);
#45= IFCPROJECT('344O7vICcwH8qAEnwJDjSU',#12,'Project',$,$,$,$,(#42),#29);
#59= IFCLOCALPLACEMENT($,#39);
#62= IFCSITE('20FpTZCqJy2vhVJYtjuIce',#12,'Site',$,$,#59,$,$,.ELEMENT.,(47,33,34,948800),(19,3,17,204400),0.,$,$);
#68= IFCRELAGGREGATES('0Du7$nzQXCktKlPUTLFSAT',#12,$,$,#45,(#62));
#74= IFCQUANTITYLENGTH('GrossPerimeter',$,$,0.);
#76= IFCQUANTITYAREA('GrossArea',$,$,0.);
#77= IFCELEMENTQUANTITY('2GNZepdf73fvGc$0W6rozj',#12,'BaseQuantities',$,'ARCHICAD BIM Base Quantities',(#74,#76));
#82= IFCRELDEFINESBYPROPERTIES('2Hm9JvZjohDNSD2kdxZI3b',#12,$,$,(#62),#77);
#93= IFCLOCALPLACEMENT(#59,#39);
#95= IFCBUILDING('00tMo7QcxqWdIGvc4sMN2A',#12,'Building',$,$,#93,$,$,.ELEMENT.,$,$,$);
#97= IFCRELAGGREGATES('2b_h_mYcGArd6glJG2Fmbt',#12,$,$,#62,(#95));
#101= IFCQUANTITYAREA('GrossFloorArea',$,$,0.);
#102= IFCELEMENTQUANTITY('1kQMlmT0rD35a9E43iKTas',#12,'BaseQuantities',$,'ARCHICAD BIM Base Quantities',(#101));
#104= IFCRELDEFINESBYPROPERTIES('0L87OdSD3DqSTjSRlAciZL',#12,$,$,(#95),#102);
#115= IFCLOCALPLACEMENT(#93,#39);
#117= IFCBUILDINGSTOREY('1oZ0wPs_PE8ANCPg3bIs4j',#12,'Ground Floor',$,$,#115,$,$,.ELEMENT.,0.);
#119= IFCRELAGGREGATES('118jwqMnuwK1xuf97w7fU5',#12,$,$,#95,(#117));
#180= IFCSLAB('3W29Drc$H6CxK3FGIxjJNl',#12,'SLA - 001',$,$,$,$,'E0089375-9BF4-4633-B503-3D04BBB535EF',.FLOOR.);
#195= IFCRELCONTAINEDINSPATIALSTRUCTURE('04ldtj6cp2dME6CiP80Bzh',#12,$,$,(#180),#117);
#326= IFCPROPERTYSINGLEVALUE('Fragility rating',$,IFCLABEL('0'),$);
#327= IFCPROPERTYSINGLEVALUE('Tile dimensions',$,IFCLABEL('Undefined'),$);
#328= IFCPROPERTYSINGLEVALUE('Anti-static Surface',$,IFCBOOLEAN(.F.),$);
#329= IFCPROPERTYSINGLEVALUE('Non-skid Surface',$,IFCBOOLEAN(.F.),$);
#330= IFCPROPERTYSET('0LYX8AqOOS9ft8M4aJYEYa',#12,'FLOORINGS',$,(#326,#327,#328,#329));
#332= IFCRELDEFINESBYPROPERTIES('1G6WWCSQGg0PdTnW7hwMrM',#12,$,$,(#180),#330);
#335= IFCPROPERTYSINGLEVALUE('Renovation Status',$,IFCLABEL('Existing'),$);
#336= IFCPROPERTYSET('0cR6wsk2QWcLKPchA8mF3u',#12,'AC_Pset_RenovationAndPhasing',$,(#335));
#338= IFCRELDEFINESBYPROPERTIES('3nYD8KGPhoBw5okmj1JjsA',#12,$,$,(#180),#336);
#341= IFCQUANTITYLENGTH('Width',$,$,300.);
#342= IFCQUANTITYLENGTH('Perimeter',$,$,22000.);
#343= IFCQUANTITYAREA('GrossArea',$,$,28.);
#344= IFCQUANTITYAREA('NetArea',$,$,28.);
#345= IFCQUANTITYVOLUME('GrossVolume',$,$,8.4);
#346= IFCQUANTITYVOLUME('NetVolume',$,$,8.4);
#347= IFCELEMENTQUANTITY('1RfXJewSc7OCIaD$L2ZoXT',#12,'BaseQuantities',$,'ARCHICAD BIM Base Quantities',(#341,#342,#343,#344,#345,#346));
#349= IFCRELDEFINESBYPROPERTIES('085uLttAQRllG3nL_YikZ8',#12,$,$,(#180),#347);
#375= IFCQUANTITYVOLUME('Gross Volume of the Slab',$,$,8.4);
#376= IFCQUANTITYVOLUME('Gross Volume of the Slab with Holes',$,$,8.4);
#377= IFCQUANTITYLENGTH('Holes Perimeter',$,$,0.);
#378= IFCQUANTITYAREA('Holes Surface Area',$,$,0.);
#379= IFCQUANTITYLENGTH('Perimeter',$,$,22000.);
#381= IFCQUANTITYAREA('Top Surface Area',$,$,28.);
#382= IFCELEMENTQUANTITY('0DuZ12CVtssgcIQPaQ$1sp',#12,'ArchiCADQuantities',$,'ARCHICAD BIM Quantities',(#375,#376,#377,#378,#379,#381));
#384= IFCRELDEFINESBYPROPERTIES('0KgGv0Y8Fc2jg8BCPhxnM5',#12,$,$,(#180),#382);
#393= IFCSLABTYPE('0K1otpnkQcEpOBXPxnZ3dB',#12,'Timber - Floor 300',$,$,(#396),$,'14072DF3-C6E6-A63B-360B-859EF18C39CB',$,.FLOOR.);
#395= IFCRELDEFINESBYTYPE('353egCMRpZtJd$CDCoSsCb',#12,$,$,(#180),#393);
#352= IFCQUANTITYAREA('Area',$,$,28.);
#353= IFCQUANTITYLENGTH('Height',$,$,300.);
#354= IFCQUANTITYVOLUME('Net Volume',$,$,8.4);
#396= IFCELEMENTQUANTITY('1Zyxf4r7NogSp4V7ORMpET',#12,'ArchiCADQuantities',$,'ARCHICAD BIM Quantities',(#352,#353,#354));
ENDSEC;
END-ISO-10303-21;

This is a slab with an area measurement attached. It should have an inverse attribute IsDefinedBy. In IFC2X3 this points to a list of entities IfcRelDefinesByProperties and IfcRelDefinesByType. With IFC4 IfcRelDefinesByType will be put in the inverse attribute IsTypedBy.

Each IfcRelDefinesByProperties point to a property set in their attribute RelatingPropertyDefinition. There are various property set types, you want it to be of type IfcElementQuantity when searching for physical quantities. You will have to check at run time which type you currently hold while iterating the list of property relations.

The quantity set has a list of IfcPhysicalQuantities attached in the attribute Quantities. These can be simple quantities or complex quantities, which are composed of multiple simple quantities. For simple quantities there are specific subtypes for area, count or weight. Again you will have to check at runtime for the concrete type.

The area quantity itself has a name and description to give further context (not ours, but possibly in the real world). The value attribute is named after the quantity type, so IfcQuantityArea has an attribute AreaValue. Also of interest is attribute Unit which is a reference to the unit of the value. If it is not set (as in our example) you will need to look for assigned units at the IfcProject entity.

Unfortunately this might not be all. If the object (here our IfcSlab) has an assigned object type, that type can also have property sets attached (I modified the example file to be this case). Thy type entity does not have an inverse attribute, but a direct one, HasProperties. If it is set, you can discover attached properties through it.

To summarise, you will probably need multiple loops:

  1. For each object, get property sets
  2. For each property set, test if it is quantity set
  3. For each quantity set, go through quantities

And potentially repeat this search if the object has a user defined type.

The following code should do exactly this (written on my machine with python 3.5.4 and ifcopenshell with IFC2X3 schema)):

  1. Get all slabs from the file (there is only one)
  2. Go through all entities in the inverse attribute IsDefinedBy - these can be IfcRelDefinesByProperties or IFcRelDefinesByType.
  3. Get property sets from the entity
  4. Check if the given property set is IfcElementQuantity and proceed to print quantitites if it is.
import ifcopenshell
def print_quantities(property_definition):
  if 'IfcElementQuantity' == property_definition.is_a():
    for quantity in property_definition.Quantities:
      if 'IfcQuantityArea' == quantity.is_a():
        print('Area value: ' + str(quantity.AreaValue))
      if 'IfcQuantityVolume' == quantity.is_a():
        print('Volume value: ' + str(quantity.VolumeValue))
      if 'IfcQuantityLength' == quantity.is_a():
        print('Length value: ' + str(quantity.LengthValue))

ifc_file = ifcopenshell.open('slab.ifc')
products = ifc_file.by_type('IfcSlab')
for product in products:
  if product.IsDefinedBy:
    definitions = product.IsDefinedBy
    for definition in definitions:
      #In IFC2X3 this could be property or type
      #in IFC4 type is in inverse attribute IsTypedBy
      if 'IfcRelDefinesByProperties' == definition.is_a():
        property_definition = definition.RelatingPropertyDefinition
        print_quantities(property_definition)
      if 'IfcRelDefinesByType' == definition.is_a():
        type = definition.RelatingType
        if type.HasPropertySets:
          for property_definition in type.HasPropertySets:
            print_quantities(property_definition)

For the example this results in:

Length value: 300.0
Length value: 22000.0
Area value: 28.0
Area value: 28.0
Volume value: 8.4
Volume value: 8.4
Volume value: 8.4
Volume value: 8.4
Length value: 0.0
Area value: 0.0
Length value: 22000.0
Area value: 28.0
Area value: 28.0
Length value: 300.0
Volume value: 8.4
Loebl
  • 1,381
  • 11
  • 21
  • Thanks Loebl! I'll look into it and report back with success/failure – Yafim Simanovsky May 24 '18 at 21:32
  • Hi Loebl, So far I've been only partially successful, but your information was very helpful! What I don't understand is where to find the correct implementable name for quantities. For example for `IsDefinedBy` the line is `IFCRELDEFINESBYPROPERTIES`, but for the line `IFCELEMENTQUANTITY` what is the correct attribute name? I looked at the links you attached but couldn't understand which one to use. Thanks – Yafim Simanovsky May 25 '18 at 16:53
  • I added the attribute names in the answer. The name of the attribute is `RelatingPropertyDefinition`. The spec defines it to be a select type, meaning it can point to different property set classes - you will have to check every time for the desired class. In the spec pages I link to you can click on the header "Attribute Inheritance" further down to see all attributes for that entity. Inverse ones are in italic. – Loebl May 26 '18 at 09:20
  • Thanks for all the help so far. From what I understand, the basic slab geometry has a `IsDefinedBy` attribute that leads to all the references of that basic type. Then if I want to reach quantities, I need to access the `Quantities` attribute in some set of quantities. So I have all of the lines of type `#102=IFCRELDEFINESBYPROPERTIES(` in a list, and I cycle through that list one by one but no matter which attribute I try it throws an error. I am trying to find the equivalent of the `IsDefinedBy` for the results of that same query. Should `IfcElementQuantitySet` be the attribute? – Yafim Simanovsky May 26 '18 at 21:55
  • Not quite. The attribute `IsDefinedBy` should return a list of `IFCRELDEFINESBYPROPERTIES` objects. Each of these has an attribute `RelatingPropertyDefiniton` pointing to an object which may be an `IfcElementQuantity` (you will have to check the type). The quantities are in a list of the attribute `Quantitites`. – Loebl May 27 '18 at 18:23
  • I found the `IFCRELDEFINESBYPROPERTIES` objects previously, but the `RelatingPropertyDefiniton` didn't exist for an instance of the list... so either i'm missing something or it's possible that there is no `RelatingPropertyDefiniton` attribute...? – Yafim Simanovsky May 27 '18 at 21:31
  • Could you add an update to your question how far you got? – Loebl May 28 '18 at 11:13
  • Just found out IfcOpenShell per default works with IFC2X3 which does a few details differently - updated the answer and gave an example. – Loebl May 28 '18 at 12:36
  • I'll check out how to compile for IFC4 because that's the problem I think. I updated my question to reflect the bit of progress that was made. – Yafim Simanovsky May 28 '18 at 16:25
  • Leobl, I've added 'edit: 2' to the original post to explain what I've done for now and where I got stuck. Do you have an idea about this issue? – Yafim Simanovsky Jun 10 '18 at 17:15
  • step1 can bei an `IfcPropertySet` or an `IfcElementQuantity` (or others) You will have to test if they are of type IfcElementQuantity. – Loebl Jun 10 '18 at 19:14
  • I dont understand your comment.. i added the print output of my code in the original post, so you can see what it gives me, but i also mentioned that i've already tested what you suggest and it gives me the mentioned error. i know step2 is a `IfcPropertySet` but I can't get any further info from that... – Yafim Simanovsky Jun 11 '18 at 15:53
  • `IfcPropertySet` is a different type than `IfcElementQuantity`. You can only get quantities from the second one. – Loebl Jun 11 '18 at 16:20
  • Yes but for now I have the slab which is a `ifcslab`, then I `slab.IsDefinedBy` which gives me a set of five `IfcPropertySet` items, which I iterate through and I know they are `IfcRelDefinesByProperties`, and for each one of those I make `step1 = item.RelatingPropertyDefinition` so this gives me those lines in the file, but from there I can't do anything with `step2`.... whatever I try (as I did in EDIT 2), it doesn't recognize it. This includes what you suggest... – Yafim Simanovsky Jun 11 '18 at 20:16
  • A `IfcPropertySet` doesn't have quantities. You can look at the properties it holds in its attribute `HasProperties` but it seems the `IfcSlab` you mentioned doesn't have quantities attached. – Loebl Jun 11 '18 at 20:32
  • Correct. By using `HasProperties` I see it does have certain parameters. But why doesn't it have `quantities`? How is that possible given that it has volume length and thickness...? – Yafim Simanovsky Jun 12 '18 at 06:09
  • `IfcElementQuantity` will have to be set by the program writing the file, as there might be cases where the 3D-geometry differs from the actual quanitities used in the construction. Not every program writes them. IfcOpenShell won't calculate those. You could try calculating some metrics based on the geometry though. – Loebl Jun 12 '18 at 07:18
  • So you're saying it depends on the ifc export settings in the program, right? – Yafim Simanovsky Jun 12 '18 at 17:27
  • Sort of. Some programs might not even support it entirely, they are not obliged to write every information possible into the file. – Loebl Jun 13 '18 at 06:48
  • Hi. Thanks. I've played with the IFC export settings and now I know the raw IFC file contains the quantities. I still can't figure out what to place in the code in order to get those referenced lines. I updated my original post in EDIT 2 to show the relevant code. – Yafim Simanovsky Jun 13 '18 at 16:38
  • Hi Loebl, I tested further and am still stuck. I've updated the original post again at `EDIT 2:`. Let me know if you can help. – Yafim Simanovsky Jun 14 '18 at 20:56
  • Well, if `line.is_a() == 'IfcRelDefinesByProperties'` applies then `line.RelatingPropertyDefinition` should never fail. Don't test for `'IfcRelDefinesByType'` there, do that separately, as this entity has other attributes. You should be able to further advance with `if step2.is_a() == 'IfcElementQuantity'` to look into quantities. – Loebl Jun 15 '18 at 08:06
  • Hmm..Thank you. Again, I think my main problem is understanding how to use attributes. I've looked at http://www.buildingsmart-tech.org/ifc/IFC4/Add2TC1/html/link/ifcelementquantity.htm but from what you've explained the attributes to use for step2 after the `if` should be either `IfcPhysicalQuantity` or `Quantities` or `IfcPhysicalQuantity`, but none of these work... – Yafim Simanovsky Jun 15 '18 at 15:53
  • Can you provide your example file? Maybe that can clear things up a bit. – Loebl Jun 15 '18 at 19:53
  • Thank you! I did figure most of it out but your solution is more efficient. What I am still having trouble with is understanding how to read the pages such as http://www.buildingsmart-tech.org/ifc/IFC4/Add2TC1/html/link/ifcreldefinesbytype.htm. How do you know to use `HasPropertySets` from that page...? Where is that mentioned? – Yafim Simanovsky Jun 18 '18 at 15:42
  • On this page nowhere. The variable `definition` in my code can be of the entity [IfcRelDefinesByType](http://www.buildingsmart-tech.org/ifc/IFC4/Add2TC1/html/link/ifcreldefinesbytype.htm) which has the attribute `RelatingType` (number 6). I assign it to variable `type`. If you follow the link in the docs you will arrive at [IfcTypeObject](http://www.buildingsmart-tech.org/ifc/IFC4/Add2TC1/html/link/ifctypeobject.htm) which has the attribute `HasPropertySets`. – Loebl Jun 18 '18 at 17:08
  • Hi Loebl. Thanks for all the help. I understand the way you handled numbers. What about materials? I see from my code experiments that [IfcMaterial](http://docs.buildingsmartalliance.org/IFC4x2_Bridge/schema/ifcmaterialresource/lexical/ifcmaterial.htm) for example has no methods, only attributes, but `.Name` isn't working in order to get the material name. – Yafim Simanovsky Jun 22 '18 at 22:58
  • I also tried looking at the [2x3](http://www.buildingsmart-tech.org/ifc/IFC2x3/TC1/html/) schema because the previous link I posted is for IFC4. But still I can't see a connection to the IfcMaterial name details. – Yafim Simanovsky Jun 23 '18 at 09:06
  • They are all just attributes. IfcMaterial is new in IFC4 - you would need an IFC4 version of IfcOpenShell to read it properly. Also if other problems arise please open a new question. We could also continue this discussion in a [chat room](https://chat.stackoverflow.com/). – Loebl Jun 23 '18 at 10:47
  • I've opened a chat room. Thanks. – Yafim Simanovsky Jun 24 '18 at 08:35
  • Hi Loebl, I've posted in the chat room but not sure you saw that. Can you update if it's visible? Thanks. – Yafim Simanovsky Jun 28 '18 at 21:36
  • `line.is_a() == 'IfcRelDefinesByProperties'` could be written as `line.is_a('IfcRelDefinesByProperties')` – Ufos Sep 25 '19 at 12:32
2

Quantities in IFC are stored in quantity sets, which are very similar in structure to property sets. IfcOpenShell offers utility functions to extract this data in a schema-agnostic manner:

for slab in ifc_file.by_type("IfcSlab"):
    quantities = ifcopenshell.util.element.get_psets(slab, qtos_only=True)
    print(quantities) # A dictionary of qtos and quantities
    # For example print(quantities["Qto_SlabBaseQuantities"]["GrossVolume"])
Dion Moult
  • 109
  • 4
0

I wrote a few functions once, to extract all properties.

https://github.com/johannesmichael/ifc-python/blob/master/modules/ifc_pset_utils.py

Might not be complete, but can give you an idea. I extract all to excel for further analyzis.

BaseQuantities:

def get_related_quantities(ifc_instance):
"""
Returns a list of IfcElementQuantity for given IFC ID
argument: ifc_instance
return: list of property sets
"""
quantities_list =[]
for x in ifc_instance.IsDefinedBy:
    if x.is_a("IfcRelDefinesByProperties"):
        if x.RelatingPropertyDefinition.is_a("IfcElementQuantity"):
            quantities_list.append(x.RelatingPropertyDefinition)
return quantities_list  

def get_quantity_single_value(x):
"""
Returns a dict of dicts of IfcElementQuantity single values.
Returning a dictionary of dictionaries
is used, because it is easy to transform to pandas.DataFrame 
argument: IFC Element as contained in list from get_related_property_sets()
return: dict of property single values like {"IfcName":"xx", "IfcGlobalId": "klkhlkh", ......}
"""
quantities_dicts = {}
for y in x.Quantities:
    if y.is_a('IfcQuantityArea'):
        quantities_dicts.update({y.Name:y.AreaValue})
    if y.is_a('IfcQuantityLength'):
        quantities_dicts.update({y.Name:y.LengthValue})
    if y.is_a('IfcQuantityVolume'):
        quantities_dicts.update({y.Name:y.VolumeValue})
    if y.is_a('IfcQuantityCount'):
        quantities_dicts.update({y.Name:y.CountValue})
    if y.is_a('IfcQuantityWeight'):
        quantities_dicts.update({y.Name:y.WeightValue})

return quantities_dicts 

This was done for IFC 2x3 TC1 Hope that helps

nanuuq
  • 169
  • 9