Editing IfcOpenShell code examples

From Wiki.OSArch

Warning: You are not logged in. Your IP address will be publicly visible if you make any edits. If you log in or create an account, your edits will be attributed to your username, along with other benefits.

The edit can be undone. Please check the comparison below to verify that this is what you want to do, and then save the changes below to finish undoing the edit.

Latest revision Your text
Line 1: Line 1:
{{Template:Start coding}}
+
Before getting started, you may be interested in [[Using the Python console with BlenderBIM Add-on]], to quickly install all the software and development environment you need for writing and running code, without any administrator privileges required.
{{Template:IfcOpenShell}}
 
Before getting started, you may be interested in [[Using the Python console with BlenderBIM Add-on]], to quickly install all the software and development environment you need for writing and running code, without any administrator privileges required. You may also find it useful watching [https://www.youtube.com/watch?v=WZPNaAM9ZuQ this video] which is complementary.
 
  
=Crash course=
+
==Crash course==
  
 
To load a file, you'll need to import IfcOpenShell and store the IFC file in a variable. We'll use the variable <code>ifc</code>. The <code>ifc</code> will be then used throughout.
 
To load a file, you'll need to import IfcOpenShell and store the IFC file in a variable. We'll use the variable <code>ifc</code>. The <code>ifc</code> will be then used throughout.
Line 10: Line 8:
 
import ifcopenshell
 
import ifcopenshell
 
ifc = ifcopenshell.open('/path/to/your/file.ifc')
 
ifc = ifcopenshell.open('/path/to/your/file.ifc')
</syntaxhighlight>
 
 
...or if you already opened the file in BlenderBIM, for example, you could use...
 
 
<syntaxhighlight lang="python">
 
import ifcopenshell
 
from blenderbim.bim.ifc import IfcStore
 
ifc = ifcopenshell.open(IfcStore.path)
 
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Line 89: Line 79:
  
 
<syntaxhighlight lang="python">
 
<syntaxhighlight lang="python">
import ifcopenshell.util
+
print(ifcopenshell.util.get_psets(wall))
import ifcopenshell.util.element
 
print(ifcopenshell.util.element.get_psets(wall))
 
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Line 195: Line 183:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
=Geometry processing=
+
==Geometry processing==
  
 
The usage of IfcOpenShell for geometry processing is currently considered to be moderate to advanced. There are two approaches to processing geometry. One approach is to traverse the <code>Representation</code> attribute of the IFC element, and parse it yourself. This requires an in-depth understanding of IFC geometric representations, as well as its many caveats with units and transformations, but can be very simple to extract specific types of geometry. The second approach is to use IfcOpenShell's shape processing features, which will convert almost all IFC representations into a triangulated mesh. Regardless of the source format, once it is in a mesh representation, you may use standard mesh geometry processing algorithms to analyse the geometry. This makes it easier to write generic code for any representation, but may be harder to extract certain geometric features.
 
The usage of IfcOpenShell for geometry processing is currently considered to be moderate to advanced. There are two approaches to processing geometry. One approach is to traverse the <code>Representation</code> attribute of the IFC element, and parse it yourself. This requires an in-depth understanding of IFC geometric representations, as well as its many caveats with units and transformations, but can be very simple to extract specific types of geometry. The second approach is to use IfcOpenShell's shape processing features, which will convert almost all IFC representations into a triangulated mesh. Regardless of the source format, once it is in a mesh representation, you may use standard mesh geometry processing algorithms to analyse the geometry. This makes it easier to write generic code for any representation, but may be harder to extract certain geometric features.
  
The simplest way to get started is to use the <code>create_shape</code> function to convert an element into vertices, edges, and faces.
+
Note: this article is a work in progress.
 
 
<syntaxhighlight lang="python">
 
import ifcopenshell
 
import ifcopenshell.geom
 
 
 
ifc_file = ifcopenshell.open('/path/to/your/file.ifc')
 
 
 
element = ifc_file.by_type('IfcWall')[0]
 
 
 
settings = ifcopenshell.geom.settings()
 
shape = ifcopenshell.geom.create_shape(settings, element)
 
faces = shape.geometry.faces # Indices of vertices per triangle face e.g. [f1v1, f1v2, f1v3, f2v1, f2v2, f2v3, ...]
 
verts = shape.geometry.verts # X Y Z of vertices in flattened list e.g. [v1x, v1y, v1z, v2x, v2y, v2z, ...]
 
materials = shape.geometry.materials # Material names and colour style information that are relevant to this shape
 
material_ids = shape.geometry.material_ids # Indices of material applied per triangle face e.g. [f1m, f2m, ...]
 
 
 
# Since the lists are flattened, you may prefer to group them per face like so depending on your geometry kernel
 
grouped_verts = [[verts[i], verts[i + 1], verts[i + 2]] for i in range(0, len(verts), 3)]
 
grouped_faces = [[faces[i], faces[i + 1], faces[i + 2]] for i in range(0, len(faces), 3)]
 
</syntaxhighlight>
 
 
 
Once you have a list of vertices, edges, and faces, you can perform any standard mesh algorithm to do more geometric analysis. There are a series of settings you can apply when creating a shape. These are documented [https://github.com/IfcOpenShell/IfcOpenShell/blob/v0.7.0/docs/geom/settings.md here].
 
 
 
All shapes are given an ID to uniquely identify it. These IDs following a [https://github.com/IfcOpenShell/IfcOpenShell/issues/866 naming scheme].
 
  
If you have a lot of geometry to process, it is advised to use the geometry iterator. This will process shapes using more than one CPU and is significantly faster.
+
TODO: talk about [https://github.com/IfcOpenShell/IfcOpenShell/issues/866 naming in ids].
 
 
<syntaxhighlight lang="python">
 
import multiprocessing
 
import ifcopenshell
 
import ifcopenshell.geom
 
 
 
try:
 
    ifc_file = ifcopenshell.open('/path/to/your/file.ifc')
 
except:
 
    print(ifcopenshell.get_log())
 
else:
 
    settings = ifcopenshell.geom.settings()
 
    iterator = ifcopenshell.geom.iterator(settings, ifc_file, multiprocessing.cpu_count())
 
    if iterator.initialize():
 
        while True:
 
            shape = iterator.get()
 
            element = ifc_file.by_guid(shape.guid)
 
            faces = shape.geometry.faces # Indices of vertices per triangle face e.g. [f1v1, f1v2, f1v3, f2v1, f2v2, f2v3, ...]
 
            verts = shape.geometry.verts # X Y Z of vertices in flattened list e.g. [v1x, v1y, v1z, v2x, v2y, v2z, ...]
 
            materials = shape.geometry.materials # Material names and colour style information that are relevant to this shape
 
            material_ids = shape.geometry.material_ids # Indices of material applied per triangle face e.g. [f1m, f2m, ...]
 
 
 
            # Since the lists are flattened, you may prefer to group them per face like so depending on your geometry kernel
 
            grouped_verts = [[verts[i], verts[i + 1], verts[i + 2]] for i in range(0, len(verts), 3)]
 
            grouped_faces = [[faces[i], faces[i + 1], faces[i + 2]] for i in range(0, len(faces), 3)]
 
            if not iterator.next():
 
                break
 
</syntaxhighlight>
 
 
 
==Geometry tree (clash detection/ray tracing etc…)==
 
You can use [[https://blenderbim.org/docs-python/ifcopenshell-python/geometry_tree.html geometry tree]] to perform various task like clash detection and ray tracing. Trees are common terms is geometry libraries. IfcOpenShell tree has [[https://en.wikipedia.org/wiki/Bounding_volume_hierarchy BVHTree]] functionalities.
 
 
 
=IFC Query Syntax=
 
 
 
Sometimes, you'd like to query an IFC file for a series of elements. It is possible to write this out manually, by means of functions like <code>by_type()</code> and <code>if</code> statements, and <code>for</code> loops. However, a shorthand query syntax has been invented that makes this process much easier. This is made available in the <code>ifcopenshell.util.selector</code> module.
 
 
 
In this simple example below, we use the <code>#</code> and <code>.</code> prefix to our query tells it that we want to search by IFC <code>GlobalId</code> and class type respectively. Whitespace is optional in queries, but is used in these examples for readability.
 
 
 
<syntaxhighlight lang="python">
 
import ifcopenshell.util
 
from ifcopenshell.util.selector import Selector
 
 
 
ifc = ifcopenshell.open('/path/to/your/file.ifc')
 
selector = Selector()
 
element = selector.parse(ifc, '#2MLFd4X2f0jRq28Dvww1Vm') # Equivalent to ifc.by_guid('2MLFd4X2f0jRq28Dvww1Vm')
 
walls = selector.parse(ifc, '.IfcWall') # This is equivalent to ifc.by_type('IfcWall')
 
</syntaxhighlight>
 
 
 
It is also possible to search by any attribute:
 
 
 
<syntaxhighlight lang="python">
 
# This is equivalent to searching by GlobalId
 
elements = selector.parse(ifc, '.IfcSlab[GlobalId = "2MLFd4X2f0jRq28Dvww1Vm"]')
 
 
 
# This finds all slabs with "Precast" (case-sensitive) in the Name
 
elements = selector.parse(ifc, '.IfcSlab[Name *= "Precast"]')
 
 
 
# This finds all slabs which have a quantified net volume greater than 10 units
 
elements = selector.parse(ifc, '.IfcSlab[Qto_SlabBaseQuantities.NetVolume > "10"]')
 
 
 
# This finds all walls which have a particular fire rating property
 
elements = selector.parse(ifc, '.IfcWall[Pset_WallCommon.FireRating = "2HR"]')
 
</syntaxhighlight>
 
 
 
You can also search by spatial containment using the <code>@</code> symbol, for example:
 
 
 
<syntaxhighlight lang="python">
 
# If 0ehnsYoIDA7wC8yu69IDjv is the GlobalId of an IfcBuildingStorey, this gets all of the elements in that storey.
 
elements = selector.parse(ifc, '@ #0ehnsYoIDA7wC8yu69IDjv')
 
</syntaxhighlight>
 
 
 
Or by type using the <code>*</code> symbol:
 
 
 
<syntaxhighlight lang="python">
 
# If 1uVUwUxTX9Jg1NHVw5KZhI is the GlobalId of an IfcTypeElement, this gets all of the elements of that type.
 
elements = selector.parse(ifc, '* #1uVUwUxTX9Jg1NHVw5KZhI')
 
</syntaxhighlight>
 
 
 
You can use <code>AND</code> and <code>OR</code> statements, using the <code>&</code> and <code>|</code> symbols respectively:
 
 
 
<syntaxhighlight lang="python">
 
# This gets all the 2HR fire rated walls in a particular building storey:
 
elements = selector.parse(ifc, '@ #0ehnsYoIDA7wC8yu69IDjv & .IfcWall[Pset_WallCommon.FireRating = "2HR"]')
 
 
 
# This is equivalent to walls = ifc.by_type('IfcWall') + ifc.by_type('IfcSlab'), i.e. all walls and slabs
 
elements = selector.parse(ifc, '.IfcWall | .IfcSlab')
 
</syntaxhighlight>
 
 
 
You can also use parenthesis to group queries and combine them:
 
 
 
<syntaxhighlight lang="python">
 
# This gets all walls and slabs in a particular building storey
 
elements = selector.parse(ifc, '@ #0ehnsYoIDA7wC8yu69IDjv & ( .IfcWall | .IfcSlab )')
 
</syntaxhighlight>
 
 
 
<syntaxhighlight lang="python">
 
# This gets all walls and slabs in a particular space (if IfcRelSpaceBoundary exist)
 
elements = selector.parse(ifc, '@@ .IfcSpace & ( .IfcWall | .IfcSlab )')
 
</syntaxhighlight>
 
 
 
 
 
You can also use query a specific element. It is what you do when using [[BlenderBIM_Add-on/BlenderBIM_IFCCSV | IfcCsv]] for example.
 
 
 
<syntaxhighlight lang="python">
 
# This gets all walls and slabs in a particular building storey
 
wall = selector.parse(ifc, '.IfcWall')[0]
 
wall_name = selector.get_element_value(wall, "Name")
 
wall_type_name = selector.get_element_value(wall, "type.Name")
 
wall_is_external = selector.get_element_value(wall, "Pset_WallCommon.IsExternal")
 
</syntaxhighlight>
 
 
 
=Exploring IFC schema=
 
Get Schema :
 
<syntaxhighlight lang="python">
 
import ifcopenshell
 
schema = ifcopenshell.ifcopenshell_wrapper.schema_by_name("IFC4")
 
</syntaxhighlight>
 
 
 
Explore class attributes :
 
<syntaxhighlight lang="python">
 
>>> ifc_pipe = schema.declaration_by_name("IfcPipeSegment")
 
>>> ifc_pipe.all_attributes()
 
(<attribute GlobalId: <type IfcGloballyUniqueId: <string>>>,
 
<attribute OwnerHistory?: <entity IfcOwnerHistory>>,
 
<attribute Name?: <type IfcLabel: <string>>>,
 
<attribute Description?: <type IfcText: <string>>>,
 
<attribute ObjectType?: <type IfcLabel: <string>>>,
 
<attribute ObjectPlacement?: <entity IfcObjectPlacement>>,
 
<attribute Representation?: <entity IfcProductRepresentation>>,
 
<attribute Tag?: <type IfcIdentifier: <string>>>,
 
<attribute PredefinedType?: <enumeration IfcPipeSegmentTypeEnum: (CULVERT, FLEXIBLESEGMENT, GUTTER, NOTDEFINED, RIGIDSEGMENT, SPOOL, USERDEFINED)>>)
 
 
 
>>> ifc_pipe.attribute_count()
 
9
 
 
 
>>> ifc_pipe.attribute_by_index(0)
 
<attribute GlobalId: <type IfcGloballyUniqueId: <string>>>
 
 
 
>>> ifc_pipe.attribute_index("Description")
 
3
 
 
 
>>> predefined_type = ifc_pipe.attribute_by_index(8)
 
>>> predefined_type.name()
 
'PredefinedType'
 
 
 
>>> predefined_type.optional()
 
True
 
 
 
>>> predefined_type.type_of_attribute()
 
<enumeration IfcPipeSegmentTypeEnum: (CULVERT, FLEXIBLESEGMENT, GUTTER, NOTDEFINED, RIGIDSEGMENT, SPOOL, USERDEFINED)>
 
 
 
# from name you can then recursively explore how create an entity as described above
 
>>> predefined_type.type_of_attribute().declared_type().name()
 
'IfcPipeSegmentTypeEnum'
 
</syntaxhighlight>
 
 
 
Get supertype :
 
<syntaxhighlight lang="python">
 
>>> ifc_pipe.supertype()
 
<entity IfcFlowSegment>
 
</syntaxhighlight>
 
 
 
Another way to get a list of supertypes :
 
<!-- From discussion here: https://app.element.io/#/room/#OSArch:matrix.org/$LKrDGOp4OT3Qfbpl-Yj8QeUDG5mowS0YXrAKr0OBjts -->
 
<syntaxhighlight lang="python">
 
>>> import ifcopenshell
 
>>> s = ifcopenshell.ifcopenshell_wrapper.schema_by_name('IFC4')
 
>>> e = s.declaration_by_name('IfcWall')
 
>>> inheritance = []
 
>>> while e.supertype():
 
...    inheritance.append(e.supertype())
 
...    e = e.supertype()
 
...
 
>>> inheritance
 
[<entity IfcBuildingElement>, <entity IfcElement>, <entity IfcProduct>, <entity IfcObject>, <entity IfcObjectDefinition>, <entity IfcRoot>]
 
</syntaxhighlight>
 
 
 
 
 
Get subtypes :
 
<syntaxhighlight lang="python">
 
>>> super_type = ifc_pipe.supertype()
 
>>> super_type.subtypes()
 
(<entity IfcCableCarrierSegment>,
 
<entity IfcCableSegment>,
 
<entity IfcDuctSegment>,
 
<entity IfcPipeSegment>)
 
</syntaxhighlight>
 
 
 
 
 
=Property and quantity sets (Pset and Qto)=
 
First import util for psets and qtos and initialise main class with schema name:
 
<syntaxhighlight lang="python">
 
>>> import ifcopenshell.util.pset
 
>>> from ifcopenshell import util
 
>>> pset_qto = util.pset.PsetQto("IFC4")
 
</syntaxhighlight>
 
 
 
Get all applicable psets/qtos names for a certain class :
 
<syntaxhighlight lang="python">
 
>>> pset_qto.get_applicable_names("IfcMaterial")
 
['Pset_MaterialCombustion',
 
'Pset_MaterialCommon',
 
'Pset_MaterialConcrete',
 
'Pset_MaterialEnergy',
 
'Pset_MaterialFuel',
 
'Pset_MaterialHygroscopic',
 
'Pset_MaterialMechanical',
 
'Pset_MaterialOptical',
 
'Pset_MaterialSteel',
 
'Pset_MaterialThermal',
 
'Pset_MaterialWater',
 
'Pset_MaterialWood',
 
'Pset_MaterialWoodBasedBeam',
 
'Pset_MaterialWoodBasedPanel']
 
</syntaxhighlight>
 
 
 
You can also get a list of all applicable pset/qto templates to get more information:
 
<syntaxhighlight lang="python">
 
>>> pset_qto.get_applicable("IfcMaterial")[0]
 
#22772=IfcPropertySetTemplate('3Eppg0qUmHuO00025QrE$V',$,'Pset_MaterialCommon','A set of general material properties.',.PSET_TYPEDRIVENOVERRIDE.,'IfcMaterial',(#22775,#22778,#22781))
 
</syntaxhighlight>
 
 
 
You can also retrieve a standard Pset by name:
 
<syntaxhighlight lang="python">
 
>>> pset_template = pset_qto.get_by_name("Pset_MaterialCommon")
 
>>> pset_template
 
#22772=IfcPropertySetTemplate('3Eppg0qUmHuO00025QrE$V',$,'Pset_MaterialCommon','A set of general material,'IfcMaterial',(#22775,#22778,#22781))
 
>>> pset_template.get_info()
 
{'id': 22772,
 
'type': 'IfcPropertySetTemplate',
 
'GlobalId': '3Eppg0qUmHuO00025QrE$V',
 
'OwnerHistory': None,
 
'Name': 'Pset_MaterialCommon',
 
'Description': 'A set of general material properties.',
 
'TemplateType': 'PSET_TYPEDRIVENOVERRIDE',
 
'ApplicableEntity': 'IfcMaterial',
 
'HasPropertyTemplates': (#22775=IfcSimplePropertyTemplate('3IOi60qUmHuO00025QrE$V',$,'MolecularWeight','Molecular weight of material (typically gas).',.P_SINGLEVALUE.,'IfcMolecularWeightMeasure','',$,$,$,$,.READWRITE.),
 
  #22778=IfcSimplePropertyTemplate('3OMAA0qUmHuO00025QrE$V',$,'Porosity','The void fraction of the total volume occupied by material (Vbr - Vnet)/Vbr.',.P_SINGLEVALUE.,'IfcNormalisedRatioMeasure','',$,$,$,$,.READWRITE.),
 
  #22781=IfcSimplePropertyTemplate('3TjUq0qUmHuO00025QrE$V',$,'MassDensity','Material mass density.',.P_SINGLEVALUE.,'IfcMassDensityMeasure','',$,$,$,$,.READWRITE.))}
 
</syntaxhighlight>
 
 
 
=File validation=
 
Ifcopenshell allows you to validate a file against its corresponding schema.
 
==From command line==
 
<syntaxhighlight lang="python">
 
python -m ifcopenshell.validate some_file.ifc
 
</syntaxhighlight>
 
On GNU/Linux you can store result in a json file:
 
<syntaxhighlight lang="bash">
 
python -m ifcopenshell.validate --json some_file.ifc >> json_output_path.json
 
</syntaxhighlight>
 
 
 
==Inside a script==
 
It looks similar to command line way but you need to provide a logger (standard logger or json_logger as below).
 
<syntaxhighlight lang="python">
 
import ifcopenshell
 
import ifcopenshell.validate
 
 
 
ifc_file = ifcopenshell.open("some_file.ifc")
 
json_logger = ifcopenshell.validate.json_logger()
 
ifcopenshell.validate.validate(ifc_file, json_logger)
 
json_logger.statements
 
</syntaxhighlight>
 
=Date and time in IFC=
 
Date and time conversion can be error prone. Fortunately IFC has chosen wide used definitions so standard python [https://docs.python.org/3/library/datetime.html datetime] and [https://docs.python.org/3/library/time.html time] modules have tools to handle most of them.
 
==IfcTimeStamp==
 
[https://standards.buildingsmart.org/IFC/RELEASE/IFC4/ADD2_TC1/HTML/link/ifctimestamp.htm IfcTimeStamp] is the elapsed number of seconds since 1 January 1970, 00:00:00 UTC. See [https://en.wikipedia.org/wiki/Unix_time wikipedia] for more detailed explanations. It is typically used to record when you create or modify an IFC object. Warning while python output a float, IFC expect an integer.
 
<syntaxhighlight lang="python">
 
import time
 
# To store current time
 
>>>int(time.time())
 
1610829915
 
# To convert it to datetime (UTC+1 in this example)
 
>>> import datetime
 
>>> datetime.date.fromtimestamp(0)
 
datetime.date(1970, 1, 1, 1, 0)
 
>>> datetime.date.fromtimestamp(1610829915)
 
datetime.date(2021, 1, 16, 21, 45, 15)
 
</syntaxhighlight>
 
 
 
==IfcDateTime==
 
[https://standards.buildingsmart.org/IFC/RELEASE/IFC4/ADD2_TC1/HTML/link/ifcdatetime.htm IfcDateTime] is stored in ISO 8601 format : YYYY-MM-DDThh:mm:ss
 
Convert back and forth :
 
<syntaxhighlight lang="python">
 
from datetime import datetime
 
>>> dt = datetime.fromisoformat("2021-01-16T21:45:15")
 
>>> dt
 
datetime.datetime(2021, 1, 16, 21, 45, 15)
 
>>> dt.isoformat()
 
'2021-01-16T21:45:15'
 
</syntaxhighlight>
 
==IfcDate==
 
[https://standards.buildingsmart.org/IFC/RELEASE/IFC4/ADD2_TC1/HTML/link/ifcdate.htm IfcDate] is similar to IfcDateTime but without the time part : YYYY-MM-DD
 
You can use <code>datetime.date</code> instead of <code>datetime.datetime</code> the same way.
 
==IfcTime==
 
[https://standards.buildingsmart.org/IFC/RELEASE/IFC4/ADD2_TC1/HTML/link/ifctime.htm IfcTime] is similar to IfcDateTime but without the date part : hh:mm:ss
 
You can use <code>datetime.time</code> instead of <code>datetime.datetime</code> the same way.
 
==IfcDuration==
 
[https://standards.buildingsmart.org/IFC/RELEASE/IFC4/ADD2_TC1/HTML/link/ifcduration.htm IfcDuration] is used to store a time interval (eg. time to perform a task) in ISO 8601 format. There is apparently no ready to use standard python module to handle it. It can be handled using regular expressions. For format given as example in IFC documentation :
 
<syntaxhighlight lang="python">
 
>>> import re
 
>>> re.match("P(\d+)Y(\d+)M(\d+)DT(\d+)H(\d+)M(\d+)S", "P2Y10M15DT10H30M20S").groups()
 
('2', '10', '15', '10', '30', '20')
 
</syntaxhighlight>
 
 
 
To handle all available formatting options defined in [https://en.wikipedia.org/wiki/ISO_8601#Durations ISO 8601] a more complex regular expression is required like following.
 
[https://pythex.org/?regex=P(%3F%3A(%3FP%3Cyear%3E%5Cd%2B%3F%5B%2C%5C.%5D%3F%5Cd*)%5BY-%5D)%3F(%3F%3A(%3FP%3Cmonth%3E%5Cd%2B%3F%5B%2C%5C.%5D%3F%5Cd*)%5BM-%5D)%3F(%3F%3A(%3FP%3Cweek%3E%5Cd%2B%3F%5B%2C%5C.%5D%3F%5Cd*)W)%3F(%3F%3A(%3FP%3Cday%3E%5Cd%2B%3F%5B%2C%5C.%5D%3F%5Cd*)D%3F)%3F(%3F%3AT(%3F%3A(%3FP%3Chour%3E%5Cd%2B%3F%5B%2C%5C.%5D%3F%5Cd*)%5BH%3A%5D)%3F(%3F%3A(%3FP%3Cminute%3E%5Cd%2B%3F%5B%2C%5C.%5D%3F%5Cd*)%5BM%3A%5D)%3F(%3F%3A(%3FP%3Csecond%3E%5Cd%2B%3F%5B%2C%5C.%5D%3F%5Cd*)S%3F)%3F)%3F&test_string=P3Y6M4DT12H30M5S%0AP1M%0APT1M%0AP1DT12H%0AP0%2C5Y%0AP0.5Y%0APT36H%0AP1DT12H%0AP0003-06-04T12%3A30%3A05%0AP05Y%0AP0..5Y%0AP0%2C.5Y&ignorecase=0&multiline=0&dotall=0&verbose=0 You can test it on pythex].
 
 
 
<code>P(?:(?P<year>\d+?[,\.]?\d*)[Y-])?(?:(?P<month>\d+?[,\.]?\d*)[M-])?(?:(?P<week>\d+?[,\.]?\d*)W)?(?:(?P<day>\d+?[,\.]?\d*)D?)?(?:T(?:(?P<hour>\d+?[,\.]?\d*)[H:])?(?:(?P<minute>\d+?[,\.]?\d*)[M:])?(?:(?P<second>\d+?[,\.]?\d*)S?)?)?</code>
 
 
 
==IfcCalendarDate==
 
{{warning|Deprecated: IFC2X3 only}}
 
Similar to <code>IfcDate</code> but in a different format. It has 3 attribute for day, month and year.
 
<syntaxhighlight lang="python">
 
>>> from datetime import date
 
>>> import ifcopenshell
 
>>> ifc = ifcopenshell.file(schema="IFC2X3")
 
>>> ifc_date = ifc.createIfcCalendarDate(16, 1, 2021)
 
>>> py_date = date(ifc_date.YearComponent, ifc_date.MonthComponent, ifc_date.DayComponent)
 
>>> py_date
 
datetime.date(2021, 1, 16)
 
>>> ifc.createIfcCalendarDate(py_date.day, py_date.month, py_date.year)
 
#4=IfcCalendarDate(16,1,2021)
 
</syntaxhighlight>
 
  
 
=Samples from web=
 
=Samples from web=
Line 557: Line 197:
 
!Version
 
!Version
 
!Additional infos
 
!Additional infos
|-
 
| [https://academy.ifcopenshell.org/posts/ifcopenshell-optimizer-tutorial/ Optimize IFC files]
 
| python
 
| 0.6.0-0d93633
 
|-
 
| [https://academy.ifcopenshell.org/posts/calculate-differences-of-ifc-files-with-hashing/ Calculate Differences of IFC files with Hashing]
 
| python
 
| 0.6.0-0d93633
 
 
|-
 
|-
 
|[https://pythoncvc.net/?p=851 Understanding placements in IFC using IfcOpenShell and FreeCAD]
 
|[https://pythoncvc.net/?p=851 Understanding placements in IFC using IfcOpenShell and FreeCAD]
Line 584: Line 216:
 
| FreeCAD 0.18 git
 
| FreeCAD 0.18 git
 
|-
 
|-
| [https://academy.ifcopenshell.org/posts/using-ifcopenshell-and-c%2B%2B-to-generate-alignments-through-the-ifc-4x1-schema/ Using IfcOpenShell and C++ to generate Alignments through the IFC 4×1 schema]
+
| [http://academy.ifcopenshell.org/using-ifcopenshell-and-c-to-generate-alignments-through-the-ifc-4x1-schema/ Using IfcOpenShell and C++ to generate Alignments through the IFC 4×1 schema]
 
| python/C++
 
| python/C++
 
|-
 
|-
| [https://academy.ifcopenshell.org/posts/creating-a-simple-wall-with-property-set-and-quantity-information/ Creating a simple wall with property set and quantity information]
+
| [http://academy.ifcopenshell.org/creating-a-simple-wall-with-property-set-and-quantity-information/ Creating a simple wall with property set and quantity information]
 
| python
 
| python
 
|-
 
|-
| [https://academy.ifcopenshell.org/posts/using-ifcopenshell-and-pythonocc-to-generate-cross-sections-directly-from-an-ifc-file/ Using IfcOpenshell and pythonOCC to generate cross sections directly from an IFC file]
+
| [http://academy.ifcopenshell.org/using-ifcopenshell-and-pythonocc-to-generate-cross-sections-directly-from-an-ifc-file/ Using IfcOpenshell and pythonOCC to generate cross sections directly from an IFC file]
 
| python
 
| python
 
| <= 0.6 ?
 
| <= 0.6 ?
 
| pythonOCC 0.16.0 ?
 
| pythonOCC 0.16.0 ?
 
|-
 
|-
|[https://academy.ifcopenshell.org/posts/using-the-parsing-functionality-of-ifcopenshell-interactively/ Using the parsing functionality of IfcOpenShell interactively]
+
|[http://academy.ifcopenshell.org/using-the-parsing-functionality-of-ifcopenshell-interactively/ Using the parsing functionality of IfcOpenShell interactively]
 
| python
 
| python
 
|-
 
|-
|[https://academy.ifcopenshell.org/posts/using-ifcopenshell-and-pythonocc-to-construct-new-geometry/ Using IfcOpenShell and pythonOCC to construct new geometry]
+
|[http://academy.ifcopenshell.org/using-ifcopenshell-and-pythonocc-to-construct-new-geometry/ Using IfcOpenShell and pythonOCC to construct new geometry]
 
| python
 
| python
 
| <= 0.6
 
| <= 0.6
Line 606: Line 238:
 
| C++
 
| C++
 
|}
 
|}
 
[[Category:IfcOpenShell]]
 

Please note that all contributions to Wiki.OSArch are considered to be released under the Creative Commons Attribution-ShareAlike (see Wiki.OSArch:Copyrights for details). If you do not want your writing to be edited mercilessly and redistributed at will, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource. Do not submit copyrighted work without permission!

To edit this page, please answer the question that appears below (more info):

Cancel Editing help (opens in new window)