[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