/* called from drawview.c, as an extra per-window draw option */ void drawPropCircle(const struct bContext *C, TransInfo *t) { if (t->flag & T_PROP_EDIT) { RegionView3D *rv3d = CTX_wm_region_view3d(C); float tmat[4][4], imat[4][4]; float center[3]; UI_ThemeColor(TH_GRID); if(t->spacetype == SPACE_VIEW3D && rv3d != NULL) { copy_m4_m4(tmat, rv3d->viewmat); invert_m4_m4(imat, tmat); } else { unit_m4(tmat); unit_m4(imat); } glPushMatrix(); VECCOPY(center, t->center); if((t->spacetype == SPACE_VIEW3D) && t->obedit) { mul_m4_v3(t->obedit->obmat, center); /* because t->center is in local space */ } else if(t->spacetype == SPACE_IMAGE) { float aspx, aspy; ED_space_image_uv_aspect(t->sa->spacedata.first, &aspx, &aspy); glScalef(1.0f/aspx, 1.0f/aspy, 1.0); } set_inverted_drawing(1); drawcircball(GL_LINE_LOOP, center, t->prop_size, imat); set_inverted_drawing(0); glPopMatrix(); } }
static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, EditMesh *em, MTFace *activetf) { EditFace *efa; MTFace *tf; Image *ima= sima->image; float aspx, aspy, col[4], tf_uv[4][2]; ED_space_image_uv_aspect(sima, &aspx, &aspy); switch(sima->dt_uvstretch) { case SI_UVDT_STRETCH_AREA: { float totarea=0.0f, totuvarea=0.0f, areadiff, uvarea, area; for(efa= em->faces.first; efa; efa= efa->next) { tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); uv_copy_aspect(tf->uv, tf_uv, aspx, aspy); totarea += EM_face_area(efa); //totuvarea += tf_area(tf, efa->v4!=0); totuvarea += uv_area(tf_uv, efa->v4!=0); if(uvedit_face_visible(scene, ima, efa, tf)) { efa->tmp.p = tf; } else { if(tf == activetf) activetf= NULL; efa->tmp.p = NULL; } } if(totarea < FLT_EPSILON || totuvarea < FLT_EPSILON) { col[0] = 1.0; col[1] = col[2] = 0.0; glColor3fv(col); for(efa= em->faces.first; efa; efa= efa->next) { if((tf=(MTFace *)efa->tmp.p)) { glBegin(efa->v4?GL_QUADS:GL_TRIANGLES); glVertex2fv(tf->uv[0]); glVertex2fv(tf->uv[1]); glVertex2fv(tf->uv[2]); if(efa->v4) glVertex2fv(tf->uv[3]); glEnd(); } } } else { for(efa= em->faces.first; efa; efa= efa->next) { if((tf=(MTFace *)efa->tmp.p)) { area = EM_face_area(efa) / totarea; uv_copy_aspect(tf->uv, tf_uv, aspx, aspy); //uvarea = tf_area(tf, efa->v4!=0) / totuvarea; uvarea = uv_area(tf_uv, efa->v4!=0) / totuvarea; if(area < FLT_EPSILON || uvarea < FLT_EPSILON) areadiff = 1.0; else if(area>uvarea) areadiff = 1.0-(uvarea/area); else areadiff = 1.0-(area/uvarea); weight_to_rgb(areadiff, col, col+1, col+2); glColor3fv(col); glBegin(efa->v4?GL_QUADS:GL_TRIANGLES); glVertex2fv(tf->uv[0]); glVertex2fv(tf->uv[1]); glVertex2fv(tf->uv[2]); if(efa->v4) glVertex2fv(tf->uv[3]); glEnd(); } } } break; } case SI_UVDT_STRETCH_ANGLE: { float uvang1,uvang2,uvang3,uvang4; float ang1,ang2,ang3,ang4; float av1[3], av2[3], av3[3], av4[3]; /* use for 2d and 3d angle vectors */ float a; col[3] = 0.5; /* hard coded alpha, not that nice */ glShadeModel(GL_SMOOTH); for(efa= em->faces.first; efa; efa= efa->next) { tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); if(uvedit_face_visible(scene, ima, efa, tf)) { efa->tmp.p = tf; uv_copy_aspect(tf->uv, tf_uv, aspx, aspy); if(efa->v4) { #if 0 /* Simple but slow, better reuse normalized vectors */ uvang1 = RAD2DEG(Vec2Angle3(tf_uv[3], tf_uv[0], tf_uv[1])); ang1 = RAD2DEG(VecAngle3(efa->v4->co, efa->v1->co, efa->v2->co)); uvang2 = RAD2DEG(Vec2Angle3(tf_uv[0], tf_uv[1], tf_uv[2])); ang2 = RAD2DEG(VecAngle3(efa->v1->co, efa->v2->co, efa->v3->co)); uvang3 = RAD2DEG(Vec2Angle3(tf_uv[1], tf_uv[2], tf_uv[3])); ang3 = RAD2DEG(VecAngle3(efa->v2->co, efa->v3->co, efa->v4->co)); uvang4 = RAD2DEG(Vec2Angle3(tf_uv[2], tf_uv[3], tf_uv[0])); ang4 = RAD2DEG(VecAngle3(efa->v3->co, efa->v4->co, efa->v1->co)); #endif /* uv angles */ VECSUB2D(av1, tf_uv[3], tf_uv[0]); Normalize2(av1); VECSUB2D(av2, tf_uv[0], tf_uv[1]); Normalize2(av2); VECSUB2D(av3, tf_uv[1], tf_uv[2]); Normalize2(av3); VECSUB2D(av4, tf_uv[2], tf_uv[3]); Normalize2(av4); /* This is the correct angle however we are only comparing angles * uvang1 = 90-((NormalizedVecAngle2_2D(av1, av2) * 180.0/M_PI)-90);*/ uvang1 = NormalizedVecAngle2_2D(av1, av2)*180.0/M_PI; uvang2 = NormalizedVecAngle2_2D(av2, av3)*180.0/M_PI; uvang3 = NormalizedVecAngle2_2D(av3, av4)*180.0/M_PI; uvang4 = NormalizedVecAngle2_2D(av4, av1)*180.0/M_PI; /* 3d angles */ VECSUB(av1, efa->v4->co, efa->v1->co); Normalize(av1); VECSUB(av2, efa->v1->co, efa->v2->co); Normalize(av2); VECSUB(av3, efa->v2->co, efa->v3->co); Normalize(av3); VECSUB(av4, efa->v3->co, efa->v4->co); Normalize(av4); /* This is the correct angle however we are only comparing angles * ang1 = 90-((NormalizedVecAngle2(av1, av2) * 180.0/M_PI)-90);*/ ang1 = NormalizedVecAngle2(av1, av2)*180.0/M_PI; ang2 = NormalizedVecAngle2(av2, av3)*180.0/M_PI; ang3 = NormalizedVecAngle2(av3, av4)*180.0/M_PI; ang4 = NormalizedVecAngle2(av4, av1)*180.0/M_PI; glBegin(GL_QUADS); /* This simple makes the angles display worse then they really are ;) * 1.0-pow((1.0-a), 2) */ a = fabs(uvang1-ang1)/180.0; weight_to_rgb(1.0-pow((1.0-a), 2), col, col+1, col+2); glColor3fv(col); glVertex2fv(tf->uv[0]); a = fabs(uvang2-ang2)/180.0; weight_to_rgb(1.0-pow((1.0-a), 2), col, col+1, col+2); glColor3fv(col); glVertex2fv(tf->uv[1]); a = fabs(uvang3-ang3)/180.0; weight_to_rgb(1.0-pow((1.0-a), 2), col, col+1, col+2); glColor3fv(col); glVertex2fv(tf->uv[2]); a = fabs(uvang4-ang4)/180.0; weight_to_rgb(1.0-pow((1.0-a), 2), col, col+1, col+2); glColor3fv(col); glVertex2fv(tf->uv[3]); } else { #if 0 /* Simple but slow, better reuse normalized vectors */ uvang1 = RAD2DEG(Vec2Angle3(tf_uv[2], tf_uv[0], tf_uv[1])); ang1 = RAD2DEG(VecAngle3(efa->v3->co, efa->v1->co, efa->v2->co)); uvang2 = RAD2DEG(Vec2Angle3(tf_uv[0], tf_uv[1], tf_uv[2])); ang2 = RAD2DEG(VecAngle3(efa->v1->co, efa->v2->co, efa->v3->co)); uvang3 = M_PI-(uvang1+uvang2); ang3 = M_PI-(ang1+ang2); #endif /* uv angles */ VECSUB2D(av1, tf_uv[2], tf_uv[0]); Normalize2(av1); VECSUB2D(av2, tf_uv[0], tf_uv[1]); Normalize2(av2); VECSUB2D(av3, tf_uv[1], tf_uv[2]); Normalize2(av3); /* This is the correct angle however we are only comparing angles * uvang1 = 90-((NormalizedVecAngle2_2D(av1, av2) * 180.0/M_PI)-90); */ uvang1 = NormalizedVecAngle2_2D(av1, av2)*180.0/M_PI; uvang2 = NormalizedVecAngle2_2D(av2, av3)*180.0/M_PI; uvang3 = NormalizedVecAngle2_2D(av3, av1)*180.0/M_PI; /* 3d angles */ VECSUB(av1, efa->v3->co, efa->v1->co); Normalize(av1); VECSUB(av2, efa->v1->co, efa->v2->co); Normalize(av2); VECSUB(av3, efa->v2->co, efa->v3->co); Normalize(av3); /* This is the correct angle however we are only comparing angles * ang1 = 90-((NormalizedVecAngle2(av1, av2) * 180.0/M_PI)-90); */ ang1 = NormalizedVecAngle2(av1, av2)*180.0/M_PI; ang2 = NormalizedVecAngle2(av2, av3)*180.0/M_PI; ang3 = NormalizedVecAngle2(av3, av1)*180.0/M_PI; /* This simple makes the angles display worse then they really are ;) * 1.0-pow((1.0-a), 2) */ glBegin(GL_TRIANGLES); a = fabs(uvang1-ang1)/180.0; weight_to_rgb(1.0-pow((1.0-a), 2), col, col+1, col+2); glColor3fv(col); glVertex2fv(tf->uv[0]); a = fabs(uvang2-ang2)/180.0; weight_to_rgb(1.0-pow((1.0-a), 2), col, col+1, col+2); glColor3fv(col); glVertex2fv(tf->uv[1]); a = fabs(uvang3-ang3)/180.0; weight_to_rgb(1.0-pow((1.0-a), 2), col, col+1, col+2); glColor3fv(col); glVertex2fv(tf->uv[2]); } glEnd(); } else { if(tf == activetf) activetf= NULL; efa->tmp.p = NULL; } } glShadeModel(GL_FLAT); break; } } }