Skip to content
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

Entity Labels are not unique / Entities cannot be indentified #10

Closed
RespectableRuessel opened this issue Nov 3, 2020 · 19 comments
Closed
Assignees
Labels
enhancement New feature or request

Comments

@RespectableRuessel
Copy link

Hi @CBenghi ,

my team is using the GLTF converter to load IFC models into Unity3d.
While working on the implementation we noticed that there can be duplicate entity labels or that some entity labels belong to the parent and not to the actual entity.
I looked at the GLTF JSON data and noticed that the issue lies in the xBimGltf converter.

{
	"mesh": 348,
	"name": "Basic Roof:Live Roof over Wood Joist Flat Roof:184483 #4229"
},
{
	"mesh": 349,
	"name": "Stair:Residential - 200mm Max Riser 250mm Tread:151086:1 #5984"
},
{
	"mesh": 350,
	"name": "Stair:Residential - 200mm Max Riser 250mm Tread:151086:1 #5984"
},
{
	"mesh": 351,
	"name": "Stair:Residential - 200mm Max Riser 250mm Tread:151086:1 #5984"
},
{
	"mesh": 352,
	"name": "Stair:Residential - 200mm Max Riser 250mm Tread:151086:1 #5984"
},
{
	"mesh": 353,
	"name": "Stair:Residential - 200mm Max Riser 250mm Tread:151086:1 #5984"
},

The name is always the same with the same entity label (#5984) only with different mesh ids.
Gltf
In unity the mesh id gets added to the entity label because otherwise the name is not unique.
Our problem is that we need the actual entity ids to match them with existing IFC data.

For example we have a table with different mesh components that have different surface styles but due to the converter issue we get the same entity id for every mesh and therefore cannot match the surface styles to the entity label.

While looking at your code I also noticed some strange lines like

if (productLabel != shapeInstance.IfcProductLabel)

in Builder.cs#375 because you never change the productLabel after initializing it to zero in Builder.cs#348.

Is it possible to fix these issues?
I would be willing to fix parts of it myself, if you can tell me where exactly our issue is located.

Thanks for reading.

@CBenghi
Copy link
Member

CBenghi commented Nov 3, 2020

Hi,
can you share a small model to be sure we are on the same page?
You can use the simplify feature of XbimExplorer to retain just a couple of elements to avoid disclosing models.
Thanks,
Claudio

@RespectableRuessel
Copy link
Author

The building has a coffee table that has a inner glass and outer wood surface.
Duplex_A_20110907_optimized.zip

coffeetable

And in the GLTF file every mesh has the same entity label (see below) which is a problem because we are not able to match it to the entity labels from the surface styles.

 {
      "matrix": [
        -1.0,
        0.0,
        0.0,
        0.0,
        0.0,
        -1.0,
        0.0,
        0.0,
        0.0,
        0.0,
        1.0,
        0.0,
        2.61916518,
        -15.3431711,
        0.0,
        1.0
      ],
      "mesh": 288,
      "name": "M_Table-Coffee:0915 x 1830 x 0457mm:0915 x 1830 x 0457mm:168381 #498"
    },
    {
      "matrix": [
        -1.0,
        0.0,
        0.0,
        0.0,
        0.0,
        -1.0,
        0.0,
        0.0,
        0.0,
        0.0,
        1.0,
        0.0,
        2.61916518,
        -15.3431711,
        0.0,
        1.0
      ],
      "mesh": 289,
      "name": "M_Table-Coffee:0915 x 1830 x 0457mm:0915 x 1830 x 0457mm:168381 #498"
    },
    {
      "matrix": [
        -1.0,
        0.0,
        0.0,
        0.0,
        0.0,
        -1.0,
        0.0,
        0.0,
        0.0,
        0.0,
        1.0,
        0.0,
        2.61916518,
        -15.3431711,
        0.0,
        1.0
      ],
      "mesh": 290,
      "name": "M_Table-Coffee:0915 x 1830 x 0457mm:0915 x 1830 x 0457mm:168381 #498"
    },

@RespectableRuessel
Copy link
Author

RespectableRuessel commented Nov 3, 2020

I think the Builder.cs#352 and Builder.cs#375 lines are on the right track.

foreach (var shapeInstance in shapeInstances.OrderBy(x => x.IfcProductLabel))
if (productLabel != shapeInstance.IfcProductLabel)

Check the product label.
A. If its the same product label (because its ordered) add the mesh to the group.
B. If the product label does not match create a new group and add the mesh to it.

A and B are not in there because in the source int productLabel = 0; is never changed. So the actual comparison is

if (0 != shapeInstance.IfcProductLabel)

which is always true.

The same issue with Builder.cs#402.

targetMesh = new gltf.Mesh
{
    Name = $"Instance {productLabel}"
};

The productLabel is always zero which leads to the string Instance 0 everytime.
instance0

@CBenghi
Copy link
Member

CBenghi commented Nov 3, 2020 via email

@RespectableRuessel
Copy link
Author

I'll see if I can fix it. I'm sure these lines (productLabel) are not correct, but I'm not sure if this will fix the problem.

@CBenghi
Copy link
Member

CBenghi commented Nov 3, 2020 via email

@RespectableRuessel
Copy link
Author

RespectableRuessel commented Nov 3, 2020

I have tested the changes and it looks like the hierarchy is now correct (single parent, one entity label) but the mesh names are now duplicates and I'm not able to get the entity labels for the child elements.
If you have time I would be thankful if you can take a look.

Here is what I've done:
RespectableRuessel@d6c4525

@RespectableRuessel
Copy link
Author

RespectableRuessel commented Nov 23, 2020

@CBenghi tried a few more solutions but none worked. Would it be possible for you to look at the EntityLabel issue?

@CBenghi
Copy link
Member

CBenghi commented Nov 23, 2020 via email

@RespectableRuessel
Copy link
Author

Will do. Big thanks!

@RespectableRuessel
Copy link
Author

Reminder ⏰ if you have some time.

CBenghi added a commit that referenced this issue Dec 4, 2020
@CBenghi CBenghi self-assigned this Dec 4, 2020
@CBenghi
Copy link
Member

CBenghi commented Dec 4, 2020

Hello @RespectableRuessel,
I've looked at the code and you were clearly working in the right direction.
So I've changed the code to something much aligned to what you did.
But then I cannot understand your outstanding issue:

but the mesh names are now duplicates and I'm not able to get the entity labels for the child elements.

In the duplex that I get after conversion there are 215 meshes and they all have different instance names.
Can you clarify? Thanks.

@CBenghi CBenghi added the question Further information is requested label Dec 4, 2020
@RespectableRuessel
Copy link
Author

Sry for the late response.
The issue is that in my tests the mesh names are duplicates with an additional number added (prop. automatically) to guarantee uniqueness (see pictures below).

Mesh-Names-Duplicates

Also the mesh instances cannot be identified separately because they all belong to the same parent which only has one GUID. The goal is to identify every mesh by the entity label. That allows us to texturize every mesh based on the material for that specific mesh. The table for example has a glass surface and a wooden frame. But at the moment we are only able to identify the table because its the only element with a GUID / entity label.

Thanks again for looking into my problem.

@RespectableRuessel
Copy link
Author

In the duplex that I get after conversion there are 215 meshes and they all have different instance names.
Can you clarify? Thanks.

Ahh sry I found the misunderstanding:
The mesh with the instance 274 has multiple primitives that are split to different objects by our converter to allow us to texture them separately.

{
      "primitives": [
        {
          "attributes": {
            "NORMAL": 355,
            "POSITION": 356
          },
          "indices": 354,
          "material": 9
        },
        {
          "attributes": {
            "NORMAL": 358,
            "POSITION": 359
          },
          "indices": 357,
          "material": 9
        },
        {
          "attributes": {
            "NORMAL": 361,
            "POSITION": 362
          },
          "indices": 360,
          "material": 9
        },
        {
          "attributes": {
            "NORMAL": 364,
            "POSITION": 365
          },
          "indices": 363,
          "material": 16
        }
      ],
      "name": "Instance 274"
    },

The xBimGltf converter should instead write out several meshes with the entity labels as names instead of one mesh with several primitives. That would allow referencing the unique parts of the table, for example.

@CBenghi CBenghi added enhancement New feature or request and removed question Further information is requested labels Dec 8, 2020
@CBenghi
Copy link
Member

CBenghi commented Dec 8, 2020

I get it now.
It sounds something that I might do as a future development, but at the moment this is not high in my roadmap.

I would welcome a PR that implemented this via a configurable flag in the exporter, as I see many scenarios where breaking the sub-meshes might not be beneficial for rendering performance.
Ideally there could be a selector that made this entity-dependent or type-dependent so that only portions of the model follow this logic.

Thanks,
Claudio

@RespectableRuessel
Copy link
Author

Can you point me to the things that I need to resolve the shape instance into the right entity?
Because GetShapeInstancesToRender does not return actual entities. I can only extract the product name.

@CBenghi
Copy link
Member

CBenghi commented Dec 8, 2020

Sorry, I don't understand what you meant here.
The code is not richly documented, but have you tried to see what comes through in debugging?
There's much more than the name in the XbimShapeInstance class.

@RespectableRuessel
Copy link
Author

Sorry, I don't understand what you meant here.

Was a bad explanation by me, what I meant is the following:
The moment GetShapeInstancesToRender reads the shape instances from the geomReader.ShapeInstances the connection between entities and their shapes is lost (at least for my understanding). If I'm correct the converter just reads the data from the geometry store and writes it to GLTF.
What I don't get is how to receive the actual entity that the shape belongs to.
For example: Table (Product) -> Table surface (Entity) -> Shape
I get the shape from the geometry reader but I need to move up higher in the hierarchy to get the entity instance that the shape belongs to.
It is also possible that I simply do not understand xBim architecture because there is so little documentation.

@RespectableRuessel
Copy link
Author

Closed because of #17

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants