commit of patch 19268, rotate uvs by wael oraiby

This commit is contained in:
Joseph Eagar
2009-09-02 20:26:12 +00:00
parent bb28b5d1fe
commit cdce0f03c8
9 changed files with 136 additions and 229 deletions

View File

@@ -97,6 +97,10 @@ static void mesh_ensure_tesselation_customdata(Mesh *me)
totcol != CustomData_number_of_layers(&me->ldata, CD_MLOOPCOL))
{
CustomData_free(&me->fdata, me->totface);
me->mface = (void*)me->mtface = (void*)me->mcol = NULL;
me->totface = 0;
memset(&me->fdata, 0, sizeof(&me->fdata));
CustomData_from_bmeshpoly(&me->fdata, &me->pdata, &me->ldata, me->totface);

View File

@@ -50,6 +50,16 @@ enum {
SIMVERT_VGROUP,
};
enum {
OPUVC_AXIS_X = 1,
OPUVC_AXIS_Y
};
enum {
DIRECTION_CW = 1,
DIRECTION_CCW
};
extern BMOpDefine *opdefines[];
extern int bmesh_total_ops;

View File

@@ -246,7 +246,7 @@ void BM_add_data_layer(BMesh *bm, CustomData *data, int type)
olddata= *data;
olddata.layers= (olddata.layers)? MEM_dupallocN(olddata.layers): NULL;
CustomData_add_layer(data, type, CD_CALLOC, NULL, 0);
CustomData_add_layer(data, type, CD_DEFAULT, NULL, 0);
update_data_blocks(bm, &olddata, data);
if (olddata.layers) MEM_freeN(olddata.layers);

View File

@@ -690,6 +690,19 @@ BMOpDefine def_similarverts = {
0
};
/*
** uv rotation
** cycle the uvs
*/
BMOpDefine def_meshrotateuvs = {
"meshrotateuvs",
{{BMOP_OPSLOT_ELEMENT_BUF, "faces"}, /* input faces */
{BMOP_OPSLOT_INT, "dir"}, /* direction */
{0} /*null-terminating sentinel*/},
bmesh_rotateuvs_exec,
0
};
BMOpDefine *opdefines[] = {
&def_splitop,
&def_dupeop,
@@ -735,6 +748,7 @@ BMOpDefine *opdefines[] = {
&def_similarverts,
&def_pointmerge_facedata,
&def_vert_average_facedata,
&def_meshrotateuvs,
};
int bmesh_total_ops = (sizeof(opdefines) / sizeof(void*));

View File

@@ -51,5 +51,6 @@ void bmesh_similaredges_exec(BMesh *bm, BMOperator *op);
void bmesh_similarverts_exec(BMesh *bm, BMOperator *op);
void bmesh_pointmerge_facedata_exec(BMesh *bm, BMOperator *op);
void bmesh_vert_average_facedata_exec(BMesh *bm, BMOperator *op);
void bmesh_rotateuvs_exec(BMesh *bm, BMOperator *op);
#endif

View File

@@ -891,11 +891,11 @@ void bmesh_similarverts_exec(BMesh *bm, BMOperator *op)
switch( type ) {
case SIMVERT_FACE:
/* calling BM_Vert_FaceCount every time is time consumming, so call it only once per vertex */
v_ext[i].num_faces = BM_Vert_FaceCount(v);
v_ext[i].num_faces = BM_Vert_FaceCount(v);
break;
case SIMVERT_VGROUP:
if( CustomData_has_layer(&(bm->vdata), CD_MDEFORMVERT) ) {
if( CustomData_has_layer(&(bm->vdata),CD_MDEFORMVERT) ) {
v_ext[i].dvert = CustomData_bmesh_get(&bm->vdata, v_ext[i].v->head.data, CD_MDEFORMVERT);
} else v_ext[i].dvert = NULL;
break;
@@ -952,3 +952,75 @@ void bmesh_similarverts_exec(BMesh *bm, BMOperator *op)
BMO_Flag_To_Slot(bm, op, "vertout", VERT_MARK, BM_VERT);
}
/******************************************************************************
** Cycle UVs for a face
******************************************************************************/
void bmesh_rotateuvs_exec(BMesh *bm, BMOperator *op)
{
BMOIter fs_iter; /* selected faces iterator */
BMFace *fs; /* current face */
BMIter l_iter; /* iteration loop */
int n;
int dir = BMO_Get_Int(op, "dir");
BMO_ITER(fs, &fs_iter, bm, op, "faces", BM_FACE) {
if( CustomData_has_layer(&(bm->ldata), CD_MLOOPUV) ) {
if( dir == DIRECTION_CW ) { /* same loops direction */
BMLoop *lf; /* current face loops */
MLoopUV *f_luv; /* first face loop uv */
float p_uv[2]; /* previous uvs */
float t_uv[2]; /* tmp uvs */
int n = 0;
BM_ITER(lf, &l_iter, bm, BM_LOOPS_OF_FACE, fs) {
/* current loop uv is the previous loop uv */
MLoopUV *luv = CustomData_bmesh_get(&bm->ldata, lf->head.data, CD_MLOOPUV);
if( n == 0 ) {
f_luv = luv;
p_uv[0] = luv->uv[0];
p_uv[1] = luv->uv[1];
} else {
t_uv[0] = luv->uv[0];
t_uv[1] = luv->uv[1];
luv->uv[0] = p_uv[0];
luv->uv[1] = p_uv[1];
p_uv[0] = t_uv[0];
p_uv[1] = t_uv[1];
}
n++;
}
f_luv->uv[0] = p_uv[0];
f_luv->uv[1] = p_uv[1];
} else if( dir == DIRECTION_CCW ) { /* counter loop direction */
BMLoop *lf; /* current face loops */
MLoopUV *p_luv; /*previous loop uv */
MLoopUV *luv;
float t_uv[2]; /* current uvs */
int n = 0;
BM_ITER(lf, &l_iter, bm, BM_LOOPS_OF_FACE, fs) {
/* previous loop uv is the current loop uv */
luv = CustomData_bmesh_get(&bm->ldata, lf->head.data, CD_MLOOPUV);
if( n == 0 ) {
p_luv = luv;
t_uv[0] = luv->uv[0];
t_uv[1] = luv->uv[1];
} else {
p_luv->uv[0] = luv->uv[0];
p_luv->uv[1] = luv->uv[1];
p_luv = luv;
}
n++;
}
luv->uv[0] = t_uv[0];
luv->uv[1] = t_uv[1];
}
}
}
}

View File

@@ -710,205 +710,6 @@ static EnumPropertyItem prop_simedge_types[] = {
{0, NULL, 0, NULL, NULL}
};
static int similar_edge_select__internal(Scene *scene, EditMesh *em, int mode)
{
#if 0
EditEdge *eed, *base_eed=NULL;
unsigned int selcount=0; /* count how many new edges we select*/
/*count how many visible selected edges there are,
so we can return when there are none left */
unsigned int deselcount=0;
short ok=0;
float thresh= scene->toolsettings->select_thresh;
for(eed= em->edges.first; eed; eed= eed->next) {
if (!eed->h) {
if (eed->f & SELECT) {
eed->f1=1;
ok=1;
} else {
eed->f1=0;
deselcount++;
}
/* set all eed->tmp.l to 0 we use it later.
for counting face users*/
eed->tmp.l=0;
eed->f2=0; /* only for mode SIMEDGE_FACE_ANGLE, edge animations */
}
}
if (!ok || !deselcount) /* no data selected OR no more data to select*/
return 0;
if (mode==SIMEDGE_LENGTH) { /*store length*/
for(eed= em->edges.first; eed; eed= eed->next) {
if (!eed->h) /* dont calc data for hidden edges*/
eed->tmp.fp= VecLenf(eed->v1->co, eed->v2->co);
}
} else if (mode==SIMEDGE_FACE) { /*store face users*/
EditFace *efa;
/* cound how many faces each edge uses use tmp->l */
for(efa= em->faces.first; efa; efa= efa->next) {
efa->e1->tmp.l++;
efa->e2->tmp.l++;
efa->e3->tmp.l++;
if (efa->e4) efa->e4->tmp.l++;
}
} else if (mode==SIMEDGE_FACE_ANGLE) { /*store edge angles */
EditFace *efa;
int j;
/* cound how many faces each edge uses use tmp.l */
for(efa= em->faces.first; efa; efa= efa->next) {
/* here we use the edges temp data to assign a face
if a face has alredy been assigned (eed->f2==1)
we calculate the angle between the current face and
the edges previously found face.
store the angle in eed->tmp.fp (loosing the face eed->tmp.f)
but tagging eed->f2==2, so we know not to look at it again.
This only works for edges that connect to 2 faces. but its good enough
*/
/* se we can loop through face edges*/
j=0;
eed= efa->e1;
while (j<4) {
if (j==1) eed= efa->e2;
else if (j==2) eed= efa->e3;
else if (j==3) {
eed= efa->e4;
if (!eed)
break;
} /* done looping */
if (!eed->h) { /* dont calc data for hidden edges*/
if (eed->f2==2)
break;
else if (eed->f2==0) /* first access, assign the face */
eed->tmp.f= efa;
else if (eed->f2==1) /* second, we assign the angle*/
eed->tmp.fp= VecAngle2(eed->tmp.f->n, efa->n)/180;
eed->f2++; /* f2==0 no face assigned. f2==1 one face found. f2==2 angle calculated.*/
}
j++;
}
}
}
for(base_eed= em->edges.first; base_eed; base_eed= base_eed->next) {
if (base_eed->f1) {
if (mode==SIMEDGE_LENGTH) { /* same length */
for(eed= em->edges.first; eed; eed= eed->next) {
if (
!(eed->f & SELECT) &&
!eed->h &&
SCALE_CMP(base_eed->tmp.fp, eed->tmp.fp)
) {
EM_select_edge(eed, 1);
selcount++;
deselcount--;
if (!deselcount) /*have we selected all posible faces?, if so return*/
return selcount;
}
}
} else if (mode==SIMEDGE_DIR) { /* same direction */
float base_dir[3], dir[3], angle;
VecSubf(base_dir, base_eed->v1->co, base_eed->v2->co);
for(eed= em->edges.first; eed; eed= eed->next) {
if (!(eed->f & SELECT) && !eed->h) {
VecSubf(dir, eed->v1->co, eed->v2->co);
angle= VecAngle2(base_dir, dir);
if (angle>90) /* use the smallest angle between the edges */
angle= fabs(angle-180.0f);
if (angle/90.0<=thresh) {
EM_select_edge(eed, 1);
selcount++;
deselcount--;
if (!deselcount) /*have we selected all posible faces?, if so return*/
return selcount;
}
}
}
} else if (mode==SIMEDGE_FACE) { /* face users */
for(eed= em->edges.first; eed; eed= eed->next) {
if (
!(eed->f & SELECT) &&
!eed->h &&
base_eed->tmp.l==eed->tmp.l
) {
EM_select_edge(eed, 1);
selcount++;
deselcount--;
if (!deselcount) /*have we selected all posible faces?, if so return*/
return selcount;
}
}
} else if (mode==SIMEDGE_FACE_ANGLE && base_eed->f2==2) { /* edge angles, f2==2 means the edge has an angle. */
for(eed= em->edges.first; eed; eed= eed->next) {
if (
!(eed->f & SELECT) &&
!eed->h &&
eed->f2==2 &&
(fabs(base_eed->tmp.fp-eed->tmp.fp)<=thresh)
) {
EM_select_edge(eed, 1);
selcount++;
deselcount--;
if (!deselcount) /*have we selected all posible faces?, if so return*/
return selcount;
}
}
} else if (mode==SIMEDGE_CREASE) { /* edge crease */
for(eed= em->edges.first; eed; eed= eed->next) {
if (
!(eed->f & SELECT) &&
!eed->h &&
(fabs(base_eed->crease-eed->crease) <= thresh)
) {
EM_select_edge(eed, 1);
selcount++;
deselcount--;
if (!deselcount) /*have we selected all posible faces?, if so return*/
return selcount;
}
}
} else if (mode==SIMEDGE_SEAM) { /* edge seam */
for(eed= em->edges.first; eed; eed= eed->next) {
if (
!(eed->f & SELECT) &&
!eed->h &&
(eed->seam == base_eed->seam)
) {
EM_select_edge(eed, 1);
selcount++;
deselcount--;
if (!deselcount) /*have we selected all posible faces?, if so return*/
return selcount;
}
}
} else if (mode==SIMEDGE_SHARP) { /* edge sharp */
for(eed= em->edges.first; eed; eed= eed->next) {
if (
!(eed->f & SELECT) &&
!eed->h &&
(eed->sharp == base_eed->sharp)
) {
EM_select_edge(eed, 1);
selcount++;
deselcount--;
if (!deselcount) /*have we selected all posible faces?, if so return*/
return selcount;
}
}
}
}
}
return selcount;
#endif
}
/* wrap the above function but do selection flushing edge to face */
static int similar_edge_select_exec(bContext *C, wmOperator *op)
{
@@ -945,25 +746,6 @@ static int similar_edge_select_exec(bContext *C, wmOperator *op)
/* we succeeded */
return OPERATOR_FINISHED;
#if 0
Scene *scene= CTX_data_scene(C);
Object *obedit= CTX_data_edit_object(C);
Mesh *me= obedit->data;
EditMesh *em= BKE_mesh_get_editmesh(me);
int selcount = similar_edge_select__internal(scene, em, RNA_int_get(op->ptr, "type"));
if (selcount) {
/* here was an edge-mode only select flush case, has to be generalized */
EM_selectmode_flush(em);
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
BKE_mesh_end_editmesh(me, em);
return OPERATOR_FINISHED;
}
BKE_mesh_end_editmesh(me, em);
return OPERATOR_CANCELLED;
#endif
}
/* ********************************* */

View File

@@ -1617,8 +1617,8 @@ void MESH_OT_flip_normals(wmOperatorType *ot)
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
}
#define DIRECTION_CW 1
#define DIRECTION_CCW 2
//#define DIRECTION_CW 1
//#define DIRECTION_CCW 2
static const EnumPropertyItem direction_items[]= {
{DIRECTION_CW, "CW", 0, "Clockwise", ""},
@@ -2061,16 +2061,40 @@ void MESH_OT_faces_shade_flat(wmOperatorType *ot)
/********************** UV/Color Operators *************************/
#define AXIS_X 1
#define AXIS_Y 2
static const EnumPropertyItem axis_items[]= {
{AXIS_X, "X", 0, "X", ""},
{AXIS_Y, "Y", 0, "Y", ""},
{OPUVC_AXIS_X, "X", 0, "X", ""},
{OPUVC_AXIS_Y, "Y", 0, "Y", ""},
{0, NULL, 0, NULL, NULL}};
static int mesh_rotate_uvs(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
Object *ob = CTX_data_edit_object(C);
BMEditMesh *em = ((Mesh*)ob->data)->edit_btmesh;
BMOperator bmop;
/* get the direction from RNA */
int dir = RNA_enum_get(op->ptr, "direction");
/* initialize the bmop using EDBM api, which does various ui error reporting and other stuff */
EDBM_InitOpf(em, &bmop, op, "meshrotateuvs faces=%hf dir=%d", BM_SELECT, dir);
/* execute the operator */
BMO_Exec_Op(em->bm, &bmop);
/* finish the operator */
if( !EDBM_FinishOp(em, &bmop, op, 1) )
return OPERATOR_CANCELLED;
/* dependencies graph and notification stuff */
DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT | ND_GEOM_SELECT, ob);
/* we succeeded */
return OPERATOR_FINISHED;
#if 0
Scene *scene= CTX_data_scene(C);
Object *obedit= CTX_data_edit_object(C);

View File

@@ -340,9 +340,9 @@ void make_vertexcol(Scene *scene, int shade) /* single ob */
/* copies from shadedisplist to mcol */
if(!me->mcol)
CustomData_add_layer(&me->fdata, CD_MCOL, CD_CALLOC, NULL, me->totface);
CustomData_add_layer(&me->fdata, CD_MCOL, CD_DEFAULT, NULL, me->totface);
if (!me->mloopcol)
CustomData_add_layer(&me->ldata, CD_MLOOPCOL, CD_CALLOC, NULL, me->totloop);
CustomData_add_layer(&me->ldata, CD_MLOOPCOL, CD_DEFAULT, NULL, me->totloop);
mesh_update_customdata_pointers(me);