[Bf-blender-cvs] [f8b4961] soc-2014-remesh: Method for choose face that serve to build a line gradient flow Method to project vector field on certain face and intersect this with adjacent edges. Fixed problem about computation of gradient field vector, i misinterpreted the matrix representation.
Alexander Pinzon Fernandez
noreply at git.blender.org
Sat Jul 19 04:05:15 CEST 2014
Commit: f8b49614c149172f8137944d630ac1e92828a162
Author: Alexander Pinzon Fernandez
Date: Fri Jul 18 21:00:49 2014 -0500
https://developer.blender.org/rBf8b49614c149172f8137944d630ac1e92828a162
Method for choose face that serve to build a line gradient flow
Method to project vector field on certain face and intersect this with adjacent edges.
Fixed problem about computation of gradient field vector, i misinterpreted the matrix representation.
===================================================================
M source/blender/modifiers/intern/MOD_quadremesh.c
===================================================================
diff --git a/source/blender/modifiers/intern/MOD_quadremesh.c b/source/blender/modifiers/intern/MOD_quadremesh.c
index 1493b54..2772941 100644
--- a/source/blender/modifiers/intern/MOD_quadremesh.c
+++ b/source/blender/modifiers/intern/MOD_quadremesh.c
@@ -44,10 +44,16 @@
#include "ONL_opennl.h"
-typedef struct GradientFlowLine {
- int total_verts;
- float(*co)[3];
+#define FLOW_LINE_POINT_TYPE_VERTEX 0
+#define FLOW_LINE_POINT_TYPE_EDGE 1
+
+typedef struct GradientFlowLine {
+ char *type; /* The point is over a vertex or a edge, 1:edge, 0:vertex */
+ float(*co)[3]; /* Vertex coordinate */
+ int *index; /* Pointer to a vertex or a edge */
+ int total_verts; /* Total number of points in a flow line */
+ int total_allocated; /* Total number of elements allocated */
} GradientFlowLine;
typedef struct LaplacianSystem {
@@ -68,23 +74,38 @@ typedef struct LaplacianSystem {
int *constraints; /* Feature points constraints*/
int *ringf_indices; /* Indices of faces per vertex */
int *ringv_indices; /* Indices of neighbors(vertex) per vertex */
- GradientFlowLine *gflines; /* Gradien flow lines of field g1*/
unsigned int(*faces)[4]; /* Copy of MFace (tessface) v1-v4 */
+ GradientFlowLine *gflines; /* Gradien flow lines of field g1*/
MeshElemMap *ringf_map; /* Map of faces per vertex */
MeshElemMap *ringv_map; /* Map of vertex per vertex */
NLContext *context; /* System for solve general implicit rotations */
} LaplacianSystem;
-static GradientFlowLine *newGradientFlowLine(LaplacianSystem *sys)
+static GradientFlowLine *initGradientFlowLine(GradientFlowLine *gfl, int expected_size){
+ gfl->type = MEM_mallocN(sizeof(char) * expected_size, __func__); /* over-alloc */
+ gfl->co = MEM_mallocN(sizeof(float[3]) * expected_size, __func__); /* over-alloc */
+ gfl->index = MEM_mallocN(sizeof(int)* expected_size, __func__); /* over-alloc */
+ gfl->total_allocated = expected_size;
+ gfl->total_verts = 0;
+ return gfl;
+}
+
+static void addPointToGradientFlowLine(GradientFlowLine *gfl, char type, float p[3], int index)
{
- if (sys->total_gflines == 0){
- sys->gflines = MEM_mallocN(sizeof(GradientFlowLine), "QuadRemeshgflines");
- }
- else {
- sys->gflines = MEM_reallocN(sys->gflines, sizeof(GradientFlowLine)* sys->total_gflines + 1);
- sys->total_gflines += 1;
+ if (index >= 0 && (type == FLOW_LINE_POINT_TYPE_EDGE || type == FLOW_LINE_POINT_TYPE_VERTEX)) {
+
+ if (index >= gfl->total_allocated){
+ gfl->type = MEM_reallocN(gfl->type, sizeof(char) * (gfl->total_allocated + 1));
+ gfl->co = MEM_reallocN(gfl->co, sizeof(float[3]) * (gfl->total_allocated + 1));
+ gfl->index = MEM_reallocN(gfl->index, sizeof(int) * (gfl->total_allocated + 1));
+ gfl->total_allocated++;
+ }
+
+ copy_v3_v3(gfl->co[gfl->total_verts], p);
+ gfl->type[gfl->total_verts] = type;
+ gfl->index[gfl->total_verts] = index;
+ gfl->total_verts++;
}
- return &(sys->gflines[sys->total_gflines - 1]);
}
static LaplacianSystem *newLaplacianSystem(void)
@@ -97,6 +118,7 @@ static LaplacianSystem *newLaplacianSystem(void)
sys->total_edges = 0;
sys->total_features = 0;
sys->total_faces = 0;
+ sys->total_gflines = 0;
sys->features_grp_name[0] = '\0';
return sys;
@@ -139,6 +161,11 @@ static void UNUSED_FUNCTION(deleteLaplacianSystem)(LaplacianSystem *sys)
MEM_SAFE_FREE(sys->ringv_indices);
MEM_SAFE_FREE(sys->ringf_map);
MEM_SAFE_FREE(sys->ringv_map);
+ for (int i = 0; i < sys->total_gflines; i++) {
+ MEM_SAFE_FREE(sys->gflines[i].co);
+ MEM_SAFE_FREE(sys->gflines[i].index);
+ MEM_SAFE_FREE(sys->gflines[i].type);
+ }
MEM_SAFE_FREE(sys->gflines);
if (sys->context) {
nlDeleteContext(sys->context);
@@ -146,6 +173,83 @@ static void UNUSED_FUNCTION(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)
+{
+ int i, j, totalr = 0;
+ int *indices, *index_iter;
+ MeshElemMap *map = MEM_callocN(sizeof(MeshElemMap)* mvert_tot, "DeformRingMap");
+ const MFace *mf;
+
+ 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].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;
+ }
+ 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++;
+ }
+ }
+ *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)
+{
+ MeshElemMap *map = MEM_callocN(sizeof(MeshElemMap)* mvert_tot, "DeformNeighborsMap");
+ int i, vid[2], totalr = 0;
+ int *indices, *index_iter;
+ const MEdge *me;
+
+ 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++;
+ 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;
+ }
+ 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++;
+ }
+ *r_map = map;
+ *r_indices = indices;
+}
+
static void initLaplacianMatrix(LaplacianSystem *sys)
{
@@ -275,7 +379,7 @@ static void computeScalarField(LaplacianSystem *sys)
}
/**
- * Compute the gradiente fields
+ * Compute the gradient fields
*
* xi, xj, xk, are the vertices of the face
* ui, uj, uk, are the values of scalar fields for every vertex of the face
@@ -293,6 +397,7 @@ static void computeGradientFields(LaplacianSystem * sys)
{
int fi, i, j, k;
float a[3][3], u[3], inv_a[3][3];
+
for (fi = 0; fi < sys->total_faces; fi++) {
const unsigned int *vidf = sys->faces[fi];
i = vidf[0];
@@ -301,6 +406,9 @@ static void computeGradientFields(LaplacianSystem * sys)
sub_v3_v3v3(a[0], sys->co[j], sys->co[i]);
sub_v3_v3v3(a[1], sys->co[k], sys->co[j]);
copy_v3_v3 (a[2], sys->no[fi]);
+
+ /* Correct way*/
+ transpose_m3(a);
u[0] = sys->U_field[j] - sys->U_field[i];
u[1] = sys->U_field[k] - sys->U_field[j];
u[2] = 0;
@@ -308,6 +416,43 @@ static void computeGradientFields(LaplacianSystem * sys)
mul_v3_m3v3(sys->gf1[fi], inv_a, u);
cross_v3_v3v3(sys->gf2[fi], sys->no[fi], sys->gf1[fi]);
}
+
+
+}
+
+/**
+* Project vector of gradient field on face,
+*/
+static void computeDirectionVectorOnFace(float dir[3], LaplacianSystem * sys, float origin[3], int indexf)
+{
+}
+
+/**
+* return the index of face with less value of U scalar field
+* return -1 if any value is less.
+*/
+static int getNeighborFaceWithMinUField(LaplacianSystem * sys, int index, float value){
+ int *vin, has4v;
+ int *fidn, numf;
+ int i, j;
+ int indexf = -1;
+ float minvalue = value;
+
+ vin = sys->faces[index];
+ has4v = vin[3] ? 4 : 3;
+ for (i = 0; i < has4v; i++) {
+ numf = sys->ringf_map[vin[i]].count;
+ fidn = sys->ringf_map[vin[i]].indices;
+ for (j = 0; j < numf; j++){
+ if (fidn[j] != index){
+ if (sys->U_field[fidn[j]] < minvalue){
+ minvalue = sys->U_field[fidn[j]];
+ indexf = fidn[j];
+ }
+ }
+ }
+ }
+ return indexf;
}
/**
@@ -315,7 +460,7 @@ static void computeGradientFields(LaplacianSystem * sys)
*/
static void computeGradientFlowLine(LaplacianSystem * sys, int ivs){
float uvalue, minU, tempminU, x[3], p[3], q[3], i1[3], i2[3];
- int i, numf, indexf, actualf;
+ int i, numf, indexf, actualf, indf;
int *fidn;
int *vin, has4v;
int totalverts = 0;
@@ -346,7 +491,13 @@ static void computeGradientFlowLine(LaplacianSystem * sys, int ivs){
tempminU = 1000000;
actualf = indexf;
- while (minU < tempminU) {
+ indf = indexf;
+ while (indf > 0) {
+
+
+
+ indf = getNeighborFaceWithMinUField(sys, actualf, tempminU);
+
copy_v3_v3(p, vflowline[totalverts - 1]);
vin = sys->faces[actualf];
has4v = vin[3] ? 4 : 3;
More information about the Bf-blender-cvs
mailing list