Commit: f4795564b88d4419b5aea4b8f33979486bd5a232
Author: mattoverby
Date:   Mon Aug 17 14:34:48 2020 -0500
Branches: soc-2020-soft-body
https://developer.blender.org/rBf4795564b88d4419b5aea4b8f33979486bd5a232

added tetgen mode

===================================================================

M       CMakeLists.txt
M       extern/softbody/src/admmpd_energy.cpp
M       extern/softbody/src/admmpd_mesh.cpp
M       intern/softbody/CMakeLists.txt
M       intern/softbody/admmpd_api.cpp
M       release/datafiles/locale
M       release/scripts/addons
M       source/blender/makesrna/intern/rna_object_force.c

===================================================================

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2ce08e72cd9..d59a57ba70b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -222,7 +222,7 @@ mark_as_advanced(WITH_HEADLESS)
 
 option(WITH_QUADRIFLOW    "Build with quadriflow remesher support" ON)
 
-option(WITH_TETGEN    "Build with tetgen remesher support" OFF)
+option(WITH_TETGEN    "Build with tetgen remesher support" ON)
 
 option(WITH_AUDASPACE    "Build with blenders audio library (only disable if 
you know what you're doing!)" ON)
 option(WITH_SYSTEM_AUDASPACE "Build with external audaspace library installed 
on the system (only enable if you know what you're doing!)" OFF)
diff --git a/extern/softbody/src/admmpd_energy.cpp 
b/extern/softbody/src/admmpd_energy.cpp
index 7ee3a60428d..e485725f0b7 100644
--- a/extern/softbody/src/admmpd_energy.cpp
+++ b/extern/softbody/src/admmpd_energy.cpp
@@ -94,7 +94,7 @@ void EnergyTerm::update_tet(
        Matrix3d U, V;
        Vector3d S;
        signed_svd(zi, U, S, V);
-       Vector3d s0 = S;
+       const Vector3d s0 = S;
 
        switch (options->elastic_material)
        {
@@ -110,7 +110,6 @@ void EnergyTerm::update_tet(
                } break;
                case ELASTIC_NH:
                {
-                       S = Vector3d::Ones();
                        solve_prox(options,index,lame,s0,S);
                        zi = U * S.asDiagonal() * V.transpose();
                } break;
@@ -266,6 +265,11 @@ void EnergyTerm::solve_prox(
        Eigen::Vector3d &s)
 {
        (void)(index);
+
+       // Always start prox solve at positive singular vals
+       if( s[2] < 0.0 ){ s[2] *= -1.0; }
+//     s = Vector3d::Ones();
+
        Vector3d g; // gradient
        Vector3d p; // descent
        Vector3d s_prev;
@@ -273,9 +277,10 @@ void EnergyTerm::solve_prox(
        double energy_k, energy_k1;
        const bool add_admm_pen = true;
        const double eps = 1e-6;
+       const int max_ls_iter = 20;
 
        int iter = 0;
-       for(; iter<20; ++iter)
+       for(; iter<10; ++iter)
        {
                g.setZero();
                energy_k = energy_density(options,lame,add_admm_pen,s0,s,&g); 
// e and g
@@ -294,7 +299,6 @@ void EnergyTerm::solve_prox(
                // Backtracking line search
                double alpha = 1;
                int ls_iter = 0;
-               const int max_ls_iter = 20;
                while(energy_k1>energy_k && ls_iter<max_ls_iter)
                {
                        alpha *= 0.5;
@@ -306,10 +310,8 @@ void EnergyTerm::solve_prox(
                // Sometimes flattened tets will have a hard time
                // uninverting, in which case they get linesearch
                // blocked. There are ways around this, but for now
-               // simply quitting is fine. I've tried a few tricks
-               // to get past this, but in the end it doesn't really
-               // matter. The global step will smooth things over
-               // and get us in a better state next time ;)
+               // simply quitting is fine. The global step will smooth
+               // things over and get us in a better state next time.
                if (ls_iter>=max_ls_iter)
                {
                        s = s_prev;
diff --git a/extern/softbody/src/admmpd_mesh.cpp 
b/extern/softbody/src/admmpd_mesh.cpp
index f3dee2b9ee1..4afa2f5c228 100644
--- a/extern/softbody/src/admmpd_mesh.cpp
+++ b/extern/softbody/src/admmpd_mesh.cpp
@@ -578,8 +578,9 @@ void TetMesh::compute_masses(
                edges.col(1) = x->row(tet[2]) - tet_v0;
                edges.col(2) = x->row(tet[3]) - tet_v0;
                double vol = edges.determinant()/6.0;
-               if (vol <= 0)
+               if (vol <= 0) {
                        throw_err("compute_masses","Inverted or flattened tet");
+               }
 
                double tet_mass = density_kgm3 * vol;
                m[tet[0]] += tet_mass / 4.0;
diff --git a/intern/softbody/CMakeLists.txt b/intern/softbody/CMakeLists.txt
index fd951ae7afd..0fedbfaa6a9 100644
--- a/intern/softbody/CMakeLists.txt
+++ b/intern/softbody/CMakeLists.txt
@@ -25,7 +25,7 @@ set(INC
 set(INC_SYS
   ../../extern/softbody/src
   ../../extern/discregrid/discregrid/include
-  ../tetgen
+  ../../extern/tetgen
   ../../source/blender/makesdna
   ../../source/blender/blenkernel
   ../../source/blender/blenlib
@@ -42,4 +42,12 @@ set(LIB
   extern_admmpd
 )
 
+if(WITH_TETGEN)
+  set(LIB
+    ${LIB}
+    extern_tetgen
+  )
+  add_definitions(-DWITH_TETGEN)
+endif()
+
 blender_add_lib(bf_intern_admmpd "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/intern/softbody/admmpd_api.cpp b/intern/softbody/admmpd_api.cpp
index 8e5455387a4..85d4718bf7f 100644
--- a/intern/softbody/admmpd_api.cpp
+++ b/intern/softbody/admmpd_api.cpp
@@ -27,8 +27,7 @@
 #include "admmpd_mesh.h"
 #include "admmpd_collision.h"
 #ifdef WITH_TETGEN
-  #include "tetgen_api.h"
-  #include "BKE_mesh_remesh_voxel.h" // TetGen
+  #include "tetgen.h"
 #endif
 #include "DNA_mesh_types.h" // Mesh
 #include "DNA_meshdata_types.h" // MVert
@@ -50,6 +49,12 @@ struct CollisionObstacle
   Eigen::VectorXf x0, x1;
   std::vector<unsigned int> F;
   bool needs_sdf_recompute;
+  void reset() {
+    x0 = Eigen::VectorXf();
+    x1 = Eigen::VectorXf();
+    F.clear();
+    needs_sdf_recompute = true;
+  }
 };
 
 struct ADMMPDInternalData
@@ -173,69 +178,7 @@ void admmpd_dealloc(ADMMPDInterfaceData *iface)
   iface->idata = nullptr;
 }
 
-static inline int admmpd_init_with_tetgen(ADMMPDInterfaceData *iface, Object 
*ob, float (*vertexCos)[3])
-{
-#ifdef WITH_TETGEN
-  std::vector<float> v;
-  std::vector<unsigned int> f;
-  vecs_from_object(ob,vertexCos,v,f);
-
-  TetGenRemeshData tg;
-  init_tetgenremeshdata(&tg);
-  tg.in_verts = v.data();
-  tg.in_totverts = v.size()/3;
-  tg.in_faces = f.data();
-  tg.in_totfaces = f.size()/3;
-  bool success = tetgen_resmesh(&tg);
-  if (!success || tg.out_tottets==0)
-  {
-    strcpy_error(iface, "TetGen failed to generate");
-    return 0;
-  }
-
-  // Double check assumption, the first
-  // mesh_totverts vertices remain the same
-  // for input and output mesh.
-    for (int i=0; i<tg.in_totverts; ++i)
-    {
-      for (int j=0; j<3; ++j)
-      {
-        float diff = std::abs(v[i*3+j]-tg.out_verts[i*3+j]);
-        if (diff > 1e-10)
-        {
-          strcpy_error(iface, "Bad TetGen assumption: change in surface 
verts");
-          return 0;
-        }
-      }
-    }
-
-  iface->idata->mesh = std::make_shared<admmpd::TetMesh>();
-  success = iface->idata->mesh->create(
-    tg.out_verts,
-    tg.out_totverts,
-    tg.out_facets,
-    tg.out_totfacets,
-    tg.out_tets,
-    tg.out_tottets);
-
-  if (!success) {
-    strcpy_error(iface, "TetMesh failed on creation");
-    return 0;
-  }
-
-  // Clean up tetgen output data
-  MEM_freeN(tg.out_tets);
-  MEM_freeN(tg.out_facets);
-  MEM_freeN(tg.out_verts);
-
-  return 1;
-#else
-  (void)(ob);
-  (void)(vertexCos);
-  strcpy_error(iface, "TetGen not available");
-  return 0;
-#endif
-}
+static inline int admmpd_init_with_tetgen(ADMMPDInterfaceData *iface, Object 
*ob, float (*vertexCos)[3]);
 
 static inline int admmpd_init_with_lattice(ADMMPDInterfaceData *iface, Object 
*ob, float (*vertexCos)[3])
 {
@@ -348,7 +291,6 @@ int admmpd_update_mesh(ADMMPDInterfaceData *iface, Object 
*ob, float (*vertexCos
       } break;
     }
     if (!gen_success || !iface->idata->mesh || x0==nullptr) {
-      strcpy_error(iface, "failed to init mesh");
       return 0;
     }
   }
@@ -422,6 +364,7 @@ int admmpd_update_solver(ADMMPDInterfaceData *iface,  Scene 
*sc, Object *ob, flo
   // Reset options and data
   iface->idata->options = std::make_shared<admmpd::Options>();
   iface->idata->data = std::make_shared<admmpd::SolverData>();
+  iface->idata->obs.reset();
 
   admmpd::Options *op = iface->idata->options.get();
   options_from_object(iface,sc,ob,op,false);
@@ -523,7 +466,7 @@ void admmpd_update_obstacles(
     return;
   }
   if (!iface->idata) { return; }
-  if (!iface->idata->collision) { return; }
+
   if (nf==0 || nv==0) { return; }
   int nv3 = nv*3;
   int nf3 = nf*3;
@@ -680,6 +623,17 @@ int admmpd_solve(ADMMPDInterfaceData *iface, Object *ob, 
float (*vertexCos)[3])
   admmpd_update_goals(iface,ob,vertexCos);
   update_selfcollision_group(iface,ob);
 
+  // Obstacle collisions not yet implemented
+  // for cloth or tet mesh.
+  bool had_set_obstacle_error = false;
+  if ((ob->soft->admmpd_mesh_mode == MESHTYPE_TET ||
+    ob->soft->admmpd_mesh_mode == MESHTYPE_TRIANGLE) &&
+    iface->idata->obs.x0.size()>0)
+  {
+    had_set_obstacle_error = true;
+    strcpy_error(iface, "Obstacle collision not yet available for selected 
mesh mode.");
+  }
+
   // Changing the location of the obstacles requires a recompuation
   // of the SDF. So we'll only do that if:
   // a) we are substepping (need to lerp)
@@ -694,7 +648,6 @@ int admmpd_solve(ADMMPDInterfaceData *iface, Object *ob, 
float (*vertexCos)[3])
     iface->idata->options->substeps>1 &&
     (iface->idata->obs.x0-iface->idata->obs.x1).lpNorm<Eigen::Infinity>()>1e-6;
 
-  bool had_set_obstacle_error = false;
   if (has_obstacles && iface->idata->obs.needs_sdf_recompute && 
!lerp_obstacles) {
     std::string set_obs_error = "";
     if (!iface->idata->collision->set_obstacles(
@@ -754,3 +707,186 @@ int admmpd_solve(ADMMPDInterfaceData *iface, Object *ob, 
float (*vertexCos)[3])
 
   return 1;
 }
+
+
+#ifdef WITH_TETGEN
+
+static void make_tetgenio(
+  float *verts,
+  unsigned int *faces,
+  int numverts,
+  int numfaces,
+  tetgenio &tgio )
+{
+  tgio.initialize();
+  tgio.firstnumber = 0;
+  tgio.mesh_dim = 3;
+  tgio.numberofpoints = numverts;
+  tgio.pointlist = new REAL[tgio.numberofpoints * 3];
+//     tgio.pointlist = (REAL *)MEM_malloc_arrayN(
+//             tgio.numberofpoints, 3 * sizeof(REAL), "tetgen remesh out 
verts");
+  for (int i=0; i < tgio.numberofpoints; ++i)
+    {
+    tgio.pointlist[i*3+0] = verts[i*3+0];
+    tgio.pointlist[i*3+1] = verts[i*3+1];
+    tgio.pointlist[i*3+2] = verts[i*3+2];
+  }
+  tgio.numberoffacets = numfaces;
+  tgio.facetlist = new tetgenio::facet[tgio.numberoffacets];
+//     tgio.facetlist = (tetgenio::facet *)MEM_malloc_arrayN(
+//             tgio.numberoffacets, sizeof(tetgenio::facet), "tetgen remesh 
out facets");  
+  tgio.facetmarkerlist = new int[tgio.numberoffacets];
+//     tgio.facetmarkerlist = (int *)MEM_malloc_arrayN(
+//             tgio.numberoffacets, sizeof(int), "tetgen remesh out marker 
list");
+  for (int i=0; i<numfaces; ++i)
+    {
+    tgio.facetmarkerlist[i] = i;
+    tetgenio::facet *f = &tgio.facetlist[i];
+    f->numberofholes = 0;
+    f->holelist = NULL;
+    f->numberofpolygons = 1;
+    f->polygonlist = new tetgenio::polygon[1];
+    tetgenio::polygon *p = &f->polygonlist[0];
+    p->numberofvertices = 3;
+    p->vertexlist = new int[3];
+    p->vertexlist[0] = faces[i*3+0];
+    p->vertexlist[1] = faces[i*3+

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to