Commit: b987a43d2f9363711b78cdc30462f8d60ee15431
Author: Alexander Pinzon Fernandez
Date:   Fri Jul 25 20:35:22 2014 -0500
Branches: soc-2014-remesh
https://developer.blender.org/rBb987a43d2f9363711b78cdc30462f8d60ee15431

Method to store a map of edges around vertex.
Method to project a gradient field vector on a plane defined by face for define 
the direction of flow line over this face.
Method to intersect a face with line projected from seed point on gradient 
direction.

===================================================================

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 8bc8025..199659b 100644
--- a/source/blender/modifiers/intern/MOD_quadremesh.c
+++ b/source/blender/modifiers/intern/MOD_quadremesh.c
@@ -44,14 +44,9 @@
 
 #include "ONL_opennl.h"
 
-
-#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 *index;                             /* Pointer to a edge */
        int total_verts;                /* Total number of points in a flow 
line */
        int total_allocated;    /* Total number of elements allocated */
 } GradientFlowLine;
@@ -74,15 +69,17 @@ 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 */
+       int *ringe_indices;                     /* Indices of edges per vertex 
*/
        unsigned int(*faces)[4];        /* Copy of MFace (tessface) v1-v4 */
+       unsigned int(*edges)[2];        /* Copy of edges v1-v2 */
        GradientFlowLine *gflines;  /* Gradien flow lines of field g1*/
        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 */
 } LaplacianSystem;
 
 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;
@@ -90,19 +87,17 @@ static GradientFlowLine 
*initGradientFlowLine(GradientFlowLine *gfl, int expecte
        return gfl;
 }
 
-static void addPointToGradientFlowLine(GradientFlowLine *gfl, char type, float 
p[3], int index)
+static void addPointToGradientFlowLine(GradientFlowLine *gfl, float p[3], int 
index)
 {
-       if (index >= 0 && (type == FLOW_LINE_POINT_TYPE_EDGE || type == 
FLOW_LINE_POINT_TYPE_VERTEX)) {
+       if (index >= 0 ) {
 
                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++;
        }
@@ -137,6 +132,7 @@ static LaplacianSystem *initLaplacianSystem(int totalVerts, 
int totalEdges, int
        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->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");
@@ -150,6 +146,7 @@ static LaplacianSystem *initLaplacianSystem(int totalVerts, 
int totalEdges, int
 static void UNUSED_FUNCTION(deleteLaplacianSystem)(LaplacianSystem *sys)
 {
        MEM_SAFE_FREE(sys->faces);
+       MEM_SAFE_FREE(sys->edges);
        MEM_SAFE_FREE(sys->co);
        MEM_SAFE_FREE(sys->no);
        MEM_SAFE_FREE(sys->constraints);
@@ -159,12 +156,13 @@ static void 
UNUSED_FUNCTION(deleteLaplacianSystem)(LaplacianSystem *sys)
        MEM_SAFE_FREE(sys->gf2);
        MEM_SAFE_FREE(sys->ringf_indices);
        MEM_SAFE_FREE(sys->ringv_indices);
+       MEM_SAFE_FREE(sys->ringe_indices);
        MEM_SAFE_FREE(sys->ringf_map);
        MEM_SAFE_FREE(sys->ringv_map);
+       MEM_SAFE_FREE(sys->ringe_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) {
@@ -250,6 +248,40 @@ static void createVertRingMap(
        *r_indices = indices;
 }
 
+static void createEdgeRingMap(
+       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] = i;
+               map[vid[0]].count++;
+               map[vid[1]].indices[map[vid[1]].count] = i;
+               map[vid[1]].count++;
+       }
+       *r_map = map;
+       *r_indices = indices;
+}
 
 static void initLaplacianMatrix(LaplacianSystem *sys)
 {
@@ -378,6 +410,16 @@ static void computeScalarField(LaplacianSystem *sys)
 #endif
 }
 
+static void print_face(LaplacianSystem *sys, int indexf)
+{
+       int *vin;
+       vin = sys->faces[indexf];
+       print_v3_id(sys->co[vin[0]]);
+       print_v3_id(sys->co[vin[1]]);
+       print_v3_id(sys->co[vin[2]]);
+
+}
+
 /** 
  * Compute the gradient fields
  * 
@@ -416,128 +458,194 @@ 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]);
        }
+}
 
-
+void printff_v3(const char *str, const float v[3])
+{
+       printf("%s: %.7f %.7f %.7f\n", str, v[0], v[1], v[2]);
 }
 
 /**
 * Project vector of gradient field on face, 
 */
-static void computeDirectionVectorOnFace(float dir[3], LaplacianSystem * sys, 
float origin[3], int indexf)
+static void projectGradientOnFace(float dir[3], LaplacianSystem * sys, 
float(*gf)[3], int indexf)
 {
-
+       int i;
+       float  g[3], u[3], w[3], val;
+       normalize_v3_v3(g, gf[indexf]);
+       val = dot_v3v3(g, sys->no[indexf]);
+       mul_v3_v3fl(u, sys->no[indexf], val);
+       sub_v3_v3v3(w, g, u);
+       normalize_v3_v3(dir, w);
 }
 
-/**
-* 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;
+static void getFacesAdjacentToEdge(int fs[2], LaplacianSystem *sys, int indexe)
+{
+       int i, v1, v2, counter;
        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];
-                               }
-                       }
+       int *vin;
+       v1 = sys->edges[indexe][0];
+       v2 = sys->edges[indexe][1];
+       numf = sys->ringf_map[v1].count;
+       fidn = sys->ringf_map[v1].indices;
+       counter = 0;
+       fs[0] = -1;
+       fs[1] = -1;
+
+       for (i = 0; i < numf && counter < 2; i++) {
+               vin = sys->faces[fidn[i]];
+               if (vin[0] == v2 || vin[1] == v2 || vin[2] == v2) {
+                       fs[counter++] = fidn[i];
                }
        }
-       return indexf;
 }
 
-/** 
-* int ifs; Index of vertx, this vertex is the seed for trace this flow line
-*/
-static void computeGradientFlowLine(LaplacianSystem * sys, int ivs){
-       float minU, tempminU, x[3], p[3], i1[3], i2[3];
-       int i, numf, indexf, actualf, indf;
-       int *fidn;
-       int *vin, has4v;
-       int totalverts = 0;
-       float(*vflowline)[3] = MEM_mallocN(sizeof(float[3]) * sys->total_verts, 
__func__);  /* over-alloc */
-       
-
-       numf = sys->ringf_map[ivs].count;
-       /* Choose the face with minimun value of U field*/
-       minU = 1000000;
-       fidn = sys->ringf_map[ivs].indices;
-       for (i = 0; i < numf; i++) {
-               indexf = fidn[i];
-               if (sys->U_field[indexf] < minU){
-                       minU = sys->U_field[indexf];
-                       i = numf + 1;
+static int getEdgeFromVerts(LaplacianSystem *sys, int v1, int v2)
+{
+       int *eidn, nume, i;
+       nume = sys->ringe_map[v1].count;
+       eidn = sys->ringe_map[v1].indices;
+       for (i = 0; i < nume; i++) {
+               if (sys->edges[eidn[i]][0] == v2 || sys->edges[eidn[i]][1] == 
v2){
+                       return eidn[i];
                }
        }
+       return -1;
+}
 
-       vin = sys->faces[indexf];
-       has4v = vin[3] ? 4 : 3;
-       zero_v3(x);
-       for (i = 0; i < has4v; i++){
-               add_v3_v3(x, sys->co[vin[i]]);
+static bool isBetweenLine(float p1[3], float p2[3], float q[3]){
+       if (   (q[0] >= min_ff(p1[0], p2[0]))
+               && (q[1] >= min_ff(p1[1], p2[1]))
+               && (q[2] >= min_ff(p1[2], p2[2]))
+               && (q[0] <= max_ff(p1[0], p2[0]))
+               && (q[1] <= max_ff(p1[1], p2[1]))
+               && (q[2] <= max_ff(p1[2], p2[2]))
+               ) {
+               return true;
        }
-       mul_v3_fl(x, 1.0 / ((float)has4v));
-       copy_v3_v3(vflowline[0], x);
-       totalverts++;
+       return false;
+}
 
-       tempminU = 1000000;
-       actualf = indexf;
-       indf = indexf;
-       while (indf > 0) {
+static int isectLineToEdges(float r[3], LaplacianSystem *sys, float ori[3], 
int indexf, int indexe)
+{
+       int *vin, ev1, ev2, ev3;
+       float p1[3], p2[3], p3[3], dir[3], q[3], i1[3], i2[3];
+       float l;
+       
+       ev1 = sys->edges[indexe][0];
+       ev2 = sys->edges[indexe][1];
 
+       vin = sys->faces[indexf];
+       projectGradientOnFace(dir, sys, sys->gf1, indexf);
 
+       mul_v3_fl(dir, 100);
 
-               indf = getNeighborFaceWithMinUField(sys, actualf, tempminU);
-               
-               copy_v3_v3(p, vflowline[totalverts - 1]);
-               vin = sys->faces[actualf];
-               has4v = vin[3] ? 4 : 3;
-               if (has4v == 3) {
-                       /** 1 - lines are coplanar, i1 is set to intersection*/
-                       if (isect_line_line_v3(sys->co[vin[0]], 
sys->co[vin[1]], p, sys->gf1[actualf], i1, i2) == 1) {
-                               copy_v3_v3(vflowline[totalverts], i1);
-                               totalverts++;
-                       }
-                       else if (isect_line_line_v3(sys->co[vin[1]], 
sys->co[vin[2]], p, sys->gf1[actualf], i1, i2) == 1) {
-                               copy_v3_v3(vflowline[totalve

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to