[Bf-blender-cvs] [b987a43] soc-2014-remesh: 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.

Alexander Pinzon Fernandez noreply at git.blender.org
Sat Jul 26 03:38:20 CEST 2014


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. @@




More information about the Bf-blender-cvs mailing list