Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/intern
diff options
context:
space:
mode:
authorover0219 <over0219@umn.edu>2020-06-16 02:30:34 +0300
committerover0219 <over0219@umn.edu>2020-06-16 02:30:34 +0300
commitadc3d113f248ca036fcb8e530aba31edc24cb5f2 (patch)
treeca23ecd99bf4984cab09ece462020343c5fae683 /intern
parent4ff3bb13e35fb190c8510bf4daa7ded0a0c3b777 (diff)
improved API for less for-all-verts loops
Diffstat (limited to 'intern')
-rw-r--r--intern/softbody/admmpd_api.cpp154
-rw-r--r--intern/softbody/admmpd_api.h32
-rw-r--r--intern/tetgen/tetgen_api.cpp6
3 files changed, 68 insertions, 124 deletions
diff --git a/intern/softbody/admmpd_api.cpp b/intern/softbody/admmpd_api.cpp
index 62dc1e7bba5..ade895a1971 100644
--- a/intern/softbody/admmpd_api.cpp
+++ b/intern/softbody/admmpd_api.cpp
@@ -29,6 +29,7 @@
#include "DNA_meshdata_types.h" // MVert
#include "BKE_mesh_remesh_voxel.h" // TetGen
#include "BKE_mesh.h" // BKE_mesh_free
+#include "BKE_softbody.h" // BodyPoint
#include "MEM_guardedalloc.h" //
#include <iostream>
@@ -38,55 +39,17 @@ struct ADMMPDInternalData {
admmpd::Options *options;
admmpd::Data *data;
// admmpd::Lattice *lattice;
+ int in_totverts; // number of input verts
};
-
-void admmpd_alloc(ADMMPDInterfaceData *iface)
-{
- if (iface==NULL)
- return;
-
- if (iface->in_verts != NULL)
- {
- MEM_freeN(iface->in_verts);
- iface->in_verts = NULL;
- }
- if (iface->in_vel != NULL)
- {
- MEM_freeN(iface->in_vel);
- iface->in_vel = NULL;
- }
- if (iface->in_faces != NULL)
- {
- MEM_freeN(iface->in_faces);
- iface->in_faces = NULL;
- }
-
- iface->in_verts = (float *)MEM_mallocN(iface->in_totverts*3*sizeof(float), "admmpd_verts");
- iface->in_vel = (float *)MEM_mallocN(iface->in_totverts*3*sizeof(float), "admmpd_vel");
- iface->in_faces = (unsigned int *)MEM_mallocN(iface->in_totfaces*3*sizeof(unsigned int), "admmpd_faces");
-}
-
void admmpd_dealloc(ADMMPDInterfaceData *iface)
{
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_freeN(iface->out_vel);
+ iface->totverts = 0;
+ iface->mesh_totverts = 0;
+ iface->mesh_totfaces = 0;
if (iface->data)
{
@@ -97,52 +60,32 @@ void admmpd_dealloc(ADMMPDInterfaceData *iface)
delete iface->data;
}
- iface->in_verts = NULL;
- iface->in_vel = NULL;
- iface->in_faces = NULL;
- iface->out_verts = NULL;
- iface->out_vel = NULL;
iface->data = NULL;
}
-int admmpd_init(ADMMPDInterfaceData *iface)
+int admmpd_init(ADMMPDInterfaceData *iface, float *in_verts, unsigned int *in_faces)
{
+
if (iface==NULL)
return 0;
- if (iface->in_verts==NULL || iface->in_vel==NULL || iface->in_faces==NULL)
+ if (in_verts==NULL || in_faces==NULL)
return 0;
- if (iface->in_totverts<=0 || iface->in_totfaces<=0)
+ if (iface->mesh_totverts<=0 || iface->mesh_totfaces<=0)
return 0;
// Generate tets
TetGenRemeshData tg;
init_tetgenremeshdata(&tg);
- tg.in_verts = iface->in_verts;
- tg.in_totverts = iface->in_totverts;
- tg.in_faces = iface->in_faces;
- tg.in_totfaces = iface->in_totfaces;
+ tg.in_verts = in_verts;
+ tg.in_totverts = iface->mesh_totverts;
+ tg.in_faces = in_faces;
+ tg.in_totfaces = iface->mesh_totfaces;
bool success = tetgen_resmesh(&tg);
if (!success || tg.out_tottets==0)
return 0;
- // Resize data
- iface->out_totverts = tg.out_totverts;
- if (iface->out_verts != NULL)
- {
- MEM_freeN(iface->out_verts);
- iface->out_verts = NULL;
- }
- if (iface->out_vel != NULL)
- {
- MEM_freeN(iface->out_vel);
- iface->out_vel = NULL;
- }
- iface->out_verts = (float *)MEM_callocN(
- iface->out_totverts*3*sizeof(float), "ADMMPD_out_verts");
- iface->out_vel = (float *)MEM_callocN(
- iface->out_totverts*3*sizeof(float), "ADMMPD_out_vel");
-
// Create initializer for ADMMPD
+ iface->totverts = tg.out_totverts;
int nv = tg.out_totverts;
int nt = tg.out_tottets;
Eigen::MatrixXd V(nv,3);
@@ -153,8 +96,6 @@ int admmpd_init(ADMMPDInterfaceData *iface)
for (int j=0; j<3; ++j)
{
V(i,j) = tg.out_verts[i*3+j];
- iface->out_verts[i*3+j] = tg.out_verts[i*3+j];
- iface->out_vel[i*3+j] = 0;
}
}
T.setZero();
@@ -191,60 +132,63 @@ int admmpd_init(ADMMPDInterfaceData *iface)
return int(init_success);
}
-void admmpd_solve(ADMMPDInterfaceData *iface)
+void admmpd_copy_from_bodypoint(ADMMPDInterfaceData *iface, const BodyPoint *pts)
{
- if (iface == NULL)
+ if (iface == NULL || pts == NULL)
return;
- // Whatever is in out_verts and out_vel needs
- // to be mapped to internal data, as it's used as input
- // when reading from cached data.
- int nv = iface->out_totverts;
- for (int i=0; i<nv; ++i)
+ for (int i=0; i<iface->totverts; ++i)
{
- for (int j=0; j<3; ++j)
+ const BodyPoint *pt = &pts[i];
+ for(int j=0; j<3; ++j)
{
- iface->data->data->x(i,j) = iface->out_verts[i*3+j];
- iface->data->data->v(i,j) = iface->out_vel[i*3+j];
+ iface->data->data->x(i,j)=pt->pos[j];
+ iface->data->data->v(i,j)=pt->vec[j];
}
}
+}
- try
+void admmpd_copy_to_bodypoint_and_object(ADMMPDInterfaceData *iface, BodyPoint *pts, float (*vertexCos)[3])
+{
+ if (iface == NULL)
+ return;
+
+ for (int i=0; i<iface->totverts; ++i)
{
- admmpd::Solver().solve(iface->data->options,iface->data->data);
- for (int i=0; i<iface->data->data->x.rows(); ++i)
+ if (pts != NULL)
{
- for (int j=0; j<3; ++j)
+ BodyPoint *pt = &pts[i];
+ for(int j=0; j<3; ++j)
{
- iface->out_verts[i*3+j] = iface->data->data->x(i,j);
- iface->out_vel[i*3+j] = iface->data->data->v(i,j);
+ pt->pos[j] = iface->data->data->x(i,j);
+ pt->vec[j] = iface->data->data->v(i,j);
}
}
- }
- catch(const std::exception &e)
- {
- printf("**ADMMPD Error on solve: %s\n", e.what());
+
+ // TODO eventually replace with mapping. For now
+ // we assume TetGen, which the first N vertices are
+ // mapped one-to-one.
+ if (vertexCos != NULL && i<iface->mesh_totverts)
+ {
+ vertexCos[i][0] = iface->data->data->x(i,0);
+ vertexCos[i][1] = iface->data->data->x(i,1);
+ vertexCos[i][2] = iface->data->data->x(i,2);
+ }
}
}
-void admmpd_get_vertices(ADMMPDInterfaceData *iface, float (*vertexCos)[3], int numVerts)
+void admmpd_solve(ADMMPDInterfaceData *iface)
{
+
if (iface == NULL)
return;
- if (numVerts != iface->in_totverts || numVerts > iface->out_totverts)
+ try
{
- printf("**ADMMPD TODO: PROPER VERTEX MAPPINGS\n");
- return;
+ admmpd::Solver().solve(iface->data->options,iface->data->data);
}
- // TODO double check this, but I believe the first n verts
- // created by tetgen are the same as the input. I hope. We'll find out I guess.
- // If not, this function will be a placeholder for the mapping that
- // will have to occur.
- for (int i=0; i<numVerts; ++i)
+ catch(const std::exception &e)
{
- vertexCos[i][0] = iface->out_verts[i*3+0];
- vertexCos[i][1] = iface->out_verts[i*3+1];
- vertexCos[i][2] = iface->out_verts[i*3+2];
+ printf("**ADMMPD Error on solve: %s\n", e.what());
}
} \ No newline at end of file
diff --git a/intern/softbody/admmpd_api.h b/intern/softbody/admmpd_api.h
index f90f75a0405..36cbe684e9e 100644
--- a/intern/softbody/admmpd_api.h
+++ b/intern/softbody/admmpd_api.h
@@ -29,40 +29,40 @@ extern "C" {
#endif
typedef struct ADMMPDInterfaceData {
- float *in_verts;
- float *in_vel;
- unsigned int *in_faces;
- int in_totfaces;
- int in_totverts;
- // Num output verts might be different than num input verts.
+ // totverts is usually different than mesh_totverts.
// This is due to the lattice/tetmesh that is generated
// in init. You can use them as input if reading from cache,
// as they will be copied to internal solver data before admmpd_solve.
- float *out_verts;
- float *out_vel;
- int out_totverts;
+ int totverts; // number of deformable verts (output)
+ int mesh_totverts; // number of surface mesh vertices (input)
+ int mesh_totfaces; // number of surface mesh faces (input)
// Solver data used internally
struct ADMMPDInternalData *data;
} ADMMPDInterfaceData;
-// Allocates ADMMPDInterfaceData, using in_totfaces and in_totverts.
-// Does not allocate solver data, which is created on admmpd_init
-void admmpd_alloc(ADMMPDInterfaceData*);
+// SoftBody bodypoint (contains pos,vec)
+typedef struct BodyPoint BodyPoint;
// Clears all solver data and ADMMPDInterfaceData
void admmpd_dealloc(ADMMPDInterfaceData*);
// Initializes solver and allocates internal data
-int admmpd_init(ADMMPDInterfaceData*);
+int admmpd_init(ADMMPDInterfaceData*, float *in_verts, unsigned int *in_faces);
+
+// Copies BodyPoint data (from SoftBody)
+// to internal vertex position and velocity
+void admmpd_copy_from_bodypoint(ADMMPDInterfaceData*, const BodyPoint *pts);
+
+// Copies internal vertex position and velocity data
+// to BodyPoints (from SoftBody) AND surface mesh vertices.
+// If pts or vertexCos is null, its skipped
+void admmpd_copy_to_bodypoint_and_object(ADMMPDInterfaceData*, BodyPoint *pts, float (*vertexCos)[3]);
// Copies out_verts and out_verts to internal data
// Performs solve over the time step
// Copies internal data to out_verts and out_vel
void admmpd_solve(ADMMPDInterfaceData*);
-// Copies ADMMPDInterfaceData::out_ to vertexCos
-void admmpd_get_vertices(ADMMPDInterfaceData*, float (*vertexCos)[3], int numVerts);
-
#ifdef __cplusplus
}
#endif
diff --git a/intern/tetgen/tetgen_api.cpp b/intern/tetgen/tetgen_api.cpp
index 50b8201caac..33115411d82 100644
--- a/intern/tetgen/tetgen_api.cpp
+++ b/intern/tetgen/tetgen_api.cpp
@@ -101,14 +101,14 @@ static void make_tetgenio(
bool tetgen_resmesh(TetGenRemeshData *tg)
{
// float maxvol = compute_maxvol(tg->in_verts, tg->in_faces, tg->in_totfaces);
-// float quality = 1.4;
+ float quality = 1.4;
// Set up the switches
std::stringstream switches;
// switches << "Q"; // quiet
// switches << "a" << maxvol;
-// if (quality>0)
-// switches << "q" << quality;
+ if (quality>0)
+ switches << "q" << quality;
tetgenio in;