[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