Skip to content

Conversation

@romanarust
Copy link
Member

Gltf update for allowing extensions, see here. Check the changelog for details.

What type of change is this?

  • Bug fix in a backwards-compatible manner.
  • New feature in a backwards-compatible manner.
  • Breaking change: bug fix or new feature that involve incompatible API changes.
  • Other (e.g. doc update, configuration, etc)

Checklist

Put an x in the boxes that apply. You can also fill these out after creating the PR. If you're unsure about any of them, don't hesitate to ask. We're here to help! This is simply a reminder of what we are going to look for before merging your code.

  • I added a line to the CHANGELOG.md file in the Unreleased section under the most fitting heading (e.g. Added, Changed, Removed).
  • I ran all tests on my computer and it's all green (i.e. invoke test).
  • I ran lint on my computer and there are no errors (i.e. invoke lint).
  • I added new functions/classes and made them available on a second-level import, e.g. compas.datastructures.Mesh.
  • I have added tests that prove my fix is effective or that my feature works.
  • I have added necessary documentation (if appropriate)

# ==============================================================================

if __name__ == '__main__':
if __name__ == "__main__":
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see the value of the changes you've made to this sections pointing out caveats to adding images and textures. But I also see the value of providing a bare minimum example of how to create a GLTF. Do you think it would be worthwhile to keep both?

The other changes in the PR look great!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thank you beverly!
yes, for now, I would like to keep both, as there might be further improvements needed.

-------
int or None
"""
for key, material in self.materials:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this needs .items()

@romanarust
Copy link
Member Author

ipy keeps failing, but the tests with ipy work fine on my computer

@chenkasirer
Copy link
Member

Since for me locally these tests fail as well, I had a look and to be honest I had difficulties following everything that's happening in this code (again, not familiar with GLTF) so I'll go ahead and put here what I could find and maybe it would have more of a meaning to you, knowing what's going on.

Focusing on parsing and exporting of SpecularTest.glb:
4 textures are loaded and parsed from the .glb file and AFAIK all is parsed properly.

When exporting though, 3 out of the four textures are removed here for being "unvisited"

# in GLTFExporter.load()
self._content.remove_orphans()
#before removing orphans: 
    {
        0: <TextureData object at 0x0000000000000A7A>, 
        1: <TextureData object at 0x0000000000000A7B>,  
        2: <TextureData object at 0x0000000000000A7C>, 
        3: <TextureData object at 0x0000000000000A7D>
    }

# removing unvisited item - key:1 item:<TextureData object at 0x0000000000000A7B>
# removing unvisited item - key:2 item:<TextureData object at 0x0000000000000A7C>
# removing unvisited item - key:3 item:<TextureData object at 0x0000000000000A7D>

which results in the following self._content.textures:

{
    0: <TextureData object at 0x0000000000000A7A>
}

Later, in _add_materials(), =>
material_data.to_data(self._texture_index_by_key) =>
self.extensions_to_data(texture_index_by_key=texture_index_by_key) =>
self.specular_texture.to_data(texture_index_by_key)

The index of the TextureInfoData that's inside the extension is being looked up in texture_index_by_key, but it's not there since it has been removed earlier in remove_orphans().

Whether or not these textures should have been removed, or if this should get somehow updated in the references to them inside the extensions, I cannot say. But it seems that the reason these tests don't fail in CPython is that there these textures don't get removed in the first place.

@romanarust can you say if these textures should even be removed or not?

@romanarust
Copy link
Member Author

@chenkasirer : Thanks a lot for checking and the detailed explanation!
I suspect that the new function check_extensions_texture_recursively(material), which is called in remove_orphans is not working properly in ipy.
which ipy version are you using?

@chenkasirer
Copy link
Member

>>> ipy
IronPython 2.7.12 (2.7.12.1000)
[.NETFramework,Version=v4.5 on .NET Framework 4.8.4510.0 (64-bit)]
>>> ipy -m compas
Yay! COMPAS is installed correctly!

COMPAS: 1.16.0-fea3e9f7

@beverlylytle
Copy link
Member

I was just thinking about this, and I agree with your suspicions @romanarust. There are a few things in python 2 that can behave a bit differently than in python 3 that might be exposed in that function. In particular, there is always the new vs old style class issue (which I think shouldn't be a problem because everything inherits from object), but still I wonder if isinstance is behaving the way it is intended. I also wonder if dir and callable behave in exactly the same way between the two versions. Another (perhaps far-flung) thought is scoping. Python 2's scoping of variables is a little different, but only with list/dict comprehensions and not recursive functions as far as I know.

@chenkasirer
Copy link
Member

@romanarust @beverlylytle So following your suspicions, I put some more time into this issue and sure enough, the culprit seems to be isinstance in check_extensions_texture_recursively.
Some calls to isinstance(item, TextureInfoData) return False even though type is actually a child of TextureInfoData.

Excerpt from my debugging extravaganza:

# GLTFExporter.check_extensions_texture_recursively
print("a: {} instance:{} is texture:{}".format(a, a_instance, isinstance(a_instance, TextureInfoData)))
...
a: specular_texture instance:<TextureInfoData object at 0x0000000000000352> is texture:False

This prevents the texture from being flagged as visited and it gets removed later, which causes all the trouble when exporting.

Annoyingly enough, this problem is intermittent:

  1. It doesn't happen when running the code directly from an ipy session
  2. Is doesn't happen when running just one of the tests, only when running both
  3. the worst: it doesn't always happen for both tests, sometimes only one of them fails

To check for the types more reliably I'd suggest either comparing strings e.g. a.__class__.__name__ == "compas.files.TextureDataInfo"
Or the more elegant (but still hacky) solution, in my opinion, add some class attribute and check for it instead:

# data_classes.py
class TextureInfoData(object):
    IS_TEXTURE_INFO_DATA = True  # value is not actually checked..
    ...

# gltf_content.py
...
if getattr(instance, "IS_TEXTURE_INFO_DATA", False):  # instead of isinstance(a, TextureInfoData)
    texture_visit_log[getattr(item, a).index] = True
...

I'd do the same for the check isinstance(a, BaseGLTFDataClass) although I haven't had issues with it with the current tests.

@beverlylytle
Copy link
Member

oh ironpython... what is dead may never die.

@romanarust
Copy link
Member Author

Thank you @chenkasirer for the detailed analysis and yet more proof of why IronPython should be buried.
I implemented your suggested changes. It fails again, but due to a different problem.

@chenkasirer
Copy link
Member

chenkasirer commented Aug 9, 2022

@romanarust Not your fault actually. Seems there's a new version of flake8 which enforces some stuff that hasn't been detected/enforced before. The code that causes it to fail has been around for at least the past 15 months..

I'll sort it out in a separate PR.

**Update: opened #1061

Copy link
Member

@chenkasirer chenkasirer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@romanarust romanarust merged commit e48757d into main Aug 15, 2022
@romanarust romanarust deleted the gltf_update branch August 15, 2022 11:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants