Commit: 22507773eb2dea4f09098bb32135b3b445dea196
Author: mattoverby
Date: Tue Aug 11 21:17:14 2020 -0500
Branches: soc-2020-soft-body
https://developer.blender.org/rB22507773eb2dea4f09098bb32135b3b445dea196
updated max depth for lattice gen
===================================================================
M extern/softbody/src/admmpd_mesh.cpp
M extern/softbody/src/admmpd_mesh.h
M source/blender/makesrna/intern/rna_object_force.c
===================================================================
diff --git a/extern/softbody/src/admmpd_mesh.cpp
b/extern/softbody/src/admmpd_mesh.cpp
index d130b6345b0..075f21d7f18 100644
--- a/extern/softbody/src/admmpd_mesh.cpp
+++ b/extern/softbody/src/admmpd_mesh.cpp
@@ -7,6 +7,7 @@
#include <unordered_map>
#include <set>
#include <iostream>
+#include <algorithm>
#include "BLI_assert.h"
#include "BLI_task.h"
@@ -22,9 +23,7 @@ static void gather_octree_tets(
Octree<double,3>::Node *node,
const MatrixXd *emb_V,
const MatrixXi *emb_F,
- Eigen::VectorXi *emb_v_to_tet,
- Eigen::MatrixXd *emb_barys,
- Discregrid::CubicLagrangeDiscreteGrid *sdf,
+ const Discregrid::CubicLagrangeDiscreteGrid *sdf,
std::vector<Vector3d> &verts,
std::vector<RowVector4i> &tets
)
@@ -57,7 +56,7 @@ static void gather_octree_tets(
}
for (int i=0; i<8; ++i)
{
-
gather_octree_tets(node->children[i],emb_V,emb_F,emb_v_to_tet,emb_barys,sdf,verts,tets);
+
gather_octree_tets(node->children[i],emb_V,emb_F,sdf,verts,tets);
}
} // end gather octree tets
@@ -78,24 +77,19 @@ bool EmbeddedMesh::create(
(void)(tets);
(void)(nt);
- MicroTimer t;
-
- AlignedBox<double,3> domain;
- std::vector<double> verts_dbl(nv*3);
+// std::vector<std::set<int> > mesh_faces;
+// std::vector<std::set<int> > mesh_vertices;
+ std::vector<AlignedBox<double,3> > emb_leaves(nf);
emb_V0.resize(nv,3);
+ emb_F.resize(nf,3);
+
for (int i=0; i<nv; ++i)
{
emb_V0(i,0) = verts[i*3+0];
emb_V0(i,1) = verts[i*3+1];
emb_V0(i,2) = verts[i*3+2];
- verts_dbl[i*3+0] = verts[i*3+0];
- verts_dbl[i*3+1] = verts[i*3+1];
- verts_dbl[i*3+2] = verts[i*3+2];
- domain.extend(emb_V0.row(i).transpose());
}
- emb_F.resize(nf,3);
- std::vector<AlignedBox<double,3> > emb_leaves(nf);
for (int i=0; i<nf; ++i)
{
emb_F(i,0) = faces[i*3+0];
@@ -107,83 +101,61 @@ bool EmbeddedMesh::create(
box.extend(emb_V0.row(emb_F(i,2)).transpose());
box.extend(box.min()-Vector3d::Ones()*1e-4);
box.extend(box.max()+Vector3d::Ones()*1e-4);
- }
-// std::cout << "T CREATE BOXES: " << t.elapsed_ms() << std::endl;
- t.reset();
-
- // Create the signed distance field for inside/outside tests
- {
- Discregrid::TriangleMesh tm(verts_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();
- std::array<unsigned int, 3> resolution;
- resolution[0] = 30; resolution[1] = 30; resolution[2] = 30;
- emb_sdf = Discregrid::CubicLagrangeDiscreteGrid(domain,
resolution);
- auto func = Discregrid::DiscreteGrid::ContinuousFunction{};
- func = [&md](Eigen::Vector3d const& xi) {
- return md.signedDistanceCached(xi);
- };
- emb_sdf.addFunction(func, false);
- }
-
-// std::cout << "T SDF: " << t.elapsed_ms() << std::endl;
- t.reset();
-
- // Create a tree of the facets
+ // This code works just fine and does what I want:
+ // splits a triangle mesh into multiple meshes
+ // based on connectivity. However, it isn't as helpful
+ // in practice as I hoped.
+// std::vector<int> in_mesh;
+// for (int j=0; j<(int)mesh_vertices.size(); ++j)
+// {
+// if (mesh_vertices[j].count(faces[i*3+0]) ||
+// mesh_vertices[j].count(faces[i*3+1]) ||
+// mesh_vertices[j].count(faces[i*3+2]))
+// in_mesh.emplace_back(j);
+// }
+//
+// // If it's in no mesh, create a new one
+// if (in_mesh.size()==0)
+// {
+// mesh_vertices.emplace_back(std::set<int>());
+// mesh_faces.emplace_back(std::set<int>());
+// mesh_vertices.back().emplace(faces[i*3+0]);
+// mesh_vertices.back().emplace(faces[i*3+1]);
+// mesh_vertices.back().emplace(faces[i*3+2]);
+// mesh_faces.back().emplace(i);
+// continue;
+// }
+//
+// // Otherwise, combine meshes if in muliple
+// for (int j=0; j<(int)in_mesh.size(); ++j)
+// {
+// int mesh0 = in_mesh[0];
+// int meshj = in_mesh[j];
+// if (j==0) // insert into lowest index mesh
+// {
+// mesh_vertices[mesh0].emplace(faces[i*3+0]);
+// mesh_vertices[mesh0].emplace(faces[i*3+1]);
+// mesh_vertices[mesh0].emplace(faces[i*3+2]);
+// mesh_faces[mesh0].emplace(i);
+// continue;
+// }
+// // Merge meshes if shared stencil
+// mesh_faces[mesh0].insert(mesh_faces[meshj].begin(),
mesh_faces[meshj].end());
+//
mesh_vertices[mesh0].insert(mesh_vertices[meshj].begin(),
mesh_vertices[meshj].end());
+// mesh_faces.erase(mesh_faces.begin()+meshj);
+// mesh_vertices.erase(mesh_vertices.begin()+meshj);
+// }
+
+ } // end loop faces
+
+ // Compute SDF and tree on the full mesh.
+ compute_sdf(&emb_V0, &emb_F, &emb_sdf);
emb_rest_facet_tree.init(emb_leaves);
- // Create an octree to generate the tets from
- Octree<double,3> octree;
- octree.init(&emb_V0,&emb_F,options.max_subdiv_levels);
-
-// std::cout << "T OCTREE AND BVH TREE INIT: " << t.elapsed_ms() <<
std::endl;
- t.reset();
-
- emb_v_to_tet.resize(nv);
- emb_v_to_tet.array() = -1;
- emb_barys.resize(nv,4);
- emb_barys.setZero();
-
- std::vector<Vector3d> lat_verts;
- std::vector<RowVector4i> lat_tets;
- Octree<double,3>::Node *root = octree.root().get();
- gather_octree_tets(
- root,
- &emb_V0,
- &emb_F,
- &emb_v_to_tet,
- &emb_barys,
- &emb_sdf,
- lat_verts,
- lat_tets);
- geom::merge_close_vertices(lat_verts,lat_tets);
-
-// std::cout << "T GATHER TETS: " << t.elapsed_ms() << std::endl;
- t.reset();
-
- int nlv = lat_verts.size();
- lat_V0.resize(nlv,3);
- for (int i=0; i<nlv; ++i)
- {
- for(int j=0; j<3; ++j){
- lat_V0(i,j) = lat_verts[i][j];
- }
- }
- int nlt = lat_tets.size();
- lat_T.resize(nlt,4);
- for(int i=0; i<nlt; ++i){
- for(int j=0; j<4; ++j){
- lat_T(i,j) = lat_tets[i][j];
- }
- }
-
+ compute_lattice();
compute_embedding();
-// std::cout << "T COMPUTE EMBEDDING: " << t.elapsed_ms() << std::endl;
- t.reset();
-
// Verify embedding is correct
for (int i=0; i<nv; ++i)
{
@@ -210,6 +182,80 @@ bool EmbeddedMesh::create(
return true;
}
+void EmbeddedMesh::compute_sdf(
+ const Eigen::MatrixXd *emb_v,
+ const Eigen::MatrixXi *emb_f,
+ SDFType *sdf) const
+{
+ Matrix<double,Dynamic,Dynamic,RowMajor> v_rm = *emb_v;
+ Matrix<unsigned int,Dynamic,Dynamic,RowMajor> f_rm =
emb_f->cast<unsigned int>();
+
+ Vector3d min_x(v_rm.col(0).minCoeff(), v_rm.col(1).minCoeff(),
v_rm.col(2).minCoeff());
+ Vector3d max_x(v_rm.col(0).maxCoeff(), v_rm.col(1).maxCoeff(),
v_rm.col(2).maxCoeff());
+ AlignedBox<double,3> domain;
+ domain.extend(min_x);
+ domain.extend(max_x);
+ domain.max() += 1e-3 * domain.diagonal().norm() *
Eigen::Vector3d::Ones();
+ domain.min() -= 1e-3 * domain.diagonal().norm() *
Eigen::Vector3d::Ones();
+
+ Discregrid::TriangleMesh tm(v_rm.data(), f_rm.data(), v_rm.rows(),
f_rm.rows());
+ Discregrid::MeshDistance md(tm);
+ std::array<unsigned int, 3> resolution;
+ resolution[0] = 30; resolution[1] = 30; resolution[2] = 30;
+ *sdf = Discregrid::CubicLagrangeDiscreteGrid(domain, resolution);
+ auto func = Discregrid::DiscreteGrid::ContinuousFunction{};
+ func = [&md](Eigen::Vector3d const& xi) {
+ return md.signedDistanceCached(xi);
+ };
+ sdf->addFunction(func, false);
+}
+
+bool EmbeddedMesh::compute_lattice()
+{
+ // Create subset of faces
+// if (emb_faces.size()==0) { return false; }
+// MatrixXi F(emb_faces.size(),3);
+// int f_count = 0;
+// for (std::set<int>::const_iterator it = emb_faces.begin();
+// it != emb_faces.end(); ++it)
+// {
+// F.row(f_count) = emb_F.row(*it);
+// f_count++;
+// }
+ MatrixXi &F = emb_F;
+
+ // Create an octree to generate the tets from
+ Octree<double,3> octree;
+ octree.init(&emb_V0,&F,options.max_subdiv_levels);
+
+ std::vector<Vector3d> lat_verts;
+ std::vector<RowVector4i> lat_tets;
+ Octree<double,3>::Node *root = octree.root().get();
+ gather_octree_tets(
+ root,
+ &emb_V0,
+ &F,
+ &emb_sdf,
+ lat_verts,
+ lat_tets);
+
+ geom::merge_close_vertices(lat_verts,lat_tets);
+ int nlv = lat_verts.size();
+ int nlt = lat_tets.size();
+ int prev_lv = lat_V0.rows();
+ int prev_lt = lat_T.rows();
+ lat_V0.conservativeResize(prev_lv+nlv,3);
+ lat_T.conservativeResize(prev_lt+nlt,4);
+
+ for (int i=0; i<nlv; ++i)
+ lat_V0.row(prev_lv+i) = lat_verts[i];
+
+ for (int i=0; i<nlt; ++i)
+ lat_T.row(prev_lt+i) = lat_tets[i];
+
+ return nlt>0;
+}
+
bool EmbeddedMesh::compute_embedding()
{
struct FindTetThreadData {
@@ -259,8 +305,9 @@ bool EmbeddedMesh::compute_embedding()
}
emb_barys.resize(nv,4);
- emb_barys.setOnes();
+ emb_barys.setZero();
emb_v_to_tet.resize(nv);
+ emb_v_to_tet.array() = -1;
int nt = lat_T.rows();
// BVH tree for finding point-in-tet and computing
@@ -421,15 +468,13 @@ bool EmbeddedMesh::linearize_pins(
q.emplace_back(qi[i]*ki);
}
- double btb = 1;//bary.dot(bary);
-
if (replicate)
{
for (int i=0; i<3; ++i)
{
for (int j=0; j<4; ++j)
{
- double wi = bary[j]/btb;
+ double wi = bary[j];
trips.emplace_back(p_idx*3+i,
tet[j]*3+i, wi*ki);
}
}
@@ -438,7 +483,7 @@ bool EmbeddedMesh::linearize_pins(
{
for (int j=0; j<4; ++j)
{
- double wi = bary[j]/btb;
+ double wi = bary[j];
trips.emplace_back(p_idx, tet[j], wi*ki);
}
}
diff --git a/extern/softbody/src/admmpd_mesh.h
b/extern/softbody/src/admmpd_mesh.h
index b1a787d5b4e..364355a8a06 100644
--- a/extern/softbody/src/admmpd_mesh.h
+++ b/extern/softbody/src/admmpd_mesh.h
@@ -90,6 +90,14 @@ protected:
bool compute_embedding();
+ // Computes the tet mesh on a subset of faces
+ bool compute_lattice();
+
+ void compute_sdf(
+ const Eigen::MatrixXd *emb_v,
+ const Eigen::MatrixXi *emb_f,
+ SDFType *sdf) const;
+
public:
int type() const { return MESHTYPE_EMBEDDED; }
diff --git a/source/blender/makesrna/intern/rna_object_force.c
b/source/blender/makesrna/intern/rna_object_force.c
index c7a10c59f17..d71601e17a7 100644
--- a/source/blender/makesrna/intern/rna_object_force.c
+++ b/source/blender/makesrna/intern/rna_object_force.c
@@ -1916,7 +1916,7 @@ static void rna_def_softbody(BlenderRNA *brna)
prop = RNA_def_property(srna, "admmpd_embed_res", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "admmpd_embed_res");
- RNA_def_property_range(prop, 1.f, 5.f);
+ RNA_def_property_range(prop, 1
@@ Diff output truncated at 10240 characters. @@
_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs