[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [35907] branches/bmesh/blender/source/ blender: =bmesh=
Joseph Eagar
joeedh at gmail.com
Thu Mar 31 00:46:57 CEST 2011
Revision: 35907
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=35907
Author: joeedh
Date: 2011-03-30 22:46:56 +0000 (Wed, 30 Mar 2011)
Log Message:
-----------
=bmesh=
Multires interpolation now works on cases like
simple cubes. (though it isn't perfect
when bevelling sharp corners).
Normal flipping is handled correctly, and
multires interpolation now works on
normal-inconsistent meshes (so long as
they are manifold, at least).
Modified Paths:
--------------
branches/bmesh/blender/source/blender/bmesh/bmesh.h
branches/bmesh/blender/source/blender/bmesh/bmesh_class.h
branches/bmesh/blender/source/blender/bmesh/bmesh_operator_api.h
branches/bmesh/blender/source/blender/bmesh/intern/bmesh_interp.c
branches/bmesh/blender/source/blender/bmesh/intern/bmesh_mesh.c
branches/bmesh/blender/source/blender/bmesh/intern/bmesh_newcore.c
branches/bmesh/blender/source/blender/bmesh/intern/bmesh_opdefines.c
branches/bmesh/blender/source/blender/bmesh/intern/bmesh_operators.c
branches/bmesh/blender/source/blender/bmesh/operators/utils.c
branches/bmesh/blender/source/blender/editors/mesh/bmesh_tools.c
Modified: branches/bmesh/blender/source/blender/bmesh/bmesh.h
===================================================================
--- branches/bmesh/blender/source/blender/bmesh/bmesh.h 2011-03-30 16:44:18 UTC (rev 35906)
+++ branches/bmesh/blender/source/blender/bmesh/bmesh.h 2011-03-30 22:46:56 UTC (rev 35907)
@@ -112,6 +112,7 @@
#define BM_ACTIVE (1<<6)
#define BM_NONORMCALC (1<<7)
#define BM_PINNED (1<<8)
+#define BM_FLIPPED (1<<9) /*internal flag, used for ensuring correct normals during multires interpolation*/
#include "bmesh_class.h"
@@ -149,6 +150,7 @@
#define BM_TestHFlag(ele, f) (ele && (((BMHeader*)ele)->flag & (f)))
#define BM_SetHFlag(ele, f) (((BMHeader*)ele)->flag = ((BMHeader*)ele)->flag | (f))
#define BM_ClearHFlag(ele, f) (((BMHeader*)ele)->flag = ((BMHeader*)ele)->flag & ~(f))
+#define BM_ToggleHFlag(ele, f) (((BMHeader*)ele)->flag = ((BMHeader*)ele)->flag ^ (f))
/*stuff for setting indices in elements.*/
#define BMINDEX_SET(ele, i) (((BMHeader*)ele)->index = i)
Modified: branches/bmesh/blender/source/blender/bmesh/bmesh_class.h
===================================================================
--- branches/bmesh/blender/source/blender/bmesh/bmesh_class.h 2011-03-30 16:44:18 UTC (rev 35906)
+++ branches/bmesh/blender/source/blender/bmesh/bmesh_class.h 2011-03-30 22:46:56 UTC (rev 35907)
@@ -255,6 +255,8 @@
ListBase errorstack;
struct Object *ob; /*owner object*/
+
+ int opflag; /*current operator flag*/
} BMesh;
BMFace *BM_Copy_Face(BMesh *bm, BMFace *f, int copyedges, int copyverts);
Modified: branches/bmesh/blender/source/blender/bmesh/bmesh_operator_api.h
===================================================================
--- branches/bmesh/blender/source/blender/bmesh/bmesh_operator_api.h 2011-03-30 16:44:18 UTC (rev 35906)
+++ branches/bmesh/blender/source/blender/bmesh/bmesh_operator_api.h 2011-03-30 22:46:56 UTC (rev 35907)
@@ -119,6 +119,12 @@
/*BMOpDefine->flag*/
#define BMOP_UNTAN_MULTIRES 1 /*switch from multires tangent space to absolute coordinates*/
+/*ensures consistent normals before operator execution,
+ restoring the original ones windings/normals afterwards.
+ keep in mind, this won't work if the input mesh isn't
+ manifold.*/
+#define BMOP_RATIONALIZE_NORMALS 2
+
/*------------- Operator API --------------*/
/*data types that use pointers (arrays, etc) should never
@@ -147,6 +153,7 @@
#define BMO_TestFlag(bm, element, flag) (((BMHeader*)(element))->flags[bm->stackdepth-1].f & (flag))
#define BMO_SetFlag(bm, element, flag) (((BMHeader*)(element))->flags[bm->stackdepth-1].f |= (flag))
#define BMO_ClearFlag(bm, element, flag) (((BMHeader*)(element))->flags[bm->stackdepth-1].f &= ~(flag))
+#define BMO_ToggleFlag(bm, element, flag) (((BMHeader*)(element))->flags[bm->stackdepth-1].f ^= (flag))
/*profiling showed a significant amount of time spent in BMO_TestFlag
void BMO_SetFlag(struct BMesh *bm, void *element, int flag);
Modified: branches/bmesh/blender/source/blender/bmesh/intern/bmesh_interp.c
===================================================================
--- branches/bmesh/blender/source/blender/bmesh/intern/bmesh_interp.c 2011-03-30 16:44:18 UTC (rev 35906)
+++ branches/bmesh/blender/source/blender/bmesh/intern/bmesh_interp.c 2011-03-30 22:46:56 UTC (rev 35907)
@@ -457,9 +457,9 @@
int quad_co(double *x, double *y, double v1[3], double v2[3], double v3[3], double v4[3], double p[3], float n[3])
{
- float projverts[5][3];
- double xn, yn, zn, dprojverts[4][3], origin[3]={0.0f, 0.0f, 0.0f};
- int i, ax, ay;
+ float projverts[5][3], n2[3];
+ double dprojverts[4][3], origin[3]={0.0f, 0.0f, 0.0f};
+ int i;
/*project points into 2d along normal*/
VECCOPY(projverts[0], v1);
@@ -467,7 +467,12 @@
VECCOPY(projverts[2], v3);
VECCOPY(projverts[3], v4);
VECCOPY(projverts[4], p);
-
+
+ normal_quad_v3(n2, projverts[0], projverts[1], projverts[2], projverts[3]);
+
+ if (INPR(n, n2) < -FLT_EPSILON)
+ return 0;
+
/*rotate*/
poly_rotate_plane(n, projverts, 5);
@@ -494,8 +499,8 @@
}
-/*tl is loop to project onto, sl is loop whose internal displacement, co, is being
- projected. x and y are location in loop's mdisps grid of co.*/
+/*tl is loop to project onto, l is loop whose internal displacement, co, is being
+ projected. x and y are location in loop's mdisps grid of point co.*/
static int mdisp_in_mdispquad(BMesh *bm, BMLoop *l, BMLoop *tl, double p[3], double *x, double *y, int res)
{
double v1[3], v2[3], c[3], v3[3], v4[3], e1[3], e2[3];
@@ -534,6 +539,10 @@
double x, y, d, v1[3], v2[3], v3[3], v4[3] = {0.0f, 0.0f, 0.0f}, e1[3], e2[3], e3[3], e4[3];
int ix, iy, res;
+ /*ignore 2-edged faces*/
+ if (target->f->len < 3)
+ return;
+
if (!CustomData_has_layer(&bm->ldata, CD_MDISPS))
return;
Modified: branches/bmesh/blender/source/blender/bmesh/intern/bmesh_mesh.c
===================================================================
--- branches/bmesh/blender/source/blender/bmesh/intern/bmesh_mesh.c 2011-03-30 16:44:18 UTC (rev 35906)
+++ branches/bmesh/blender/source/blender/bmesh/intern/bmesh_mesh.c 2011-03-30 22:46:56 UTC (rev 35907)
@@ -294,18 +294,47 @@
MEM_freeN(projectverts);
}
-/*
- * BMESH BEGIN/END EDIT
- *
- * Functions for setting up a mesh for editing and cleaning up after
- * the editing operations are done. These are called by the tools/operator
- * API for each time a tool is executed.
- *
- * Returns -
- * Nothing
- *
+/*
+ This function ensures correct normals for the mesh, but
+ sets the flag BM_FLIPPED in flipped faces, to allow restoration
+ of original normals.
+
+ if undo is 0: calculate right normals
+ if undo is 1: restore original normals
*/
+//keep in sycn with utils.c!
+#define FACE_FLIP 8
+static void bmesh_rationalize_normals(BMesh *bm, int undo) {
+ BMOperator bmop;
+ BMFace *f;
+ BMIter iter;
+
+ if (undo) {
+ BM_ITER(f, &iter, bm, BM_FACES_OF_MESH, NULL) {
+ if (BM_TestHFlag(f, BM_FLIPPED)) {
+ BM_flip_normal(bm, f);
+ }
+ BM_ClearHFlag(f, BM_FLIPPED);
+ }
+
+ return;
+ }
+
+ BMO_InitOpf(bm, &bmop, "righthandfaces faces=%af doflip=%d", 0);
+
+ BMO_push(bm, &bmop);
+ bmesh_righthandfaces_exec(bm, &bmop);
+
+ BM_ITER(f, &iter, bm, BM_FACES_OF_MESH, NULL) {
+ if (BMO_TestFlag(bm, f, FACE_FLIP))
+ BM_SetHFlag(f, BM_FLIPPED);
+ else BM_ClearHFlag(f, BM_FLIPPED);
+ }
+ BMO_pop(bm);
+ BMO_Finish_Op(bm, &bmop);
+}
+
void bmesh_set_mdisps_space(BMesh *bm, int from, int to)
{
/*switch multires data out of tangent space*/
@@ -357,18 +386,45 @@
}
}
+/*
+ * BMESH BEGIN/END EDIT
+ *
+ * Functions for setting up a mesh for editing and cleaning up after
+ * the editing operations are done. These are called by the tools/operator
+ * API for each time a tool is executed.
+ *
+ * Returns -
+ * Nothing
+ *
+*/
void bmesh_begin_edit(BMesh *bm, int flag) {
+ bm->opflag = flag;
+
/*switch multires data out of tangent space*/
- if ((flag & BMOP_UNTAN_MULTIRES) && CustomData_has_layer(&bm->ldata, CD_MDISPS))
+ if ((flag & BMOP_UNTAN_MULTIRES) && CustomData_has_layer(&bm->ldata, CD_MDISPS)) {
bmesh_set_mdisps_space(bm, MULTIRES_SPACE_TANGENT, MULTIRES_SPACE_ABSOLUTE);
+
+ /*ensure correct normals, if possible*/
+ bmesh_rationalize_normals(bm, 0);
+ BM_Compute_Normals(bm);
+ } else if (flag & BMOP_RATIONALIZE_NORMALS) {
+ bmesh_rationalize_normals(bm, 0);
+ }
}
void bmesh_end_edit(BMesh *bm, int flag){
+ /*switch multires data into tangent space*/
+ if ((flag & BMOP_UNTAN_MULTIRES) && CustomData_has_layer(&bm->ldata, CD_MDISPS)) {
+ /*set normals to their previous winding*/
+ bmesh_rationalize_normals(bm, 1);
+ bmesh_set_mdisps_space(bm, MULTIRES_SPACE_ABSOLUTE, MULTIRES_SPACE_TANGENT);
+ } else if (flag & BMOP_RATIONALIZE_NORMALS) {
+ bmesh_rationalize_normals(bm, 1);
+ }
+
+ bm->opflag = 0;
+
/*compute normals, clear temp flags and flush selections*/
BM_Compute_Normals(bm);
BM_SelectMode_Flush(bm);
-
- /*switch multires data into tangent space*/
- if ((flag & BMOP_UNTAN_MULTIRES) && CustomData_has_layer(&bm->ldata, CD_MDISPS))
- bmesh_set_mdisps_space(bm, MULTIRES_SPACE_ABSOLUTE, MULTIRES_SPACE_TANGENT);
}
Modified: branches/bmesh/blender/source/blender/bmesh/intern/bmesh_newcore.c
===================================================================
--- branches/bmesh/blender/source/blender/bmesh/intern/bmesh_newcore.c 2011-03-30 16:44:18 UTC (rev 35906)
+++ branches/bmesh/blender/source/blender/bmesh/intern/bmesh_newcore.c 2011-03-30 22:46:56 UTC (rev 35907)
@@ -665,15 +665,12 @@
int bmesh_loop_reverse_loop(BMesh *bm, BMFace *f, BMLoopList *lst){
BMLoop *l = lst->first, *curloop, *oldprev, *oldnext;
- BMEdge *staticedar[64], **edar;
- int i, j, edok, len = 0;
+ BMEdge **edar = NULL;
+ MDisps *md;
+ BLI_array_staticdeclare(edar, 64);
+ int i, j, edok, len = 0, do_disps = CustomData_has_layer(&bm->ldata, CD_MDISPS);
len = bmesh_loop_length(l);
- if(len >= 64){
- edar = MEM_callocN(sizeof(BMEdge *)* len, "BM Edge pointer array");
- } else {
- edar = staticedar;
- }
for(i=0, curloop = l; i< len; i++, curloop= ((BMLoop*)(curloop->next)) ){
curloop->e->head.eflag1 = 0;
@@ -681,7 +678,7 @@
bmesh_radial_remove_loop(curloop, curloop->e);
/*in case of border edges we HAVE to zero out curloop->radial Next/Prev*/
curloop->radial_next = curloop->radial_prev = NULL;
- edar[i] = curloop->e;
+ BLI_array_append(edar, curloop->e);
}
/*actually reverse the loop.*/
@@ -691,6 +688,24 @@
curloop->next = (BMLoop*)oldprev;
curloop->prev = (BMLoop*)oldnext;
curloop = oldnext;
+
+ if (do_disps) {
+ float (*co)[3];
+ int x, y, sides;
+
+ md = CustomData_bmesh_get(&bm->ldata, curloop->head.data, CD_MDISPS);
+ if (!md->totdisp || !md->disps)
+ continue;
+
+ sides=sqrt(md->totdisp);
+ co = md->disps;
+
+ for (x=0; x<sides; x++) {
+ for (y=0; y<x; y++) {
+ swap_v3_v3(co[y*sides+x], co[sides*x + y]);
+ }
+ }
+ }
}
if(len == 2){ //two edged face
@@ -722,8 +737,7 @@
CHECK_ELEMENT(bm, curloop->f);
}
- if (edar != staticedar)
- MEM_freeN(edar);
+ BLI_array_free(edar);
CHECK_ELEMENT(bm, f);
Modified: branches/bmesh/blender/source/blender/bmesh/intern/bmesh_opdefines.c
===================================================================
--- branches/bmesh/blender/source/blender/bmesh/intern/bmesh_opdefines.c 2011-03-30 16:44:18 UTC (rev 35906)
+++ branches/bmesh/blender/source/blender/bmesh/intern/bmesh_opdefines.c 2011-03-30 22:46:56 UTC (rev 35907)
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list