archilogic-com / 3dio-js

JavaScript toolkit for interior apps
https://3d.io
MIT License
273 stars 73 forks source link

Grouped furniture returned by io3d.furniture.search throws errors #102

Open bnjm opened 6 years ago

bnjm commented 6 years ago

Looks like are a few results returned by io3d.furniture.search are groups, causing errors for a-frame, furniture.get and storage.export* methods.

For example: https://furniture.3d.io/#furnitureId=68833b2a-6559-4b25-8690-8ee18ecc9d41

To Reproduce io3d.furniture.get('68833b2a-6559-4b25-8690-8ee18ecc9d41')

Actual error gets thrown: File header error: Wrong magic number. File is probably not data3d buffer format.

Expected Either no error to be thrown, or no groups to be returned by io3d.furniture.search

As a work around you can pass -group to the search string, but thought I would make this issue incase anyone else comes across it.

AVGP commented 6 years ago

This is a great bug for a first-time contributor!

Short version

  1. Check if the response from io3d.furniture.get contains a fileKeyfield, if it does, done
  2. If it doesn't, check if it contains a modelStructurefield. If it doesn't, there's something wrong here. If it does contain the field, go to (3)
  3. Parse the modelStructure field into an object with JSON.parse
  4. Take the object from step (3) and iterate over the children array in it
  5. For each child, remove the leading exclamation mark from the src property of the child
  6. Make a separate io3d.furniture.get call with the src value (without the leading "!") and work with the results

Long version (explanation)

Here is what's going on:

The story for individual furniture (working)

The furniture app takes a product ID from the URL (in the example above that's the 68833b2a-6559-4b25-8690-8ee18ecc9d41.

In cases where a product ID refers to an individual piece of furniture the response looks like this:

{
  // ...
  "fileKey": "left-out-for-brevity.gz.data3d.buffer"
  // ...
}

This fileKey is referencing a 3D file that can directly be displayed by the io3d-furniture component that this app uses.

The story for groups of furniture pieces (not working)

When a group of furniture, like the Product ID 68833b2a-6559-4b25-8690-8ee18ecc9d41 is requested, the response differs:

{
  // ...
  "modelStructure": "{...}"
  // ...
}

So this one does not have a fileKey but a modelStructure field instead! Let's look at the modelStructure:

{
    "type": "group",
    "children": [{
        "x": -9.5367431640625e-7,
        "y": 0,
        "z": 0,
        "ry": 0,
        "src": "!ec5ebfed-9c0c-4da7-9832-5b5a3b990f75",
        "type": "interior",
        "children": [],
        "materials": {}
    },
    // ...

This carries a bit of historical baggage, but basically it is a JSON-String that contains a list of children.

Each child represents an individual piece of furniture within the group. The important part in each child is the src. Cut off the leading exclamation mark and you get the Product ID that you can pass into another io3d.furniture.get call to get the fileKey and then display it.