forked from xBimTeam/XbimGeometry
-
Notifications
You must be signed in to change notification settings - Fork 0
Home
ncr-399 edited this page Mar 11, 2024
·
2 revisions
-
Xbim Geometry Exploration
- Case Study IXbimGeometryEngine Interface
- How Xbim.Geometry.Engine computes Geometry and Tessellation
- Adding New Classes to Xbim.Geometry.Engine Project
- Building XbimEssentials Project
- Packaging the XbimEssentials Project
- Building XbimGeometry Project
- Packaging XbimGeometry Project
- Testing, Debugging, and Profiling Geometry Engine Projects
- Using the Generated Packages in Another Project
- Risks
- Additional Resources and References
- The IXbimGeometryEngine Interface is defined in Xbim.Essentials.Ifc4 Module
- IXbimGeometryEngine Interface is Implemented Xbim.Geometry.Engine.Interop > XbimGeometryEngine.cs Project as a Wrapper for the Native Code
- XbimGeometryEngine class defined in XbimGeometryEngine.cs internally calls the Functions defined in Xbim.Geometry.Engine (Native C++ Project) which uses OCCT Code
- Both XbimGeometryEngine classes defined in C# and C++ derive from the IXbimGeometryEngine interface defined in Xbim.Essentials.Ifc4 Module.
- The XbimGeometryEngine's Constructor loads the Xbim.GeometryEngine32.dll or Xbim.GeometryEngine64.dll depending upon the platform architecture (x86 or x64)
- It grabs the function XbimGeometryEngine class defined in native code and then creates an instance of it
- To call the methods defined in the XbimGeometry's instance created loaded from the dll it has to be cast as IXbimGeometryEngine
- This is why both XbimGeometryEngine classes defined in C# and C++ are derived from a Common Interface. If they don't implement the same interface the instance created at runtime cannot access the methods.
- All the calls made to XbimGeometryEngine C# code then call the native methods defined in C++ through the instance loaded through the dll.
- Add an Interface called IXbimEdgeGeometry in Xbim.Essentials.Ifc4 Module
- Build the Xbim.Essentials Project with the new IXbimEdgeGeometry interface and create custom packages
- Import the Custom Packages in Xbim.Geometry Project
- Add a class called XbimEdgeGeometry in Xbim.Geometry.Engine.Interop Project which implements Xbim.Essentials.Ifc4.IXbimEdgeGeometry interface
- The XbimEdgeGeometry class has a member variable of type IXbimEdgeGeometry which will be used to access native code loaded from the dll at runtime
- Add a class called XbimEdgeGeometry in Xbim.Geometry.Engine which extends from Xbim.Essentials.Ifc4.IXbimEdgeGeometry and implement all the methods defined in the interface. Use OCCT to extract edges.
- The Xbim.Geometry.Engine.Interop.XbimEdgeGeometry class then loads the Xbim.Geometry.Engine.XbimEdgeGeometry class from dll at runtime to access its functionality.
- The Xbim.Geometry.Engine.Interop.XbimEdgeGeometry is just a wrapper class that forwards the calls to native code using OCCT.
- Build the XbimGeometry and XbimEssentials Solutions and generate new packages
- Install the newly generated packages into another project to use the new functionality.
- Consider a Simple Wall having IfcShapeRepresentationType as IfcExtrudedAreaSolid
- All processes related to Geometry Generation and Triangulation are carried out in Xbim.ModelGeometry.Scene.Xbim3DModelContext class's CreateContext method
- Xbim.Geometry.Engine Module and Xbim.Tessellator Modules are used for generating Geometry and Triangulation
- The Tesselation is either generated by Xbim.Tessellator or Xbim.Geometry.Engine Module depending upon the type of the module (See Table Below)
- For ShapeRepresentation like IfcExtrudedArea where the shape is not defined the Xbim.Geometry.Engine first generates a Geometry Model and based on the model, the tessellation is computed.
- Xbim.Geometry.Engine uses OCCT to generate Geometry Model and Triangulation.
- In the case of simple shape representation types like IfcFacetedBrep the tesselation is computed by Xbim.Tesselator module.
Shape Representation | Module Used |
---|---|
IfcFacetedBrep | Xbim.Tesselator |
IIfcFaceBasedSurfaceModel | Xbim.Tesselator |
IIfcShellBasedSurfaceModel | Xbim.Tesselator |
IIfcConnectedFaceSet | Xbim.Tesselator |
IIfcTessellatedFaceSet | Xbim.Tesselator |
IfcExtrudedArea | Xbim.Geometry.Engine |
All Other | Xbim.Geometry.Engine |
- Load the Model using Xbim SDK, and create an instance of Xbim.ModelGeometry.Scene class using the model and call the
CreateContext()
method. - Inside
CreateContext()
method, first the Shape is queried using ShapeId and stored as IIfcGeometricRepresentationItem - Using this Shape of type IIfcGeometricRepresentationItem we check if its triangulation can be computed using Xbim.Tesselator method using
Xbim.Tesselator.CanMesh()
method. - In this case, since the type of IIfcGeometricReprsentationItem is of type IfcExtrudedArea it cannot be computed using Xbim.Tesselator module.
- Next, we use Xbim.Geometry.Engine module to generate a Geometry Model for the ShapeRepresentation IfcExtrudedArea.
- For ShapeRepresentation of type IfcExtrudedArea, to create a geometry model we need a Base Shape and a Direction.
- Xbim.Geometry.Engine creates an XbimSolid the ShapeRepresentation using OCCT. Using the SweptArea property of the ShapeRepresentation creates an object of type XbimFace which can be used as a Base Shape along with the ExtrudeDirection property of ShapeRepresentation to create a geometry model. Thsese two parameters are then passed to OCCT: BRepPrimAPI_MakePrism api which returns a Shape using the inputs.
- XbimSolid is derived from TopDS_Shape so it can be used with Meshing Algorithms
- At this point, we have a geometry model which we can use to generate Triangulation. We use the XbimSolid created in the previous step and pass it Xbim.Geometry.Engine.CreateShapeGeometry method to compute tesselation and return a buffer containing the tesselated data.
- Internally, Xbim.Geometry.Engine.CreateShapeGeometry calls Xbim.Geometry.Engine.WriteTriangulation method to compute the tesselation using OCCT and writes it back into a buffer. This buffer is then stored in Xbim.Model.GeometryStor
- Right-click on the Xbim.Geometry.Engine Project in Visual Studio
- Select Add from the Dropdown Menu
- Create a .cpp and .h file
- Right Click on the .cpp file and select properties
- Go to C/C++ Section
- Make Sure the Common Language Runtime Support Option is set to Common Language Runtime Support (/clr) otherwise the build will throw fatal errors if any C# Interop Code is Used in the File.
- Clone the XbimEssentials repo from XbimEssentials
- Switch to Branch issues/issue465
- Open the Solution using Visual Studio
- Build the Solution (It will build 9 Projects)
- After Successfully building the projects, right-click on the Project and Select the Pack option from the dropdown menu
- Selecting the Pack option will generate a .nuget package with version 5.1.341 e.g (Xbim.Common.5.1.341.nupkg)
- Do this for all the Projects (Ignore the Test Projects)
- Make Sure to Build the Packages in Release Mode
- Go to Project Root Folder (C:\workspace\Xbim\XbimEssentials)
- Search for .nupkg in the Search Bar. It will return all the packages
- Copy all the Packages and place them in a new Folder called packages
- Clone the XbimGeometry repo from XbimGeometry
- Switch to Branch issues/issue465
- Open the Solution using Visual Studio
- It will restore the required packages from nuget.org instead of our custom packages
- Go Project > Manage Nuget Packages
- Click on the Settings Icon on the Right Most Corner next to Package Sources. It will open up the menu to configure package sources
- Click on the + Sign to Add a new Package Source and Set the Path to the new Package Folder created while building XbimEssential packages (See Packaging XbimEssentials Project Step 7)
- Uncheck the nuget.org as Package Source in the Config Menu.
- Go to C:\Users\{UserName}\.nuget\packages and remove all the xbim packages
- Restart Visual Studio
- New Custom Packages are restored from the local source created in Building XbimGeometry Project > Step 7
- Build the Xbim.Geometry.Engine.Interop Project First and then build the rest of the projects
- Directly Building the Solution May Fail and Throw a Lot of Errors
- Once all the Projects are Built, Right Click on the C# Projects and Click on Pack from the dropdown menu to generate the nuget packages (Ignore the Regression and Tests Projects). It will generate a nupkg file with version 5.1.437
- Place the generated packages into the local package folder.
- To Test, Debug, or Profile the Xbim.Geometry.Engine and Xbim.Geometry.Engine.Interop projects use the Xbim.Regression Project
- Modify the **Xbim.Regression > Program. cs and add custom logic to test and debug the changes
- Follow the Steps mentioned in Building Xbim Geometry Project to add a Custom Package Source for nuget packages.
- Install the Custom Packages from the Local folder to use the custom functionality in another project
- Difficult to Maintain the Custom Packages
- Need to Push the Packages on some remote sources to reduce a few steps while building the projects.
- The Current Solution is based on XbimGeometry 5.1.437 and XbimEssentials 5.1.341 which no longer contain the latest changes. These Projects have been migrated to netcore version 6.0