Closed EricBeetsOfficial-Opuscope closed 4 years ago
It is possible, but not as trivial as it should.
Keep in mind that a mesh depends on its materials, the materials on textures, the textures on images, etc, so you have to take that into account when exporting a sub-mesh.
Also, it is nearly impossible to edit a loaded gltf to remove all the meshes and resources except the ones you want to export.
That being said, the best approach you can follow is this:
Use the glTF toolkit to access the methods and structures you need.
then do:
var sceneBuilder = srcModel.DefaultScene.ToSceneBuilder();
Then, you can use the sceneBuilder
to edit or reuse components in other editable meshes.
Finally, you convert it back to a new glTF and export it:
var finalScene = sceneBuilder.ToGltf2();
finalScene.Save(...);
Some notes about Toolkit's SceneBuilder
: Right now it's API is designed only to append new meshes, and it does not have any API to remove elements, yet.
But in this case, and unlike glTF, SceneBuilder elements can be shared between multiple SceneBuilder instances, so you can create a new SceneBuilder, add the mesh you want to export from the source's SceneBuilder, and then export it.
I have not tested that particular workflow, let me know if it works for you.
Hi, I've added an example on how to extract and save individual meshes:
Hi,
Thanks a lot, it was what I having done and it works ;) But, finally, I used another way (as I didn't need material, but just geometry):
ModelRoot modelRoot = ModelRoot.CreateModel();
// Default material
Material materialToExport = modelRoot.CreateMaterial();
// Create Mesh
Mesh meshToExport = modelRoot.CreateMesh(this.name);
foreach(MeshPrimitive meshPrimitive in mesh.Primitives)
{
var positions = meshPrimitive.GetVertexAccessor("POSITION").AsVector3Array().ToArray();
var normals = meshPrimitive.GetVertexAccessor("NORMAL").AsVector3Array().ToArray();
var texcoord = meshPrimitive.GetVertexAccessor("TEXCOORD_0").AsVector2Array().ToArray();
var indices = (int[])(object)meshPrimitive.GetIndexAccessor().AsIndicesArray().ToArray();
meshToExport.CreatePrimitive().WithVertexAccessor("POSITION", positions)
.WithVertexAccessor("NORMAL", normals)
.WithVertexAccessor("TEXCOORD_0", texcoord)
.WithIndicesAccessor(PrimitiveType.TRIANGLES, indices)
.WithMaterial(materialToExport);
}
Scene sceneModel = modelRoot.UseScene("Default");
sceneModel.CreateNode("RootNode").WithMesh(meshToExport);
modelRoot.SaveGLB(this.pathFile);
Thank you again for your project and your reactivity (next step: get the model bounding box ;) )
It's actually much easier if you use the Toolkit extensions:
var mesh = modelRoot.LogicalMeshes[17]; // get the mesh we want to extract
var meshBuilder = mesh.ToMeshBuilder(); // Toolkit extension extracts the mesh to a MeshBuilder
var sceneBuilder = new SceneBuilder(); // create a new scene that will act as a container of the mesh.
sceneBuilder.AddRigidMesh(meshBuilder, Matrix4x4.Indentity);
var gltf = sceneBuilder.ToGltf2();
gltf.SaveGLB(this.pathFile);
Hi !
It's a great project !
I was wondering if it's possible to extract a sub mesh ? I mean, for instance, create a
ModelRoot
from aMesh
(and save it ..) ?Thanks in advance Eric