Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTon Roosendaal <ton@blender.org>2005-12-01 22:04:57 +0300
committerTon Roosendaal <ton@blender.org>2005-12-01 22:04:57 +0300
commitc4a1d655aeb54abcb4bdf02491e002d69020a786 (patch)
tree733461cbe1559e14738c5b72f6716c77dcd656e2
parenta09fbc080dea64078a6cfb307a720194ee30e6db (diff)
True X-mirror mesh editing!
Set the option in EditMode, in 2nd mesh tools panel. It only works on transform options now (grab/rot/scale), and of course assumes a near- perfect symmetrical mesh. Mesh Object itself can be on any location though (and rotated etc).
-rw-r--r--source/blender/blenkernel/BKE_utildefines.h5
-rw-r--r--source/blender/include/BIF_meshtools.h4
-rw-r--r--source/blender/include/blendef.h2
-rwxr-xr-xsource/blender/include/transform.h1
-rw-r--r--source/blender/src/buttons_editing.c1
-rw-r--r--source/blender/src/editmesh.c3
-rw-r--r--source/blender/src/editmesh_mods.c12
-rw-r--r--source/blender/src/meshtools.c55
-rwxr-xr-xsource/blender/src/transform_conversions.c25
-rwxr-xr-xsource/blender/src/transform_generics.c27
10 files changed, 96 insertions, 39 deletions
diff --git a/source/blender/blenkernel/BKE_utildefines.h b/source/blender/blenkernel/BKE_utildefines.h
index a18a43fb7b8..f0b05802e97 100644
--- a/source/blender/blenkernel/BKE_utildefines.h
+++ b/source/blender/blenkernel/BKE_utildefines.h
@@ -58,11 +58,6 @@
#define ELEM7(a, b, c, d, e, f, g, h) ( ELEM3(a, b, c, d) || ELEM4(a, e, f, g, h) )
#define ELEM8(a, b, c, d, e, f, g, h, i) ( ELEM4(a, b, c, d, e) || ELEM4(a, f, g, h, i) )
-/* pointer magic, only to be used for the max 16 Gig mem period */
-/* note that int is signed! */
-#define POINTER_TO_INT(poin) (int)( ((long)(poin))>>3 )
-#define INT_TO_POINTER(int) (void *)( ((long)(int))<<3 )
-
/* string compare */
#define STREQ(str, a) ( strcmp((str), (a))==0 )
#define STREQ2(str, a, b) ( STREQ(str, a) || STREQ(str, b) )
diff --git a/source/blender/include/BIF_meshtools.h b/source/blender/include/BIF_meshtools.h
index b5f5a91c50c..8df5e7255a5 100644
--- a/source/blender/include/BIF_meshtools.h
+++ b/source/blender/include/BIF_meshtools.h
@@ -34,6 +34,7 @@
#define BIF_MESHTOOLS_H
struct Object;
+struct EditVert;
extern void join_mesh(void);
@@ -42,8 +43,9 @@ extern void slowerdraw(void);
extern void sort_faces(void);
-extern int mesh_octree_table(struct Object *ob, float *co, char mode);
+extern long mesh_octree_table(struct Object *ob, float *co, char mode);
extern int mesh_get_x_mirror_vert(struct Object *ob, int index);
+extern struct EditVert *editmesh_get_x_mirror_vert(struct Object *ob, float *co);
#endif
diff --git a/source/blender/include/blendef.h b/source/blender/include/blendef.h
index ab36972ea18..05e06afca4e 100644
--- a/source/blender/include/blendef.h
+++ b/source/blender/include/blendef.h
@@ -388,7 +388,7 @@
#define B_AUTOFGON 32
#define B_KNIFE 0x80
#define B_PERCENTSUBD 0x40
-
+#define B_MESH_X_MIRROR 0x100
/* DISPLAYMODE */
#define R_DISPLAYVIEW 0
diff --git a/source/blender/include/transform.h b/source/blender/include/transform.h
index 463fceaa0a1..c8781a75e2e 100755
--- a/source/blender/include/transform.h
+++ b/source/blender/include/transform.h
@@ -125,6 +125,7 @@ typedef struct TransData {
struct Object *ob;
TransDataExtension *ext; /* for objects, poses. 1 single malloc per TransInfo! */
TransDataIpokey *tdi; /* for objects, ipo keys. per transdata a malloc */
+ void *tdmir; /* mirrored element pointer, in editmode mesh to EditVert */
short flag; /* Various flags */
short protectflag; /* If set, copy of Object or PoseChannel protection */
} TransData;
diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c
index 53607bbe848..17b72a856c2 100644
--- a/source/blender/src/buttons_editing.c
+++ b/source/blender/src/buttons_editing.c
@@ -3262,6 +3262,7 @@ static void editing_panel_mesh_tools1(Object *ob, Mesh *me)
uiDefButBitI(block, TOG, G_DRAW_FACEAREA, REDRAWVIEW3D, "Face Area", 1125,44,150,19, &G.f, 0, 0, 0, 0, "Displays the area of selected faces");
uiBlockEndAlign(block);
+ uiDefButBitS(block, TOG, B_MESH_X_MIRROR, B_DIFF, "X-axis mirror",1125,0,150,19, &G.scene->toolsettings->editbutflag, 0, 0, 0, 0, "While using transforms, mirrors the transformation");
}
char *get_vertexgroup_menustr(Object *ob)
diff --git a/source/blender/src/editmesh.c b/source/blender/src/editmesh.c
index 2eb59c146f2..eb77356ecdc 100644
--- a/source/blender/src/editmesh.c
+++ b/source/blender/src/editmesh.c
@@ -78,6 +78,7 @@
#include "BIF_editmesh.h"
#include "BIF_editmode_undo.h"
#include "BIF_interface.h"
+#include "BIF_meshtools.h"
#include "BIF_mywindow.h"
#include "BIF_space.h"
#include "BIF_screen.h"
@@ -537,6 +538,8 @@ void free_editMesh(EditMesh *em)
em->alledges= em->curedge= NULL;
em->allfaces= em->curface= NULL;
+ mesh_octree_table(NULL, NULL, 'e');
+
G.totvert= G.totface= 0;
}
diff --git a/source/blender/src/editmesh_mods.c b/source/blender/src/editmesh_mods.c
index 2d1d20c6b8e..3c568266c05 100644
--- a/source/blender/src/editmesh_mods.c
+++ b/source/blender/src/editmesh_mods.c
@@ -103,16 +103,6 @@ editmesh_mods.c, UI level access, no geometry changes
/* ****************************** MIRROR **************** */
-static EditVert *get_x_mirror_vert(EditVert *eve)
-{
- int index;
-
- index= mesh_get_x_mirror_vert(G.obedit, POINTER_TO_INT(eve));
- if(index != -1)
- return INT_TO_POINTER(index);
- return NULL;
-}
-
void EM_select_mirrored(void)
{
if(G.scene->selectmode & SCE_SELECT_VERTEX) {
@@ -121,7 +111,7 @@ void EM_select_mirrored(void)
for(eve= em->verts.first; eve; eve= eve->next) {
if(eve->f & SELECT) {
- v1= get_x_mirror_vert(eve);
+ v1= editmesh_get_x_mirror_vert(G.obedit, eve->co);
if(v1) {
eve->f &= ~SELECT;
v1->f |= SELECT;
diff --git a/source/blender/src/meshtools.c b/source/blender/src/meshtools.c
index 1ef7320763c..2b96bbc20b6 100644
--- a/source/blender/src/meshtools.c
+++ b/source/blender/src/meshtools.c
@@ -602,7 +602,7 @@ void sort_faces(void)
typedef struct MocNode {
struct MocNode *next;
- int index[MOC_NODE_RES];
+ long index[MOC_NODE_RES];
} MocNode;
static int mesh_octree_get_base_offs(float *co, float *offs, float *div)
@@ -620,7 +620,7 @@ static int mesh_octree_get_base_offs(float *co, float *offs, float *div)
return (vx*MOC_RES*MOC_RES) + vy*MOC_RES + vz;
}
-static void mesh_octree_add_node(MocNode **bt, int index)
+static void mesh_octree_add_node(MocNode **bt, long index)
{
if(*bt==NULL) {
*bt= MEM_callocN(sizeof(MocNode), "MocNode");
@@ -652,7 +652,7 @@ static void mesh_octree_free_node(MocNode **bt)
/* temporal define, just to make nicer code below */
#define MOC_ADDNODE(vx, vy, vz) mesh_octree_add_node(basetable + ((vx)*MOC_RES*MOC_RES) + (vy)*MOC_RES + (vz), index)
-static void mesh_octree_add_nodes(MocNode **basetable, float *co, float *offs, float *div, int index)
+static void mesh_octree_add_nodes(MocNode **basetable, float *co, float *offs, float *div, long index)
{
float fx, fy, fz;
int vx, vy, vz;
@@ -693,7 +693,7 @@ static void mesh_octree_add_nodes(MocNode **basetable, float *co, float *offs, f
}
-static int mesh_octree_find_index(MocNode **bt, MVert *mvert, float *co)
+static long mesh_octree_find_index(MocNode **bt, MVert *mvert, float *co)
{
float *vec;
int a;
@@ -706,15 +706,13 @@ static int mesh_octree_find_index(MocNode **bt, MVert *mvert, float *co)
/* does mesh verts and editmode, code looks potential dangerous, octree should really be filled OK! */
if(mvert) {
vec= (mvert+(*bt)->index[a]-1)->co;
-
if(FloatCompare(vec, co, MOC_THRESH))
return (*bt)->index[a]-1;
}
else {
- EditVert *eve= (EditVert *)INT_TO_POINTER((*bt)->index[a]);
-
+ EditVert *eve= (EditVert *)((*bt)->index[a]);
if(FloatCompare(eve->co, co, MOC_THRESH))
- return (int)eve;
+ return (*bt)->index[a];
}
}
else return -1;
@@ -728,7 +726,7 @@ static int mesh_octree_find_index(MocNode **bt, MVert *mvert, float *co)
/* mode is 's' start, or 'e' end, or 'u' use */
/* if end, ob can be NULL */
-int mesh_octree_table(Object *ob, float *co, char mode)
+long mesh_octree_table(Object *ob, float *co, char mode)
{
MocNode **bt;
static MocNode **basetable= NULL;
@@ -754,21 +752,23 @@ int mesh_octree_table(Object *ob, float *co, char mode)
/* for quick unit coordinate calculus */
VECCOPY(offs, bb->vec[0]);
- offs[0]+= MOC_THRESH; /* we offset it 1 threshold unit extra */
- offs[1]+= MOC_THRESH;
- offs[2]+= MOC_THRESH;
+ offs[0]-= MOC_THRESH; /* we offset it 1 threshold unit extra */
+ offs[1]-= MOC_THRESH;
+ offs[2]-= MOC_THRESH;
- VecSubf(div, bb->vec[6], offs);
- div[0]+= MOC_THRESH; /* and divide with 1 threshold unit more extra (try 8x8 unit grid on paint) */
- div[1]+= MOC_THRESH;
- div[2]+= MOC_THRESH;
+ VecSubf(div, bb->vec[6], bb->vec[0]);
+ div[0]+= 2*MOC_THRESH; /* and divide with 2 threshold unit more extra (try 8x8 unit grid on paint) */
+ div[1]+= 2*MOC_THRESH;
+ div[2]+= 2*MOC_THRESH;
VecMulf(div, 1.0f/MOC_RES);
if(div[0]==0.0f) div[0]= 1.0f;
if(div[1]==0.0f) div[1]= 1.0f;
if(div[2]==0.0f) div[2]= 1.0f;
-
- if(basetable) /* happens when entering wpaint without closing it */
+ printvecf("ofs", offs);
+ printvecf("div", div);
+
+ if(basetable) /* happens when entering this call without ending it */
mesh_octree_table(ob, co, 'e');
basetable= MEM_callocN(MOC_RES*MOC_RES*MOC_RES*sizeof(void *), "sym table");
@@ -777,12 +777,12 @@ int mesh_octree_table(Object *ob, float *co, char mode)
EditVert *eve;
for(eve= G.editMesh->verts.first; eve; eve= eve->next) {
- mesh_octree_add_nodes(basetable, eve->co, offs, div, POINTER_TO_INT(eve));
+ mesh_octree_add_nodes(basetable, eve->co, offs, div, (long)(eve));
}
}
else {
MVert *mvert;
- int a;
+ long a;
for(a=1, mvert= me->mvert; a<=me->totvert; a++, mvert++) {
mesh_octree_add_nodes(basetable, mvert->co, offs, div, a);
@@ -815,3 +815,18 @@ int mesh_get_x_mirror_vert(Object *ob, int index)
return mesh_octree_table(ob, vec, 'u');
}
+
+EditVert *editmesh_get_x_mirror_vert(Object *ob, float *co)
+{
+ float vec[3];
+ long poinval;
+
+ vec[0]= -co[0];
+ vec[1]= co[1];
+ vec[2]= co[2];
+
+ poinval= mesh_octree_table(ob, vec, 'u');
+ if(poinval != -1)
+ return (EditVert *)(poinval);
+ return NULL;
+} \ No newline at end of file
diff --git a/source/blender/src/transform_conversions.c b/source/blender/src/transform_conversions.c
index 354ab917dd0..6d834129c67 100755
--- a/source/blender/src/transform_conversions.c
+++ b/source/blender/src/transform_conversions.c
@@ -100,6 +100,7 @@
#include "BIF_editsima.h"
#include "BIF_gl.h"
#include "BIF_poseobject.h"
+#include "BIF_meshtools.h"
#include "BIF_mywindow.h"
#include "BIF_resources.h"
#include "BIF_screen.h"
@@ -1409,6 +1410,7 @@ static void VertsToTransData(TransData *td, EditVert *eve)
td->ext = NULL;
td->tdi = NULL;
td->val = NULL;
+ td->tdmir= NULL;
}
static void make_vertexcos__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s)
@@ -1503,7 +1505,8 @@ static void createTransEditVerts(TransInfo *t)
float mtx[3][3], smtx[3][3];
int count=0, countsel=0;
int propmode = t->flag & T_PROP_EDIT;
-
+ int mirror= (G.scene->toolsettings->editbutflag & B_MESH_X_MIRROR);
+
// transform now requires awareness for select mode, so we tag the f1 flags in verts
if(G.scene->selectmode & SCE_SELECT_VERTEX) {
for(eve= em->verts.first; eve; eve= eve->next) {
@@ -1570,6 +1573,17 @@ static void createTransEditVerts(TransInfo *t)
}
}
+ /* find out which half we do */
+ if(mirror) {
+ for (eve=em->verts.first; eve; eve=eve->next) {
+ if(eve->h==0 && eve->f1 && eve->co[0]!=0.0f) {
+ if(eve->co[0]<0.0f)
+ mirror = -1;
+ break;
+ }
+ }
+ }
+
for (eve=em->verts.first; eve; eve=eve->next) {
if(eve->h==0) {
if(propmode || eve->f1) {
@@ -1604,6 +1618,12 @@ static void createTransEditVerts(TransInfo *t)
Mat3CpyMat3(tob->smtx, smtx);
Mat3CpyMat3(tob->mtx, mtx);
}
+
+ /* Mirror? */
+ if( (mirror>0 && tob->iloc[0]>0.0f) || (mirror<0 && tob->iloc[0]<0.0f)) {
+ EditVert *vmir= editmesh_get_x_mirror_vert(G.obedit, tob->iloc); /* initializes octree on first call */
+ if(vmir!=eve) tob->tdmir= vmir;
+ }
tob++;
}
}
@@ -2025,6 +2045,9 @@ void special_aftertrans_update(TransInfo *t)
if(G.obedit) {
if(t->mode==TFM_BONESIZE || t->mode==TFM_BONE_ENVELOPE)
allqueue(REDRAWBUTSEDIT, 0);
+
+ /* table needs to be created for each edit command, since vertices can move etc */
+ mesh_octree_table(G.obedit, NULL, 'e');
}
else if( (t->flag & T_POSE) && t->poseobj) {
bArmature *arm;
diff --git a/source/blender/src/transform_generics.c b/source/blender/src/transform_generics.c
index 0003ce71471..78aa7fe6122 100755
--- a/source/blender/src/transform_generics.c
+++ b/source/blender/src/transform_generics.c
@@ -57,6 +57,7 @@
#include "BIF_editarmature.h"
#include "BIF_editmesh.h"
#include "BIF_editsima.h"
+#include "BIF_meshtools.h"
#include "BKE_action.h"
#include "BKE_anim.h"
@@ -78,6 +79,7 @@
#include "BLI_arithb.h"
#include "BLI_blenlib.h"
+#include "BLI_editVert.h"
#include "blendef.h"
@@ -174,6 +176,28 @@ static void clipMirrorModifier(TransInfo *t, Object *ob)
}
}
+/* assumes G.obedit set to mesh object */
+static void editmesh_apply_to_mirror(TransInfo *t)
+{
+ TransData *td = t->data;
+ EditVert *eve;
+ int i;
+
+ for(i = 0 ; i < t->total; i++, td++) {
+ if (td->flag & TD_NOACTION)
+ break;
+ if (td->loc==NULL)
+ break;
+
+ eve= td->tdmir;
+ if(eve) {
+ eve->co[0]= -td->loc[0];
+ eve->co[1]= td->loc[1];
+ eve->co[2]= td->loc[2];
+ }
+ }
+}
+
/* called for updating while transform acts, once per redraw */
void recalcData(TransInfo *t)
{
@@ -186,6 +210,9 @@ void recalcData(TransInfo *t)
if(t->state != TRANS_CANCEL)
clipMirrorModifier(t, G.obedit);
+ if(G.scene->toolsettings->editbutflag & B_MESH_X_MIRROR)
+ editmesh_apply_to_mirror(t);
+
DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); /* sets recalc flags */
recalc_editnormals();