diff options
author | over0219 <over0219@umn.edu> | 2020-06-10 02:13:56 +0300 |
---|---|---|
committer | over0219 <over0219@umn.edu> | 2020-06-10 02:13:56 +0300 |
commit | 9819c3576cdce6c5f9efca1a821997a856ad66d7 (patch) | |
tree | eb64726c94c866c1c2f549d16e95072a61d29c11 /intern | |
parent | 5128d86a6f587bd49eaf2207c7b1d5c67b1ff728 (diff) |
working on interface
Diffstat (limited to 'intern')
-rw-r--r-- | intern/softbody/CMakeLists.txt | 3 | ||||
-rw-r--r-- | intern/softbody/admmpd_api.cpp | 225 | ||||
-rw-r--r-- | intern/softbody/admmpd_api.h | 39 | ||||
-rw-r--r-- | intern/tetgen/tetgen_api.cpp | 1 |
4 files changed, 185 insertions, 83 deletions
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_freeN(iface->out_vel); + + if (iface->data) + { + if(iface->data->options) + delete iface->data->options; + if(iface->data->data) + delete iface->data->data; + delete iface->data; + } + + iface->data = NULL; + iface->in_verts = NULL; + iface->in_vel = NULL; + iface->in_faces = NULL; + iface->out_verts = NULL; +} + +int admmpd_init(ADMMPDInterfaceData *iface) +{ + if (iface==NULL) + return 0; + if (iface->in_verts==NULL || iface->in_vel==NULL || iface->in_faces==NULL) + return 0; + if (iface->in_totverts<=0 || iface->in_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; + bool success = tetgen_resmesh(&tg); + if (!success || tg.out_tottets==0) + return 0; + + // Resize data + iface->out_totverts = tg.out_totverts; + 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_verts"); + + // Create initializer for ADMMPD + int nv = tg.out_totverts; + int nt = tg.out_tottets; + Eigen::MatrixXd V(nv,3); + Eigen::MatrixXi T(nt,4); V.setZero(); - for (int i = 0; i < numVerts; ++i) + for (int i=0; i<nv; ++i) { - BodyPoint &bpi = bp[i]; - V(i,0) = bpi.pos[0]; - V(i,1) = bpi.pos[1]; - V(i,2) = bpi.pos[2]; + 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(); + for (int i=0; i<nt; ++i) + { + T(i,0) = tg.out_tets[i*4+0]; + T(i,1) = tg.out_tets[i*4+1]; + T(i,2) = tg.out_tets[i*4+2]; + T(i,3) = tg.out_tets[i*4+3]; } - // Generate a mapping from x -> V - // Usually, dim(x) < dim(V) - Eigen::MatrixXd x; - Eigen::MatrixXi T; - lattice->generate(V, &x, &T); + // Generate solver data + iface->data = new ADMMPDInternalData(); + iface->data->options = new admmpd::Options(); + admmpd::Options *options = iface->data->options; + iface->data->data = new admmpd::Data(); + admmpd::Data *data = iface->data->data; + // Initialize + bool init_success = false; try { - admmpd::Solver().init(x, T, options, data); + init_success = admmpd::Solver().init(V, T, options, data); } catch(const std::exception &e) { printf("**ADMMPD Error on init: %s\n", e.what()); - // Should probably return nullptr } - return admmpd_data; + // Clean up tetgen data + MEM_freeN(tg.out_tets); + MEM_freeN(tg.out_facets); + MEM_freeN(tg.out_verts); + return int(init_success); } -void admmpd_cleanup(ADMMPD_Data *admmpd_data) +int admmpd_cache_valid(ADMMPDInterfaceData *iface, int numVerts) { - if (!admmpd_data) - return; - - delete admmpd_data->data; - delete admmpd_data->options; - delete admmpd_data->lattice; - delete admmpd_data; + if (iface == NULL) // we haven't initialized yet + return true; + + return iface->in_totverts == numVerts; } -void admmpd_solve(ADMMPD_Data *admmpd_data) +void admmpd_solve(ADMMPDInterfaceData *iface) { + if (iface == NULL) + return; + try { - admmpd::Solver().solve(admmpd_data->options,admmpd_data->data); + admmpd::Solver().solve(iface->data->options,iface->data->data); + for (int i=0; i<iface->data->data->x.rows(); ++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); + } + } } catch(const std::exception &e) { @@ -102,35 +198,24 @@ void admmpd_solve(ADMMPD_Data *admmpd_data) } } -void admmpd_to_bodypoint( - ADMMPD_Data* data, - BodyPoint *bp, - int numVerts) +void admmpd_map_vertices(ADMMPDInterfaceData *iface, float (*vertexCos)[3], int numVerts) { - if (!data || !bp) - { - printf("DATA OR BP NULL!?\n"); + if (iface == NULL) return; - } - if (!data->data || !data->lattice) + if (numVerts != iface->in_totverts || numVerts > iface->out_totverts) + { + printf("**ADMMPD TODO: PROPER VERTEX MAPPINGS\n"); return; - - // Map x -> BodyPoint - // Usually, dim(x) < dim(V) + } + // 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) { - BodyPoint &bpi = bp[i]; - Eigen::Vector3d xi = data->lattice->get_mapped_vertex( - i, &data->data->x, &data->data->tets); - Eigen::Vector3d vi = data->lattice->get_mapped_vertex( - i, &data->data->v, &data->data->tets); - bpi.pos[0] = xi[0]; - bpi.pos[1] = xi[1]; - bpi.pos[2] = xi[2]; - bpi.vec[0] = vi[0]; // vec is velocity? - bpi.vec[1] = vi[1]; - bpi.vec[2] = vi[2]; + 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]; } - -} // end map to object
\ No newline at end of file +}
\ No newline at end of file diff --git a/intern/softbody/admmpd_api.h b/intern/softbody/admmpd_api.h index c43f0b62375..bcfe37403c0 100644 --- a/intern/softbody/admmpd_api.h +++ b/intern/softbody/admmpd_api.h @@ -28,23 +28,38 @@ extern "C" { #endif -typedef struct ADMMPD_Data ADMMPD_Data; -typedef struct Object Object; -typedef struct BodyPoint BodyPoint; +//typedef struct Mesh Mesh_; -ADMMPD_Data* admmpd_init( - BodyPoint *bp, - int numVerts); +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. + // This is due to the lattice/tetmesh that is generated + // in init. They need to be cached by the system + float *out_verts; + float *out_vel; + int out_totverts; + // Solver data used internally + struct ADMMPDInternalData *data; +} ADMMPDInterfaceData; -void admmpd_cleanup(ADMMPD_Data*); +void admmpd_alloc(ADMMPDInterfaceData*, int in_verts, int in_faces); +void admmpd_dealloc(ADMMPDInterfaceData*); +int admmpd_init(ADMMPDInterfaceData*); +int admmpd_cache_valid(ADMMPDInterfaceData*, int numVerts); +void admmpd_solve(ADMMPDInterfaceData*); +void admmpd_map_vertices(ADMMPDInterfaceData*, float (*vertexCos)[3], int numVerts); -void admmpd_solve(ADMMPD_Data*); +//void admmpd_solve(ADMMPDInterfaceData*); // Copies the results of the solve (pos, vel) into BodyPoint -void admmpd_to_bodypoint( - ADMMPD_Data *data, - BodyPoint *bp, - int numVerts); +//void admmpd_to_bodypoint( +// ADMMPD_Data *data, +// BodyPoint *bp, +// int numVerts); #ifdef __cplusplus } diff --git a/intern/tetgen/tetgen_api.cpp b/intern/tetgen/tetgen_api.cpp index c2edcfd650f..16d403975a0 100644 --- a/intern/tetgen/tetgen_api.cpp +++ b/intern/tetgen/tetgen_api.cpp @@ -100,7 +100,6 @@ static void make_tetgenio( bool tetgen_resmesh(TetGenRemeshData *tg) { - printf("\n\n\n\nCALLING TETGEN\n"); // float maxvol = compute_maxvol(tg->in_verts, tg->in_faces, tg->in_totfaces); // float quality = 1.4; |