vpenades / SharpGLTF

glTF reader and writer for .NET Standard
MIT License
454 stars 72 forks source link

[BUG] when merging meshes with buffers exceeding the maximum capacity #196

Closed KisliPlug closed 8 months ago

KisliPlug commented 8 months ago

Hello! I try convert big model from Navisworks (i think it's not important) I can do it with part of this model, but when i try export whole model i got this error.

[ERR] System.OverflowException: Arithmetic operation resulted in an overflow. at System.Linq.Enumerable.Sum(IEnumerable1 source) at SharpGLTF.Geometry.PackedBuffer.MergeBuffers() at SharpGLTF.Geometry.PackedPrimitiveBuilder1.MergeBuffers(IEnumerable1 primitives) at SharpGLTF.Schema2.Toolkit.CreateMeshes[TMaterial](ModelRoot root, Converter2 materialConverter, SceneBuilderSchema2Settings settings, IMeshBuilder1[] meshBuilders) at SharpGLTF.Scenes.Schema2SceneBuilder.AddGeometryResources(ModelRoot root, IEnumerable1 srcScenes, SceneBuilderSchema2Settings settings) at SharpGLTF.Scenes.SceneBuilder.ToGltf2(IEnumerable`1 srcScenes, SceneBuilderSchema2Settings settings) at SharpGLTF.Scenes.SceneBuilder.ToGltf2(SceneBuilderSchema2Settings settings) at MeshToBim.Navis.Logic.MeshExporter.d__6.MoveNext()

vpenades commented 8 months ago

This is probably happening because one of the optimization steps (buffer merging) is unable to run because the resulting buffer will be too large.

Look into the export settings, I think there's a parameter that disables buffer merging.

KisliPlug commented 8 months ago

Hello! Thanks for clarification! I disabled buffer merge, but it this problem not gone. I think it happen in this place

https://github.com/vpenades/SharpGLTF/blob/master/src/SharpGLTF.Toolkit/Schema2/MeshExtensions.cs on 87 line.

In this place buffer always merged, and settings not checked. I'm not sure if it part of algorithm or can be skiped.

vpenades commented 8 months ago

I'll look into it

vpenades commented 8 months ago

I've uploaded some changes that fix the line you mentioned, could you try the code from the repository and tell me if it successfully loads the model?

KisliPlug commented 8 months ago

Hello! Thank you very match! I will check it today, and let you know about results!

KisliPlug commented 8 months ago

I thing now it's works in huge modes. thanks!

KisliPlug commented 8 months ago

Hello! I have meet this error when try save big model as glb

System.InvalidOperationException: Can't merge a buffer larger than 2Gb at SharpGLTF.Schema2.ModelRoot.MergeBuffers() at SharpGLTF.Schema2.WriteContext._PreprocessSchema2(ModelRoot model, Boolean imagesAsBufferViews, Boolean mergeBuffers, Int32 buffersMaxSize) at SharpGLTF.Schema2.WriteContext.WriteBinarySchema2(String baseName, ModelRoot model)

Also found that in this place https://github.com/vpenades/SharpGLTF/blob/master/src/SharpGLTF.Core/Schema2/Serialization.WriteContext.cs on 249 line option for buffer merging always true.

Can problem happen in this place? Or for glb we always must merge buffers?

vpenades commented 8 months ago

Or for glb we always must merge buffers?

Yes, this is a requirement of the GLB format, because GLBs only support one buffer.

See:

And, although they state the maximum limit is 4gb, not 2gb, later it was established that most clients use a 32 bit signed integer to address the buffer, which reduces the buffer size by half, an example of this is:

In practice, in c# the maximum size of a Byte Array is exactly 2 gb because it uses signed integers.

so if you're trying to save a very big model, your only choice left is to save it to glTF.

KisliPlug commented 8 months ago

Thanks for clarification! I's very sad 😢

vpenades commented 8 months ago

Indeed. My feeling is that the khronos board thought that GLB is to create relatively small, self contained packages, and whoever needs very large models should use glTF format, possibly compressed inside a ZIP file.