Initial changes to the remesher.

This commit is contained in:
2015-04-07 05:02:54 +02:00
parent fcbf92eb10
commit 2cd0a07e34
3 changed files with 795 additions and 1116 deletions

View File

@@ -43,59 +43,13 @@
#ifdef WITH_OPENNL
static LaplacianSystem *newLaplacianSystem(void)
{
LaplacianSystem *sys;
sys = MEM_callocN(sizeof(LaplacianSystem), "QuadRemeshCache");
sys->command_compute_flow = false;
sys->has_solution = false;
sys->total_verts = 0;
sys->total_edges = 0;
sys->total_features = 0;
sys->total_faces = 0;
sys->total_gflines = 0;
sys->total_gfverts = 0;
sys->features_grp_name[0] = '\0';
return sys;
}
static LaplacianSystem *initLaplacianSystem(int totalVerts, int totalEdges, int totalFaces, int totalFeatures,
const char defgrpName[64])
{
LaplacianSystem *sys = newLaplacianSystem();
sys->command_compute_flow = false;
sys->has_solution = false;
sys->total_verts = totalVerts;
sys->total_edges = totalEdges;
sys->total_faces = totalFaces;
sys->total_features = totalFeatures;
BLI_strncpy(sys->features_grp_name, defgrpName, sizeof(sys->features_grp_name));
sys->faces = MEM_mallocN(sizeof(int[4]) * totalFaces, "QuadRemeshFaces");
sys->edges = MEM_mallocN(sizeof(int[2]) * totalEdges, "QuadRemeshEdges");
sys->faces_edge = MEM_mallocN(sizeof(int[2]) * totalEdges, "QuadRemeshFacesEdge");
sys->co = MEM_mallocN(sizeof(float[3]) * totalVerts, "QuadRemeshCoordinates");
sys->no = MEM_callocN(sizeof(float[3]) * totalFaces, "QuadRemeshNormals");
sys->gf1 = MEM_mallocN(sizeof(float[3]) * totalFaces, "QuadRemeshGradientField1");
sys->gf2 = MEM_mallocN(sizeof(float[3]) * totalFaces, "QuadRemeshGradientField2");
sys->constraints = MEM_mallocN(sizeof(int) * totalVerts, "QuadRemeshConstraints");
sys->weights = MEM_mallocN(sizeof(float)* (totalVerts), "QuadRemeshWeights");
sys->U_field = MEM_mallocN(sizeof(float)* (totalVerts), "QuadRemeshUField");
sys->h1 = MEM_mallocN(sizeof(float)* (totalVerts), "QuadRemeshH1");
sys->h2 = MEM_mallocN(sizeof(float)* (totalVerts), "QuadRemeshH2");
sys->gfsys = NULL;
return sys;
}
static void deleteLaplacianSystem(LaplacianSystem *sys)
{
deleteGradientFlowSystem(sys->gfsys1);
MEM_SAFE_FREE(sys->faces);
MEM_SAFE_FREE(sys->edges);
MEM_SAFE_FREE(sys->faces_edge);
MEM_SAFE_FREE(sys->co);
MEM_SAFE_FREE(sys->cogfl);
MEM_SAFE_FREE(sys->no);
MEM_SAFE_FREE(sys->constraints);
MEM_SAFE_FREE(sys->weights);
@@ -116,116 +70,92 @@ static void deleteLaplacianSystem(LaplacianSystem *sys)
MEM_SAFE_FREE(sys);
}
static void createFaceRingMap(
const int mvert_tot, const MFace *mface, const int mface_tot,
MeshElemMap **r_map, int **r_indices)
static void createFaceRingMap(LaplacianSystem *sys)
{
int i, j, totalr = 0;
int *indices, *index_iter;
MeshElemMap *map = MEM_callocN(sizeof(MeshElemMap)* mvert_tot, "DeformRingMap");
const MFace *mf;
int *index_iter;
for (i = 0, mf = mface; i < mface_tot; i++, mf++) {
bool has_4_vert;
sys->ringf_map = MEM_callocN(sizeof(MeshElemMap) * sys->total_verts, "DeformRingMap");
has_4_vert = mf->v4 ? 1 : 0;
for (j = 0; j < (has_4_vert ? 4 : 3); j++) {
const unsigned int v_index = (*(&mf->v1 + j));
map[v_index].count++;
for (i = 0; i < sys->total_faces; i++) {
for (j = 0; j < 3; j++) {
sys->ringf_map[sys->faces[i][j]].count++;
totalr++;
}
}
indices = MEM_callocN(sizeof(int)* totalr, "DeformRingIndex");
index_iter = indices;
for (i = 0; i < mvert_tot; i++) {
map[i].indices = index_iter;
index_iter += map[i].count;
map[i].count = 0;
sys->ringf_indices = MEM_callocN(sizeof(int) * totalr, "DeformRingIndex");
index_iter = sys->ringf_indices;
for (i = 0; i < sys->total_verts; i++) {
sys->ringf_map[i].indices = index_iter;
index_iter += sys->ringf_map[i].count;
sys->ringf_map[i].count = 0;
}
for (i = 0, mf = mface; i < mface_tot; i++, mf++) {
bool has_4_vert;
has_4_vert = mf->v4 ? 1 : 0;
for (j = 0; j < (has_4_vert ? 4 : 3); j++) {
const unsigned int v_index = (*(&mf->v1 + j));
map[v_index].indices[map[v_index].count] = i;
map[v_index].count++;
for (i = 0; i < sys->total_faces; i++) {
for (j = 0; j < 3; j++) {
MeshElemMap *map = &sys->ringf_map[sys->faces[i][j]];
map->indices[map->count++] = i;
}
}
*r_map = map;
*r_indices = indices;
}
static void createVertRingMap(
const int mvert_tot, const MEdge *medge, const int medge_tot,
MeshElemMap **r_map, int **r_indices)
static void createVertRingMap(LaplacianSystem *sys)
{
MeshElemMap *map = MEM_callocN(sizeof(MeshElemMap)* mvert_tot, "DeformNeighborsMap");
int i, vid[2], totalr = 0;
int *indices, *index_iter;
const MEdge *me;
int i, totalr = 0;
int *index_iter;
for (i = 0, me = medge; i < medge_tot; i++, me++) {
vid[0] = me->v1;
vid[1] = me->v2;
map[vid[0]].count++;
map[vid[1]].count++;
sys->ringv_map = MEM_callocN(sizeof(MeshElemMap) * sys->total_verts, "DeformNeighborsMap");
for (i = 0; i < sys->total_edges; i++) {
sys->ringv_map[sys->edges[i][0]].count++;
sys->ringv_map[sys->edges[i][1]].count++;
totalr += 2;
}
indices = MEM_callocN(sizeof(int)* totalr, "DeformNeighborsIndex");
index_iter = indices;
for (i = 0; i < mvert_tot; i++) {
map[i].indices = index_iter;
index_iter += map[i].count;
map[i].count = 0;
sys->ringv_indices = MEM_callocN(sizeof(int) * totalr, "DeformNeighborsIndex");
index_iter = sys->ringv_indices;
for (i = 0; i < sys->total_verts; i++) {
sys->ringv_map[i].indices = index_iter;
index_iter += sys->ringv_map[i].count;
sys->ringv_map[i].count = 0;
}
for (i = 0, me = medge; i < medge_tot; i++, me++) {
vid[0] = me->v1;
vid[1] = me->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++;
for (i = 0; i < sys->total_edges; i++) {
MeshElemMap *map1 = &sys->ringv_map[sys->edges[i][0]];
MeshElemMap *map2 = &sys->ringv_map[sys->edges[i][1]];
map1->indices[map1->count++] = sys->edges[i][1];
map2->indices[map2->count++] = sys->edges[i][0];
}
*r_map = map;
*r_indices = indices;
}
static void createEdgeRingMap(
const int mvert_tot, const MEdge *medge, const int medge_tot,
MeshElemMap **r_map, int **r_indices)
static void createEdgeRingMap(LaplacianSystem *sys)
{
MeshElemMap *map = MEM_callocN(sizeof(MeshElemMap)* mvert_tot, "DeformNeighborsMap");
int i, vid[2], totalr = 0;
int *indices, *index_iter;
const MEdge *me;
int i, totalr = 0;
int *index_iter;
for (i = 0, me = medge; i < medge_tot; i++, me++) {
vid[0] = me->v1;
vid[1] = me->v2;
map[vid[0]].count++;
map[vid[1]].count++;
sys->ringe_map = MEM_callocN(sizeof(MeshElemMap) * sys->total_verts, "DeformNeighborsMap");
for (i = 0; i < sys->total_edges; i++) {
sys->ringe_map[sys->edges[i][0]].count++;
sys->ringe_map[sys->edges[i][1]].count++;
totalr += 2;
}
indices = MEM_callocN(sizeof(int)* totalr, "DeformNeighborsIndex");
index_iter = indices;
for (i = 0; i < mvert_tot; i++) {
map[i].indices = index_iter;
index_iter += map[i].count;
map[i].count = 0;
sys->ringe_indices = MEM_callocN(sizeof(int) * totalr, "DeformNeighborsIndex");
index_iter = sys->ringe_indices;
for (i = 0; i < sys->total_verts; i++) {
sys->ringe_map[i].indices = index_iter;
index_iter += sys->ringe_map[i].count;
sys->ringe_map[i].count = 0;
}
for (i = 0, me = medge; i < medge_tot; i++, me++) {
vid[0] = me->v1;
vid[1] = me->v2;
map[vid[0]].indices[map[vid[0]].count] = i;
map[vid[0]].count++;
map[vid[1]].indices[map[vid[1]].count] = i;
map[vid[1]].count++;
for (i = 0; i < sys->total_edges; i++) {
MeshElemMap *map1 = &sys->ringe_map[sys->edges[i][0]];
MeshElemMap *map2 = &sys->ringe_map[sys->edges[i][1]];
map1->indices[map1->count++] = i;
map2->indices[map2->count++] = i;
}
*r_map = map;
*r_indices = indices;
}
static void computeFacesAdjacentToEdge(int fs[2], LaplacianSystem *sys, int indexe)
@@ -266,20 +196,25 @@ static void createFacesByEdge(LaplacianSystem *sys){
static void computeSampleDistanceFunctions(LaplacianSystem *sys, float user_h, float user_alpha) {
int i, j, *fin, lin;
float avg1[3], avg2[3], no[3], k1, k2, h1, h2;
for (i = 0; i < sys->total_verts; i++) {
zero_v3(avg1);
zero_v3(avg2);
fin = sys->ringf_map[i].indices;
lin = sys->ringf_map[i].count;
for (j = 0; j < lin; j++) {
add_v3_v3(avg1, sys->gf1[j]);
add_v3_v3(avg2, sys->gf2[j]);
}
mul_v3_fl(avg1, 1.0f / ((float)lin));
mul_v3_fl(avg2, 1.0f / ((float)lin));
copy_v3_v3(no, sys->no[i]);
mul_v3_fl(no, 2.0f);
k1 = dot_v3v3(no, avg1) / dot_v3v3(avg1, avg1);
k2 = dot_v3v3(no, avg2) / dot_v3v3(avg2, avg2);
@@ -293,11 +228,10 @@ static void computeSampleDistanceFunctions(LaplacianSystem *sys, float user_h, f
static void initLaplacianMatrix(LaplacianSystem *sys)
{
float v1[3], v2[3], v3[3], v4[3], no[3];
float w2, w3, w4;
int i, j, fi;
bool has_4_vert;
unsigned int idv1, idv2, idv3, idv4;
float v1[3], v2[3], v3[3], no[3];
float w2, w3;
int j, fi;
unsigned int idv1, idv2, idv3;
for (fi = 0; fi < sys->total_faces; fi++) {
const unsigned int *vidf = sys->faces[fi];
@@ -305,56 +239,29 @@ static void initLaplacianMatrix(LaplacianSystem *sys)
idv1 = vidf[0];
idv2 = vidf[1];
idv3 = vidf[2];
idv4 = vidf[3];
has_4_vert = vidf[3] ? 1 : 0;
if (has_4_vert) {
normal_quad_v3(no, sys->co[idv1], sys->co[idv2], sys->co[idv3], sys->co[idv4]);
i = 4;
}
else {
normal_tri_v3(no, sys->co[idv1], sys->co[idv2], sys->co[idv3]);
i = 3;
}
normal_tri_v3(no, sys->co[idv1], sys->co[idv2], sys->co[idv3]);
copy_v3_v3(sys->no[fi], no);
for (j = 0; j < i; j++) {
for (j = 0; j < 3; j++) {
idv1 = vidf[j];
idv2 = vidf[(j + 1) % i];
idv3 = vidf[(j + 2) % i];
idv4 = has_4_vert ? vidf[(j + 3) % i] : 0;
idv2 = vidf[(j + 1) % 3];
idv3 = vidf[(j + 2) % 3];
copy_v3_v3(v1, sys->co[idv1]);
copy_v3_v3(v2, sys->co[idv2]);
copy_v3_v3(v3, sys->co[idv3]);
if (has_4_vert) {
copy_v3_v3(v4, sys->co[idv4]);
}
if (has_4_vert) {
w2 = (cotangent_tri_weight_v3(v4, v1, v2) + cotangent_tri_weight_v3(v3, v1, v2)) / 2.0f;
w3 = (cotangent_tri_weight_v3(v2, v3, v1) + cotangent_tri_weight_v3(v4, v1, v3)) / 2.0f;
w4 = (cotangent_tri_weight_v3(v2, v4, v1) + cotangent_tri_weight_v3(v3, v4, v1)) / 2.0f;
if (sys->constraints[idv1] == 0) {
nlMatrixAdd(idv1, idv4, -w4);
}
}
else {
w2 = cotangent_tri_weight_v3(v3, v1, v2);
w3 = cotangent_tri_weight_v3(v2, v3, v1);
w4 = 0.0f;
}
w2 = cotangent_tri_weight_v3(v3, v1, v2);
w3 = cotangent_tri_weight_v3(v2, v3, v1);
if (sys->constraints[idv1] == 1) {
nlMatrixAdd(idv1, idv1, w2 + w3 + w4);
nlMatrixAdd(idv1, idv1, w2 + w3);
}
else {
nlMatrixAdd(idv1, idv2, -w2);
nlMatrixAdd(idv1, idv3, -w3);
nlMatrixAdd(idv1, idv1, w2 + w3 + w4);
nlMatrixAdd(idv1, idv1, w2 + w3);
}
}
@@ -366,32 +273,28 @@ static void computeScalarField(LaplacianSystem *sys)
{
int vid, i, n;
n = sys->total_verts;
printf("computeScalarField 0 \n");
#ifdef OPENNL_THREADING_HACK
modifier_opennl_lock();
#endif
printf("computeScalarField 1 \n");
nlNewContext();
sys->context = nlGetCurrent();
printf("computeScalarField 2 \n");
nlSolverParameteri(NL_NB_VARIABLES, n);
nlSolverParameteri(NL_SYMMETRIC, NL_FALSE);
nlSolverParameteri(NL_LEAST_SQUARES, NL_TRUE);
nlSolverParameteri(NL_NB_ROWS, n);
nlSolverParameteri(NL_NB_RIGHT_HAND_SIDES, 1);
nlBegin(NL_SYSTEM);
printf("computeScalarField 3 \n");
for (i = 0; i < n; i++) {
nlSetVariable(0, i, 0);
}
nlBegin(NL_MATRIX);
printf("computeScalarField 4 \n");
initLaplacianMatrix(sys);
printf("computeScalarField 5 \n");
for (i = 0; i < n; i++) {
if (sys->constraints[i] == 1) {
@@ -403,9 +306,8 @@ static void computeScalarField(LaplacianSystem *sys)
}
nlEnd(NL_MATRIX);
nlEnd(NL_SYSTEM);
printf("computeScalarField 6 \n");
if (nlSolveAdvanced(NULL, NL_TRUE)) {
printf("computeScalarField 7 \n");
sys->has_solution = true;
for (vid = 0; vid < sys->total_verts; vid++) {
@@ -464,7 +366,6 @@ static void computeGradientFields(LaplacianSystem * sys)
mul_v3_v3fl(u, sys->no[fi], val);
sub_v3_v3v3(w, g, u);
normalize_v3_v3(sys->gf1[fi], w);
cross_v3_v3v3(g, sys->no[fi], sys->gf1[fi]);
normalize_v3_v3(sys->gf2[fi], g);
@@ -501,87 +402,96 @@ static void uniformRandomPointWithinFace(float r[3], LaplacianSystem *sys, int i
uniformRandomPointWithinTriangle(r, sys->co[vin[0]], sys->co[vin[1]], sys->co[vin[2]]);
}
static LaplacianSystem * initSystem(QuadRemeshModifierData *qmd, Object *ob, DerivedMesh *dm,
float(*vertexCos)[3], int numVerts)
static LaplacianSystem* initSystem(QuadRemeshModifierData *qmd, Object *ob, DerivedMesh *dm)
{
int i, j;
int defgrp_index;
int total_features;
int i, defgrp_index;
float wpaint;
MDeformVert *dvert = NULL;
MDeformVert *dv = NULL;
LaplacianSystem *sys = NULL;
MDeformVert *dv = NULL, *d;
LaplacianSystem *sys = MEM_callocN(sizeof(LaplacianSystem), "QuadRemeshCache");
int *constraints = MEM_mallocN(sizeof(int)* numVerts, __func__);
float *weights = MEM_mallocN(sizeof(float)* numVerts, __func__);
MFace *tessface;
MEdge *arrayedge;
printf("initSystem 0\n");
modifier_get_vgroup(ob, dm, qmd->anchor_grp_name, &dvert, &defgrp_index);
printf("initSystem 1\n");
BLI_assert(dvert != NULL);
printf("initSystem 2\n");
dv = dvert;
j = 0;
for (i = 0; i < numVerts; i++) {
wpaint = defvert_find_weight(dv, defgrp_index);
dv++;
if (wpaint < 0.19 || wpaint > 0.89) {
constraints[i] = 1;
weights[i] = -1.0f + wpaint * 2.0f;
j++;
}
else {
constraints[i] = 0;
}
}
printf("initSystem 3\n");
total_features = j;
DM_ensure_tessface(dm);
sys = initLaplacianSystem(numVerts, dm->getNumEdges(dm), dm->getNumTessFaces(dm), total_features, qmd->anchor_grp_name);
printf("initSystem 4\n");
memcpy(sys->co, vertexCos, sizeof(float[3]) * numVerts);
memcpy(sys->constraints, constraints, sizeof(int)* numVerts);
memcpy(sys->weights, weights, sizeof(float)* numVerts);
MEM_freeN(weights);
MEM_freeN(constraints);
printf("initSystem 5\n");
createFaceRingMap(
dm->getNumVerts(dm), dm->getTessFaceArray(dm), dm->getNumTessFaces(dm),
&sys->ringf_map, &sys->ringf_indices);
createVertRingMap(
dm->getNumVerts(dm), dm->getEdgeArray(dm), dm->getNumEdges(dm),
&sys->ringv_map, &sys->ringv_indices);
createEdgeRingMap(
dm->getNumVerts(dm), dm->getEdgeArray(dm), dm->getNumEdges(dm),
&sys->ringe_map, &sys->ringe_indices);
tessface = dm->getTessFaceArray(dm);
for (i = 0; i < sys->total_faces; i++) {
memcpy(&sys->faces[i], &tessface[i].v1, sizeof(*sys->faces));
/* Get vertices */
sys->total_verts = dm->getNumVerts(dm);
sys->co = MEM_mallocN(sizeof(float[3]) * sys->total_verts, "QuadRemeshCoordinates");
MVert *arrayvect = dm->getVertArray(dm);
for (i = 0; i < dm->getNumVerts(dm); i++) {
copy_v3_v3(sys->co[i], arrayvect[i].co);
}
arrayedge = dm->getEdgeArray(dm);
for (i = 0; i < sys->total_edges; i++) {
memcpy(&sys->edges[i], &arrayedge[i].v1, sizeof(*sys->edges));
/* Get edges */
sys->edges = MEM_mallocN(sizeof(int[2]) * dm->getNumEdges(dm) * 2, "QuadRemeshEdges");
MEdge *arrayedge = dm->getEdgeArray(dm);
for (sys->total_edges = 0, i = 0; i < dm->getNumEdges(dm); i++) {
sys->edges[sys->total_edges][0] = arrayedge[i].v1;
sys->edges[sys->total_edges][1] = arrayedge[i].v2;
sys->total_edges++;
}
/* Get faces */
MFace *tessface = dm->getTessFaceArray(dm);
sys->faces = MEM_mallocN(sizeof(int[3]) * dm->getNumTessFaces(dm) * 2, "QuadRemeshFaces");
for (sys->total_faces = 0, i = 0; i < dm->getNumTessFaces(dm); i++) {
sys->faces[sys->total_faces][0] = tessface[i].v1;
sys->faces[sys->total_faces][1] = tessface[i].v2;
sys->faces[sys->total_faces][2] = tessface[i].v3;
sys->total_faces++;
if (tessface[i].v4 != 0) {
sys->faces[sys->total_faces][0] = tessface[i].v1;
sys->faces[sys->total_faces][1] = tessface[i].v3;
sys->faces[sys->total_faces][2] = tessface[i].v4;
sys->total_faces++;
sys->edges[sys->total_edges][0] = tessface[i].v1;
sys->edges[sys->total_edges][1] = tessface[i].v3;
sys->total_edges++;
}
}
/* Get features */
sys->constraints = MEM_callocN(sizeof(int) * sys->total_verts, __func__);
sys->weights = MEM_callocN(sizeof(float) * sys->total_verts, __func__);
modifier_get_vgroup(ob, dm, qmd->anchor_grp_name, &dvert, &defgrp_index);
BLI_assert(dvert != NULL);
dv = dvert;
for (i = 0, sys->total_features = 0; i < sys->total_verts; i++, dv++) {
d = defvert_find_index(dv, defgrp_index);
wpaint = defvert_find_weight(dv, defgrp_index);
if (d && wpaint < 0.19 || wpaint > 0.89) {
sys->constraints[i] = 1;
sys->weights[i] = -1.0f + wpaint * 2.0f;
sys->total_features++;
}
}
/* Allocate rest of memory */
sys->faces_edge = MEM_mallocN(sizeof(int[2]) * sys->total_edges, "QuadRemeshFacesEdge");
sys->no = MEM_callocN(sizeof(float[3]) * sys->total_faces, "QuadRemeshNormals");
sys->gf1 = MEM_mallocN(sizeof(float[3]) * sys->total_faces, "QuadRemeshGradientField1");
sys->gf2 = MEM_mallocN(sizeof(float[3]) * sys->total_faces, "QuadRemeshGradientField2");
sys->U_field = MEM_mallocN(sizeof(float) * sys->total_verts, "QuadRemeshUField");
sys->h1 = MEM_mallocN(sizeof(float) * sys->total_verts, "QuadRemeshH1");
sys->h2 = MEM_mallocN(sizeof(float) * sys->total_verts, "QuadRemeshH2");
sys->gfsys1 = sys->gfsys2 = NULL;
createFaceRingMap(sys);
createVertRingMap(sys);
createEdgeRingMap(sys);
createFacesByEdge(sys);
computeSampleDistanceFunctions(sys, 2.0, 10.0f);
printf("initSystem 6\n");
//computeSampleDistanceFunctions(sys, 2.0, 10.0f);
return sys;
}
static GradientFlowSystem *QuadRemeshModifier_do(
QuadRemeshModifierData *qmd, Object *ob, DerivedMesh *dm,
float(*vertexCos)[3], int numVerts)
static GradientFlowSystem *QuadRemeshModifier_do(QuadRemeshModifierData *qmd, Object *ob, DerivedMesh *dm)
{
int i;
LaplacianSystem *sys = NULL;
@@ -594,25 +504,31 @@ static GradientFlowSystem *QuadRemeshModifier_do(
int x;
GradientFlowSystem *gfsys = NULL;
qmd->flag |= MOD_QUADREMESH_COMPUTE_FLOW;
qmd->flag |= MOD_QUADREMESH_REMESH;
strcpy(qmd->anchor_grp_name, "Group");
if (qmd->flag & MOD_QUADREMESH_COMPUTE_FLOW) {
if (strlen(qmd->anchor_grp_name) >= 1) {
printf("QuadRemeshModifier_do 0.1 \n");
if (qmd->cache_system) {
sys = qmd->cache_system;
deleteLaplacianSystem(sys);
}
qmd->cache_system = initSystem(qmd, ob, dm, vertexCos, numVerts);
qmd->cache_system = initSystem(qmd, ob, dm);
sys = qmd->cache_system;
computeScalarField(sys);
if (sys->has_solution) {
computeGradientFields(sys);
printf("QuadRemeshModifier_do 0 \n");
if (!defgroup_find_name(ob, "QuadRemeshFlow")) {
printf("QuadRemeshModifier_do 1 \n");
/* normalization of vgroup weights */
/*if (!defgroup_find_name(ob, "QuadRemeshFlow")) {
BKE_defgroup_new(ob, "QuadRemeshFlow");
modifier_get_vgroup(ob, dm, "QuadRemeshFlow", &dvert, &defgrp_index);
BLI_assert(dvert != NULL);
dv = dvert;
for (i = 0; i < numVerts; i++) {
mmin = min_ff(mmin, sys->U_field[i]);
mmax = max_ff(mmax, sys->U_field[i]);
@@ -625,10 +541,10 @@ static GradientFlowSystem *QuadRemeshModifier_do(
defvert_add_index_notest(dv, defgrp_index, y);
dv++;
}
}
}*/
}
}
printf("QuadRemeshModifier_do 2 \n");
qmd->flag &= ~MOD_QUADREMESH_COMPUTE_FLOW;
}
@@ -637,7 +553,7 @@ static GradientFlowSystem *QuadRemeshModifier_do(
if (sys->has_solution) {
sys->h = 2.0f;
computeFlowLines(sys);
gfsys = sys->gfsys;
gfsys = sys->gfsys1;
}
qmd->flag &= ~MOD_QUADREMESH_REMESH;
}
@@ -645,13 +561,12 @@ static GradientFlowSystem *QuadRemeshModifier_do(
if (qmd->cache_system) {
sys = qmd->cache_system;
if (sys->has_solution) {
if (sys->gfsys) {
gfsys = sys->gfsys;
if (sys->gfsys1) {
gfsys = sys->gfsys1;
}
}
}
return gfsys;
}
@@ -698,16 +613,19 @@ static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
return dataMask;
}
#if 0
static void deformVerts(ModifierData *md, Object *ob, DerivedMesh *derivedData,
float (*vertexCos)[3], int numVerts, ModifierApplyFlag UNUSED(flag))
float(*vertexCos)[3], int numVerts, ModifierApplyFlag UNUSED(flag))
{
DerivedMesh *dm = get_dm(ob, NULL, derivedData, NULL, false, false);
QuadRemeshModifier_do((QuadRemeshModifierData *)md, ob, dm, vertexCos, numVerts, NULL);
QuadRemeshModifier_do((QuadRemeshModifierData *)md, ob, dm);
if (dm != derivedData) {
dm->release(dm);
}
}
#endif // 0
static DerivedMesh *applyModifier(ModifierData *md,
Object *ob,
@@ -717,27 +635,36 @@ static DerivedMesh *applyModifier(ModifierData *md,
//DerivedMesh *dm2 = get_dm(ob, NULL, dm, NULL, false, false);
//QuadRemeshModifier_do((QuadRemeshModifierData *)md, ob, dm, (void *)dm->getVertArray(dm), dm->getNumVerts(dm));
float (*myco)[3];
MVert *arrayvect;
MEdge *arrayedge;
int i;
float(*vertexCos)[3];
GradientFlowSystem *gfsys = NULL;
DerivedMesh *result;
vertexCos = MEM_mallocN(sizeof(float[3]) * dm->getNumVerts(dm), __func__);
arrayvect = dm->getVertArray(dm);
for (i = 0; i < dm->getNumVerts(dm); i++) {
copy_v3_v3(vertexCos[i], arrayvect[i].co);
}
if (!gfsys) {
gfsys = QuadRemeshModifier_do((QuadRemeshModifierData *)md, ob, dm, vertexCos, dm->getNumVerts(dm), gfsys);
gfsys = QuadRemeshModifier_do((QuadRemeshModifierData *)md, ob, dm);
}
MEM_SAFE_FREE(vertexCos);
LaplacianSystem *sys = (LaplacianSystem *)((QuadRemeshModifierData *)md)->cache_system;
if (gfsys) {
result = CDDM_new(gfsys->mesh->totvert, gfsys->mesh->totedge, 0, gfsys->mesh->totedge, 0);
/*result = CDDM_new(gfsys->totalf * 2, gfsys->totalf, 0, 0, 0);
arrayvect = result->getVertArray(result);
for (i = 0; i < gfsys->totalf; i++) {
float cent[3], v[3];
cent_tri_v3(cent, sys->co[sys->faces[i][0]], sys->co[sys->faces[i][1]], sys->co[sys->faces[i][2]]);
mul_v3_fl(gfsys->gfield[i], 0.1f);
add_v3_v3v3(v, cent, gfsys->gfield[i]);
copy_v3_v3(arrayvect[i * 2].co, v);
copy_v3_v3(arrayvect[i * 2 + 1].co, cent);
}
arrayedge = result->getEdgeArray(result);
for (i = 0; i < gfsys->totalf; i++) {
arrayedge[i].v1 = i * 2;
arrayedge[i].v2 = i * 2 + 1;
arrayedge[i].flag |= ME_EDGEDRAW;
}*/
result = CDDM_new(gfsys->mesh->totvert, gfsys->mesh->totedge, 0, 0, 0);
arrayvect = result->getVertArray(result);
for (i = 0; i < gfsys->mesh->totvert; i++) {
copy_v3_v3(arrayvect[i].co, gfsys->mesh->mvert[i].co);
@@ -746,15 +673,13 @@ static DerivedMesh *applyModifier(ModifierData *md,
for (i = 0; i < gfsys->mesh->totedge; i++) {
arrayedge[i].v1 = gfsys->mesh->medge[i].v1;
arrayedge[i].v2 = gfsys->mesh->medge[i].v2;
arrayedge[i].flag |= ME_EDGEDRAW;
}
dm = result;
}
else{
result = dm;
}
//CDDM_calc_edges_tessface(result);
return result;

File diff suppressed because it is too large Load Diff

View File

@@ -38,54 +38,58 @@
#include "BKE_mesh_mapping.h"
#include "BLI_heap.h"
#include "BLI_linklist.h"
typedef struct GFList {
int index; /*Index pointer to face or edge on original mesh*/
struct GFList *next;
} GFList;
typedef int GFEdgeID;
typedef int GFVertID;
typedef struct GradientFlowVert {
float co[3]; /*Vert coordinates*/
int ori_e; /*Edge index on original Mesh -1 if not inside a edge*/
} GradientFlowVert;
typedef struct GFVert {
float co[3]; /* Vert position on edge */
int idev; /* Edge/vertex index on original Mesh - negative if on vertex */
} GFVert;
typedef struct GradientFlowEdge {
int v1, v2; /*Vert indices on gradient flow mesh*/
int ori_f; /*Face index on original Mesh -1 if not inside a face*/
} GradientFlowEdge;
typedef struct GFEdge {
int v1, v2; /* Vert indices on gradient flow mesh */
int face; /* Face/edge index on original Mesh - negative if on original edge */
} GFEdge;
typedef struct GradientFlowMesh {
int totvert, allocvert;
int totedge, allocedge;
GradientFlowVert *mvert; /* array of verts */
GradientFlowEdge *medge; /* array of edges */
GFVert *mvert; /* array of verts */
GFEdge *medge; /* array of edges */
} GradientFlowMesh;
/*GradientFlowSysten, one gfsys for every gradient field*/
typedef struct LaplacianSystem LaplacianSystem;
/* GradientFlowSysten, one gfsys for every gradient field */
typedef struct GradientFlowSystem {
GradientFlowMesh *mesh; /* Mesh pointer*/
GFList **ringf_list; /* Array list of of GradientFlowEdge per original face*/
GFList **ringe_list; /* Array list of of GradientFlowVert per original edge*/
GradientFlowMesh *mesh; /* Mesh pointer */
LinkNode **ringf_list; /* Array list of of GFEdge per original face */
LinkNode **ringe_list; /* Array list of of GFVert per original edge */
struct Heap *heap_seeds;
int totalf;
int totale;
float *hfunction;
float(*gfield)[3]; /* Gradient Field g1 */
LaplacianSystem *sys;
} GradientFlowSystem;
typedef struct LaplacianSystem {
bool command_compute_flow;
bool has_solution;
bool command_remesh;
int total_verts;
int total_edges;
int total_faces;
int total_features;
int total_gflines;
int total_gfverts;
char features_grp_name[64]; /* Vertex Group name */
int total_verts;
float(*co)[3]; /* Original vertex coordinates */
float(*cogfl)[3]; /* Vertex coordinate Gradient flow line */
float(*no)[3]; /* Original face normal */
float(*gf1)[3]; /* Gradient Field g1 */
float(*gf2)[3]; /* Gradient Field g2 */
@@ -94,24 +98,24 @@ typedef struct LaplacianSystem {
float *h1; /* Sampling distance function h1*/
float *h2; /* Sampling distance function h2*/
float h;
int *constraints; /* Feature points constraints*/
int *ringf_indices; /* Indices of faces per vertex */
int *ringv_indices; /* Indices of neighbors(vertex) per vertex */
int *ringe_indices; /* Indices of edges per vertex */
unsigned int(*faces)[4]; /* Copy of MFace (tessface) v1-v4 */
unsigned int(*faces)[3]; /* Copy of MFace (tessface) v1-v3, v2-v4 */
unsigned int(*edges)[2]; /* Copy of edges v1-v2 */
unsigned int(*faces_edge)[2]; /* Faces by edges */
MeshElemMap *ringf_map; /* Map of faces per vertex */
MeshElemMap *ringv_map; /* Map of vertex per vertex */
MeshElemMap *ringe_map; /* Map of edges per vertex */
NLContext *context; /* System for solve general implicit rotations */
GradientFlowSystem *gfsys;
} LaplacianSystem;
GFList *newGFList(int value);
void deleteGFList(GFList *l);
void addNodeGFList(GFList *l, int value);
int getSizeGFList(GFList *l);
NLContext *context; /* System for solve general implicit rotations */
GradientFlowSystem *gfsys1, *gfsys2;
} LaplacianSystem;
/*
* alpha is degree of anisotropic curvature sensitivity
@@ -122,44 +126,44 @@ int getSizeGFList(GFList *l);
void estimateNumberGFVerticesEdges(int ve[2], LaplacianSystem *sys, float h);
GradientFlowMesh *newGradientFlowMesh(int totalvert, int totaledge);
void deleteGradientFlowMesh(GradientFlowMesh * gfmesh);
int addGFVertGFMesh(GradientFlowMesh *gfmesh, GradientFlowVert gfvert);
int addVertGFMesh(GradientFlowMesh *gfmesh, float co[3], int index_edge);
int addGFEdgeGFMesh(GradientFlowMesh *gfmesh, GradientFlowEdge gfedge);
int addEdgeGFMesh(GradientFlowMesh *gfmesh, int index_v1, int index_v2, int index_face);
GradientFlowSystem *newGradientFlowSystem(LaplacianSystem *sys, float *mhfunction, float(*mgfield)[3]);
//void deleteGradientFlowMesh(GradientFlowMesh * gfmesh);
//int addGFVertGFMesh(GradientFlowMesh *gfmesh, GFVert gfvert);
//int addVertGFMesh(GradientFlowMesh *gfmesh, float co[3], int index_edge);
//int addGFEdgeGFMesh(GradientFlowMesh *gfmesh, GFEdge gfedge);
//int addEdgeGFMesh(GradientFlowMesh *gfmesh, int index_v1, int index_v2, int index_face);
//
//GradientFlowSystem *newGradientFlowSystem(LaplacianSystem *sys, float *mhfunction, float(*mgfield)[3]);
void deleteGradientFlowSystem(GradientFlowSystem *gfsys);
int addGFVertGFSystem(GradientFlowSystem *gfsys, GradientFlowVert gfvert);
int addVertGFSystem(GradientFlowSystem *gfsys, float co[3], int index_edge);
int addGFEdgeGFSystem(GradientFlowSystem *gfsys, GradientFlowEdge gfedge);
int addEdgeGFSystem(GradientFlowSystem *gfsys, int index_v1, int index_v2, int index_face);
int addEdgeTwoFacesGFSystem(GradientFlowSystem *gfsys, int index_v1, int index_v2, int index_face1, int index_face2);
int *findFeaturesOnMesh(int size[2], LaplacianSystem *sys);
void addSeedToQueue(struct Heap *aheap, float value, GradientFlowVert *vert);
GradientFlowVert *getTopSeedFromQueue(struct Heap *aheap);
bool isOnSegmentLine(float p1[3], float p2[3], float q[3]);
bool intersecionLineSegmentWithVector(float r[3], float p1[3], float p2[3], float ori[3], float dir[3]);
int getEdgeFromVerts(LaplacianSystem *sys, int v1, int v2);
int getOtherFaceAdjacentToEdge(LaplacianSystem *sys, int oldface, int inde);
void projectVectorOnFace(float r[3], float no[3], float dir[3]);
int getDifferentVertexFaceEdge(LaplacianSystem *sys, int oldface, int inde);
#define GRA_DIR_ON_NONE 0
#define GRA_DIR_ON_FACE 1
#define GRA_DIR_ON_EDGE 2
void computeGradientDirectionOnVert(int rind[2], float r[3], LaplacianSystem *sys, GradientFlowSystem *gfsys, int indexvert);
void computeGradientDirectionOnEdgeInverse(int rind[2], float r[3], LaplacianSystem *sys, GradientFlowSystem *gfsys, int indexedge);
int nearGFEdgeInGFMesh(LaplacianSystem *sys, GradientFlowSystem *gfsys, float ori[3], float dir[3], int indexface, float maxradius);
int nearGFEdgeInGFMeshFromEdge(LaplacianSystem *sys, GradientFlowSystem *gfsys, float ori[3], float dir[3], int indexedge, float maxradius);
int nextPointFlowLine(float r[3], LaplacianSystem *sys, float q[3], int oldface, int inde);
int nextPointFlowLineInverse(float r[3], LaplacianSystem *sys, float q[3], int oldface, int inde);
float getSamplingDistanceFunctionOnFace(LaplacianSystem *sys, GradientFlowSystem *gfsys, int indexface);
float getMaxSamplingDistanceFunctionOnFace(LaplacianSystem *sys, GradientFlowSystem *gfsys, int indexface);
void computeGFLine(LaplacianSystem *sys, GradientFlowSystem *gfsys, GradientFlowVert *gfvert_seed);
int computeNewSeed(float r[3], LaplacianSystem *sys, GradientFlowSystem *gfsys, int indexf, float ori[3], float dir[3], float mh);
//int addGFVertGFSystem(GradientFlowSystem *gfsys, GFVert gfvert);
//int addVertGFSystem(GradientFlowSystem *gfsys, float co[3], int index_edge);
//int addGFEdgeGFSystem(GradientFlowSystem *gfsys, GFEdge gfedge);
//int addEdgeGFSystem(GradientFlowSystem *gfsys, int index_v1, int index_v2, int index_face);
//int addEdgeTwoFacesGFSystem(GradientFlowSystem *gfsys, int index_v1, int index_v2, int index_face1, int index_face2);
//
//int *findFeaturesOnMesh(int size[2], LaplacianSystem *sys);
//void addSeedToQueue(struct Heap *aheap, float value, GFVert *vert);
//GFVert *getTopSeedFromQueue(struct Heap *aheap);
//
//bool isOnSegmentLine(float p1[3], float p2[3], float q[3]);
//bool intersecionLineSegmentWithVector(float r[3], float p1[3], float p2[3], float ori[3], float dir[3]);
//int getEdgeFromVerts(LaplacianSystem *sys, int v1, int v2);
//int getOtherFaceAdjacentToEdge(LaplacianSystem *sys, int oldface, int inde);
//void projectVectorOnFace(float r[3], float no[3], float dir[3]);
//int getDifferentVertexFaceEdge(LaplacianSystem *sys, int oldface, int inde);
//#define GRA_DIR_ON_NONE 0
//#define GRA_DIR_ON_FACE 1
//#define GRA_DIR_ON_EDGE 2
//void computeGradientDirectionOnVert(int rind[2], float r[3], LaplacianSystem *sys, GradientFlowSystem *gfsys, int indexvert);
//void computeGradientDirectionOnEdgeInverse(int rind[2], float r[3], LaplacianSystem *sys, GradientFlowSystem *gfsys, int indexedge);
//int nearGFEdgeInGFMesh(LaplacianSystem *sys, GradientFlowSystem *gfsys, float ori[3], float dir[3], int indexface, float maxradius);
//int nearGFEdgeInGFMeshFromEdge(LaplacianSystem *sys, GradientFlowSystem *gfsys, float ori[3], float dir[3], int indexedge, float maxradius);
//int nextPointFlowLine(float r[3], LaplacianSystem *sys, float q[3], int oldface, int inde);
//int nextPointFlowLineInverse(float r[3], LaplacianSystem *sys, float q[3], int oldface, int inde);
//float getSamplingDistanceFunctionOnFace(LaplacianSystem *sys, GradientFlowSystem *gfsys, int indexface);
//float getMaxSamplingDistanceFunctionOnFace(LaplacianSystem *sys, GradientFlowSystem *gfsys, int indexface);
//void computeGFLine(LaplacianSystem *sys, GradientFlowSystem *gfsys, GFVert *gfvert_seed);
//
//int computeNewSeed(float r[3], LaplacianSystem *sys, GradientFlowSystem *gfsys, int indexf, float ori[3], float dir[3], float mh);
void computeFlowLines(LaplacianSystem *sys);