-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Issue 740 - Ifc Importer Upgrades #748
Open
sebjf
wants to merge
43
commits into
ISSUE_741
Choose a base branch
from
ISSUE_740
base: ISSUE_741
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
…shell and occt. have bouncer importing geometry using reposcenebuilder.
…arents, which work via decomposition
…into its own module. fixed cmake files. updated serialiser to build tree closest to navis.
… append IFC Space label
…etry and perform baking itself
This reverts commit 738b064.
…ferent compile flags, added support for units for both values and attributes
… minor fixes to import
…without suitable definitions
…than buffering threshold
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This fixes #740
This PR is currently based against #747 to check travis, which is why it is tagged invalid. Once #747 is merged, it should be based against staging.
Description
This PR upgrades the IFC Importer, in order to gain the following improvements:
Product Team Issue: https://github.com/3drepo/3D-Repo-Product-Team/issues/680
Known Bugs/Errata
Major Changes
Structure
The Ifc importer dependencies have been rearranged.
Before, bouncer would link to IFCOS and its dependencies directly & invoke a serialiser for each schema:
Now, a new module,
ifcUtils
, acts as an intermediary:ifcUtils
is responsible for identifying the file version, etc and instantiating the correct serialiser. The schema-dependent compilation is performed at the "serialiser" level (the individual projects are now called "ifcSerialiser_###"). The serialisers are linked to ifcUtils (instead of bouncer) and are invoked by the schema-agnostic ifcUtils project.This pattern more closely matches IFCOS.
Dependencies exclusive to IFCOS are now resolved in the ifcUtils CMakeLists, which exports a single variable (
IFCUTILS_LIBRARIES
) for use by 3drepobouncer & 3drepobouncerTests.Static Libraries
Our libraries (ifcUtils and the serialisers) are now static. This is because they now reference complex types such as
RepoSceneBuilder
that are outside ofrepo::lib
, for which dynamic linking would result in a circular dependency. Since each schema gets its own compilation, and the libraries are only ever used in bouncer, dynamic linking offers no real advantages.IFCOS is still built as a shared library.
Serialiser Pattern
The importer design now follows the serialiser pattern of IFCOS. A "serialiser" is created which outputs geometric entities (IfcGeom::Elements) from an iterator. For each of these elements, the tree above it is built on-demand by recursing the Ifc Relationship objects.
For each tree node built, we build the metadata nodes in the same way, by pulling values from Ifc Value objects, and recursively traversing Relationship types. Geometric entities are written using
RepoSceneBuilder
, so only exist inside that loop iteration, reducing memory.Instancing
Instancing is used inside IFCOS, significantly reducing import time by allowing IFCOS to reuse mesh data instead of re-triangulating it each time. These instances are baked however before being handed to RepoSceneBuilder, as other parts of the platform don't properly support true instancing. Baking is performed using the matrix returned by the iterator, which is the same one IFCOS would use to bake before triangulation.
Metadata and Units
The approach to metadata and units has also been changed, to rely more on IFCOS' dynamic type system.
(1) Unit labels are built the same way as before (e.g. from
IfcUnit
objects and enums), but are now associated with specific Ifc Types (e.g. IfcLengthMeasure) dynamically through a dictionary. This dictionary is initialised on start-up based on the resource schema tables in the spec. (There is no programmatic mapping inside IFCOS.)(2) The code no longer explicitly casts to simple named types, such as
IfcLengthMeasure
, to get their values or units. Only a specific subset of types which are involved in indirection to other entities holding metadata, are handled explicitly. Values are extracted from entities by directly accessing their attributes as instances ofAttributeValue
. AttributeValue holds the type of the underlying primitive at runtime, allowing it to be converted directly to a RepoValue. The Id (RTTI) of the class/type containing the attribute is used to get the units from the dictionary built at start-up.Only a subset of Value types requiring complex formatting, such as GIS coordinates, are explicitly handled - the others go directly into RepoVariants.
The relationship tree is still searched recursively to extract metadata;
determineActionsByElementType
has effectively becomecollectMetadata
, except thatcollectMetadata
doesn't affect the tree (which is now built bygetParent
).(3) Similarly, predefined property sets are extracted by enumerating over their attributes, as are classifications.
This reduces the number of types we need to maintain in
if..else
trees, along with the number ofSCHEMA_HAS_... #ifdef
pairs. It also unifies the handling ofIfcValues
andAttributeValues
, maximising code reuse and allowing, e.g. units to automatically work for attributes in complex types such asIfcSite
, as well as in property sets.An example is the
IfcClassification
, which had theLocation
attribute removed in IFC4 and theSpecification
attribute added instead. Under the new pattern, we don't need to check the version of schema because all attributes are enumerated dynamically, so the correct name and string-ification is retrieved without selectivity.The approach of using a recursive method to walk both relationships and interpret the objects they reference is still used;
determineActionsByElementType
has substantially becomecollectMetadata
, though the difference is that the latter doesn't build the tree, as this is now handled separately viagetParent
.RepoVariants
RepoVariants are used for metadata, instead of converting all metadata to strings.
LOD Support
LOD support has been added (though most IFC files contain tessellations already as the procedural geometry schema is not easy to use...)
Unit Tests
A full set of unit tests have been added for Ifc. The test files have been created by examining the spec, and the scripts and starter files to build them added to the
tests
repository.The Ifc regression tests have been moved from st_3drepobouncerClient.cpp to ut_repo_model_import_ifc.cpp.
Due to the way the import now works - with tree nodes only being built for successfully tessellated geometry - and IFCOS handling all exceptions internally, the importer will no longer create scenes with missing nodes, so this test has been removed.
Dependencies
The IfcOpenShell libraries on travis have been rebuilt from IfcOpenShell 0.8.0 for Noble. The head of 0.8.0 as of writing this contains all the fixes in our local fork.
travis now uses the package manager's copy of OCCT, as IFCOS requires a later version and the infinite loop bug appears to have been fixed upstream.
Test cases