The STEP ISO 10303 standard allows you to reference other IFC files, and even create a compressed collection of IFC files, see: http://www.steptools.com/stds/step/IS_final_p21e3.html#clause-A-4
In fact, they even give examples of how to do it! It's awesome! I can't believe nobody is doing this! Just search that page for ".ifc" for more cool examples!
Can you please implement support for IfcOpenShell to write an ANCHOR; and REFERENCE; section, and therefore reference URIs and URI fragments? I can help build in support in Blender as an authoring tool.
Here is a small demonstration of an IFC file referencing another one (and providing useful anchors to be referenced by another IFC file):
project.ifc
ISO-10303-21;
HEADER;
FILE_DESCRIPTION(('ViewDefinition [CoordinationView]'),'4;2');
FILE_NAME('$filename','2019-05-12T12:33:45',('$owner','$email'),('$company'),'IfcOpenShell','IfcOpenShell','');
FILE_SCHEMA(('IFC4'));
ENDSEC;
ANCHOR;
<origin>=#9;
<project>=#30;
ENDSEC;
DATA;
#1=IFCPERSON($,$,'$owner',$,$,$,$,$);
#2=IFCORGANIZATION($,'$company',$,$,$);
#3=IFCPERSONANDORGANIZATION(#1,#2,$);
#4=IFCAPPLICATION(#2,'0.0.1','Blender BIM IFC','118df2cf_ed21_438e_a41');
#5=IFCOWNERHISTORY(#3,#4,$,.ADDED.,$,#3,#4,1557664425);
#6=IFCDIRECTION((1.,0.,0.));
#7=IFCDIRECTION((0.,0.,1.));
#8=IFCCARTESIANPOINT((0.,0.,0.));
#9=IFCAXIS2PLACEMENT3D(#8,#7,#6);
#10=IFCDIRECTION((0.,1.,0.));
#12=IFCDIMENSIONALEXPONENTS(0,0,0,0,0,0,0);
#13=IFCSIUNIT(*,.LENGTHUNIT.,$,.METRE.);
#14=IFCSIUNIT(*,.AREAUNIT.,$,.SQUARE_METRE.);
#15=IFCSIUNIT(*,.VOLUMEUNIT.,$,.CUBIC_METRE.);
#16=IFCSIUNIT(*,.PLANEANGLEUNIT.,$,.RADIAN.);
#17=IFCMEASUREWITHUNIT(IFCPLANEANGLEMEASURE(0.017453292519943295),#16);
#18=IFCCONVERSIONBASEDUNIT(#12,.PLANEANGLEUNIT.,'DEGREE',#17);
#19=IFCUNITASSIGNMENT((#13,#14,#15,#18));
#28=IFCGEOMETRICREPRESENTATIONCONTEXT($,'Model',3,1.E-05,#9,$);
#29=IFCGEOMETRICREPRESENTATIONSUBCONTEXT('Body','Model',*,*,*,*,#28,$,.MODEL_VIEW.,$);
#30=IFCPROJECT('0ovDN8c9v9xABetj5G4Toz',$,'My project',$,$,$,$,(#28),#19);
ENDSEC;
END-ISO-10303-21;
and now building.ifc
ISO-10303-21;
HEADER;
FILE_DESCRIPTION(('ViewDefinition [CoordinationView]'),'4;2');
FILE_NAME('$filename','2019-05-12T12:33:45',('$owner','$email'),('$company'),'IfcOpenShell','IfcOpenShell','');
FILE_SCHEMA(('IFC4'));
ENDSEC;
ANCHOR;
<site>=#4
<building>=#6
<ground_floor>=#8
ENDSEC;
REFERENCE;
#1=<project.ifc#origin>;
#2=<project.ifc#project>;
ENDSEC;
DATA;
#3=IFCLOCALPLACEMENT($,#1);
#4=IFCSITE('3K6Po8Fj9CQhOzaTgeZZlU',$,'My site',$,$,#3,$,$,$,$,$,$,$,$);
#5=IFCLOCALPLACEMENT(#3,#1);
#6=IFCBUILDING('0tjzSZIM97xO19qEfAUfEt',$,'My building',$,$,#5,$,$,$,$,$,$);
#7=IFCLOCALPLACEMENT(#5,#1);
#8=IFCBUILDINGSTOREY('0GelCcLR9Cf9zvW$jhWkTS',$,'Ground floor',$,$,#7,$,$,$,$);
#9=IFCRELAGGREGATES('2BzqY$ZaDCtBnXHyoN8zrY',$,$,$,#6,(#8));
#10=IFCRELAGGREGATES('2iMphooOTB2g9POWkmwFtf',$,$,$,#4,(#6));
#11=IFCRELAGGREGATES('2iBQDyzurBMugUedxwQ$FP',$,$,$,#2,(#4));
ENDSEC;
END-ISO-10303-21;
... there may also be a root file ISO-10303.p21 with the following content:
ISO-10303-21;
HEADER;
FILE_DESCRIPTION(('ViewDefinition [CoordinationView]'),'4;2');
FILE_NAME('$filename','2019-05-12T12:33:45',('$owner','$email'),('$company'),'IfcOpenShell','IfcOpenShell','');
FILE_SCHEMA(('IFC4'));
ENDSEC;
REFERENCE;
#1=<project.ifc>;
#2=<building.ifc>;
ENDSEC;
END-ISO-10303-21;
Yes, this really is quite awesome, but this comes from ISO 10303-21:2016, at IFC we're a couple versions back. I think we're on the 1994 version, two versions back, but not entirely sure. But yes without the cool stuff.
I think you are aware modularization and federation are really high up the agenda within buildingSMART. And I also think that this 3rd edition provides interesting things to make this happen. Within the IFC community though I think it's seen as too little too late and UML/JSON/OWL are seen as more viable modern alternatives.
If you haven't done so already share this with the crowd at the buildingSMART forums. It will definitely paint them a picture of what's possible with the modern editions of EXPRESS.
Yeah - I figured that they were using an outdated STEP version. That said, perhaps we can implement it anyway as an experimental feature, as it makes sense to use the current STEP version, and other developers too desperately want this feature?
Also I can only find references to the STEP spec ISO 10303-21 with no year specified:
https://www.iso.org/standard/70303.html
https://standards.buildingsmart.org/IFC/DEV/IFC4_2/FINAL/HTML/schema/chapter-2.htm
Oh, and given that ISO 10303-21 actually _uses_ IFC as an example of how to reference suggests that they support it with IFC...
The bS format page links to ISO 10303-21:2016, which has these features:
ISO 10303-21:2016 adds anchor, reference and signature sections to support external references, support for compressed exchange structures in an archive, digital signatures and UTF-8 character encoding.
I have updated my code sample above to fix the HEADER section. It previously had an implementation level set to 2;1, whereas this refers to the 1994 ISO standard. The appropriate level to use in 4;2, as described here.
Here is the equivalent combined IFC file in 2;1 1994 implementation level, for testing purposes. The output of the following code snippet when parsed should be identical to the 2 (or 3, if you distribute as a compressed bundle) files above:
ISO-10303-21;
HEADER;
FILE_DESCRIPTION(('ViewDefinition [CoordinationView]'),'2;1');
FILE_NAME('$filename','2019-05-12T12:33:45',('$owner','$email'),('$company'),'IfcOpenShell','IfcOpenShell','');
FILE_SCHEMA(('IFC4'));
ENDSEC;
DATA;
#1=IFCPERSON($,$,'$owner',$,$,$,$,$);
#2=IFCORGANIZATION($,'$company',$,$,$);
#3=IFCPERSONANDORGANIZATION(#1,#2,$);
#4=IFCAPPLICATION(#2,'0.0.1','Blender BIM IFC','118df2cf_ed21_438e_a41');
#5=IFCOWNERHISTORY(#3,#4,$,.ADDED.,$,#3,#4,1557664425);
#6=IFCDIRECTION((1.,0.,0.));
#7=IFCDIRECTION((0.,0.,1.));
#8=IFCCARTESIANPOINT((0.,0.,0.));
#9=IFCAXIS2PLACEMENT3D(#8,#7,#6);
#10=IFCDIRECTION((0.,1.,0.));
#12=IFCDIMENSIONALEXPONENTS(0,0,0,0,0,0,0);
#13=IFCSIUNIT(*,.LENGTHUNIT.,$,.METRE.);
#14=IFCSIUNIT(*,.AREAUNIT.,$,.SQUARE_METRE.);
#15=IFCSIUNIT(*,.VOLUMEUNIT.,$,.CUBIC_METRE.);
#16=IFCSIUNIT(*,.PLANEANGLEUNIT.,$,.RADIAN.);
#17=IFCMEASUREWITHUNIT(IFCPLANEANGLEMEASURE(0.017453292519943295),#16);
#18=IFCCONVERSIONBASEDUNIT(#12,.PLANEANGLEUNIT.,'DEGREE',#17);
#19=IFCUNITASSIGNMENT((#13,#14,#15,#18));
#28=IFCGEOMETRICREPRESENTATIONCONTEXT($,'Model',3,1.E-05,#9,$);
#29=IFCGEOMETRICREPRESENTATIONSUBCONTEXT('Body','Model',*,*,*,*,#28,$,.MODEL_VIEW.,$);
#30=IFCPROJECT('0ovDN8c9v9xABetj5G4Toz',$,'My project',$,$,$,$,(#28),#19);
#31=IFCLOCALPLACEMENT($,#9);
#32=IFCSITE('3K6Po8Fj9CQhOzaTgeZZlU',$,'My site',$,$,#31,$,$,$,$,$,$,$,$);
#33=IFCLOCALPLACEMENT(#31,#9);
#34=IFCBUILDING('0tjzSZIM97xO19qEfAUfEt',$,'My building',$,$,#33,$,$,$,$,$,$);
#35=IFCLOCALPLACEMENT(#33,#9);
#36=IFCBUILDINGSTOREY('0GelCcLR9Cf9zvW$jhWkTS',$,'Ground floor',$,$,#35,$,$,$,$);
#37=IFCRELAGGREGATES('2BzqY$ZaDCtBnXHyoN8zrY',$,$,$,#34,(#36));
#38=IFCRELAGGREGATES('2iMphooOTB2g9POWkmwFtf',$,$,$,#32,(#34));
#39=IFCRELAGGREGATES('2iBQDyzurBMugUedxwQ$FP',$,$,$,#30,(#32));
ENDSEC;
END-ISO-10303-21;
@aothms I'd like to have a stab at implementing this :) but my C++ is not so good so I might try on an experimental branch which can be deleted later and cleaned up. I saw the classes in IFC parser that defines some tokens, such as https://github.com/IfcOpenShell/IfcOpenShell/blob/v0.6.0/src/ifcparse/IfcSpfHeader.cpp - so I might create a new class for, say, IfcSpfAnchor and IfcSpfReference ... do you have any advice or can you give me a short summary of where I can find things in the code, or what you might poke to implement it?
defines some tokens
Those are only related to the header, these use the same token structure as the body
The main lexing happens here. A bit implicitly.
https://github.com/IfcOpenShell/IfcOpenShell/blob/v0.6.0/src/ifcparse/IfcParse.cpp#L309
The set of supported tokens is here
https://github.com/IfcOpenShell/IfcOpenShell/blob/v0.6.0/src/ifcparse/IfcParse.h#L69
< and > are new. I can imagine the reuse of # in an anchor might make the lexing a bit more complicated. But not sure.
In this case the very convenient thing is that IfcOpenShell only does a single pass parse. Resolving entity name ids to actual instances happens at runtime. https://github.com/IfcOpenShell/IfcOpenShell/blob/v0.6.0/src/ifcparse/IfcParse.cpp#L1923
This can be extended to look in an additional mapping of anchor strings to instances.
Sorry @aothms - this is a bit over my head to implement. Would you have time to take a stab at it?
well, I can try to make some time, but the hardest thing for me would be trying to figure out an API to use it. Can you sketch your intended usage of this?
Thanks, @aothms - here's an example repo I can imagine:
ISO-10303.p21 # root file as per spec
coordinates.ifc
project.ifc
building-foo.ifc
building-bar.ifc
building-foo/architectural/level-0.ifc
building-foo/architectural/level-1.ifc
building-foo/mechanical/level-0.ifc
building-foo/leasing-spaces/level-0.ifc
building-foo/energy-zones/level-0.ifc
building-foo/energy-zones/level-0.gbxml
building-foo/facility-management/warranties.ifc
building-foo/facility-management/product-certificate.ifc
building-foo/facility-management/documents/product.pdf # e.g. for RelAssociatesDocument
building-foo/doors/D01.ifc
building-foo/doors/D02.ifc
building-foo/windows/W01.ifc
building-foo/walls/BLK01.ifc
building-foo/environmental-analysis/concrete-psets.ifc
building-foo/external-materials/concrete.mat # e.g. for ExternallyDefinedSurfaceStyle
building-foo/external-materials/sky/sky.rad # e.g. for ExternallyDefinedSurfaceStyle
To read one, here is an initial idea
cd my-project-dir/
f = ifcopenshell.open('ISO-10303.p21') # As this opens the root file, all references are recursively iterated through and parsed.
f.by_type('IfcBuilding') # returns the IFCBUILDING defined in building-foo.ifc and building-bar.ifc
f = ifcopenshell.open('building-foo/architectural/level-0.ifc', lazy_loading = True) # just like image lazy-loading on the web, this only parses the references if you ask to resolve an anchor later on
f.by_type('IfcBuilding') # returns [], as this is not defined in this file
x = f.by_type('IfcWall')[0].ReferencedInStructures.RelatingStructure # returns IfcBuildingStorey defined in building-foo.ifc, which is lazy-loaded from an explicit request to resolve an anchor
To write one, here's a thought:
f = ifcopenshell.open('ISO-10303.p21')
f.create_reference('project.ifc')
f.create_reference('building.ifc')
f = ifcopenshell.open('project.ifc')
project = f.create_entity('IfcProject')
f.create_anchor('project', project)
f = ifcopenshell.open('building.ifc')
site = f.create_entity('IfcSite')
project = f.create_reference('project.ifc', 'project')
f.create_entity('IfcRelAggregates', **{'RelatingObject': project, 'RelatedObjects': [site]})
# So that this does not fail, the data type of f.create_reference needs to be a "mock" type. It would basically mock any IFC element, so there is no strict type checking.
I hope it makes sense.
# So that this does not fail, the data type of f.create_reference needs to be a "mock" type. It would basically mock any IFC element, so there is no strict type checking.
IfcBaseEntity exists in C++ that is the base class of all entity instances. It would pretty automatically enable this functionality, I think, just need to create a subclass then for ReferencedEntity or something.
project = f.create_reference('project.ifc', 'project')
Should there be something like an anchor class instead or is strings sufficient?
How about an alternative though. That given two files with instances F0 { i_0, ..., i_n } and F1 { ... }. And F0 references F1. And then when one does F1.create_entity(...., i_n) it will automatically create anchors and references. Or do you prefer this process more explicit and with more control over anchor names?
Awesome, an IfcBaseEntity sounds like it might fit the bill!
I think it is necessary to be explicit about anchor names. That way it works just like an "interface" in programming languages. Two parties can agree that their IFC files will provide various anchors with certain agreed upon names, and then people can reference them even before they have been created.
E.g. The client agrees that he will provide the anchor project. The architect agrees that he will provide then anchor building-foo, building-foo-ground-floor, building-foo-level-1, etc.
Two parties can agree that their IFC files will provide various anchors with certain agreed upon names
Good point, hadn't thought of that.
+1
Think this would be an exciting feature.
By the way, in the latest buildingSMART meeting in Vilnius, it was agreed to move to the latest version of STEP, which would support referencing and anchors. Whoo!
https://github.com/buildingSMART/NextGen-IFC/issues/38
https://github.com/buildingSMART/NextGen-IFC/issues/9
This is exactly what i'm looking for. Especially when moving to the exploitation phase of construction, it would be wise to know explicitly which 'network' of ifc models create the federated model. Problem is otherwise not to know if the federated model is complete or which models might be impacted by each other.
I searched a bit, but currently there is no update on this yet?
I have been discussing this informally with others in the community and the main issue people see with this approach is that it requires naming anchors specifically. This works well for the case presented here such as building storeys of which there are a well-defined handful. But does not work so well for other federated model use case such as attaching a propertyset to nearly every element in the model. I find it still rather file-centric (you still don't know if the network of files is up to date for example) and don't look forward to the syntax changes. So far I've not found the motivation to implement this.
Thx for your response Thomas, i see your point. Are there other solutions which ifc provides to relate ifc files to eachother, atleast to kind of know which models are in the federated model? As far as i can come up with otherwise is the IfcDocumentReference. Another option would be using an other system to gather track of the related models, e.g. an ontology describing it, however you would never know it when you're looking at a certain ifc file itself.
I think that last option is the most realistic. Like Information Container
for Data Drop ICDD for example.
Sent from a mobile device. Excuse my brevity. Kind regards, Thomas
Op do 18 feb. 2021 12:03 schreef JakkoH notifications@github.com:
Thx for your response Thomas, i see your point. Are there other solutions
which ifc provides to relate ifc files to eachother, atleast to kind of
know which models are in the federated model? As far as i can come up with
otherwise is the IfcDocumentReference. Another option would be using an
other system to gather track of the related models, e.g. an ontology
describing it, however you would never know it when you're looking at a
certain ifc file itself.—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/IfcOpenShell/IfcOpenShell/issues/668#issuecomment-781263636,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAILWV2XJVMYS72SWFTMHKLS7TXW3ANCNFSM4IUZSPPA
.
The main advantage of the STEP anchors/references is that it allows data be referenced from different files, which prevents duplication for both efficiency and to prevent duplication errors. This request is not to do with model federation, which to me is a separate, but much simpler issue (but is solved by coincidence via the ISO-10303.p21 root file in this proposal). Most federated models do not reference - they duplicate, and are basically nothing more than a list of files, some of which may have coordinate offsets, which could be described as:
[
{"file": "/path/to/a.ifc", "matrix": [...]},
{"file": "/path/to/b.ifc", "matrix": [...]},
]
I'm not sure what other metadata would be useful (e.g. things like author, discipline are already in the IFC).
What did you have in mind @JakkoH ?
Most helpful comment
Good point, hadn't thought of that.