[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [23136] branches/bmesh/blender/source/ blender/blenkernel: finished edgesplit, from face angle option now works

Joseph Eagar joeedh at gmail.com
Sat Sep 12 08:47:59 CEST 2009


Revision: 23136
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=23136
Author:   joeedh
Date:     2009-09-12 08:47:59 +0200 (Sat, 12 Sep 2009)

Log Message:
-----------
finished edgesplit, from face angle option now works

Modified Paths:
--------------
    branches/bmesh/blender/source/blender/blenkernel/BKE_mesh.h
    branches/bmesh/blender/source/blender/blenkernel/intern/mesh.c
    branches/bmesh/blender/source/blender/blenkernel/intern/modifier.c

Modified: branches/bmesh/blender/source/blender/blenkernel/BKE_mesh.h
===================================================================
--- branches/bmesh/blender/source/blender/blenkernel/BKE_mesh.h	2009-09-12 05:06:28 UTC (rev 23135)
+++ branches/bmesh/blender/source/blender/blenkernel/BKE_mesh.h	2009-09-12 06:47:59 UTC (rev 23136)
@@ -65,6 +65,10 @@
 	struct CustomData *pdata, struct MVert *mvert, int totface, 
 	int totloop, int totpoly);
 
+/*calculates a face normal.*/
+void mesh_calc_poly_normal(struct MPoly *mpoly, struct MLoop *loopstart, 
+                           struct MVert *mvarray, float *no);
+
 void unlink_mesh(struct Mesh *me);
 void free_mesh(struct Mesh *me, int unlink);
 struct Mesh *add_mesh(char *name);

Modified: branches/bmesh/blender/source/blender/blenkernel/intern/mesh.c
===================================================================
--- branches/bmesh/blender/source/blender/blenkernel/intern/mesh.c	2009-09-12 05:06:28 UTC (rev 23135)
+++ branches/bmesh/blender/source/blender/blenkernel/intern/mesh.c	2009-09-12 06:47:59 UTC (rev 23136)
@@ -71,6 +71,7 @@
 #include "BLI_blenlib.h"
 #include "BLI_editVert.h"
 #include "BLI_arithb.h"
+#include "BLI_cellalloc.h"
 
 #include "bmesh.h"
 
@@ -79,6 +80,7 @@
 	return bmesh_to_editmesh(me->edit_btmesh->bm);
 }
 
+void free_editMesh(EditMesh *em);
 void BKE_mesh_end_editmesh(Mesh *me, EditMesh *em)
 {
 	BM_Free_Mesh(me->edit_btmesh->bm);
@@ -1569,3 +1571,104 @@
 
 	return totface;
 }
+
+/*
+ * COMPUTE POLY NORMAL
+ *
+ * Computes the normal of a planar 
+ * polygon See Graphics Gems for 
+ * computing newell normal.
+ *
+*/
+static void mesh_calc_ngon_normal(MPoly *mpoly, MLoop *loopstart, 
+				  MVert *mvert, float *normal)
+{
+
+	MVert *v1, *v2, *v3;
+	double u[3],  v[3], w[3];
+	double n[3] = {0.0, 0.0, 0.0}, l;
+	int i, s=0;
+
+	for(i = 0; i < mpoly->totloop; i++){
+		v1 = mvert + loopstart[i].v;
+		v2 = mvert + loopstart[(i+1)%mpoly->totloop].v;
+		v3 = mvert + loopstart[(i+2)%mpoly->totloop].v;
+		
+		VECCOPY(u, v1->co);
+		VECCOPY(v, v2->co);
+		VECCOPY(w, v3->co);
+
+		/*this fixes some weird numerical error*/
+		if (i==0) {
+			u[0] += 0.0001f;
+			u[1] += 0.0001f;
+			u[2] += 0.0001f;
+		}
+		
+		/* newell's method
+		
+		so thats?:
+		(a[1] - b[1]) * (a[2] + b[2]);
+		a[1]*b[2] - b[1]*a[2] - b[1]*b[2] + a[1]*a[2]
+
+		odd.  half of that is the cross product. . .what's the
+		other half?
+
+		also could be like a[1]*(b[2] + a[2]) - b[1]*(a[2] - b[2])
+		*/
+
+		n[0] += (u[1] - v[1]) * (u[2] + v[2]);
+		n[1] += (u[2] - v[2]) * (u[0] + v[0]);
+		n[2] += (u[0] - v[0]) * (u[1] + v[1]);
+	}
+	
+	l = n[0]*n[0]+n[1]*n[1]+n[2]*n[2];
+	l = sqrt(l);
+
+	if (l == 0.0) {
+		normal[0] = 0.0f;
+		normal[1] = 0.0f;
+		normal[2] = 1.0f;
+
+		return;
+	} else l = 1.0f / l;
+
+	n[0] *= l;
+	n[1] *= l;
+	n[2] *= l;
+	
+	normal[0] = (float) n[0];
+	normal[1] = (float) n[1];
+	normal[2] = (float) n[2];
+
+}
+
+void mesh_calc_poly_normal(MPoly *mpoly, MLoop *loopstart, 
+                           MVert *mvarray, float *no)
+{
+	if(mpoly->totloop > 4) {
+		mesh_calc_ngon_normal(mpoly, loopstart, mvarray, no);
+	}
+	else if(mpoly->totloop == 3){
+		MVert *v1, *v2, *v3;
+
+		v1 = mvarray + (loopstart++)->v;
+		v2 = mvarray + (loopstart++)->v;
+		v3 = mvarray + loopstart->v;
+		CalcNormFloat(v1->co, v2->co, v3->co, no);
+	}
+	else if(mpoly->totloop == 4){
+		MVert *v1, *v2, *v3, *v4;
+
+		v1 = mvarray + (loopstart++)->v;
+		v2 = mvarray + (loopstart++)->v;
+		v3 = mvarray + (loopstart++)->v;
+		v4 = mvarray + loopstart->v;
+		CalcNormFloat4(v1->co, v2->co, v3->co, v4->co, no);
+	}
+	else{ /*horrible, two sided face!*/
+		no[0] = 0.0;
+		no[1] = 0.0;
+		no[2] = 1.0;
+	}
+}

Modified: branches/bmesh/blender/source/blender/blenkernel/intern/modifier.c
===================================================================
--- branches/bmesh/blender/source/blender/blenkernel/intern/modifier.c	2009-09-12 05:06:28 UTC (rev 23135)
+++ branches/bmesh/blender/source/blender/blenkernel/intern/modifier.c	2009-09-12 06:47:59 UTC (rev 23136)
@@ -2180,7 +2180,6 @@
 */
 
 /*new cddm-based edge split code*/
-#if 1
 typedef struct VertUser {
 	int ov, v, done;
 	ListBase users;
@@ -2194,6 +2193,8 @@
 typedef struct EdgeData {
 	EdgeNode v1node, v2node;
 	VertUser *v1user, *v2user;
+	float fno[3]; /*used to calculate face angles*/
+	int has_fno;
 	int tag;
 	int v1, v2;
 	int used;
@@ -2286,6 +2287,8 @@
 	MemBase *membase;
 	CustomData edata, vdata;
 	int i, j, curv, cure;
+	float threshold = cos((emd->split_angle + 0.00001) * M_PI / 180.0);
+	float no[3], edge_angle_cos;
 
 	if (!cddm->numVertData || !cddm->numEdgeData)
 		return cddm;
@@ -2312,6 +2315,26 @@
 		etags[i].v2node.edge = etags+i;
 	}
 
+	if (emd->flags & MOD_EDGESPLIT_FROMANGLE) {
+		mp = mpoly;
+		for (i=0; i<cddm->numPolyData; i++, mp++) {
+			mesh_calc_poly_normal(mp, mloop+mp->loopstart, mvert, no);
+
+			ml = mloop + mp->loopstart;
+			for (j=0; j<mp->totloop; j++, ml++) {
+				if (!etags[ml->e].has_fno) {
+					VECCOPY(etags[ml->e].fno, no);
+					etags[ml->e].has_fno = 1;
+				} else if (!etags[ml->e].tag) {
+					edge_angle_cos = MTC_dot3Float(etags[ml->e].fno, no);
+					if (edge_angle_cos < threshold) {
+						etags[ml->e].tag = 1;
+					}
+				}
+			}
+		}
+	}
+
 	mp = mpoly;
 	for (i=0; i<cddm->numPolyData; i++, mp++) {
 		ml = mloop + mp->loopstart;
@@ -2539,1212 +2562,6 @@
 	return edgesplitModifier_applyModifier(md, ob, derivedData, 0, 1);
 }
 
-#else
-
-#if 0
-#define EDGESPLIT_DEBUG_3
-#define EDGESPLIT_DEBUG_2
-#define EDGESPLIT_DEBUG_1
-#define EDGESPLIT_DEBUG_0
-#endif
-
-/* Mesh data for edgesplit operation */
-typedef struct SmoothVert {
-	LinkNode *faces;     /* all faces which use this vert */
-	int oldIndex; /* the index of the original DerivedMesh vert */
-	int newIndex; /* the index of the new DerivedMesh vert */
-} SmoothVert;
-
-#define SMOOTHEDGE_NUM_VERTS 2
-
-typedef struct SmoothEdge {
-	SmoothVert *verts[SMOOTHEDGE_NUM_VERTS]; /* the verts used by this edge */
-	LinkNode *faces;     /* all faces which use this edge */
-	int oldIndex; /* the index of the original DerivedMesh edge */
-	int newIndex; /* the index of the new DerivedMesh edge */
-	short flag; /* the flags from the original DerivedMesh edge */
-} SmoothEdge;
-
-#define SMOOTHFACE_MAX_EDGES 4
-
-typedef struct SmoothFace {
-	SmoothEdge *edges[SMOOTHFACE_MAX_EDGES]; /* nonexistent edges == NULL */
-	int flip[SMOOTHFACE_MAX_EDGES]; /* 1 = flip edge dir, 0 = don't flip */
-	float normal[3]; /* the normal of this face */
-	int oldIndex; /* the index of the original DerivedMesh face */
-	int newIndex; /* the index of the new DerivedMesh face */
-} SmoothFace;
-
-typedef struct SmoothMesh {
-	SmoothVert *verts;
-	SmoothEdge *edges;
-	SmoothFace *faces;
-	int num_verts, num_edges, num_faces;
-	int max_verts, max_edges, max_faces;
-	DerivedMesh *dm;
-	float threshold; /* the cosine of the smoothing angle */
-	int flags;
-	MemArena *arena;
-	ListBase propagatestack, reusestack;
-} SmoothMesh;
-
-static SmoothVert *smoothvert_copy(SmoothVert *vert, SmoothMesh *mesh)
-{
-	SmoothVert *copy = &mesh->verts[mesh->num_verts];
-
-	if(mesh->num_verts >= mesh->max_verts) {
-		printf("Attempted to add a SmoothMesh vert beyond end of array\n");
-		return NULL;
-	}
-
-	*copy = *vert;
-	copy->faces = NULL;
-	copy->newIndex = mesh->num_verts;
-	++mesh->num_verts;
-
-#ifdef EDGESPLIT_DEBUG_2
-	printf("copied vert %4d to vert %4d\n", vert->newIndex, copy->newIndex);
-#endif
-	return copy;
-}
-
-static SmoothEdge *smoothedge_copy(SmoothEdge *edge, SmoothMesh *mesh)
-{
-	SmoothEdge *copy = &mesh->edges[mesh->num_edges];
-
-	if(mesh->num_edges >= mesh->max_edges) {
-		printf("Attempted to add a SmoothMesh edge beyond end of array\n");
-		return NULL;
-	}
-
-	*copy = *edge;
-	copy->faces = NULL;
-	copy->newIndex = mesh->num_edges;
-	++mesh->num_edges;
-
-#ifdef EDGESPLIT_DEBUG_2
-	printf("copied edge %4d to edge %4d\n", edge->newIndex, copy->newIndex);
-#endif
-	return copy;
-}
-
-static int smoothedge_has_vert(SmoothEdge *edge, SmoothVert *vert)
-{
-	int i;
-	for(i = 0; i < SMOOTHEDGE_NUM_VERTS; i++)
-		if(edge->verts[i] == vert) return 1;
-
-	return 0;
-}
-
-static SmoothMesh *smoothmesh_new(int num_verts, int num_edges, int num_faces,
-				  int max_verts, int max_edges, int max_faces)
-{
-	SmoothMesh *mesh = MEM_callocN(sizeof(*mesh), "smoothmesh");
-	mesh->verts = MEM_callocN(sizeof(*mesh->verts) * max_verts,
-				  "SmoothMesh.verts");
-	mesh->edges = MEM_callocN(sizeof(*mesh->edges) * max_edges,
-				  "SmoothMesh.edges");
-	mesh->faces = MEM_callocN(sizeof(*mesh->faces) * max_faces,
-				  "SmoothMesh.faces");
-
-	mesh->num_verts = num_verts;
-	mesh->num_edges = num_edges;
-	mesh->num_faces = num_faces;
-
-	mesh->max_verts = max_verts;
-	mesh->max_edges = max_edges;
-	mesh->max_faces = max_faces;
-
-	return mesh;
-}
-
-static void smoothmesh_free(SmoothMesh *mesh)
-{
-	int i;
-
-	for(i = 0; i < mesh->num_verts; ++i)
-		BLI_linklist_free(mesh->verts[i].faces, NULL);
-
-	for(i = 0; i < mesh->num_edges; ++i)
-		BLI_linklist_free(mesh->edges[i].faces, NULL);
-	
-	if(mesh->arena)
-		BLI_memarena_free(mesh->arena);
-
-	MEM_freeN(mesh->verts);
-	MEM_freeN(mesh->edges);
-	MEM_freeN(mesh->faces);
-	MEM_freeN(mesh);
-}
-
-static void smoothmesh_resize_verts(SmoothMesh *mesh, int max_verts)
-{
-	int i;
-	SmoothVert *tmp;
-
-	if(max_verts <= mesh->max_verts) return;
-
-	tmp = MEM_callocN(sizeof(*tmp) * max_verts, "SmoothMesh.verts");
-
-	memcpy(tmp, mesh->verts, sizeof(*tmp) * mesh->num_verts);
-
-	/* remap vert pointers in edges */
-	for(i = 0; i < mesh->num_edges; ++i) {
-		int j;
-		SmoothEdge *edge = &mesh->edges[i];
-
-		for(j = 0; j < SMOOTHEDGE_NUM_VERTS; ++j)
-			/* pointer arithmetic to get vert array index */
-			edge->verts[j] = &tmp[edge->verts[j] - mesh->verts];
-	}
-
-	MEM_freeN(mesh->verts);
-	mesh->verts = tmp;
-	mesh->max_verts = max_verts;
-}
-
-static void smoothmesh_resize_edges(SmoothMesh *mesh, int max_edges)
-{
-	int i;
-	SmoothEdge *tmp;
-
-	if(max_edges <= mesh->max_edges) return;
-
-	tmp = MEM_callocN(sizeof(*tmp) * max_edges, "SmoothMesh.edges");
-
-	memcpy(tmp, mesh->edges, sizeof(*tmp) * mesh->num_edges);
-
-	/* remap edge pointers in faces */
-	for(i = 0; i < mesh->num_faces; ++i) {
-		int j;
-		SmoothFace *face = &mesh->faces[i];
-
-		for(j = 0; j < SMOOTHFACE_MAX_EDGES; ++j)
-			if(face->edges[j])
-				/* pointer arithmetic to get edge array index */
-				face->edges[j] = &tmp[face->edges[j] - mesh->edges];
-	}
-
-	MEM_freeN(mesh->edges);
-	mesh->edges = tmp;
-	mesh->max_edges = max_edges;
-}
-
-#ifdef EDGESPLIT_DEBUG_0

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list