Ghostkeeper/Blender3mfFormat

Mesh not importing

Opened this issue · 9 comments

Importing some 3mf files results in objects without any mesh. The file was generated with Bambu Studio.

Blender 4.0 / 4.1
File I was trying to import: https://makerworld.com/en/models/20200#profileId-20736
image
image
image

Fix proposed in this PR: #70

Thank you for investigating that so thoroughly!

The 3MF specification requires that object IDs are defined before they are used: https://github.com/3MFConsortium/spec_core/blob/1.2.3/3MF%20Core%20Specification.md#34-model . In that case, the current code would work.
The spec doesn't say anything about that the object IDs are also defined in the same file as where they are used, though if it needs to be defined before used this could be implied. I could find nothing about whether IDs need to be unique to the document or to the whole 3MF file.

This extension has the philosophy that it should repair files if they are malformed instead of refuse to load them, so it'd be good to make the extension resilient to objects being defined out-of-order and your fix is good.

Before merging though, I'd like to investigate a bit more how it would work if there are duplicate object IDs in different .model files. If this is allowed by the spec, this fix could break well-formed 3MF files that use duplicate object IDs across documents (it would select an arbitrary object with that ID instead of the object from the same file). Maybe we'd have to make it "prefer" IDs from the same file, but still load IDs from different files if the ID is not in the current file. If the spec doesn't allow duplicate IDs, the proposed fix is safe and should be merged. Then it would be nice if the extension logs a warning about duplicate IDs if they are used.

I have to get out now, but I'll get back to you on this. Looks good so far at least.

I found that indeed the spec requires that IDs are unique in the "3D model": https://github.com/3MFConsortium/spec_core/blob/1.2.3/3MF%20Core%20Specification.md#34-model , and that a 3D model is contained in a single XML document in the archive.

So I think we have to extend this solution so that it prefers IDs referenced from the same document. This will allow correctly-formed 3MF files to be loaded correctly, if they use the same resource IDs across different documents, yet still allow incorrectly-formed 3MF files to be loaded as they likely intended. I'll help guide you towards a reliable implementation in the PR.

Hey there,

I just wanted to say thank you for a very well written plugin. It saved a lot of time for a project I'm working on :)

If you have a clear idea how to implement your solution then feel free to close my PR, no hard feelings!

I'll use your PR, but extend it a bit so that it prefers resources from the current file :) It's a good start.

(But more likely tomorrow or next week if I can find some time.)

@Ghostkeeper My name is Vijai, and I am one of the developers of lib3mf. We recently released official Python bindings for lib3mf that adhere to the 3MF Consortium's specification. We also have a collection of useful Python examples available here. You have done a great job in making the 3MF format work within the Blender ecosystem. We would be very interested in collaborating with you to enhance Blender's 3MF support. If you prefer to communicate via email, you can contact me at github@kaditham.meshing.engineer.

Thank you Vijai, but I'd rather not. That library is compiled, which means that I'd need to either limit the extension to a single platform, or dynamically load the correct binary depending on the platform. I've built such a system before but it's honestly more of a hassle than I'd like.

But @vijaiaeroastro perhaps do you know how lib3mf handles this case? Does it consider duplicate IDs in different documents in the archive an error? Does it refuse to load it? Does it load resources from different documents? Or will it result in errors if the IDs are missing from the same document but in different documents in the archive?

@Ghostkeeper To answer your first question, we handle all of that ourselves. The official bindings do not require dealing with library paths or DLL paths; it's all taken care of. The examples are quite simple, and I encourage you to take a look. We produce a single wheel that handles all three platforms without issues. We can even produce a python build that will always remain compatible with Blender. We are committed to making lib3mf and the 3MF file format as far-reaching as possible and will be more than happy to support you.

To answer your second question, it does throw an exception. I tried the file mentioned in the issue with the extract_info.py script

04:15:54 vijai@curie examples ±|main ✗|→ python extract_info.py /home/vijai/Downloads/morrigan_class_from_the_expanse_012_new.3mf
Traceback (most recent call last):
  File "/home/vijai/Code/3MF/3MFPython/examples/extract_info.py", line 30, in <module>
    extract_info(sys.argv[1])
  File "/home/vijai/Code/3MF/3MFPython/examples/extract_info.py", line 11, in extract_info
    read_3mf_file_to_model(model, file_path)
  File "/home/vijai/Code/3MF/3MFPython/examples/lib3mf_common.py", line 77, in read_3mf_file_to_model
    reader.ReadFromFile(file_path)
  File "/home/vijai/.local/lib/python3.10/site-packages/lib3mf/Lib3MF.py", line 4434, in ReadFromFile
    self._wrapper.checkError(self, self._wrapper.lib.lib3mf_reader_readfromfile(self._handle, pFilename))
  File "/home/vijai/.local/lib/python3.10/site-packages/lib3mf/Lib3MF.py", line 4031, in checkError
    raise ELib3MFException(errorCode, message)
lib3mf.Lib3MF.ELib3MFException: Lib3MFException 5: A UUID is not unique within a package.
04:16:00 vijai@curie examples ±|main ✗|→ 

Having this same issue -- how exactly do I go about fixing it? Or would I have to wait for a later release