I’m creating the mesh like this, using the output data from OpenVDB:
Mesh *newMesh = BKE_mesh_new_nomain(rmd.out_totverts, 0, rmd.out_totfaces, 0, 0);
for(int i = 0; i < rmd.out_totverts; i++) {
float vco[3] = { rmd.out_verts[i * 3], rmd.out_verts[i * 3 + 1], rmd.out_verts[i * 3 + 2]};
copy_v3_v3(newMesh->mvert[i].co, vco);
}
for(int i = 0; i < rmd.out_totfaces; i++) {
newMesh->mface[i].v4 = rmd.out_faces[i * 4];
newMesh->mface[i].v3 = rmd.out_faces[i * 4 + 1];
newMesh->mface[i].v2 = rmd.out_faces[i * 4 + 2];
newMesh->mface[i].v1 = rmd.out_faces[i * 4 + 3];
}
BKE_mesh_calc_edges_tessface(newMesh);
BKE_mesh_convert_mfaces_to_mpolys(newMesh);
BKE_mesh_calc_normals(newMesh);
My idea is to add extra steps before copying the new mesh data back to the original datablock, such as smoothing, reprojection or geometry checks, so newMesh
is only temporal, it should not be added to the Main database.
If after that I run BKE_mesh_isValid()
, it returns true, and the mesh looks correct in the editor when it works. Entering edit mode or sculpt mode with that object also works. The only weird thing I noticed is that I can’t assign the mesh datablock to other objects after running the remesher (Blender does not crash, it simply resets the object to the previous datablock).
If I run BKE_mesh_validate()
it says:
ERROR (bke.mesh): /home/pablo/Apps/blender/blender-git/blender/source/blender/blenkernel/intern/mesh_validate.c:849 mesh_validate_customdata: CustomDataLayer type 7 which isn't in the mask
After that, I’m doing the following:
BKE_mesh_nomain_to_mesh(newMesh, ob->data, ob, &CD_MASK_MESH, true);
BKE_mesh_batch_cache_dirty_tag(ob->data, BKE_MESH_BATCH_DIRTY_ALL);
DEG_relations_tag_update(bmain);
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
Finally, it just frees the memory and the operator finishes.
If I don’t call BKE_mesh_batch_cache_dirty_tag
, it always crashes on gpu_batch.c l:287 glBindVertexArray(new_vao)
With BKE_MESH_BATCH_DIRTY_ALL
, it crashes randomly the first or the second time the operator runs. Most of the time it crashes on gpu_immediate.c l:322 glVertexAttribPointer(loc, a->comp_len, a->gl_comp_type. GL_FALSE, stride, pointer)
. Sometimes in gpu_context.cpp l:111 glDeleteVertexArrays(orphan_len, ctx->orphaned_vertarray_ids.data())
.
The operator always finishes successfully.
By the way, if in the future I want to run this operator from sculpt mode directly, are there any extra considerations I need to take in order to make it work? For now, if it only works in object mode to evaluate the different remeshers results and performance is fine.
Thank you