[Bf-blender-cvs] [9819c3576cd] soc-2020-soft-body: working on interface
over0219
noreply at git.blender.org
Wed Jun 10 01:14:02 CEST 2020
Commit: 9819c3576cdce6c5f9efca1a821997a856ad66d7
Author: over0219
Date: Tue Jun 9 18:13:56 2020 -0500
Branches: soc-2020-soft-body
https://developer.blender.org/rB9819c3576cdce6c5f9efca1a821997a856ad66d7
working on interface
===================================================================
M extern/softbody/src/admmpd_collision.cpp
M extern/softbody/src/admmpd_energy.cpp
M extern/softbody/src/admmpd_solver.cpp
M extern/softbody/src/admmpd_solver.h
M intern/softbody/CMakeLists.txt
M intern/softbody/admmpd_api.cpp
M intern/softbody/admmpd_api.h
M intern/tetgen/tetgen_api.cpp
M source/blender/blenkernel/BKE_mesh_remesh_voxel.h
M source/blender/blenkernel/intern/mesh_remesh_voxel.c
M source/blender/blenkernel/intern/softbody.c
M source/blender/editors/object/object_remesh.c
M source/blender/makesdna/DNA_object_force_types.h
===================================================================
diff --git a/extern/softbody/src/admmpd_collision.cpp b/extern/softbody/src/admmpd_collision.cpp
index 2bce56fa9f0..0cd828011ad 100644
--- a/extern/softbody/src/admmpd_collision.cpp
+++ b/extern/softbody/src/admmpd_collision.cpp
@@ -17,16 +17,18 @@ void FloorCollider::jacobian(
std::vector<Eigen::Triplet<double> > *trips_z,
std::vector<double> *l)
{
+ const double floor_z = -2.0;
+
int nx = x->rows();
for (int i=0; i<nx; ++i)
{
- Eigen::Vector3d p = x->row(i);
- if (p[2]>0)
+ Eigen::Vector3d xi = x->row(i);
+ if (xi[2]>floor_z)
continue;
-
+
int c_idx = l->size();
trips_z->emplace_back(c_idx,i,1.0);
- l->emplace_back(0);
+ l->emplace_back(floor_z);
}
} // end floor collider Jacobian
diff --git a/extern/softbody/src/admmpd_energy.cpp b/extern/softbody/src/admmpd_energy.cpp
index ea7c68b6dca..3b90d506a2a 100644
--- a/extern/softbody/src/admmpd_energy.cpp
+++ b/extern/softbody/src/admmpd_energy.cpp
@@ -2,6 +2,7 @@
#include "admmpd_energy.h"
+#include <iostream>
namespace admmpd {
using namespace Eigen;
diff --git a/extern/softbody/src/admmpd_solver.cpp b/extern/softbody/src/admmpd_solver.cpp
index 052008121b9..008db80720e 100644
--- a/extern/softbody/src/admmpd_solver.cpp
+++ b/extern/softbody/src/admmpd_solver.cpp
@@ -19,8 +19,8 @@ template <typename T> using RowSparseMatrix = SparseMatrix<T,RowMajor>;
bool Solver::init(
const Eigen::MatrixXd &V,
const Eigen::MatrixXi &T,
- const ADMMPD_Options *options,
- ADMMPD_Data *data)
+ const Options *options,
+ Data *data)
{
if (!data || !options)
throw std::runtime_error("init: data/options null");
@@ -32,9 +32,10 @@ bool Solver::init(
} // end init
int Solver::solve(
- const ADMMPD_Options *options,
- ADMMPD_Data *data)
+ const Options *options,
+ Data *data)
{
+
// Init the solve which computes
// quantaties like M_xbar and makes sure
// the variables are sized correctly.
@@ -77,8 +78,8 @@ int Solver::solve(
} // end solve
void Solver::init_solve(
- const ADMMPD_Options *options,
- ADMMPD_Data *data)
+ const Options *options,
+ Data *data)
{
int nx = data->x.rows();
if (data->M_xbar.rows() != nx)
@@ -87,7 +88,7 @@ void Solver::init_solve(
// velocity and position
double dt = std::max(0.0, options->timestep_s);
data->x_start = data->x;
- for( int i=0; i<nx; ++i )
+ for (int i=0; i<nx; ++i)
{
data->v.row(i) += options->grav;
data->M_xbar.row(i) =
@@ -103,8 +104,8 @@ void Solver::init_solve(
} // end init solve
void Solver::update_constraints(
- const ADMMPD_Options *options,
- ADMMPD_Data *data)
+ const Options *options,
+ Data *data)
{
std::vector<double> l_coeffs;
@@ -145,8 +146,8 @@ void Solver::update_constraints(
} // end update constraints
void Solver::solve_conjugate_gradients(
- const ADMMPD_Options *options,
- ADMMPD_Data *data)
+ const Options *options,
+ Data *data)
{
// If we don't have any constraints,
// we don't need to perform CG
@@ -220,8 +221,8 @@ void Solver::solve_conjugate_gradients(
} // end solve conjugate gradients
void Solver::compute_matrices(
- const ADMMPD_Options *options,
- ADMMPD_Data *data)
+ const Options *options,
+ Data *data)
{
// Allocate per-vertex data
int nx = data->x.rows();
@@ -245,20 +246,29 @@ void Solver::compute_matrices(
// Add per-element energies to data
std::vector< Triplet<double> > trips;
append_energies(options,data,trips);
- int nw = trips.back().row()+1;
- double dt2 = std::max(0.0, options->timestep_s * options->timestep_s);
+ int n_row_D = trips.back().row()+1;
+ double dt2 = options->timestep_s * options->timestep_s;
+ if (dt2 <= 0)
+ dt2 = 1.0; // static solve
+
+ // Weight matrix
+ RowSparseMatrix<double> W2(n_row_D,n_row_D);
+ VectorXi W_nnz = VectorXi::Ones(n_row_D);
+ W2.reserve(W_nnz);
+ int ne = data->indices.size();
+ for (int i=0; i<ne; ++i)
+ {
+ const Vector2i &idx = data->indices[i];
+ for (int j=0; j<idx[1]; ++j)
+ {
+ W2.coeffRef(idx[0]+j,idx[0]+j) = data->weights[i]*data->weights[i];
+ }
+ }
- // Global matrix
- data->D.resize(nw,nx);
+ // Weighted Laplacian
+ data->D.resize(n_row_D,nx);
data->D.setFromTriplets(trips.begin(), trips.end());
data->Dt = data->D.transpose();
- VectorXd wd = Map<VectorXd>(data->weights.data(), data->weights.size());
- RowSparseMatrix<double> W2(nw,nw);
- VectorXi W_nnz = VectorXi::Ones(nw);
- W2.reserve(W_nnz);
- for(int i=0; i<nw; ++i)
- W2.coeffRef(i,i) = data->weights[i]*data->weights[i];
-
data->DtW2 = dt2 * data->Dt * W2;
data->A = data->DtW2 * data->D;
for (int i=0; i<nx; ++i)
@@ -274,16 +284,16 @@ void Solver::compute_matrices(
data->K[i].resize(1,nx);
// ADMM variables
- data->z.resize(nw,3);
+ data->z.resize(n_row_D,3);
data->z.setZero();
- data->u.resize(nw,3);
+ data->u.resize(n_row_D,3);
data->u.setZero();
} // end compute matrices
void Solver::append_energies(
- const ADMMPD_Options *options,
- ADMMPD_Data *data,
+ const Options *options,
+ Data *data,
std::vector<Triplet<double> > &D_triplets)
{
int nt = data->tets.rows();
diff --git a/extern/softbody/src/admmpd_solver.h b/extern/softbody/src/admmpd_solver.h
index ec836d3c466..6b397bee406 100644
--- a/extern/softbody/src/admmpd_solver.h
+++ b/extern/softbody/src/admmpd_solver.h
@@ -11,24 +11,24 @@
namespace admmpd {
-struct ADMMPD_Options {
+struct Options {
double timestep_s;
int max_admm_iters;
int max_cg_iters;
double mult_k; // stiffness multiplier for constraints
double min_res; // min residual for CG solver
Eigen::Vector3d grav;
- ADMMPD_Options() :
+ Options() :
timestep_s(1.0/100.0), // TODO: Figure out delta time from blender api
max_admm_iters(20),
max_cg_iters(10),
- mult_k(3.0),
+ mult_k(1.0),
min_res(1e-4),
grav(0,0,-9.8)
{}
};
-struct ADMMPD_Data {
+struct Data {
// Input:
Eigen::MatrixXi tets; // elements t x 4
Eigen::MatrixXd x; // vertices, n x 3
@@ -65,42 +65,42 @@ public:
bool init(
const Eigen::MatrixXd &V, // vertices
const Eigen::MatrixXi &T, // tets
- const ADMMPD_Options *options,
- ADMMPD_Data *data);
+ const Options *options,
+ Data *data);
// Solve a single time step.
// Returns number of iterations.
int solve(
- const ADMMPD_Options *options,
- ADMMPD_Data *data);
+ const Options *options,
+ Data *data);
protected:
void update_constraints(
- const ADMMPD_Options *options,
- ADMMPD_Data *data);
+ const Options *options,
+ Data *data);
void init_solve(
- const ADMMPD_Options *options,
- ADMMPD_Data *data);
+ const Options *options,
+ Data *data);
// Global step with CG:
// 1/2||Ax-b||^2 + k/2||Kx-l||^2
void solve_conjugate_gradients(
- const ADMMPD_Options *options,
- ADMMPD_Data *data);
+ const Options *options,
+ Data *data);
void compute_lattice(
- const ADMMPD_Options *options,
- ADMMPD_Data *data);
+ const Options *options,
+ Data *data);
void compute_matrices(
- const ADMMPD_Options *options,
- ADMMPD_Data *data);
+ const Options *options,
+ Data *data);
void append_energies(
- const ADMMPD_Options *options,
- ADMMPD_Data *data,
+ const Options *options,
+ Data *data,
std::vector<Eigen::Triplet<double> > &D_triplets);
}; // class ADMMPD_solver
diff --git a/intern/softbody/CMakeLists.txt b/intern/softbody/CMakeLists.txt
index 5c8a2da0e44..1bb705e1d1e 100644
--- a/intern/softbody/CMakeLists.txt
+++ b/intern/softbody/CMakeLists.txt
@@ -24,8 +24,11 @@ set(INC
set(INC_SYS
../../extern/softbody/src
+ ../tetgen
../../source/blender/makesdna
../../source/blender/blenkernel
+ ../../source/blender/blenlib
+ ../../intern/guardedalloc
${EIGEN3_INCLUDE_DIRS}
)
diff --git a/intern/softbody/admmpd_api.cpp b/intern/softbody/admmpd_api.cpp
index 5963c4f71c8..21e21c4cb9d 100644
--- a/intern/softbody/admmpd_api.cpp
+++ b/intern/softbody/admmpd_api.cpp
@@ -24,77 +24,173 @@
#include "admmpd_api.h"
#include "admmpd_solver.h"
#include "admmpd_lattice.h"
-#include "DNA_object_types.h" // Object
-#include "BKE_softbody.h"
+#include "tetgen_api.h"
+#include "DNA_mesh_types.h" // Mesh
+#include "DNA_meshdata_types.h" // MVert
+#include "BKE_mesh_remesh_voxel.h" // TetGen
+#include "BKE_mesh.h" // BKE_mesh_free
+#include "MEM_guardedalloc.h" //
+
#include <iostream>
-struct ADMMPD_Data {
- admmpd::ADMMPD_Options *options;
- admmpd::ADMMPD_Data *data;
- admmpd::Lattice *lattice;
+
+struct ADMMPDInternalData {
+ admmpd::Options *options;
+ admmpd::Data *data;
+// admmpd::Lattice *lattice;
};
-ADMMPD_Data* admmpd_init(
- BodyPoint *bp,
- int numVerts)
+
+void admmpd_alloc(ADMMPDInterfaceData *iface, int in_verts, int in_faces)
+{
+ if (iface==NULL)
+ return;
+
+ iface->in_totverts = in_verts;
+ iface->in_verts = (float *)MEM_mallocN(in_verts*3*sizeof(float), "admmpd_verts");
+ iface->in_vel = (float *)MEM_mallocN(in_verts*3*sizeof(float), "admmpd_vel");
+
+ iface->in_totfaces = in_faces;
+ iface->in_faces = (unsigned int *)MEM_mallocN(in_faces*3*sizeof(unsigned int), "admmpd_faces");
+}
+
+void admmpd_dealloc(ADMMPDInterfaceData *iface)
{
- if (!bp)
- return NULL;
-
- ADMMPD_Data *admmpd_data = new ADMMPD_Data();
- admmpd_data->options = new admmpd::ADMMPD_Options();
- admmpd::ADMMPD_Options *options = admmpd_data->options;
- admmpd_data->data = new admmpd::ADMMPD_Data();
- admmpd::ADMMPD_Data *data = admmpd_data->data;
- admmpd_data->lattice = new admmpd::Lattice();
- admmpd::Lattice *lattice = admmpd_data->lattice;
-
- // Create initializer
- Eigen::MatrixXd V(numVerts,3);
+ if (iface==NULL)
+ return;
+
+ iface->in_totverts = 0;
+ if (iface->in_verts != NULL)
+ MEM_freeN(iface->in_verts);
+ if (iface->in_vel != NULL)
+ MEM_freeN(iface->in_vel);
+
+ iface->in_totfaces = 0;
+ if (iface->in_faces != NULL)
+ MEM_freeN(iface->in_faces);
+
+ iface->out_totverts = 0;
+ if (iface->out_verts != NULL)
+ MEM_freeN(iface->out_verts);
+ if (iface->out_vel != NULL)
+ MEM_f
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list