brought back x-mirror editing, though it's currently buggy. also made tesselation face normals writable to disk.
This commit is contained in:
parent
b8b6fad640
commit
d6158a4019
|
@ -57,6 +57,10 @@ typedef struct BMEditMesh {
|
||||||
/*Mesh structure this editmesh came from, if it came from one*/
|
/*Mesh structure this editmesh came from, if it came from one*/
|
||||||
struct Mesh *me;
|
struct Mesh *me;
|
||||||
struct Object *ob;
|
struct Object *ob;
|
||||||
|
|
||||||
|
/*temp variables for x-mirror editing*/
|
||||||
|
int mirror_cdlayer;
|
||||||
|
int mirr_free_arrays;
|
||||||
} BMEditMesh;
|
} BMEditMesh;
|
||||||
|
|
||||||
void BMEdit_RecalcTesselation(BMEditMesh *tm);
|
void BMEdit_RecalcTesselation(BMEditMesh *tm);
|
||||||
|
|
|
@ -936,7 +936,7 @@ const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
|
||||||
layerSwap_mcol, layerDefault_mcol},
|
layerSwap_mcol, layerDefault_mcol},
|
||||||
{sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
|
{sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
|
||||||
/* 3 floats per normal vector */
|
/* 3 floats per normal vector */
|
||||||
{sizeof(float)*3, "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
|
{sizeof(float)*3, "vec3f", 1, NULL, NULL, NULL, NULL, NULL, NULL},
|
||||||
{sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
|
{sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
|
||||||
{sizeof(MFloatProperty), "MFloatProperty",1,"Float",NULL,NULL,NULL,NULL},
|
{sizeof(MFloatProperty), "MFloatProperty",1,"Float",NULL,NULL,NULL,NULL},
|
||||||
{sizeof(MIntProperty), "MIntProperty",1,"Int",NULL,NULL,NULL,NULL},
|
{sizeof(MIntProperty), "MIntProperty",1,"Int",NULL,NULL,NULL,NULL},
|
||||||
|
|
|
@ -316,6 +316,7 @@ void BM_Data_Interp_From_Verts(struct BMesh *bm, struct BMVert *v1, struct BMVer
|
||||||
void BM_Data_Facevert_Edgeinterp(struct BMesh *bm, struct BMVert *v1, struct BMVert *v2, struct BMVert *v, struct BMEdge *e1, float fac);
|
void BM_Data_Facevert_Edgeinterp(struct BMesh *bm, struct BMVert *v1, struct BMVert *v2, struct BMVert *v, struct BMEdge *e1, float fac);
|
||||||
//void bmesh_data_interp_from_face(struct BMesh *bm, struct BMFace *source, struct BMFace *target);
|
//void bmesh_data_interp_from_face(struct BMesh *bm, struct BMFace *source, struct BMFace *target);
|
||||||
void BM_add_data_layer(BMesh *em, CustomData *data, int type);
|
void BM_add_data_layer(BMesh *em, CustomData *data, int type);
|
||||||
|
void BM_add_data_layer_named(BMesh *bm, CustomData *data, int type, char *name);
|
||||||
void BM_free_data_layer(BMesh *em, CustomData *data, int type);
|
void BM_free_data_layer(BMesh *em, CustomData *data, int type);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -254,6 +254,18 @@ void BM_add_data_layer(BMesh *bm, CustomData *data, int type)
|
||||||
if (olddata.layers) MEM_freeN(olddata.layers);
|
if (olddata.layers) MEM_freeN(olddata.layers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BM_add_data_layer_named(BMesh *bm, CustomData *data, int type, char *name)
|
||||||
|
{
|
||||||
|
CustomData olddata;
|
||||||
|
|
||||||
|
olddata= *data;
|
||||||
|
olddata.layers= (olddata.layers)? MEM_dupallocN(olddata.layers): NULL;
|
||||||
|
CustomData_add_layer_named(data, type, CD_DEFAULT, NULL, 0, name);
|
||||||
|
|
||||||
|
update_data_blocks(bm, &olddata, data);
|
||||||
|
if (olddata.layers) MEM_freeN(olddata.layers);
|
||||||
|
}
|
||||||
|
|
||||||
void BM_free_data_layer(BMesh *bm, CustomData *data, int type)
|
void BM_free_data_layer(BMesh *bm, CustomData *data, int type)
|
||||||
{
|
{
|
||||||
CustomData olddata;
|
CustomData olddata;
|
||||||
|
|
|
@ -128,35 +128,14 @@ void BM_Select_Vert(BMesh *bm, BMVert *v, int select)
|
||||||
if (BM_TestHFlag(v, BM_SELECT)) bm->totvertsel -= 1;
|
if (BM_TestHFlag(v, BM_SELECT)) bm->totvertsel -= 1;
|
||||||
BM_ClearHFlag(v, BM_SELECT);
|
BM_ClearHFlag(v, BM_SELECT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*BMESH_TODO hrm, not sure if flushing here is such a good idea. . .
|
|
||||||
but probably easier then calling a EDBM_Normalize_Selection after
|
|
||||||
each tool?*/
|
|
||||||
#if 0
|
|
||||||
BM_ITER(e, &iter, bm, BM_EDGES_OF_VERT, v) {
|
|
||||||
if (!BM_TestHFlag(e, BM_SELECT) && BM_TestHFlag(e->v1, BM_SELECT)
|
|
||||||
&& BM_TestHFlag(e->v2, BM_SELECT)) {
|
|
||||||
BM_SetHFlag(e, BM_SELECT);
|
|
||||||
bm->totedgesel += 1;
|
|
||||||
} else if (BM_TestHFlag(e, BM_SELECT) && (!BM_TestHFlag(e->v1, BM_SELECT)
|
|
||||||
|| !BM_TestHFlag(e->v2, BM_SELECT))) {
|
|
||||||
BM_ClearHFlag(e, BM_SELECT);
|
|
||||||
bm->totedgesel -= 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* BMESH SELECT EDGE
|
* BMESH SELECT EDGE
|
||||||
*
|
*
|
||||||
* Changes selection state of a single edge
|
* Changes selection state of a single edge
|
||||||
* in a mesh. Note that this is actually not
|
* in a mesh. Note that this may not be
|
||||||
* 100 percent reliable. Deselecting an edge
|
* 100 percent reliable.
|
||||||
* will also deselect both its vertices
|
|
||||||
* regardless of the selection state of
|
|
||||||
* other edges incident upon it. Fixing this
|
|
||||||
* issue breaks multi-select mode though...
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -165,7 +144,7 @@ void BM_Select_Edge(BMesh *bm, BMEdge *e, int select)
|
||||||
int candesel;
|
int candesel;
|
||||||
int testiso = 1;
|
int testiso = 1;
|
||||||
|
|
||||||
/*I might move this logic to bmeshutils_mods.c, where it'd be invoked
|
/*I might move this logic to editors/mesh/bmesh_select.c, where it'd be invoked
|
||||||
by the selection tools. in that case, we'd still retain the checks
|
by the selection tools. in that case, we'd still retain the checks
|
||||||
for if an edge's verts can be deselected.*/
|
for if an edge's verts can be deselected.*/
|
||||||
|
|
||||||
|
|
|
@ -85,6 +85,28 @@ struct rcti;
|
||||||
|
|
||||||
/* bmeshutils.c */
|
/* bmeshutils.c */
|
||||||
|
|
||||||
|
/*x-mirror editing api. usage:
|
||||||
|
|
||||||
|
EDBM_CacheMirrorVerts(em);
|
||||||
|
...
|
||||||
|
...
|
||||||
|
BM_ITER(v, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
|
||||||
|
mirrorv = EDBM_GetMirrorVert(em, v);
|
||||||
|
}
|
||||||
|
...
|
||||||
|
...
|
||||||
|
EDBM_EndMirrorCache(em);
|
||||||
|
|
||||||
|
note: why do we only allow x axis mirror editing?
|
||||||
|
*/
|
||||||
|
void EDBM_CacheMirrorVerts(struct BMEditMesh *em);
|
||||||
|
|
||||||
|
/*retrieves mirrored cache vert, or NULL if there isn't one.
|
||||||
|
note: calling this without ensuring the mirror cache state
|
||||||
|
is bad.*/
|
||||||
|
struct BMVert *EDBM_GetMirrorVert(struct BMEditMesh *em, struct BMVert *v);
|
||||||
|
void EDBM_EndMirrorCache(struct BMEditMesh *em);
|
||||||
|
|
||||||
void EDBM_RecalcNormals(struct BMEditMesh *em);
|
void EDBM_RecalcNormals(struct BMEditMesh *em);
|
||||||
|
|
||||||
void EDBM_MakeEditBMesh(struct ToolSettings *ts, struct Scene *scene, struct Object *ob);
|
void EDBM_MakeEditBMesh(struct ToolSettings *ts, struct Scene *scene, struct Object *ob);
|
||||||
|
|
|
@ -73,6 +73,8 @@
|
||||||
#include "BKE_report.h"
|
#include "BKE_report.h"
|
||||||
#include "BKE_tessmesh.h"
|
#include "BKE_tessmesh.h"
|
||||||
|
|
||||||
|
#include "bmesh.h"
|
||||||
|
|
||||||
#include "BIF_gl.h"
|
#include "BIF_gl.h"
|
||||||
#include "BIF_glutil.h"
|
#include "BIF_glutil.h"
|
||||||
|
|
||||||
|
@ -86,8 +88,8 @@
|
||||||
|
|
||||||
#include "UI_interface.h"
|
#include "UI_interface.h"
|
||||||
|
|
||||||
|
#include "editbmesh_bvh.h"
|
||||||
#include "mesh_intern.h"
|
#include "mesh_intern.h"
|
||||||
#include "bmesh.h"
|
|
||||||
|
|
||||||
void EDBM_RecalcNormals(BMEditMesh *em)
|
void EDBM_RecalcNormals(BMEditMesh *em)
|
||||||
{
|
{
|
||||||
|
@ -805,3 +807,91 @@ int EDBM_vertColorCheck(BMEditMesh *em)
|
||||||
return em && em->bm->totface && CustomData_has_layer(&em->bm->ldata, CD_MLOOPCOL);
|
return em && em->bm->totface && CustomData_has_layer(&em->bm->ldata, CD_MLOOPCOL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void EDBM_CacheMirrorVerts(BMEditMesh *em)
|
||||||
|
{
|
||||||
|
BMBVHTree *tree = BMBVH_NewBVH(em);
|
||||||
|
BMIter iter;
|
||||||
|
BMVert *v;
|
||||||
|
float invmat[4][4];
|
||||||
|
int li, i;
|
||||||
|
|
||||||
|
if (!em->vert_index) {
|
||||||
|
EDBM_init_index_arrays(em, 1, 0, 0);
|
||||||
|
em->mirr_free_arrays = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!CustomData_get_layer_named(&em->bm->vdata, CD_PROP_INT, "__mirror_index")) {
|
||||||
|
BM_add_data_layer_named(em->bm, &em->bm->vdata, CD_PROP_INT, "__mirror_index");
|
||||||
|
}
|
||||||
|
|
||||||
|
li = CustomData_get_named_layer_index(&em->bm->vdata, CD_PROP_INT, "__mirror_index");
|
||||||
|
em->bm->vdata.layers[li].flag |= CD_FLAG_TEMPORARY;
|
||||||
|
|
||||||
|
/*multiply verts by object matrix, temporarily*/
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
BM_ITER(v, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
|
||||||
|
BMINDEX_SET(v, i);
|
||||||
|
i++;
|
||||||
|
|
||||||
|
if (em->ob)
|
||||||
|
mul_m4_v3(em->ob->obmat, v->co);
|
||||||
|
}
|
||||||
|
|
||||||
|
BM_ITER(v, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
|
||||||
|
BMVert *mirr;
|
||||||
|
int *idx = CustomData_bmesh_get_layer_n(&em->bm->vdata, v->head.data, li);
|
||||||
|
float co[3] = {-v->co[0], v->co[1], v->co[2]};
|
||||||
|
|
||||||
|
//temporary for testing, check for selection
|
||||||
|
if (!BM_TestHFlag(v, BM_SELECT))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
mirr = BMBVH_FindClosestVertTopo(tree, co, BM_SEARCH_MAXDIST, v);
|
||||||
|
if (mirr && mirr != v) {
|
||||||
|
*idx = BMINDEX_GET(mirr);
|
||||||
|
idx = CustomData_bmesh_get_layer_n(&em->bm->vdata,mirr->head.data, li);
|
||||||
|
*idx = BMINDEX_GET(v);
|
||||||
|
} else *idx = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*unmultiply by object matrix*/
|
||||||
|
if (em->ob) {
|
||||||
|
i = 0;
|
||||||
|
invert_m4_m4(invmat, em->ob->obmat);
|
||||||
|
BM_ITER(v, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
|
||||||
|
BMINDEX_SET(v, i);
|
||||||
|
i++;
|
||||||
|
|
||||||
|
mul_m4_v3(invmat, v->co);
|
||||||
|
}
|
||||||
|
|
||||||
|
BMBVH_FreeBVH(tree);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BMVert *EDBM_GetMirrorVert(BMEditMesh *em, BMVert *v)
|
||||||
|
{
|
||||||
|
int *mirr = CustomData_bmesh_get_layer_n(&em->bm->vdata, v->head.data, em->mirror_cdlayer);
|
||||||
|
|
||||||
|
if (mirr && *mirr >=0 && *mirr < em->bm->totvert) {
|
||||||
|
if (!em->vert_index) {
|
||||||
|
printf("err: should only be called between "
|
||||||
|
"EDBM_CacheMirrorVerts and EDBM_EndMirrorCache");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return em->vert_index[*mirr];
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EDBM_EndMirrorCache(BMEditMesh *em)
|
||||||
|
{
|
||||||
|
if (em->mirr_free_arrays) {
|
||||||
|
MEM_freeN(em->vert_index);
|
||||||
|
em->vert_index = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -325,7 +325,7 @@ static float topo_compare(BMesh *bm, BMVert *v1, BMVert *v2, int tag)
|
||||||
BLI_array_declare(stack2);
|
BLI_array_declare(stack2);
|
||||||
float vec1[3], vec2[3], minangle=FLT_MAX, w;
|
float vec1[3], vec2[3], minangle=FLT_MAX, w;
|
||||||
int lvl=1;
|
int lvl=1;
|
||||||
static int maxlevel = 8;
|
static int maxlevel = 3;
|
||||||
|
|
||||||
/*ok. see how similar v is to v2, based on topological similaritys in the local
|
/*ok. see how similar v is to v2, based on topological similaritys in the local
|
||||||
topological neighborhood*/
|
topological neighborhood*/
|
||||||
|
@ -409,17 +409,65 @@ static float topo_compare(BMesh *bm, BMVert *v1, BMVert *v2, int tag)
|
||||||
if (!s1->curl)
|
if (!s1->curl)
|
||||||
s1->curl = s1->cure->loop;
|
s1->curl = s1->cure->loop;
|
||||||
if (!s2->curl) {
|
if (!s2->curl) {
|
||||||
|
float no1[3], no2[3], angle;
|
||||||
int wind1, wind2;
|
int wind1, wind2;
|
||||||
|
|
||||||
s2->curl = s2->cure->loop;
|
s2->curl = s2->cure->loop;
|
||||||
|
|
||||||
/*find which of two possible faces to use*/
|
/*find which of two possible faces to use*/
|
||||||
wind1 = winding(s1->v->co, s1->lastv->co,
|
l1 = BM_OtherFaceLoop(s1->curl->e, s1->curl->f, s1->lastv);
|
||||||
s1->v == s1->curl->v ? ((BMLoop*)s1->curl->head.prev->prev)->v->co : ((BMLoop*)s1->curl->head.next->next)->v->co);
|
l2 = BM_OtherFaceLoop(s2->curl->e, s2->curl->f, s2->lastv);
|
||||||
|
|
||||||
wind2 = winding(s2->v->co, s2->lastv->co,
|
if (l1->v == s2->lastv) {
|
||||||
s2->v == s2->curl->v ? ((BMLoop*)s2->curl->head.prev->prev)->v->co : ((BMLoop*)s2->curl->head.next->next)->v->co);
|
l1 = (BMLoop*) l1->head.next;
|
||||||
|
if (l1->v == s2->v)
|
||||||
|
l1 = (BMLoop*) l1->head.prev->prev;
|
||||||
|
} else if (l1->v == s2->v) {
|
||||||
|
l1 = (BMLoop*) l1->head.next;
|
||||||
|
if (l1->v == s2->lastv)
|
||||||
|
l1 = (BMLoop*) l1->head.prev->prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (l2->v == s2->lastv) {
|
||||||
|
l2 = (BMLoop*) l2->head.next;
|
||||||
|
if (l2->v == s2->v)
|
||||||
|
l2 = (BMLoop*) l2->head.prev->prev;
|
||||||
|
} else if (l2->v == s2->v) {
|
||||||
|
l2 = (BMLoop*) l2->head.next;
|
||||||
|
if (l2->v == s2->lastv)
|
||||||
|
l2 = (BMLoop*) l2->head.prev->prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
wind1 = winding(s1->v->co, s1->lastv->co, l1->v->co);
|
||||||
|
|
||||||
|
wind2 = winding(s2->v->co, s2->lastv->co, l2->v->co);
|
||||||
|
|
||||||
|
/*if angle between the two adjacent faces is greater then 90 degrees,
|
||||||
|
we need to flip wind2*/
|
||||||
|
l1 = l2;
|
||||||
|
l2 = s2->curl->radial.next->data;
|
||||||
|
l2 = BM_OtherFaceLoop(l2->e, l2->f, s2->lastv);
|
||||||
|
|
||||||
|
if (l2->v == s2->lastv) {
|
||||||
|
l2 = (BMLoop*) l2->head.next;
|
||||||
|
if (l2->v == s2->v)
|
||||||
|
l2 = (BMLoop*) l2->head.prev->prev;
|
||||||
|
} else if (l2->v == s2->v) {
|
||||||
|
l2 = (BMLoop*) l2->head.next;
|
||||||
|
if (l2->v == s2->lastv)
|
||||||
|
l2 = (BMLoop*) l2->head.prev->prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
normal_tri_v3(no1, s2->v->co, s2->lastv->co, l1->v->co);
|
||||||
|
normal_tri_v3(no2, s2->v->co, s2->lastv->co, l2->v->co);
|
||||||
|
|
||||||
|
/*enforce identical winding as no1*/
|
||||||
|
mul_v3_fl(no2, -1.0);
|
||||||
|
|
||||||
|
angle = angle_v3v3(no1, no2);
|
||||||
|
if (angle > M_PI/2 - FLT_EPSILON*2)
|
||||||
|
wind2 = !wind2;
|
||||||
|
|
||||||
if (wind1 == wind2)
|
if (wind1 == wind2)
|
||||||
s2->curl = s2->curl->radial.next->data;
|
s2->curl = s2->curl->radial.next->data;
|
||||||
}
|
}
|
||||||
|
@ -444,10 +492,10 @@ static float topo_compare(BMesh *bm, BMVert *v1, BMVert *v2, int tag)
|
||||||
/*repush the current stack item*/
|
/*repush the current stack item*/
|
||||||
lvl++;
|
lvl++;
|
||||||
|
|
||||||
if (maxlevel % 2 == 0) {
|
//if (maxlevel % 2 == 0) {
|
||||||
BLI_ghash_insert(gh, v1, NULL);
|
BLI_ghash_insert(gh, v1, NULL);
|
||||||
BLI_ghash_insert(gh, v2, NULL);
|
BLI_ghash_insert(gh, v2, NULL);
|
||||||
}
|
//}
|
||||||
|
|
||||||
/*now push the child node*/
|
/*now push the child node*/
|
||||||
SPUSH(stack1, lvl, v1, lastv1, e1);
|
SPUSH(stack1, lvl, v1, lastv1, e1);
|
||||||
|
@ -565,17 +613,13 @@ BMVert *BMBVH_FindClosestVertTopo(BMBVHTree *tree, float *co, float maxdist, BMV
|
||||||
VECCOPY(hit.co, co);
|
VECCOPY(hit.co, co);
|
||||||
VECCOPY(tree->co, co);
|
VECCOPY(tree->co, co);
|
||||||
hit.index = -1;
|
hit.index = -1;
|
||||||
hit.dist = 10.0f;
|
hit.dist = maxdist;
|
||||||
|
|
||||||
tree->curw = FLT_MAX;
|
tree->curw = FLT_MAX;
|
||||||
tree->curd = FLT_MAX;
|
tree->curd = FLT_MAX;
|
||||||
tree->curv = NULL;
|
tree->curv = NULL;
|
||||||
tree->curtag = 1;
|
tree->curtag = 1;
|
||||||
|
|
||||||
BM_ITER(v, &iter, tree->bm, BM_VERTS_OF_MESH, NULL) {
|
|
||||||
BMINDEX_SET(v, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
tree->gh = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
|
tree->gh = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
|
||||||
|
|
||||||
tree->maxdist = maxdist;
|
tree->maxdist = maxdist;
|
||||||
|
|
|
@ -17,6 +17,8 @@ struct BMFace *BMBVH_RayCast(struct BMBVHTree *tree, float *co, float *dir, floa
|
||||||
int BMBVH_EdgeVisible(struct BMBVHTree *tree, struct BMEdge *e,
|
int BMBVH_EdgeVisible(struct BMBVHTree *tree, struct BMEdge *e,
|
||||||
struct RegionView3D *r3d, struct Object *obedit);
|
struct RegionView3D *r3d, struct Object *obedit);
|
||||||
|
|
||||||
|
#define BM_SEARCH_MAXDIST 0.4f
|
||||||
|
|
||||||
/*find a vert closest to co in a sphere of radius maxdist*/
|
/*find a vert closest to co in a sphere of radius maxdist*/
|
||||||
struct BMVert *BMBVH_FindClosestVert(struct BMBVHTree *tree, float *co, float maxdist);
|
struct BMVert *BMBVH_FindClosestVert(struct BMBVHTree *tree, float *co, float maxdist);
|
||||||
struct BMVert *BMBVH_FindClosestVertTopo(struct BMBVHTree *tree, float *co,
|
struct BMVert *BMBVH_FindClosestVertTopo(struct BMBVHTree *tree, float *co,
|
||||||
|
|
|
@ -2167,6 +2167,7 @@ static void createTransEditVerts(bContext *C, TransInfo *t)
|
||||||
|
|
||||||
if (t->flag & T_MIRROR)
|
if (t->flag & T_MIRROR)
|
||||||
{
|
{
|
||||||
|
EDBM_CacheMirrorVerts(em);
|
||||||
mirror = 1;
|
mirror = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2359,12 +2360,12 @@ static void createTransEditVerts(bContext *C, TransInfo *t)
|
||||||
/* Mirror? */
|
/* Mirror? */
|
||||||
|
|
||||||
//BMESH_TODO
|
//BMESH_TODO
|
||||||
//if( (mirror>0 && tob->iloc[0]>0.0f) || (mirror<0 && tob->iloc[0]<0.0f)) {
|
if( (mirror>0 && tob->iloc[0]>0.0f) || (mirror<0 && tob->iloc[0]<0.0f)) {
|
||||||
// BMVert *vmir= editmesh_get_x_mirror_vert(t->obedit, em, eve, tob->iloc, a); /* initializes octree on first call */
|
BMVert *vmir= EDBM_GetMirrorVert(em, eve); //t->obedit, em, eve, tob->iloc, a);
|
||||||
// if(vmir != eve) {
|
if(vmir && vmir != eve) {
|
||||||
// tob->extra = vmir;
|
tob->extra = vmir;
|
||||||
// }
|
}
|
||||||
//}
|
}
|
||||||
tob++;
|
tob++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2390,6 +2391,12 @@ static void createTransEditVerts(bContext *C, TransInfo *t)
|
||||||
MEM_freeN(defmats);
|
MEM_freeN(defmats);
|
||||||
|
|
||||||
BLI_array_free(selstate);
|
BLI_array_free(selstate);
|
||||||
|
|
||||||
|
if (t->flag & T_MIRROR)
|
||||||
|
{
|
||||||
|
EDBM_EndMirrorCache(em);
|
||||||
|
mirror = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* *** NODE EDITOR *** */
|
/* *** NODE EDITOR *** */
|
||||||
|
|
|
@ -250,7 +250,6 @@ static void editbmesh_apply_to_mirror(TransInfo *t)
|
||||||
{
|
{
|
||||||
TransData *td = t->data;
|
TransData *td = t->data;
|
||||||
BMVert *eve;
|
BMVert *eve;
|
||||||
BMIter iter;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for(i = 0 ; i < t->total; i++, td++) {
|
for(i = 0 ; i < t->total; i++, td++) {
|
||||||
|
|
Loading…
Reference in New Issue