[Bf-blender-cvs] [ae9ee5d2767] soc-2020-soft-body: added tet lattice gen for debugging
mattoverby
noreply at git.blender.org
Wed Aug 19 19:04:48 CEST 2020
Commit: ae9ee5d276719d0431b8ecf287286c0c7588ad96
Author: mattoverby
Date: Wed Aug 19 12:04:43 2020 -0500
Branches: soc-2020-soft-body
https://developer.blender.org/rBae9ee5d276719d0431b8ecf287286c0c7588ad96
added tet lattice gen for debugging
===================================================================
M intern/softbody/admmpd_api.cpp
M intern/softbody/admmpd_api.h
M release/scripts/startup/bl_ui/properties_data_mesh.py
M source/blender/blenkernel/BKE_mesh_remesh_voxel.h
M source/blender/blenkernel/intern/mesh_remesh_voxel.c
M source/blender/editors/object/object_intern.h
M source/blender/editors/object/object_ops.c
M source/blender/editors/object/object_remesh.c
M source/blender/makesdna/DNA_mesh_types.h
M source/blender/makesrna/intern/rna_mesh.c
===================================================================
diff --git a/intern/softbody/admmpd_api.cpp b/intern/softbody/admmpd_api.cpp
index 85d4718bf7f..5bc4d1c857f 100644
--- a/intern/softbody/admmpd_api.cpp
+++ b/intern/softbody/admmpd_api.cpp
@@ -230,6 +230,51 @@ static inline int admmpd_init_as_cloth(ADMMPDInterfaceData *iface, Object *ob, f
return 1;
}
+void admmpd_compute_lattice(
+ int subdiv,
+ float *in_verts, int in_nv,
+ unsigned int *in_faces, int in_nf,
+ float **out_verts, int *out_nv,
+ unsigned int **out_tets, int *out_nt)
+{
+
+ admmpd::EmbeddedMesh emesh;
+ emesh.options.max_subdiv_levels = subdiv;
+ bool success = emesh.create(
+ in_verts, in_nv,
+ in_faces, in_nf,
+ nullptr,
+ 0);
+
+ if (!success) {
+ return;
+ }
+
+ const Eigen::MatrixXd &vt = *emesh.rest_prim_verts();
+ const Eigen::MatrixXi &t = *emesh.prims();
+ if (vt.rows()==0 || t.rows()==0) {
+ return;
+ }
+
+ *out_nv = vt.rows();
+ *out_verts = (float*)MEM_callocN(sizeof(float)*3*(vt.rows()), "ADMMPD_lattice_verts");
+ *out_nt = t.rows();
+ *out_tets = (unsigned int*)MEM_callocN(sizeof(unsigned int)*4*(t.rows()), "ADMMPD_lattice_tets");
+
+ for (int i=0; i<vt.rows(); ++i) {
+ (*out_verts)[i*3+0] = vt(i,0);
+ (*out_verts)[i*3+1] = vt(i,1);
+ (*out_verts)[i*3+2] = vt(i,2);
+ }
+
+ for (int i=0; i<t.rows(); ++i) {
+ (*out_tets)[i*4+0] = t(i,0);
+ (*out_tets)[i*4+1] = t(i,1);
+ (*out_tets)[i*4+2] = t(i,2);
+ (*out_tets)[i*4+3] = t(i,3);
+ }
+}
+
int admmpd_mesh_needs_update(ADMMPDInterfaceData *iface, Object *ob)
{
if (!iface) { return 0; }
diff --git a/intern/softbody/admmpd_api.h b/intern/softbody/admmpd_api.h
index 18b0b8e3389..599bb523012 100644
--- a/intern/softbody/admmpd_api.h
+++ b/intern/softbody/admmpd_api.h
@@ -39,6 +39,15 @@ typedef struct ADMMPDInterfaceData {
// Frees ADMMPDInternalData
void admmpd_dealloc(ADMMPDInterfaceData*);
+// Standalone function to compute embedding lattice
+// but without the embedding info (for visual debugging)
+void admmpd_compute_lattice(
+ int subdiv,
+ float *in_verts, int in_nv,
+ unsigned int *in_faces, int in_nf,
+ float **out_verts, int *out_nv,
+ unsigned int **out_tets, int *out_nt);
+
// Test if the mesh topology has changed in a way that requires re-initialization.
// Returns 0 (no update needed) or 1 (needs update)
int admmpd_mesh_needs_update(ADMMPDInterfaceData*, Object*);
diff --git a/release/scripts/startup/bl_ui/properties_data_mesh.py b/release/scripts/startup/bl_ui/properties_data_mesh.py
index 9cb774e1d1b..2f0fdeb6a17 100644
--- a/release/scripts/startup/bl_ui/properties_data_mesh.py
+++ b/release/scripts/startup/bl_ui/properties_data_mesh.py
@@ -520,8 +520,10 @@ class DATA_PT_remesh(MeshButtonsPanel, Panel):
col.operator("object.voxel_remesh", text="Voxel Remesh")
elif mesh.remesh_mode == 'QUAD':
col.operator("object.quadriflow_remesh", text="QuadriFlow Remesh")
- else:
+ elif mesh.remesh_mode == 'TET':
col.operator("object.tetgen_remesh", text="Tetrahedralize")
+ elif mesh.remesh_mode == 'TETLATTICE':
+ col.operator("object.tetlattice_remesh", text="Generate Lattice")
diff --git a/source/blender/blenkernel/BKE_mesh_remesh_voxel.h b/source/blender/blenkernel/BKE_mesh_remesh_voxel.h
index 277747e3e27..4db933fdc09 100644
--- a/source/blender/blenkernel/BKE_mesh_remesh_voxel.h
+++ b/source/blender/blenkernel/BKE_mesh_remesh_voxel.h
@@ -59,7 +59,10 @@ struct Mesh *BKE_mesh_remesh_quadriflow_to_mesh_nomain(struct Mesh *mesh,
struct Mesh *BKE_mesh_remesh_tetgen_to_mesh_nomain(struct Mesh *mesh,
unsigned int **tets,
int *numtets);
-
+struct Mesh *BKE_mesh_remesh_tetlattice_to_mesh_nomain(struct Mesh *mesh,
+ int subdivisions,
+ unsigned int **tets,
+ int *numtets);
/* Data reprojection functions */
void BKE_mesh_remesh_reproject_paint_mask(struct Mesh *target, struct Mesh *source);
void BKE_remesh_reproject_vertex_paint(struct Mesh *target, struct Mesh *source);
diff --git a/source/blender/blenkernel/intern/mesh_remesh_voxel.c b/source/blender/blenkernel/intern/mesh_remesh_voxel.c
index 05cc9769bf7..485a4733f55 100644
--- a/source/blender/blenkernel/intern/mesh_remesh_voxel.c
+++ b/source/blender/blenkernel/intern/mesh_remesh_voxel.c
@@ -48,6 +48,8 @@
#include "bmesh_tools.h"
+#include "admmpd_api.h"
+
#ifdef WITH_OPENVDB
# include "openvdb_capi.h"
#endif
@@ -375,6 +377,118 @@ struct Mesh *BKE_mesh_remesh_tetgen_to_mesh_nomain(struct Mesh *mesh,
return NULL;
}
+static Mesh *BKE_mesh_remesh_tetlattice(struct Mesh *input_mesh,
+ int subdivisions,
+ unsigned int **tets,
+ int *numtets)
+{
+
+ // Ensure that the triangulated mesh data is up to data
+ BKE_mesh_runtime_looptri_recalc(input_mesh);
+ const MLoopTri *looptri = BKE_mesh_runtime_looptri_ensure(input_mesh);
+
+ // Gather the required data
+ MVertTri *verttri = MEM_callocN(sizeof(*verttri) * BKE_mesh_runtime_looptri_len(input_mesh),
+ "remesh_looptri");
+ BKE_mesh_runtime_verttri_from_looptri(
+ verttri, input_mesh->mloop, looptri, BKE_mesh_runtime_looptri_len(input_mesh));
+
+ unsigned int totfaces = BKE_mesh_runtime_looptri_len(input_mesh);
+ unsigned int totverts = input_mesh->totvert;
+ float *verts = (float *)MEM_malloc_arrayN(totverts * 3, sizeof(float), "remesh_input_verts");
+ unsigned int *faces = (unsigned int *)MEM_malloc_arrayN(
+ totfaces * 3, sizeof(unsigned int), "remesh_intput_faces");
+
+ for (unsigned int i = 0; i < totverts; i++) {
+ MVert *mvert = &input_mesh->mvert[i];
+ verts[i * 3] = mvert->co[0];
+ verts[i * 3 + 1] = mvert->co[1];
+ verts[i * 3 + 2] = mvert->co[2];
+ }
+
+ for (unsigned int i = 0; i < totfaces; i++) {
+ MVertTri *vt = &verttri[i];
+ faces[i * 3] = vt->tri[0];
+ faces[i * 3 + 1] = vt->tri[1];
+ faces[i * 3 + 2] = vt->tri[2];
+ }
+
+ float *out_verts = NULL;
+ int out_totverts = 0;
+ admmpd_compute_lattice(
+ subdivisions,
+ verts, totverts,
+ faces, totfaces,
+ &out_verts, &out_totverts,
+ tets, numtets);
+ bool success = out_totverts>0 && *numtets>0;
+
+ MEM_freeN(verts);
+ verts = NULL;
+ MEM_freeN(faces);
+ faces = NULL;
+ MEM_freeN(verttri);
+ verttri = NULL;
+
+ Mesh *mesh = NULL;
+ if (success) {
+
+ int nt = *numtets;
+ int nf = *numtets * 4;
+
+ // Construct the new output mesh
+ mesh = BKE_mesh_new_nomain(out_totverts, 0, 0, (nf*3), nf);
+
+ for (int i = 0; i < out_totverts; i++) {
+ copy_v3_v3(mesh->mvert[i].co, &out_verts[i * 3]);
+ }
+
+ MPoly *mp = mesh->mpoly;
+ MLoop *ml = mesh->mloop;
+ for (int i=0; i<nt; ++i) {
+
+ int tet[4];
+ tet[0] = (*tets)[i*4+0];
+ tet[1] = (*tets)[i*4+1];
+ tet[2] = (*tets)[i*4+2];
+ tet[3] = (*tets)[i*4+3];
+
+ int tet_facets[4*3] = {
+ 0, 2, 1,
+ 0, 1, 3,
+ 0, 3, 2,
+ 1, 2, 3
+ };
+
+ for (int j = 0; j < 4; j++, mp++, ml += 3) {
+ mp->loopstart = (int)(ml - mesh->mloop);
+ mp->totloop = 3;
+ ml[0].v = tet[tet_facets[j*3+0]];
+ ml[1].v = tet[tet_facets[j*3+1]];
+ ml[2].v = tet[tet_facets[j*3+2]];
+ }
+ }
+
+ } // end success
+ BKE_mesh_calc_edges(mesh, false, false);
+ BKE_mesh_calc_normals(mesh);
+
+ if (out_verts != NULL) {
+ MEM_freeN(out_verts);
+ out_verts = NULL;
+ }
+
+ return mesh;
+}
+
+struct Mesh *BKE_mesh_remesh_tetlattice_to_mesh_nomain(struct Mesh *mesh,
+ int subdivisions,
+ unsigned int **tets,
+ int *numtets)
+{
+ return BKE_mesh_remesh_tetlattice(mesh, subdivisions, tets, numtets);
+}
+
Mesh *BKE_mesh_remesh_quadriflow_to_mesh_nomain(Mesh *mesh,
int target_faces,
int seed,
diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h
index 6bc615c9b9e..5c7370334e8 100644
--- a/source/blender/editors/object/object_intern.h
+++ b/source/blender/editors/object/object_intern.h
@@ -303,6 +303,7 @@ void OBJECT_OT_voxel_remesh(struct wmOperatorType *ot);
void OBJECT_OT_voxel_size_edit(struct wmOperatorType *ot);
void OBJECT_OT_quadriflow_remesh(struct wmOperatorType *ot);
void OBJECT_OT_tetgen_remesh(struct wmOperatorType *ot);
+void OBJECT_OT_tetlattice_remesh(struct wmOperatorType *ot);
/* object_transfer_data.c */
void OBJECT_OT_data_transfer(struct wmOperatorType *ot);
diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c
index c699882ef4a..763d826dbde 100644
--- a/source/blender/editors/object/object_ops.c
+++ b/source/blender/editors/object/object_ops.c
@@ -274,6 +274,7 @@ void ED_operatortypes_object(void)
WM_operatortype_append(OBJECT_OT_quadriflow_remesh);
WM_operatortype_append(OBJECT_OT_tetgen_remesh);
+ WM_operatortype_append(OBJECT_OT_tetlattice_remesh);
}
void ED_operatormacros_object(void)
diff --git a/source/blender/editors/object/object_remesh.c b/source/blender/editors/object/object_remesh.c
index d5715cf6879..83d222b221b 100644
--- a/source/blender/editors/object/object_remesh.c
+++ b/source/blender/editors/object/object_remesh.c
@@ -1252,4 +1252,57 @@ void OBJECT_OT_tetgen_remesh(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+static int tetlattice_remesh_exec(bContext *C, wmOperator *op)
+{
+ Object *ob = CTX_data_active_object(C);
+
+ Mesh *mesh = ob->data;
+ Mesh *new_mesh = NULL;
+
+ unsigned int *tets = NULL;
+ int numtets;
+ int subdiv = 3;
+ new_mesh = BKE_mesh_remesh_tetlattice_to_mesh_nomain(mesh, subdiv, &tets, &numtets);
+ if (tets) {
+ MEM_freeN(tets);
+ }
+
+
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list