[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [61014] branches/soc-2013-sketch_mesh/ source/blender/modifiers/intern/MOD_laplaciandeform.c: The Laplacian deform eliminates the uses of BMesh .
Alexander Pinzon
apinzonf at gmail.com
Wed Oct 30 23:03:59 CET 2013
Revision: 61014
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=61014
Author: apinzonf
Date: 2013-10-30 22:03:59 +0000 (Wed, 30 Oct 2013)
Log Message:
-----------
The Laplacian deform eliminates the uses of BMesh .
The system now supports NGons
Modified Paths:
--------------
branches/soc-2013-sketch_mesh/source/blender/modifiers/intern/MOD_laplaciandeform.c
Modified: branches/soc-2013-sketch_mesh/source/blender/modifiers/intern/MOD_laplaciandeform.c
===================================================================
--- branches/soc-2013-sketch_mesh/source/blender/modifiers/intern/MOD_laplaciandeform.c 2013-10-30 21:16:13 UTC (rev 61013)
+++ branches/soc-2013-sketch_mesh/source/blender/modifiers/intern/MOD_laplaciandeform.c 2013-10-30 22:03:59 UTC (rev 61014)
@@ -29,11 +29,13 @@
*/
#include "DNA_meshdata_types.h"
+#include "DNA_mesh_types.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
#include "BLI_string.h"
#include "BLI_array.h"
#include "MEM_guardedalloc.h"
+#include "BKE_Mesh.h"
#include "BKE_cdderivedmesh.h"
#include "BKE_particle.h"
#include "BKE_deform.h"
@@ -46,6 +48,11 @@
#include "MOD_util.h"
#include "ONL_opennl.h"
+#define LAPDEFORM_SYSTEM_NOT_CHANGE 0
+#define LAPDEFORM_SYSTEM_IS_DIFFERENT 1
+#define LAPDEFORM_SYSTEM_ONLY_CHANGE_ANCHORS 2
+#define LAPDEFORM_SYSTEM_ONLY_CHANGE_GROUP 3
+
typedef struct LaplacianSystem {
bool is_matrix_computed;
bool has_solution;
@@ -59,9 +66,13 @@
float (*delta)[3]; /* Differential Coordinates*/
int *index_anchors; /* Static vertex index list*/
int *unit_verts; /* Unit vectors of projected edges onto the plane orthogonal to n*/
- BMVert **verts; /* Vertex order by index*/
- BMesh *bm; /* Bmesh structure pointer*/
+ int *ringf_indices; /* Indices of faces per vertex*/
+ int *ringv_indices; /* Indices of neighbors(vertex) per vertex*/
+ Mesh *me; /* Mesh structure pointer*/
NLContext *context; /* System for solve general implicit rotations*/
+ MeshElemMap *ringf_map; /* Map of faces per vertex*/
+ MeshElemMap *ringv_map; /* Map of vertex per vertex*/
+
} LaplacianSystem;
static LaplacianSystem *newLaplacianSystem(void)
@@ -83,9 +94,11 @@
sys->delta = NULL;
sys->index_anchors = NULL;
sys->unit_verts = NULL;
- sys->verts = NULL;
- sys->bm = NULL;
+ sys->ringf_indices = NULL;
+ sys->ringv_indices = NULL;
sys->context = NULL;
+ sys->ringf_map = NULL;
+ sys->ringv_map = NULL;
return sys;
}
@@ -108,7 +121,6 @@
sys->delta = (float (*)[3]) MEM_callocN(sizeof(float[3]) * totalVerts, "DeformDeltas");
sys->index_anchors = (int *) MEM_callocN(sizeof(int) * (totalAnchors), "DeformAnchors");
sys->unit_verts = (int *) MEM_callocN(sizeof(int) * totalVerts, "DeformUnitVerts");
- sys->verts = (BMVert**) MEM_callocN(sizeof(BMVert*) * (totalVerts), "DeformVerts");
return sys;
}
@@ -122,10 +134,10 @@
MEM_SAFE_FREE(sys->delta);
MEM_SAFE_FREE(sys->index_anchors);
MEM_SAFE_FREE(sys->unit_verts);
- MEM_SAFE_FREE(sys->verts);
- if (sys->bm) {
- BM_mesh_free(sys->bm);
- }
+ MEM_SAFE_FREE(sys->ringf_indices);
+ MEM_SAFE_FREE(sys->ringv_indices);
+ MEM_SAFE_FREE(sys->ringf_map);
+ MEM_SAFE_FREE(sys->ringv_map);
if (sys->context) {
nlDeleteContext(sys->context);
}
@@ -147,6 +159,84 @@
return dot_v3v3(a, b) / clen;
}
+static void createFaceRingMap(MeshElemMap **r_map, int **r_indices, Mesh *me)
+{
+ MeshElemMap *map = MEM_callocN(sizeof(MeshElemMap) * (size_t)me->totvert, "DeformRingMap");
+ int i, j, vid[4], has_4_vert, totalr = 0;
+ int *indices, *index_iter;
+ MFace *f;
+
+ for (i = 0; i < me->totface; i++) {
+ f = &me->mface[i];
+ has_4_vert = f->v4 ? 1 : 0;
+ vid[0] = f->v1;
+ vid[1] = f->v2;
+ vid[2] = f->v3;
+ vid[3] = has_4_vert ? f->v4 : 0;
+ for (j = 0; j < (has_4_vert ? 4 : 3); j++ ) {
+ map[vid[j]].count++;
+ totalr++;
+ }
+ }
+ indices = MEM_callocN(sizeof(int) * totalr, "DeformRingIndex");
+ index_iter = indices;
+ for (i = 0; i < me->totvert; i++) {
+ map[i].indices = index_iter;
+ index_iter += map[i].count;
+ map[i].count = 0;
+ }
+
+ for (i = 0; i < me->totface; i++) {
+ f = &me->mface[i];
+ has_4_vert = f->v4 ? 1 : 0;
+ vid[0] = f->v1;
+ vid[1] = f->v2;
+ vid[2] = f->v3;
+ vid[3] = has_4_vert ? f->v4 : 0;
+ for (j = 0; j < (has_4_vert ? 4 : 3); j++ ) {
+ map[vid[j]].indices[map[vid[j]].count] = i;
+ map[vid[j]].count++;
+ }
+ }
+
+ *r_map = map;
+ *r_indices = indices;
+}
+
+static void createVertexRingMap(MeshElemMap **r_map, int **r_indices, Mesh *me)
+{
+ MeshElemMap *map = MEM_callocN(sizeof(MeshElemMap) * (size_t)me->totvert, "DeformNeighborsMap");
+ int i, vid[2], totalr = 0;
+ int *indices, *index_iter;
+ MEdge *e;
+ for (i = 0; i < me->totedge; i++) {
+ e = &me->medge[i];
+ vid[0] = e->v1;
+ vid[1] = e->v2;
+ map[vid[0]].count++;
+ map[vid[1]].count++;
+ totalr += 2;
+ }
+ indices = MEM_callocN(sizeof(int) * totalr, "DeformNeighborsIndex");
+ index_iter = indices;
+ for (i = 0; i < me->totvert; i++) {
+ map[i].indices = index_iter;
+ index_iter += map[i].count;
+ map[i].count = 0;
+ }
+ for (i = 0; i < me->totedge; i++) {
+ e = &me->medge[i];
+ vid[0] = e->v1;
+ vid[1] = e->v2;
+ map[vid[0]].indices[map[vid[0]].count] = vid[1];
+ map[vid[0]].count++;
+ map[vid[1]].indices[map[vid[1]].count] = vid[0];
+ map[vid[1]].count++;
+ }
+ *r_map = map;
+ *r_indices = indices;
+}
+
/**
* This method computes the Laplacian Matrix and Differential Coordinates for all vertex in the mesh.
* The Linear system is LV = d
@@ -179,21 +269,19 @@
{
float v1[3], v2[3], v3[3], v4[3], no[3];
float w2, w3, w4;
- int i, j, vid, vidf[4];
+ int i, j, vidf[4], fi;
bool has_4_vert;
unsigned int idv1, idv2, idv3, idv4, idv[4];
- BMFace *f;
- BMIter fiter;
- BMIter vi;
- BMVert *vn;
+ MFace *f;
- BM_ITER_MESH (f, &fiter, sys->bm, BM_FACES_OF_MESH) {
-
- BM_ITER_ELEM_INDEX (vn, &vi, f, BM_VERTS_OF_FACE, i) {
- vid = BM_elem_index_get(vn);
- vidf[i] = vid;
- }
- has_4_vert = (i == 4) ? 1 : 0;
+ for (fi = 0; fi < sys->me->totface; fi++) {
+ f = &sys->me->mface[fi];
+ vidf[0] = f->v1;
+ vidf[1] = f->v2;
+ vidf[2] = f->v3;
+ vidf[3] = f->v4 ? f->v4 : 0;
+
+ has_4_vert = f->v4 ? 1 : 0;
idv1 = vidf[0];
idv2 = vidf[1];
idv3 = vidf[2];
@@ -201,9 +289,11 @@
if (has_4_vert) {
normal_quad_v3(no, sys->co[idv1], sys->co[idv2], sys->co[idv3], sys->co[idv4]);
add_v3_v3(sys->no[idv4], no);
+ i = 4;
}
else {
normal_tri_v3(no, sys->co[idv1], sys->co[idv2], sys->co[idv3]);
+ i = 3;
}
add_v3_v3(sys->no[idv1], no);
add_v3_v3(sys->no[idv2], no);
@@ -272,32 +362,15 @@
static void computeImplictRotations(LaplacianSystem *sys)
{
- BMEdge *e;
- BMIter eiter;
- BMIter viter;
- BMVert *v;
int vid, * vidn = NULL;
float minj, mjt, qj[3], vj[3];
int i, j, ln;
- BLI_array_declare(vidn);
-
- BM_ITER_MESH (v, &viter, sys->bm, BM_VERTS_OF_MESH) {
- i = BM_elem_index_get(v);
+ for (i = 0; i < sys->total_verts; i++) {
normalize_v3(sys->no[i]);
- BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
- vid = BM_elem_index_get(e->v1);
- if (vid == i) {
- vid = BM_elem_index_get(e->v2);
- BLI_array_append(vidn, vid);
- }
- else {
- BLI_array_append(vidn, vid);
- }
- }
- BLI_array_append(vidn, i);
- ln = BLI_array_count(vidn);
+ vidn = sys->ringv_map[i].indices;
+ ln = sys->ringv_map[i].count;
minj = 1000000.0f;
- for (j = 0; j < ln - 1; j++) {
+ for (j = 0; j < ln; j++) {
vid = vidn[j];
copy_v3_v3(qj, sys->co[vid]);
sub_v3_v3v3(vj, qj, sys->co[i]);
@@ -308,24 +381,18 @@
sys->unit_verts[i] = vidn[j];
}
}
- BLI_array_empty(vidn);
}
- BLI_array_free(vidn);
}
static void rotateDifferentialCoordinates(LaplacianSystem *sys)
{
- BMFace *f;
- BMVert *v, *v2;
- BMIter fiter;
- BMIter viter, viter2;
float alpha, beta, gamma,
pj[3], ni[3], di[3],
uij[3], dun[3], e2[3], pi[3], fni[3], vn[4][3];
- int i, j, vin[4], lvin, num_fni, k;
+ int i, j, vin[4], lvin, num_fni, k, fi;
+ int *fidn;
-
- BM_ITER_MESH_INDEX (v, &viter, sys->bm, BM_VERTS_OF_MESH, i) {
+ for (i = 0; i < sys->total_verts; i++) {
copy_v3_v3(pi, sys->co[i]);
copy_v3_v3(ni, sys->no[i]);
k = sys->unit_verts[i];
@@ -345,11 +412,14 @@
pi[2] = nlGetVariable(2, i);
ni[0] = 0.0f; ni[1] = 0.0f; ni[2] = 0.0f;
num_fni = 0;
- BM_ITER_ELEM_INDEX (f, &fiter, v, BM_FACES_OF_VERT, num_fni) {
- BM_ITER_ELEM_INDEX (v2, &viter2, f, BM_VERTS_OF_FACE, j) {
- vin[j] = BM_elem_index_get(v2);
- }
- lvin = j;
+ num_fni = sys->ringf_map[i].count;
+ for (fi = 0; fi < num_fni; fi++) {
+ fidn = sys->ringf_map[i].indices;
+ vin[0] = sys->me->mface[fidn[fi]].v1;
+ vin[1] = sys->me->mface[fidn[fi]].v2;
+ vin[2] = sys->me->mface[fidn[fi]].v3;
+ vin[3] = sys->me->mface[fidn[fi]].v4 ? sys->me->mface[fidn[fi]].v4 : 0;
+ lvin = sys->me->mface[fidn[fi]].v4 ? 4 : 3;
for (j = 0; j < lvin; j++) {
vn[j][0] = nlGetVariable(0, vin[j]);
vn[j][1] = nlGetVariable(1, vin[j]);
@@ -398,7 +468,6 @@
na = sys->total_anchors;
if (!sys->is_matrix_computed) {
-
nlNewContext();
sys->context = nlGetCurrent();
@@ -416,9 +485,9 @@
}
for (i = 0; i < na; i++) {
vid = sys->index_anchors[i];
- nlSetVariable(0, vid, sys->verts[vid]->co[0]);
- nlSetVariable(1, vid, sys->verts[vid]->co[1]);
- nlSetVariable(2, vid, sys->verts[vid]->co[2]);
+ nlSetVariable(0, vid, sys->me->mvert[vid].co[0]);
+ nlSetVariable(1, vid, sys->me->mvert[vid].co[1]);
+ nlSetVariable(2, vid, sys->me->mvert[vid].co[2]);
}
nlBegin(NL_MATRIX);
@@ -441,7 +510,6 @@
nlEnd(NL_MATRIX);
nlEnd(NL_SYSTEM);
-
if (nlSolveAdvanced(NULL, NL_TRUE)) {
sys->has_solution = true;
@@ -504,7 +572,6 @@
nlEnd(NL_MATRIX);
nlEnd(NL_SYSTEM);
-
if (nlSolveAdvanced(NULL, NL_FALSE)) {
sys->has_solution = true;
for (j = 1; j <= sys->repeat; j++) {
@@ -556,27 +623,25 @@
static void initSystem(LaplacianDeformModifierData *smd, Object *ob, DerivedMesh *dm,
float (*vertexCos)[3], int numVerts)
{
- int i, vertID;
+ int i;
int defgrp_index;
int total_anchors;
int * index_anchors = NULL;
float wpaint;
- BMIter viter;
- BMVert *v;
- BMesh *bm;
+ Mesh *me;
MDeformVert *dvert = NULL;
MDeformVert *dv = NULL;
LaplacianSystem *sys;
BLI_array_declare(index_anchors);
-
if (isValidVertexGroup(smd, ob, dm)) {
modifier_get_vgroup(ob, dm, smd->anchor_grp_name, &dvert, &defgrp_index);
if (!dvert) {
return;
}
dv = dvert;
- bm = DM_to_bmesh(dm, false);
+ me = ob->data;
+ BKE_mesh_tessface_ensure(me);
for (i = 0; i < numVerts; i++) {
wpaint = defvert_find_weight(dv, defgrp_index);
dv++;
@@ -585,24 +650,21 @@
}
}
total_anchors = BLI_array_count(index_anchors);
- smd->cacheSystem = initLaplacianSystem(numVerts, bm->totedge, total_anchors, smd->anchor_grp_name, smd->repeat);
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list