diff options
author | over0219 <over0219@umn.edu> | 2020-06-16 02:30:34 +0300 |
---|---|---|
committer | over0219 <over0219@umn.edu> | 2020-06-16 02:30:34 +0300 |
commit | adc3d113f248ca036fcb8e530aba31edc24cb5f2 (patch) | |
tree | ca23ecd99bf4984cab09ece462020343c5fae683 /intern | |
parent | 4ff3bb13e35fb190c8510bf4daa7ded0a0c3b777 (diff) |
improved API for less for-all-verts loops
Diffstat (limited to 'intern')
-rw-r--r-- | intern/softbody/admmpd_api.cpp | 154 | ||||
-rw-r--r-- | intern/softbody/admmpd_api.h | 32 | ||||
-rw-r--r-- | intern/tetgen/tetgen_api.cpp | 6 |
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; |