Commit: bd155f430964952be0b3c67e0f97c4c5e4e48f9f
Author: mattoverby
Date:   Fri Aug 14 19:20:24 2020 -0500
Branches: soc-2020-soft-body
https://developer.blender.org/rBbd155f430964952be0b3c67e0f97c4c5e4e48f9f

tetgen flag default off

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

M       CMakeLists.txt
M       
extern/discregrid/discregrid/include/Discregrid/geometry/mesh_distance.hpp
M       extern/discregrid/discregrid/include/Discregrid/mesh/triangle_mesh.hpp
M       extern/discregrid/discregrid/src/mesh/triangle_mesh.cpp
M       extern/softbody/src/admmpd_collision.cpp
M       extern/softbody/src/admmpd_collision.h
M       intern/softbody/admmpd_api.cpp
M       source/blender/blenkernel/BKE_softbody.h
M       source/blender/editors/object/object_remesh.c
M       source/blender/makesdna/DNA_object_force_types.h

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

diff --git a/CMakeLists.txt b/CMakeLists.txt
index d59a57ba70b..2ce08e72cd9 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" ON)
+option(WITH_TETGEN    "Build with tetgen remesher support" OFF)
 
 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/discregrid/discregrid/include/Discregrid/geometry/mesh_distance.hpp 
b/extern/discregrid/discregrid/include/Discregrid/geometry/mesh_distance.hpp
index 2272403f23e..910c74cec13 100755
--- a/extern/discregrid/discregrid/include/Discregrid/geometry/mesh_distance.hpp
+++ b/extern/discregrid/discregrid/include/Discregrid/geometry/mesh_distance.hpp
@@ -79,7 +79,16 @@ public:
        double unsignedDistance(Eigen::Vector3d const& x) const;
        double unsignedDistanceCached(Eigen::Vector3d const& x) const;
 
-       void set_thread_map(std::vector<std::thread::id> *thread_map_) { 
thread_map = thread_map_; }
+       // So, the original discregrid uses OpenMP which has
+       // handy functions like omp_get_thread_num(). Switching to non-OpenMP
+       // requires some overhead to get the current thread ID which is what
+       // you see here. So this pointer is passed to both the SDF
+       // generator and this SDF evaluator. The generator fills the thread map
+       // and the evaluator reads from it.
+       // Not ideal and kind of clunky, but a quick workaround for now.
+       void set_thread_map(std::vector<std::thread::id> *thread_map_) {
+               thread_map = thread_map_;
+       }
 
 private:
 
diff --git 
a/extern/discregrid/discregrid/include/Discregrid/mesh/triangle_mesh.hpp 
b/extern/discregrid/discregrid/include/Discregrid/mesh/triangle_mesh.hpp
index 66d38b52360..83accb776a8 100755
--- a/extern/discregrid/discregrid/include/Discregrid/mesh/triangle_mesh.hpp
+++ b/extern/discregrid/discregrid/include/Discregrid/mesh/triangle_mesh.hpp
@@ -27,6 +27,8 @@ public:
 
        TriangleMesh(std::string const& filename);
 
+       bool is_closed() const { return m_is_closed; }
+
        void exportOBJ(std::string const& filename) const;
 
        // Halfedge modifiers.
@@ -103,6 +105,7 @@ private:
        std::vector<std::array<Halfedge, 3>> m_e2e;
        std::vector<Halfedge> m_v2e;
        std::vector<Halfedge> m_b2e;
+       bool m_is_closed;
 };
 }
 
diff --git a/extern/discregrid/discregrid/src/mesh/triangle_mesh.cpp 
b/extern/discregrid/discregrid/src/mesh/triangle_mesh.cpp
index 8a59453be12..186e5ccebd9 100755
--- a/extern/discregrid/discregrid/src/mesh/triangle_mesh.cpp
+++ b/extern/discregrid/discregrid/src/mesh/triangle_mesh.cpp
@@ -72,6 +72,7 @@ TriangleMesh::TriangleMesh(
        std::vector<std::array<unsigned int, 3>> const& faces)
        : m_faces(faces), m_e2e(3 * faces.size()), m_vertices(vertices)
        , m_v2e(vertices.size())
+       , m_is_closed(false)
 {
        construct();
 }
@@ -79,7 +80,7 @@ TriangleMesh::TriangleMesh(
 TriangleMesh::TriangleMesh(double const* vertices,
        unsigned int const* faces,
        std::size_t nv, std::size_t nf)
-       : m_faces(nf), m_vertices(nv), m_e2e(3 * nf), m_v2e(nv)
+       : m_faces(nf), m_vertices(nv), m_e2e(3 * nf), m_v2e(nv), 
m_is_closed(false)
 {
        std::copy(vertices, vertices + 3 * nv, m_vertices[0].data());
        std::copy(faces, faces + 3 * nf, m_faces[0].data());
@@ -90,6 +91,8 @@ TriangleMesh::TriangleMesh(double const* vertices,
 
 TriangleMesh::TriangleMesh(std::string const& path)
 {
+       m_is_closed = false;
+
        std::ifstream in(path, std::ios::in);
        if (!in) 
        { 
@@ -200,7 +203,11 @@ TriangleMesh::construct()
 
        if (!m_b2e.empty())
        {
-               std::cout << std::endl << "WARNING: Mesh not closed!" << 
std::endl;
+               m_is_closed = false;
+       }
+       else
+       {
+               m_is_closed = true;
        }
 }
 
diff --git a/extern/softbody/src/admmpd_collision.cpp 
b/extern/softbody/src/admmpd_collision.cpp
index cf5a0fa68d6..f6dc94dcbdd 100644
--- a/extern/softbody/src/admmpd_collision.cpp
+++ b/extern/softbody/src/admmpd_collision.cpp
@@ -26,18 +26,27 @@ VFCollisionPair::VFCollisionPair() :
        q_bary(0,0,0)
        {}
 
-void Collision::set_obstacles(
+void Collision::ObstacleData::clear() {
+       V = MatrixXd();
+       F = MatrixXi();
+       sdf = Discregrid::CubicLagrangeDiscreteGrid();
+}
+
+
+bool Collision::set_obstacles(
        const float *v0,
        const float *v1,
        int nv,
        const unsigned int *faces,
-       int nf)
+       int nf,
+       std::string *err)
 {
        (void)(v0);
        if (nv==0 || nf==0)
        {
-               // Why do this? Are you just being mean?
-               return;
+               if (err) { *err = "Collision obstacle has no verts or faces"; }
+               obsdata.clear();
+               return false;
        }
 
        std::vector<double> v1_dbl(nv*3);
@@ -63,9 +72,16 @@ void Collision::set_obstacles(
                        obsdata.F(i,j) = faces[i*3+j];
        }
 
+       // Is the mesh closed?
+       Discregrid::TriangleMesh tm(v1_dbl.data(), faces, nv, nf);
+       if (!tm.is_closed()) {
+               if (err) { *err = "Collision obstacle not a closed mesh"; }
+               obsdata.clear();
+               return false;
+       }
+
        // Generate signed distance field
        {
-               Discregrid::TriangleMesh tm(v1_dbl.data(), faces, nv, nf);
                Discregrid::MeshDistance md(tm);
                domain.max() += 1e-3 * domain.diagonal().norm() * 
Eigen::Vector3d::Ones();
                domain.min() -= 1e-3 * domain.diagonal().norm() * 
Eigen::Vector3d::Ones();
@@ -81,6 +97,14 @@ void Collision::set_obstacles(
                obsdata.sdf.addFunction(func, &thread_map, false);
        }
 
+       if (obsdata.sdf.nCells()==0) {
+               if (err) { *err = "SDF gen failed for collision obstacle"; }
+               obsdata.clear();
+               return false;
+       }
+
+       return true;
+
 } // end add obstacle
 
 std::pair<bool,VFCollisionPair>
diff --git a/extern/softbody/src/admmpd_collision.h 
b/extern/softbody/src/admmpd_collision.h
index 819d7620a7c..25d9feb295b 100644
--- a/extern/softbody/src/admmpd_collision.h
+++ b/extern/softbody/src/admmpd_collision.h
@@ -24,6 +24,7 @@ class Collision {
 public:
     struct ObstacleData {
         bool has_obs() const { return F.rows()>0; }
+        void clear();
         Eigen::MatrixXd V;
         Eigen::MatrixXi F;
         SDFType sdf;
@@ -56,15 +57,15 @@ public:
         std::vector<std::set<int> > &g) = 0;
 
     // Set the soup of obstacles for this time step.
-    // I don't really like having to switch up interface style, but we'll
-    // do so here to avoid copies that would happen in admmpd_api.
-    // We should actually just pash in a mesh class?
-    virtual void set_obstacles(
+    // Returns true on success (SDF generation).
+    // If err not nullptr, it's set with what caused the error.
+    virtual bool set_obstacles(
         const float *v0,
         const float *v1,
         int nv,
         const unsigned int *faces,
-        int nf);
+        int nf,
+        std::string *err=nullptr);
 
     // Linearizes active collision pairs about x
     // for the constraint Cx=d
diff --git a/intern/softbody/admmpd_api.cpp b/intern/softbody/admmpd_api.cpp
index f7bc5eefcd5..2139355400f 100644
--- a/intern/softbody/admmpd_api.cpp
+++ b/intern/softbody/admmpd_api.cpp
@@ -26,12 +26,13 @@
 #include "admmpd_solver.h"
 #include "admmpd_mesh.h"
 #include "admmpd_collision.h"
-
-#include "tetgen_api.h"
+#ifdef WITH_TETGEN
+  #include "tetgen_api.h"
+  #include "BKE_mesh_remesh_voxel.h" // TetGen
+#endif
 #include "DNA_mesh_types.h" // Mesh
 #include "DNA_meshdata_types.h" // MVert
 #include "DNA_object_force_types.h" // Enums
-#include "BKE_mesh_remesh_voxel.h" // TetGen
 #include "BKE_mesh.h" // BKE_mesh_free
 #include "BKE_softbody.h" // BodyPoint
 #include "BKE_deform.h" // BKE_defvert_find_index
@@ -41,8 +42,6 @@
 #include <memory>
 #include <algorithm>
 
-#define ADMMPD_API_DEBUG
-
 // Collision obstacles are cached until
 // solve(...) is called. If we are substepping,
 // the obstacle is interpolated from start to end.
@@ -176,6 +175,7 @@ void admmpd_dealloc(ADMMPDInterfaceData *iface)
 
 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);
@@ -196,7 +196,6 @@ static inline int 
admmpd_init_with_tetgen(ADMMPDInterfaceData *iface, Object *ob
   // Double check assumption, the first
   // mesh_totverts vertices remain the same
   // for input and output mesh.
-  #ifdef ADMMPD_API_DEBUG
     for (int i=0; i<tg.in_totverts; ++i)
     {
       for (int j=0; j<3; ++j)
@@ -209,7 +208,6 @@ static inline int 
admmpd_init_with_tetgen(ADMMPDInterfaceData *iface, Object *ob
         }
       }
     }
-  #endif
 
   iface->idata->mesh = std::make_shared<admmpd::TetMesh>();
   success = iface->idata->mesh->create(
@@ -231,6 +229,12 @@ static inline int 
admmpd_init_with_tetgen(ADMMPDInterfaceData *iface, Object *ob
   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_lattice(ADMMPDInterfaceData *iface, Object 
*ob, float (*vertexCos)[3])
@@ -690,13 +694,19 @@ 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) {
-    iface->idata->collision->set_obstacles(
-      iface->idata->obs.x0.data(),
-      iface->idata->obs.x1.data(),
-      iface->idata->obs.x0.size()/3,
-      iface->idata->obs.F.data(),
-      iface->idata->obs.F.size()/3);
+    std::string set_obs_error = "";
+    if (!iface->idata->collision->set_obstacles(
+        iface->idata->obs.x0.data(),
+        iface->idata->obs.x1.data(),
+        iface->idata->obs.x0.size()/3,
+        iface->idata->obs.F.data(),
+        iface->idata->obs.F.size()/3,
+        &set_obs_error)) {
+      strcpy_error(iface, set_obs_error.c_str());
+      had_set_obstacle_error = true;
+    }
   }
 
   try
@@ -704,16 +714,23 @@ int admmpd_solve(ADMMPDInterfaceData *iface, Object *ob, 
float (*vertexCos)[3])
     Eigen::VectorXf obs_x1; // used if su

@@ 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