[Bf-blender-cvs] [cf741e802dc] soc-2020-soft-body: fixed tree bug
over0219
noreply at git.blender.org
Wed Jul 22 04:23:49 CEST 2020
Commit: cf741e802dc4ddcb850cdeaff04289dc53033b55
Author: over0219
Date: Tue Jul 21 17:31:22 2020 -0500
Branches: soc-2020-soft-body
https://developer.blender.org/rBcf741e802dc4ddcb850cdeaff04289dc53033b55
fixed tree bug
===================================================================
M extern/softbody/CMakeLists.txt
M extern/softbody/src/admmpd_collision.h
D extern/softbody/src/admmpd_embeddedmesh.cpp
D extern/softbody/src/admmpd_embeddedmesh.h
M extern/softbody/src/admmpd_mesh.cpp
M extern/softbody/src/admmpd_mesh.h
M intern/softbody/admmpd_api.cpp
===================================================================
diff --git a/extern/softbody/CMakeLists.txt b/extern/softbody/CMakeLists.txt
index c300bedeb39..8120f1ec336 100644
--- a/extern/softbody/CMakeLists.txt
+++ b/extern/softbody/CMakeLists.txt
@@ -47,16 +47,12 @@ set(SRC
src/admmpd_bvh_traverse.cpp
src/admmpd_collision.h
src/admmpd_collision.cpp
-# src/admmpd_embeddedmesh.h
-# src/admmpd_embeddedmesh.cpp
src/admmpd_energy.h
src/admmpd_energy.cpp
src/admmpd_geom.h
src/admmpd_geom.cpp
src/admmpd_linsolve.h
src/admmpd_linsolve.cpp
-# src/admmpd_pin.h
-# src/admmpd_pin.cpp
src/admmpd_sdf.h
src/admmpd_sdf.cpp
src/admmpd_solver.h
diff --git a/extern/softbody/src/admmpd_collision.h b/extern/softbody/src/admmpd_collision.h
index a5189e7c22b..96a0d978337 100644
--- a/extern/softbody/src/admmpd_collision.h
+++ b/extern/softbody/src/admmpd_collision.h
@@ -6,7 +6,6 @@
#include "admmpd_bvh.h"
#include "admmpd_types.h"
-#include "admmpd_embeddedmesh.h"
#include <set>
namespace admmpd {
diff --git a/extern/softbody/src/admmpd_embeddedmesh.cpp b/extern/softbody/src/admmpd_embeddedmesh.cpp
deleted file mode 100644
index 86f6d00086b..00000000000
--- a/extern/softbody/src/admmpd_embeddedmesh.cpp
+++ /dev/null
@@ -1,385 +0,0 @@
-// Copyright Matt Overby 2020.
-// Distributed under the MIT License.
-#if 0
-
-#include "admmpd_embeddedmesh.h"
-#include "admmpd_geom.h"
-#include "admmpd_bvh.h"
-#include "admmpd_bvh_traverse.h"
-
-#include <iostream>
-#include <fstream>
-#include <unordered_map>
-#include <set>
-#include <numeric>
-
-#include "BLI_task.h" // threading
-#include "BLI_assert.h"
-
-namespace admmpd {
-using namespace Eigen;
-
-// Gen lattice with subdivision
-struct LatticeData {
- //SDF<double> *emb_sdf;
- const Eigen::MatrixXd *V;
- const Eigen::MatrixXi *F;
- std::vector<Vector3d> verts;
- std::vector<Vector4i> tets;
-};
-
-static inline void merge_close_vertices(LatticeData *data, double eps=1e-12)
-{
- int nv = data->verts.size();
- std::vector<Vector3d> new_v(nv); // new verts
- std::vector<int> idx(nv,0); // index mapping
- std::vector<int> visited(nv,0);
- int count = 0;
- for (int i=0; i<nv; ++i)
- {
- if(!visited[i])
- {
- visited[i] = 1;
- new_v[count] = data->verts[i];
- idx[i] = count;
- Vector3d vi = data->verts[i];
- for (int j = i+1; j<nv; ++j)
- {
- if((data->verts[j]-vi).norm() < eps)
- {
- visited[j] = 1;
- idx[j] = count;
- }
- }
- count++;
- }
- }
- new_v.resize(count);
- data->verts = new_v;
- int nt = data->tets.size();
- for (int i=0; i<nt; ++i)
- {
- for (int j=0; j<4; ++j)
- {
- data->tets[i][j] = idx[data->tets[i][j]];
- }
- }
-}
-
-static inline void add_tets_from_box(
- const Vector3d &min,
- const Vector3d &max,
- std::vector<Vector3d> &verts,
- std::vector<Vector4i> &tets)
-{
- std::vector<Vector3d> v = {
- // Top plane, clockwise looking down
- max,
- Vector3d(min[0], max[1], max[2]),
- Vector3d(min[0], max[1], min[2]),
- Vector3d(max[0], max[1], min[2]),
- // Bottom plane, clockwise looking down
- Vector3d(max[0], min[1], max[2]),
- Vector3d(min[0], min[1], max[2]),
- min,
- Vector3d(max[0], min[1], min[2])
- };
- // Add vertices and get indices of the box
- std::vector<int> b;
- for(int i=0; i<8; ++i)
- {
- b.emplace_back(verts.size());
- verts.emplace_back(v[i]);
- }
- // From the box, create five new tets
- std::vector<Vector4i> new_tets = {
- Vector4i( b[0], b[5], b[7], b[4] ),
- Vector4i( b[5], b[7], b[2], b[0] ),
- Vector4i( b[5], b[0], b[2], b[1] ),
- Vector4i( b[7], b[2], b[0], b[3] ),
- Vector4i( b[5], b[2], b[7], b[6] )
- };
- for(int i=0; i<5; ++i)
- tets.emplace_back(new_tets[i]);
-};
-
-static void gather_octree_tets(
- Octree<double,3>::Node *node,
- const MatrixXd *V, const MatrixXi *F,
- AABBTree<double,3> *face_tree,
- std::vector<Vector3d> &verts,
- std::vector<Vector4i> &tets
- )
-{
- if (node == nullptr)
- {
- return;
- }
-
- bool is_leaf = node->is_leaf();
- bool has_prims = (int)node->prims.size()>0;
- if (is_leaf)
- {
- Vector3d bmin = node->center-Vector3d::Ones()*node->halfwidth;
- Vector3d bmax = node->center+Vector3d::Ones()*node->halfwidth;
-
- // If we have primitives in the cell,
- // create tets. Otherwise, launch a ray
- // to determine if we are inside or outside
- // the mesh. If we're outside, don't create tets.
- if (has_prims)
- {
- add_tets_from_box(bmin,bmax,verts,tets);
- }
- else
- {
- PointInTriangleMeshTraverse<double> pt_in_mesh(node->center,V,F);
- face_tree->traverse(pt_in_mesh);
- if (pt_in_mesh.output.is_inside())
- add_tets_from_box(bmin,bmax,verts,tets);
- }
- return;
- }
- for (int i=0; i<8; ++i)
- {
- gather_octree_tets(node->children[i],V,F,face_tree,verts,tets);
- }
-
-} // end gather octree tets
-
-
-bool EmbeddedMesh::generate(
- const Eigen::MatrixXd &V, // embedded verts
- const Eigen::MatrixXi &F, // embedded faces
- bool trim_lattice,
- int subdiv_levels)
-{
- emb_faces = F;
- emb_rest_x = V;
-
- if (F.rows()==0 || V.rows()==0)
- throw std::runtime_error("EmbeddedMesh::generate Error: Missing data");
-
- LatticeData data;
- data.V = &V;
- data.F = &F;
-
- Octree<double,3> octree;
- octree.init(&V,&F,subdiv_levels);
-
- int nf = F.rows();
- std::vector<AlignedBox<double,3> > face_boxes(nf);
- for (int i=0; i<nf; ++i)
- {
- face_boxes[i].extend(V.row(F(i,0)).transpose());
- face_boxes[i].extend(V.row(F(i,1)).transpose());
- face_boxes[i].extend(V.row(F(i,2)).transpose());
- }
-
- emb_rest_tree.init(face_boxes);
-
- Octree<double,3>::Node *root = octree.root().get();
- gather_octree_tets(root,&V,&F,&emb_rest_tree,data.verts,data.tets);
- merge_close_vertices(&data);
-
- int nv = data.verts.size();
- lat_rest_x.resize(nv,3);
- for (int i=0; i<nv; ++i)
- {
- for(int j=0; j<3; ++j){
- lat_rest_x(i,j) = data.verts[i][j];
- }
- }
- int nt = data.tets.size();
- lat_tets.resize(nt,4);
- for(int i=0; i<nt; ++i){
- for(int j=0; j<4; ++j){
- lat_tets(i,j) = data.tets[i][j];
- }
- }
-
- // Now compute the baryweighting for embedded vertices
- bool embed_success = compute_embedding();
-
- if (!emb_rest_tree.root())
- throw std::runtime_error("EmbeddedMesh::generate Error: Failed to create tree");
- if (lat_rest_x.rows()==0)
- throw std::runtime_error("EmbeddedMesh::generate Error: Failed to create verts");
- if (lat_tets.rows()==0)
- throw std::runtime_error("EmbeddedMesh::generate Error: Failed to create tets");
- if (emb_faces.rows()==0)
- throw std::runtime_error("EmbeddedMesh::generate Error: Did not set faces");
- if (emb_rest_x.rows()==0)
- throw std::runtime_error("EmbeddedMesh::generate Error: Did not set verts");
- if (!embed_success)
- throw std::runtime_error("EmbeddedMesh::generate Error: Failed embedding");
-
- // Export the mesh for funsies
-// std::ofstream of("v_lattice.txt"); of << lat_rest_x; of.close();
-// std::ofstream of2("t_lattice.txt"); of2 << lat_tets; of2.close();
-
- return embed_success;
-
-} // end gen lattice
-
-void EmbeddedMesh::compute_masses(
- Eigen::VectorXd *masses_tets, // masses of the lattice verts
- double density_kgm3)
-{
- BLI_assert(masses_tets != NULL);
- BLI_assert(density_kgm3 > 0);
-
- // TODO
- // map the area of the surface to the tet vertices
-
- // Source: https://github.com/mattoverby/mclscene/blob/master/include/MCL/TetMesh.hpp
- // Computes volume-weighted masses for each vertex
- // density_kgm3 is the unit-volume density
- int nx = lat_rest_x.rows();
- masses_tets->resize(nx);
- masses_tets->setZero();
- int n_tets = lat_tets.rows();
- for (int t=0; t<n_tets; ++t)
- {
- RowVector4i tet = lat_tets.row(t);
- RowVector3d tet_v0 = lat_rest_x.row(tet[0]);
- Matrix3d edges;
- edges.col(0) = lat_rest_x.row(tet[1]) - tet_v0;
- edges.col(1) = lat_rest_x.row(tet[2]) - tet_v0;
- edges.col(2) = lat_rest_x.row(tet[3]) - tet_v0;
- double vol = std::abs((edges).determinant()/6.f);
- double tet_mass = density_kgm3 * vol;
- masses_tets->operator[](tet[0]) += tet_mass / 4.f;
- masses_tets->operator[](tet[1]) += tet_mass / 4.f;
- masses_tets->operator[](tet[2]) += tet_mass / 4.f;
- masses_tets->operator[](tet[3]) += tet_mass / 4.f;
- }
-
- // Verify masses
- for (int i=0; i<nx; ++i)
- {
- if (masses_tets->operator[](i) <= 0.0)
- {
- printf("**EmbeddedMesh::compute_masses Error: unreferenced vertex\n");
- masses_tets->operator[](i)=1;
- }
- }
-} // end compute masses
-
-typedef struct FindTetThreadData {
- AABBTree<double,3> *tree;
- EmbeddedMesh *emb_mesh; // thread sets vtx_to_tet and barys
-} FindTetThreadData;
-
-static void parallel_point_in_tet(
- void *__restrict userdata,
- const int i,
- const TaskParallelTLS *__restrict tls)
-{
- (void)(tls);
- FindTetThreadData *td = (FindTetThreadData*)userdata;
- Vector3d pt = td->emb_mesh->emb_rest_x.row(i);
- PointInTetMeshTraverse<double> traverser(
- pt,
- &td->emb_mesh->lat_rest_x,
- &td->emb_mesh->lat_tets);
- bool success = td->tree->traverse(traverser);
- int tet_idx = traverser.output.prim;
- if (success && tet_idx >= 0)
- {
- RowVector4i tet = td->emb_mesh->lat_tets.row(tet_idx);
- Vector3d t[4] = {
- td->emb_mesh->lat_rest_x.row(tet[0]),
- td->emb_mesh->lat_rest_x.row(tet[1]),
- td->emb_mesh->lat_rest_x.row(tet[2]),
- td->emb_mesh->lat_rest_x.row(tet[3])
- };
- td->emb_mesh->emb_vtx_to_tet[i] = tet_idx;
- Vector4d b = geom::point_tet_barys(pt,t[0],t[1],t[2],t[3]);
- td->emb_mesh->emb_barys.row(i) = b;
- }
-} // end parallel lin solve
-
-bool EmbeddedMesh::compute_embedding()
-{
- int nv = emb_rest_x.rows();
- if (nv==0)
- {
- printf("**EmbeddedMesh::compute_embedding: No embedded vertices");
- return false;
- }
-
- emb_barys.resize(nv,4);
- emb_barys.setOnes();
- emb_vtx_to_tet.resize(nv);
- int nt = lat_tets.rows();
-
- // BVH tree for finding point-in-tet and computing
- // barycoords for each embedded vertex
- std::vector<AlignedBox<double,3> > tet_aabbs;
- tet_aabbs.resize(nt);
- Vector3d veta = Vector3d::Ones()*1e-12;
- for (int i=0; i<nt; ++i)
- {
- tet_aabbs[i].setEmpty();
- RowVector4i tet = lat_tets.row(i);
- for (int j=0; j<4; ++j)
- tet_aabbs[i].extend(lat_rest_x.row(tet[j]).transpose());
-
- tet_aabbs[i].extend(tet_aabbs[i].min()-veta);
- tet_aabbs[i].extend(tet_aabbs[i].max()+veta);
- }
-
- AABBTree<double,3> tree;
- tree.init(tet_aabbs);
-
- Fin
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list