xBimTeam / XbimGeometry

XbimGeometry contains the CLR interop libraries and the c++ engine used to compute the 3D geometry of models.
https://xbimteam.github.io/
Other
260 stars 131 forks source link

Getting Geometry for IfcPrducts one by one #431

Closed GVladislavG closed 1 year ago

GVladislavG commented 1 year ago

Hi, xBim team! I'm getting geometry for a model using this code

m_3DMdlContext = new Xbim3DModelContext(m_model);
m_3DMdlContext.MaxThreads = 1;
m_3DMdlContext.CreateContext();
m_ShapeInsts = m_3DMdlContext.ShapeInstances().ToList();

This way generates ShapeInstances for whole model, all IfcProducts at once. And sometimes it makes xBim crash. So is there any whay to get ShapeInstances for only one IfcProduct? To get ShapeInstances for IfcProducts one by one, skipping broken ones. Thank you!

jomijomi commented 1 year ago

You can use something like this:

IfcStore theModel = IfcStore.Open(theFileName);
var context = new Xbim3DModelContext(theModel);
foreach (IIfcProduct element in theModel.Instances.OfType<IIfcProduct>())
{
    //TODO: Do some checks on the product/element (like should you import spaces, openings, etc.?)

    var productShape = context.ShapeInstancesOf(element);

    foreach (var shapeInstance in productShape)
    {
        //TODO: Extract actual triangles, etc.
    }
}

/Mikael

GVladislavG commented 1 year ago

Hi, Mikael! Thanks for your feedback. This code wil work correctly only after calling context.CreateContext();. So there is no much difference with my sample.

jomijomi commented 1 year ago

Ok, then I understand, you don't want to mesh/process all the geometry in one go... Perhaps you can try to assign a "CustomMeshingBehaviour" before calling CreateContext() and then skip based on element ID or element type (see below). I'm using this mainly to control tessellation levels (coarse tessellation on rebars, etc.), but I think it should work also if you want to skip an object/object-type entirely.

private Xbim3DModelContext.MeshingBehaviourResult MyCustomMeshingBehaviour(int elementId, int typeId, ref double linearDeflection, ref double angularDeflection)
{
    if (typeId == 571) //rebars, just an example...
    {
        return Xbim3DModelContext.MeshingBehaviourResult.Skip;
    }

    return Xbim3DModelContext.MeshingBehaviourResult.Default;
}

IfcStore theModel = IfcStore.Open(theFileName);
var context = new Xbim3DModelContext(theModel);
context.CustomMeshingBehaviour = MyCustomMeshingBehaviour;
context.CreateContext();

/Mikael