Ifcopenshell: Proposal to create a new IfcOpenShell-python util module

Created on 9 Apr 2020  路  15Comments  路  Source: IfcOpenShell/IfcOpenShell

Ping @berndhahnebach and @yorikvanhavre and @aothms

IfcOpenShell is used in a lot of utilities, which can lead to duplicate code if the same things are implemented again and again.

I propose to create a new util module, which can be imported as import ifcopenshell.util. It will contain methods that can be reused across the many implementations.

Here are four functions I propose to add first, as I suspect they can be instantly reused in FreeCAD/BlenderBIM Add-on/IFCCSV/BIMTester/any mini-script written by someone/etc.

  • ifcopenshell.util.get_pset_property(element, pset_name, prop_name) returns the wrappedValue if it is a simple property definition, else, for now, return is undefined.
  • ifcopenshell.util.get_qto_property(element, qto_name, prop_name) - same, but for Qto
  • ifcopenshell.util.dd2dms(dd) - converts from decimal degrees to degrees minutes seconds. Returns a tuple of (d, m, s). This is required for almost all georeferencing implementations
  • ifcopenshell.util.dms2dd(dms) - the other way around

We can add more and tweak as we go along, but I suspect these 4 have little debate around them, so would be a good starting point.

Most helpful comment

Like the idea! I'd definitely try to use that in FreeCAD ;) and i like using a dict or defaultdict as well.. it's easy later on to add more specific stuff..
It would be interesting to have a function that returns the project unit too.. then the needed conversions could be done by the user for now

All 15 comments

Thanks for this initiative. Great idea.

Regarding properties and quantities: how about just enumerating all properties and quantities into a defaultdict(dict). So that users do something like

util.get_all_properties(elem)["PSet_WallCommon"].get("IsExternal").

Advantages:

  • Users can store the entire dict: more efficient when multiple props are required (in the other case one can short circuit on the pset name, but I doubt it's significant)
  • Useful for serializing to JSON or User Interface

Is it useful to distinguish type/instance prop associations?

Basically there is code for this defined here: https://github.com/IfcOpenShell/IfcOpenShell/blob/master/src/ifcopenshell-python/ifcopenshell/geom/app.py#L320

Indeed we have to think about the return type. Even for PSingleValue there can be a Unit. And if Unit is null we probably need to apply the IfcProject Unit (as that's the default for geometry too). So that e.g. the volume/surface measures correspond. Perhaps it can be some custom class to encapsulate all of this (it can inherit from str or float so that users can use it easily).

Sounds great to me! I'm more than happy to make a start on the module if @yorikvanhavre and @berndhahnebach are also keen, and then we can collectively tweak it. I like your suggestion about a default dict!

Unit is tricky - we need some util functions for unit conversions. I've got some code already related to that... but we need to agree on the function signature.

Should I do this in a PR, or? (I won't replace any existing functions with this util function until we're all happy with it)

Like the idea! I'd definitely try to use that in FreeCAD ;) and i like using a dict or defaultdict as well.. it's easy later on to add more specific stuff..
It would be interesting to have a function that returns the project unit too.. then the needed conversions could be done by the user for now

Should I do this in a PR, or?

For me a PR is not necessary.

Re unit functionality, there was somebody on the forums willing to contribute something https://sourceforge.net/p/ifcopenshell/discussion/1782717/thread/1a1c98e843/#c68f

@yorikvanhavre I will also invite you as a developer so that if you have additions to the util module or elsewhere you don't need depend on us.

Humbled by your trust @aothms . Thanks!!

We had a short disscussion about this on FreeCAD forum some days ago. Great to see this realised that fast. It would be excellent if we could move these methods mentioned by moult into ifcopenshell. All programms which use ifcopenshell would treat ifc files the same way than.
It would make things much simpler in FreeCAD too.

cheers bernd

I've made a start. The perfect is the enemy of the good, so here's what I've done ;)

  • dd2dms and dms2dd, pretty straightforward I think. they live in ifcopenshell.util.geolocation
  • added xyz2enh to convert local to global coordinates given the properties of an ifc map conversion
  • in ifcopenshell.util.element there is get_psets(element) which takes any element and will grab its psets and qtos and return a dictionary of the results as per @aothms 's code. Slight modification to allow you to feed it a type object too. I also made it _not_ return the relating type's psets, as I believe we need to think carefully how users might 1) want psets _only_ defined at the object level, and 2) want psets with type vs element pset overriding occuring.
  • in ifcopenshell.util.unit is the unit code I already use in blenderbim add-on, and I believe has some similarities in freecad. The functions are a bit simplistic, but this will be improved.
  • in ifcopenshell.util.selector is a selector allowing you to parse an IFC shorthand query (see #748). For now, it supports the CSS-style syntax which I have been using extensively to implement CLI filtering in IFCCSV, and am about to roll out to IfcClash, IfcDiff, and BlenderBIM Add-on itself. When an XPath style selector syntax is designed, it can also be supported, or may supersede the current CSS-style. I think with this code-shared, @yorikvanhavre can very quickly implement these features in FreeCAD too :)

Hello, I do not understand much of what's going on here, sorry, but as i'm becoming a real FreeCAD addict, i'm really motivated to help in this field :)

@Moult Fantastic. Maybe create a couple of issues where others (incl. me) can help. We have good first issue and help wanted labels. Edit: Tiny comment it seems in dms2dd() you don't incorporate milliseconds.

@aothms cheers and you are absolutely right about the bug in dms2dd()! @carlopav what do you reckon, is this something you'd like to fix? You can then also swap out the FreeCAD dms2dd and dd2dms code with this module?

Edit: actually, it would be cool to also use xyz2enh in FreeCAD - FreeCAD already has georeferencing entities stored, so it is fairly trivial to make a new feature which converts local to global...

... and maybe, then, we also need a enh2xyz()?

@moult sure I can try.

I'd love to see added to the utils

  • get_transform (Perhaps world and local)
  • get_material (Less clear what the data structure would be for this)

These two methods would make conversion utilities easier to write when they chose not to use the internal create_shape method.

References

https://github.com/IfcOpenShell/IfcOpenShell/commit/681a3c3a5c108e57dc74a6fc24c83135b12c2502#r39342314

862

841

I make use of ifcopenshell.util.element.get_psets(ifcfileinstance[entity]) on a regular basis. Lately even IfcComplexProperty has been added. Thanks to moult. (2a22acfdc936) One reason more to use this in FreeCAD. I may implent it in FreeCAD ...

The reason why I post is as follows. How about making get_psets working like get_info()

entityinstance.get_psets()

ping @aothms

cheers bernd

The reason why I post is as follows. How about making get_psets working like get_info(): entityinstance.get_psets()

I don't have a strong opinion. The utils thing are a bit harder to discover, on the other hand it can be made a bit clearer that not all entity instances have psets (object and typeobject, through a different mechanism). Do as you please.

Closing as the util module is well underway and evolving :)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Moult picture Moult  路  12Comments

Moult picture Moult  路  8Comments

globalcitizen picture globalcitizen  路  10Comments

AlexanderNitsch picture AlexanderNitsch  路  4Comments

Ahmed-Abdelhak picture Ahmed-Abdelhak  路  11Comments