4 * ***** BEGIN GPL LICENSE BLOCK *****
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21 * All rights reserved.
23 * The Original Code is: all of this file.
25 * Contributor(s): none yet.
27 * ***** END GPL LICENSE BLOCK *****
34 #include "MEM_guardedalloc.h"
36 #include "BLI_blenlib.h"
37 #include "BLI_arithb.h"
39 #include "BLI_edgehash.h"
40 #include "BLI_editVert.h"
42 #include "MTC_matrixops.h"
44 #include "IMB_imbuf_types.h"
45 #include "IMB_imbuf.h"
47 #include "DNA_image_types.h"
48 #include "DNA_mesh_types.h"
49 #include "DNA_meshdata_types.h"
50 #include "DNA_object_types.h"
51 #include "DNA_space_types.h"
52 #include "DNA_screen_types.h"
53 #include "DNA_scene_types.h"
54 #include "DNA_view3d_types.h"
56 #include "BKE_brush.h"
57 #include "BKE_customdata.h"
58 #include "BKE_depsgraph.h"
59 #include "BKE_DerivedMesh.h"
60 #include "BKE_displist.h"
61 #include "BKE_global.h"
63 #include "BKE_multires.h"
64 #include "BKE_object.h"
65 #include "BKE_texture.h"
66 #include "BKE_utildefines.h"
67 #include "BKE_customdata.h"
71 #include "BSE_drawview.h" /* for backdrawview3d */
73 #include "BIF_editsima.h"
74 #include "BIF_editmesh.h"
75 #include "BIF_interface.h"
76 #include "BIF_mywindow.h"
77 #include "BIF_toolbox.h"
78 #include "BIF_resources.h"
79 #include "BIF_screen.h"
81 #include "BIF_graphics.h"
82 #include "BIF_space.h" /* for allqueue */
83 #include "BIF_drawimage.h" /* for allqueue */
85 #include "BDR_editface.h"
86 #include "BDR_vpaint.h"
88 #include "BDR_editface.h"
89 #include "BDR_vpaint.h"
97 #include "BSE_trans_types.h"
99 #include "BDR_unwrapper.h"
100 #include "BDR_editobject.h"
102 #ifndef DISABLE_PYTHON
103 #include "BPY_extern.h"
104 #include "BPY_menus.h"
108 #define UV_CUBE_MAPPING 2
109 #define UV_CYL_MAPPING 3
110 #define UV_SPHERE_MAPPING 4
111 #define UV_BOUNDS_MAPPING 5
112 #define UV_RESET_MAPPING 6
113 #define UV_WINDOW_MAPPING 7
114 #define UV_UNWRAP_MAPPING 8
116 #define UV_SPHERE_EX 34
118 /* Some macro tricks to make pupmenu construction look nicer :-)
119 Sorry, just did it for fun. */
121 #define _STR(x) " " #x
122 #define STRING(x) _STR(x)
124 #define MENUSTRING(string, code) string " %x" STRING(code)
125 #define MENUTITLE(string) string " %t|"
128 /* returns 0 if not found, otherwise 1 */
129 int facesel_face_pick(Mesh *me, short *mval, unsigned int *index, short rect)
131 if (!me || me->totface==0)
134 if (G.vd->flag & V3D_NEEDBACKBUFDRAW) {
140 /* sample rect to increase changes of selecting, so that when clicking
141 on an edge in the backbuf, we can still select a face */
143 *index = sample_backbuf_rect(mval, 3, 1, me->totface+1, &dist,0,NULL);
146 /* sample only on the exact position */
147 *index = sample_backbuf(mval[0], mval[1]);
149 if ((*index)<=0 || (*index)>(unsigned int)me->totface)
157 /* only operates on the edit object - this is all thats needed at the moment */
158 static void uv_calc_center_vector(float *result, Object *ob, EditMesh *em)
160 float min[3], max[3], *cursx;
163 switch (G.vd->around)
165 case V3D_CENTER: /* bounding box center */
166 min[0]= min[1]= min[2]= 1e20f;
167 max[0]= max[1]= max[2]= -1e20f;
169 for (efa= em->faces.first; efa; efa= efa->next) {
170 if (efa->f & SELECT) {
171 DO_MINMAX(efa->v1->co, min, max);
172 DO_MINMAX(efa->v2->co, min, max);
173 DO_MINMAX(efa->v3->co, min, max);
174 if(efa->v4) DO_MINMAX(efa->v4->co, min, max);
177 VecMidf(result, min, max);
179 case V3D_CURSOR: /*cursor center*/
180 cursx= give_cursor();
181 /* shift to objects world */
182 result[0]= cursx[0]-ob->obmat[3][0];
183 result[1]= cursx[1]-ob->obmat[3][1];
184 result[2]= cursx[2]-ob->obmat[3][2];
186 case V3D_LOCAL: /*object center*/
187 case V3D_CENTROID: /* multiple objects centers, only one object here*/
189 result[0]= result[1]= result[2]= 0.0;
194 static void uv_calc_map_matrix(float result[][4], Object *ob, float upangledeg, float sideangledeg, float radius)
196 float rotup[4][4], rotside[4][4], viewmatrix[4][4], rotobj[4][4];
197 float sideangle= 0.0, upangle= 0.0;
200 /* get rotation of the current view matrix */
201 Mat4CpyMat4(viewmatrix,G.vd->viewmat);
203 for( k= 0; k< 4; k++) viewmatrix[3][k] =0.0;
205 /* get rotation of the current object matrix */
206 Mat4CpyMat4(rotobj,ob->obmat);
208 for( k= 0; k< 4; k++) rotobj[3][k] =0.0;
213 /* compensate front/side.. against opengl x,y,z world definition */
214 /* this is "kanonen gegen spatzen", a few plus minus 1 will do here */
215 /* i wanted to keep the reason here, so we're rotating*/
216 sideangle= M_PI * (sideangledeg + 180.0) /180.0;
217 rotside[0][0]= (float)cos(sideangle);
218 rotside[0][1]= -(float)sin(sideangle);
219 rotside[1][0]= (float)sin(sideangle);
220 rotside[1][1]= (float)cos(sideangle);
223 upangle= M_PI * upangledeg /180.0;
224 rotup[1][1]= (float)cos(upangle)/radius;
225 rotup[1][2]= -(float)sin(upangle)/radius;
226 rotup[2][1]= (float)sin(upangle)/radius;
227 rotup[2][2]= (float)cos(upangle)/radius;
228 rotup[0][0]= (float)1.0/radius;
230 /* calculate transforms*/
231 Mat4MulSerie(result,rotup,rotside,viewmatrix,rotobj,NULL,NULL,NULL,NULL);
234 static void uv_calc_shift_project(float *target, float *shift, float rotmat[][4], int projectionmode, float *source, float *min, float *max)
238 VecSubf(pv, source, shift);
239 Mat4MulVecfl(rotmat, pv);
241 switch(projectionmode) {
242 case B_UVAUTO_CYLINDER:
243 tubemap(pv[0], pv[1], pv[2], &target[0],&target[1]);
244 /* split line is always zero */
245 if (target[0] >= 1.0f) target[0] -= 1.0f;
248 case B_UVAUTO_SPHERE:
249 spheremap(pv[0], pv[1], pv[2], &target[0],&target[1]);
250 /* split line is always zero */
251 if (target[0] >= 1.0f) target[0] -= 1.0f;
254 case 3: /* ortho special case for BOUNDS */
261 /* very special case for FROM WINDOW */
262 float pv4[4], dx, dy, x= 0.0, y= 0.0;
264 dx= G.vd->area->winx;
265 dy= G.vd->area->winy;
267 VecCopyf(pv4, source);
270 /* rotmat is the object matrix in this case */
271 Mat4MulVec4fl(rotmat,pv4);
273 /* almost project_short */
274 Mat4MulVec4fl(G.vd->persmat,pv4);
275 if (fabs(pv4[3]) > 0.00001) { /* avoid division by zero */
276 target[0] = dx/2.0 + (dx/2.0)*pv4[0]/pv4[3];
277 target[1] = dy/2.0 + (dy/2.0)*pv4[1]/pv4[3];
280 /* scaling is lost but give a valid result */
281 target[0] = dx/2.0 + (dx/2.0)*pv4[0];
282 target[1] = dy/2.0 + (dy/2.0)*pv4[1];
285 /* G.vd->persmat seems to do this funky scaling */
294 target[0]= (x + target[0])/dx;
295 target[1]= (y + target[1])/dy;
305 /* we know the values here and may need min_max later */
306 /* max requests independand from min; not fastest but safest */
308 min[0] = MIN2(target[0], min[0]);
309 min[1] = MIN2(target[1], min[1]);
312 max[0] = MAX2(target[0], max[0]);
313 max[1] = MAX2(target[1], max[1]);
317 static void correct_uv_aspect( void )
319 float aspx=1, aspy=1;
320 EditMesh *em = G.editMesh;
321 EditFace *efa = EM_get_actFace(1);
325 tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
326 image_final_aspect(tface->tpage, &aspx, &aspy);
331 EditMesh *em = G.editMesh;
336 for (efa= em->faces.first; efa; efa= efa->next) {
337 if (efa->f & SELECT) {
338 tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
339 tface->uv[0][0] = ((tface->uv[0][0]-0.5)*scale)+0.5;
340 tface->uv[1][0] = ((tface->uv[1][0]-0.5)*scale)+0.5;
341 tface->uv[2][0] = ((tface->uv[2][0]-0.5)*scale)+0.5;
343 tface->uv[3][0] = ((tface->uv[3][0]-0.5)*scale)+0.5;
349 for (efa= em->faces.first; efa; efa= efa->next) {
350 if (efa->f & SELECT) {
351 tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
352 tface->uv[0][1] = ((tface->uv[0][1]-0.5)*scale)+0.5;
353 tface->uv[1][1] = ((tface->uv[1][1]-0.5)*scale)+0.5;
354 tface->uv[2][1] = ((tface->uv[2][1]-0.5)*scale)+0.5;
356 tface->uv[3][1] = ((tface->uv[3][1]-0.5)*scale)+0.5;
364 void calculate_uv_map(unsigned short mapmode)
368 float dx, dy, rotatematrix[4][4], radius= 1.0, min[3], cent[3], max[3];
369 float fac= 1.0, upangledeg= 0.0, sideangledeg= 90.0;
372 EditMesh *em = G.editMesh;
375 if(G.scene->toolsettings->uvcalc_mapdir==1) {
380 if(G.scene->toolsettings->uvcalc_mapalign==1) sideangledeg= 0.0;
381 else sideangledeg= 90.0;
384 /* add uvs if there not here */
385 if (!EM_texFaceCheck()) {
386 if (em && em->faces.first)
387 EM_add_data_layer(&em->fdata, CD_MTFACE);
389 if (G.sima && G.sima->image) /* this is a bit of a kludge, but assume they want the image on their mesh when UVs are added */
390 image_changed(G.sima, G.sima->image);
392 if (!EM_texFaceCheck())
395 /* select new UV's */
396 if ((G.sima && G.sima->flag & SI_SYNC_UVSEL)==0) {
397 for(efa=em->faces.first; efa; efa=efa->next) {
398 MTFace *tf= (MTFace *)CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
399 simaFaceSel_Set(efa, tf);
407 case B_UVAUTO_BOUNDS:
408 min[0]= min[1]= 10000000.0;
409 max[0]= max[1]= -10000000.0;
411 cent[0] = cent[1] = cent[2] = 0.0;
412 uv_calc_map_matrix(rotatematrix, ob, upangledeg, sideangledeg, 1.0f);
414 for (efa= em->faces.first; efa; efa= efa->next) {
415 if (efa->f & SELECT) {
416 tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
417 uv_calc_shift_project(tface->uv[0],cent,rotatematrix,3, efa->v1->co, min,max);
418 uv_calc_shift_project(tface->uv[1],cent,rotatematrix,3, efa->v2->co, min,max);
419 uv_calc_shift_project(tface->uv[2],cent,rotatematrix,3, efa->v3->co,min,max);
421 uv_calc_shift_project(tface->uv[3],cent,rotatematrix,3, efa->v4->co,min,max);
425 /* rescale UV to be in 1/1 */
429 for (efa= em->faces.first; efa; efa= efa->next) {
430 if (efa->f & SELECT) {
431 tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
432 if(efa->v4) b= 3; else b= 2;
434 tface->uv[b][0]= ((tface->uv[b][0]-min[0])*fac)/dx;
435 tface->uv[b][1]= 1.0-fac+((tface->uv[b][1]-min[1])/* *fac */)/dy;
441 case B_UVAUTO_WINDOW:
442 cent[0] = cent[1] = cent[2] = 0.0;
443 Mat4CpyMat4(rotatematrix,ob->obmat);
444 for (efa= em->faces.first; efa; efa= efa->next) {
445 if (efa->f & SELECT) {
446 tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
447 uv_calc_shift_project(tface->uv[0],cent,rotatematrix,4, efa->v1->co, NULL,NULL);
448 uv_calc_shift_project(tface->uv[1],cent,rotatematrix,4, efa->v2->co, NULL,NULL);
449 uv_calc_shift_project(tface->uv[2],cent,rotatematrix,4, efa->v3->co, NULL,NULL);
451 uv_calc_shift_project(tface->uv[3],cent,rotatematrix,4, efa->v4->co, NULL,NULL);
457 for (efa= em->faces.first; efa; efa= efa->next) {
458 if (efa->f & SELECT) {
459 tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
460 default_uv(tface->uv, 1.0);
465 case B_UVAUTO_CYLINDER:
466 case B_UVAUTO_SPHERE:
467 uv_calc_center_vector(cent, ob, em);
469 if(mapmode==B_UVAUTO_CYLINDER) radius = G.scene->toolsettings->uvcalc_radius;
471 /* be compatible to the "old" sphere/cylinder mode */
472 if (G.scene->toolsettings->uvcalc_mapdir== 2)
473 Mat4One(rotatematrix);
475 uv_calc_map_matrix(rotatematrix,ob,upangledeg,sideangledeg,radius);
476 for (efa= em->faces.first; efa; efa= efa->next) {
477 if (efa->f & SELECT) {
478 tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
479 uv_calc_shift_project(tface->uv[0],cent,rotatematrix,mapmode, efa->v1->co, NULL,NULL);
480 uv_calc_shift_project(tface->uv[1],cent,rotatematrix,mapmode, efa->v2->co, NULL,NULL);
481 uv_calc_shift_project(tface->uv[2],cent,rotatematrix,mapmode, efa->v3->co, NULL,NULL);
484 uv_calc_shift_project(tface->uv[3],cent,rotatematrix,mapmode, efa->v4->co, NULL,NULL);
489 for (i = 1; i < n; i++)
490 if (tface->uv[i][0] > tface->uv[mi][0]) mi = i;
492 for (i = 0; i < n; i++) {
494 dx = tface->uv[mi][0] - tface->uv[i][0];
495 if (dx > 0.5) tface->uv[i][0] += 1.0;
505 /* choose x,y,z axis for projetion depending on the largest normal */
506 /* component, but clusters all together around the center of map */
509 float *loc= ob->obmat[3];
510 /*MVert *mv= me->mvert;*/
511 float cubesize = G.scene->toolsettings->uvcalc_cubesize;
513 for (efa= em->faces.first; efa; efa= efa->next) {
514 if (efa->f & SELECT) {
515 tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
516 CalcNormFloat(efa->v1->co, efa->v2->co, efa->v3->co, no);
523 if(no[2]>=no[0] && no[2]>=no[1]);
524 else if(no[1]>=no[0] && no[1]>=no[2]) coy= 2;
525 else { cox= 1; coy= 2; }
527 tface->uv[0][0]= 0.5+0.5*cubesize*(loc[cox] + efa->v1->co[cox]);
528 tface->uv[0][1]= 0.5+0.5*cubesize*(loc[coy] + efa->v1->co[coy]);
529 dx = floor(tface->uv[0][0]);
530 dy = floor(tface->uv[0][1]);
531 tface->uv[0][0] -= dx;
532 tface->uv[0][1] -= dy;
533 tface->uv[1][0]= 0.5+0.5*cubesize*(loc[cox] + efa->v2->co[cox]);
534 tface->uv[1][1]= 0.5+0.5*cubesize*(loc[coy] + efa->v2->co[coy]);
535 tface->uv[1][0] -= dx;
536 tface->uv[1][1] -= dy;
537 tface->uv[2][0]= 0.5+0.5*cubesize*(loc[cox] + efa->v3->co[cox]);
538 tface->uv[2][1]= 0.5+0.5*cubesize*(loc[coy] + efa->v3->co[coy]);
539 tface->uv[2][0] -= dx;
540 tface->uv[2][1] -= dy;
542 tface->uv[3][0]= 0.5+0.5*cubesize*(loc[cox] + efa->v4->co[cox]);
543 tface->uv[3][1]= 0.5+0.5*cubesize*(loc[coy] + efa->v4->co[coy]);
544 tface->uv[3][0] -= dx;
545 tface->uv[3][1] -= dy;
552 if ((G.scene->toolsettings->uvcalc_flag & UVCALC_NO_ASPECT_CORRECT)==0)
555 } /* end switch mapmode */
557 /* clipping and wrapping */
558 if(G.sima && G.sima->flag & SI_CLIP_UV) {
559 for (efa= em->faces.first; efa; efa= efa->next) {
560 if (!(efa->f & SELECT)) continue;
561 tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
564 if(efa->v4) b= 3; else b= 2;
566 while(tface->uv[b][0] + dx < 0.0) dx+= 0.5;
567 while(tface->uv[b][0] + dx > 1.0) dx-= 0.5;
568 while(tface->uv[b][1] + dy < 0.0) dy+= 0.5;
569 while(tface->uv[b][1] + dy > 1.0) dy-= 0.5;
572 if(efa->v4) b= 3; else b= 2;
574 tface->uv[b][0]+= dx;
575 CLAMP(tface->uv[b][0], 0.0, 1.0);
577 tface->uv[b][1]+= dy;
578 CLAMP(tface->uv[b][1], 0.0, 1.0);
583 if ( (mapmode!=B_UVAUTO_BOUNDS) &&
584 (mapmode!=B_UVAUTO_RESET) &&
585 (G.scene->toolsettings->uvcalc_flag & UVCALC_NO_ASPECT_CORRECT)==0
590 BIF_undo_push("UV calculation");
592 object_uvs_changed(OBACT);
594 allqueue(REDRAWVIEW3D, 0);
595 allqueue(REDRAWIMAGE, 0);
598 /* last_sel, use em->act_face otherwise get the last selected face in the editselections
599 * at the moment, last_sel is mainly useful for gaking sure the space image dosnt flicker */
600 MTFace *get_active_mtface(EditFace **act_efa, MCol **mcol, int sloppy)
602 EditMesh *em = G.editMesh;
603 EditFace *efa = NULL;
605 if(!EM_texFaceCheck())
608 efa = EM_get_actFace(sloppy);
612 if (CustomData_has_layer(&em->fdata, CD_MCOL))
613 *mcol = CustomData_em_get(&em->fdata, efa->data, CD_MCOL);
617 if (act_efa) *act_efa = efa;
618 return CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
620 if (act_efa) *act_efa= NULL;
621 if(mcol) *mcol = NULL;
625 void default_uv(float uv[][2], float size)
629 if(size>1.0) size= 1.0;
646 void make_tfaces(Mesh *me)
650 multires_add_layer(me, &me->mr->fdata, CD_MTFACE,
651 CustomData_number_of_layers(&me->fdata, CD_MTFACE));
654 me->mtface= CustomData_add_layer(&me->fdata, CD_MTFACE, CD_DEFAULT,
667 if(me==0 || me->totface==0) return;
672 if(mface->flag & ME_HIDE) {
673 mface->flag |= ME_FACE_SEL;
674 mface->flag -= ME_HIDE;
679 BIF_undo_push("Reveal face");
681 object_tface_flags_changed(OBACT, 0);
691 if(me==0 || me->totface==0) return;
693 if(G.qual & LR_ALTKEY) {
701 if(mface->flag & ME_HIDE);
703 if(G.qual & LR_SHIFTKEY) {
704 if( (mface->flag & ME_FACE_SEL)==0) mface->flag |= ME_HIDE;
707 if( (mface->flag & ME_FACE_SEL)) mface->flag |= ME_HIDE;
710 if(mface->flag & ME_HIDE) mface->flag &= ~ME_FACE_SEL;
715 BIF_undo_push("Hide face");
717 object_tface_flags_changed(OBACT, 0);
720 void select_linked_tfaces(int mode)
725 unsigned int index=0;
729 if(me==0 || me->totface==0) return;
731 if (mode==0 || mode==1) {
732 if (!(ob->lay & G.vd->lay))
733 error("The active object is not in this layer");
735 getmouseco_areawin(mval);
736 if (!facesel_face_pick(me, mval, &index, 1)) return;
739 select_linked_tfaces_with_seams(mode, me, index);
742 void deselectall_tface()
755 if(mface->flag & ME_HIDE);
756 else if(mface->flag & ME_FACE_SEL) sel= 1;
763 if(mface->flag & ME_HIDE);
765 if(sel) mface->flag &= ~ME_FACE_SEL;
766 else mface->flag |= ME_FACE_SEL;
771 BIF_undo_push("(De)select all faces");
773 object_tface_flags_changed(OBACT, 0);
776 void selectswap_tface(void)
788 if(mface->flag & ME_HIDE);
790 if(mface->flag & ME_FACE_SEL) mface->flag &= ~ME_FACE_SEL;
791 else mface->flag |= ME_FACE_SEL;
796 BIF_undo_push("Select inverse face");
798 object_tface_flags_changed(OBACT, 0);
801 int minmax_tface(float *min, float *max)
809 float vec[3], bmat[3][3];
812 if (ob==0) return ok;
814 if(me==0 || me->mtface==0) return ok;
816 Mat3CpyMat4(bmat, ob->obmat);
821 for (a=me->totface; a>0; a--, mf++, tf++) {
822 if (mf->flag & ME_HIDE || !(mf->flag & ME_FACE_SEL))
825 VECCOPY(vec, (mv+mf->v1)->co);
826 Mat3MulVecfl(bmat, vec);
827 VecAddf(vec, vec, ob->obmat[3]);
828 DO_MINMAX(vec, min, max);
830 VECCOPY(vec, (mv+mf->v2)->co);
831 Mat3MulVecfl(bmat, vec);
832 VecAddf(vec, vec, ob->obmat[3]);
833 DO_MINMAX(vec, min, max);
835 VECCOPY(vec, (mv+mf->v3)->co);
836 Mat3MulVecfl(bmat, vec);
837 VecAddf(vec, vec, ob->obmat[3]);
838 DO_MINMAX(vec, min, max);
841 VECCOPY(vec, (mv+mf->v4)->co);
842 Mat3MulVecfl(bmat, vec);
843 VecAddf(vec, vec, ob->obmat[3]);
844 DO_MINMAX(vec, min, max);
851 #define ME_SEAM_DONE 2 /* reuse this flag */
853 static float edgetag_cut_cost(EditMesh *em, int e1, int e2, int vert)
855 EditVert *v = EM_get_vert_for_index(vert);
856 EditEdge *eed1 = EM_get_edge_for_index(e1), *eed2 = EM_get_edge_for_index(e2);
857 EditVert *v1 = EM_get_vert_for_index( (eed1->v1->tmp.l == vert)? eed1->v2->tmp.l: eed1->v1->tmp.l );
858 EditVert *v2 = EM_get_vert_for_index( (eed2->v1->tmp.l == vert)? eed2->v2->tmp.l: eed2->v1->tmp.l );
859 float cost, d1[3], d2[3];
861 cost = VecLenf(v1->co, v->co);
862 cost += VecLenf(v->co, v2->co);
864 VecSubf(d1, v->co, v1->co);
865 VecSubf(d2, v2->co, v->co);
867 cost = cost + 0.5f*cost*(2.0f - fabs(d1[0]*d2[0] + d1[1]*d2[1] + d1[2]*d2[2]));
872 static void edgetag_add_adjacent(EditMesh *em, Heap *heap, int mednum, int vertnum, int *nedges, int *edges, int *prevedge, float *cost)
874 int startadj, endadj = nedges[vertnum+1];
876 for (startadj = nedges[vertnum]; startadj < endadj; startadj++) {
877 int adjnum = edges[startadj];
878 EditEdge *eedadj = EM_get_edge_for_index(adjnum);
881 if (eedadj->f2 & ME_SEAM_DONE)
884 newcost = cost[mednum] + edgetag_cut_cost(em, mednum, adjnum, vertnum);
886 if (cost[adjnum] > newcost) {
887 cost[adjnum] = newcost;
888 prevedge[adjnum] = mednum;
889 BLI_heap_insert(heap, newcost, SET_INT_IN_POINTER(adjnum));
894 void edgetag_context_set(EditEdge *eed, int val)
896 switch (G.scene->toolsettings->edge_mode) {
897 case EDGE_MODE_TAG_SEAM:
898 if (val) {eed->seam = 255;}
899 else {eed->seam = 0;}
901 case EDGE_MODE_TAG_SHARP:
902 if (val) {eed->sharp = 1;}
903 else {eed->sharp = 0;}
905 case EDGE_MODE_TAG_CREASE:
906 if (val) {eed->crease = 1.0f;}
907 else {eed->crease = 0.0f;}
909 case EDGE_MODE_TAG_BEVEL:
910 if (val) {eed->bweight = 1.0f;}
911 else {eed->bweight = 0.0f;}
916 int edgetag_context_check(EditEdge *eed)
918 switch (G.scene->toolsettings->edge_mode) {
919 case EDGE_MODE_TAG_SEAM:
920 return eed->seam ? 1 : 0;
921 case EDGE_MODE_TAG_SHARP:
922 return eed->sharp ? 1 : 0;
923 case EDGE_MODE_TAG_CREASE:
924 return eed->crease ? 1 : 0;
925 case EDGE_MODE_TAG_BEVEL:
926 return eed->bweight ? 1 : 0;
932 int edgetag_shortest_path(EditEdge *source, EditEdge *target)
934 EditMesh *em = G.editMesh;
940 int a, totvert=0, totedge=0, *nedges, *edges, *prevedge, mednum = -1, nedgeswap = 0;
943 /* we need the vert */
944 for (ev= em->verts.first, totvert=0; ev; ev= ev->next) {
949 for (eed= em->edges.first; eed; eed = eed->next) {
952 eed->f2 |= ME_SEAM_DONE;
954 eed->tmp.l = totedge;
959 nedges = MEM_callocN(sizeof(*nedges)*totvert+1, "SeamPathNEdges");
960 edges = MEM_mallocN(sizeof(*edges)*totedge*2, "SeamPathEdges");
961 prevedge = MEM_mallocN(sizeof(*prevedge)*totedge, "SeamPathPrevious");
962 cost = MEM_mallocN(sizeof(*cost)*totedge, "SeamPathCost");
964 /* count edges, compute adjacent edges offsets and fill adjacent edges */
965 for (eed= em->edges.first; eed; eed = eed->next) {
966 nedges[eed->v1->tmp.l+1]++;
967 nedges[eed->v2->tmp.l+1]++;
970 for (a=1; a<totvert; a++) {
971 int newswap = nedges[a+1];
972 nedges[a+1] = nedgeswap + nedges[a];
975 nedges[0] = nedges[1] = 0;
977 for (a=0, eed= em->edges.first; eed; a++, eed = eed->next) {
978 edges[nedges[eed->v1->tmp.l+1]++] = a;
979 edges[nedges[eed->v2->tmp.l+1]++] = a;
985 /* regular dijkstra shortest path, but over edges instead of vertices */
986 heap = BLI_heap_new();
987 BLI_heap_insert(heap, 0.0f, SET_INT_IN_POINTER(source->tmp.l));
988 cost[source->tmp.l] = 0.0f;
990 EM_init_index_arrays(1, 1, 0);
993 while (!BLI_heap_empty(heap)) {
994 mednum = GET_INT_FROM_POINTER(BLI_heap_popmin(heap));
995 eed = EM_get_edge_for_index( mednum );
997 if (mednum == target->tmp.l)
1000 if (eed->f2 & ME_SEAM_DONE)
1003 eed->f2 |= ME_SEAM_DONE;
1005 edgetag_add_adjacent(em, heap, mednum, eed->v1->tmp.l, nedges, edges, prevedge, cost);
1006 edgetag_add_adjacent(em, heap, mednum, eed->v2->tmp.l, nedges, edges, prevedge, cost);
1013 BLI_heap_free(heap, NULL);
1015 for (eed= em->edges.first; eed; eed = eed->next) {
1016 eed->f2 &= ~ME_SEAM_DONE;
1019 if (mednum != target->tmp.l) {
1020 MEM_freeN(prevedge);
1021 EM_free_index_arrays();
1025 /* follow path back to source and mark as seam */
1026 if (mednum == target->tmp.l) {
1029 mednum = target->tmp.l;
1031 eed = EM_get_edge_for_index( mednum );
1032 if (!edgetag_context_check(eed)) {
1036 mednum = prevedge[mednum];
1037 } while (mednum != source->tmp.l);
1039 mednum = target->tmp.l;
1041 eed = EM_get_edge_for_index( mednum );
1043 edgetag_context_set(eed, 0);
1045 edgetag_context_set(eed, 1);
1046 mednum = prevedge[mednum];
1047 } while (mednum != -1);
1050 MEM_freeN(prevedge);
1051 EM_free_index_arrays();
1055 static void seam_edgehash_insert_face(EdgeHash *ehash, MFace *mf)
1057 BLI_edgehash_insert(ehash, mf->v1, mf->v2, NULL);
1058 BLI_edgehash_insert(ehash, mf->v2, mf->v3, NULL);
1060 BLI_edgehash_insert(ehash, mf->v3, mf->v4, NULL);
1061 BLI_edgehash_insert(ehash, mf->v4, mf->v1, NULL);
1064 BLI_edgehash_insert(ehash, mf->v3, mf->v1, NULL);
1067 void seam_mark_clear_tface(short mode)
1074 me= get_mesh(OBACT);
1075 if(me==0 || me->totface==0) return;
1078 mode = pupmenu("Seams%t|Mark Border Seam %x1|Clear Seam %x2");
1080 if (mode != 1 && mode != 2)
1084 EdgeHash *ehash = BLI_edgehash_new();
1086 for (a=0, mf=me->mface; a<me->totface; a++, mf++)
1087 if (!(mf->flag & ME_HIDE) && (mf->flag & ME_FACE_SEL))
1088 seam_edgehash_insert_face(ehash, mf);
1090 for (a=0, med=me->medge; a<me->totedge; a++, med++)
1091 if (BLI_edgehash_haskey(ehash, med->v1, med->v2))
1092 med->flag &= ~ME_SEAM;
1094 BLI_edgehash_free(ehash, NULL);
1097 /* mark edges that are on both selected and deselected faces */
1098 EdgeHash *ehash1 = BLI_edgehash_new();
1099 EdgeHash *ehash2 = BLI_edgehash_new();
1101 for (a=0, mf=me->mface; a<me->totface; a++, mf++) {
1102 if ((mf->flag & ME_HIDE) || !(mf->flag & ME_FACE_SEL))
1103 seam_edgehash_insert_face(ehash1, mf);
1105 seam_edgehash_insert_face(ehash2, mf);
1108 for (a=0, med=me->medge; a<me->totedge; a++, med++)
1109 if (BLI_edgehash_haskey(ehash1, med->v1, med->v2) &&
1110 BLI_edgehash_haskey(ehash2, med->v1, med->v2))
1111 med->flag |= ME_SEAM;
1113 BLI_edgehash_free(ehash1, NULL);
1114 BLI_edgehash_free(ehash2, NULL);
1121 BIF_undo_push("Mark Seam");
1123 object_tface_flags_changed(OBACT, 1);
1130 MFace *mface, *msel;
1132 unsigned int a, index;
1134 /* Get the face under the cursor */
1136 if (!(ob->lay & G.vd->lay)) {
1137 error("The active object is not in this layer");
1140 getmouseco_areawin(mval);
1142 if (!facesel_face_pick(me, mval, &index, 1)) return;
1144 msel= (((MFace*)me->mface)+index);
1145 if (msel->flag & ME_HIDE) return;
1150 if ((G.qual & LR_SHIFTKEY)==0) {
1152 mface->flag &= ~ME_FACE_SEL;
1157 me->act_face = (int)index;
1159 if (G.qual & LR_SHIFTKEY) {
1160 if (msel->flag & ME_FACE_SEL)
1161 msel->flag &= ~ME_FACE_SEL;
1163 msel->flag |= ME_FACE_SEL;
1165 else msel->flag |= ME_FACE_SEL;
1167 /* image window redraw */
1169 BIF_undo_push("Select UV face");
1171 object_tface_flags_changed(OBACT, 1);
1174 void face_borderselect()
1181 int a, sx, sy, index, val;
1184 me= get_mesh(OBACT);
1186 if(me->totface==0) return;
1188 val= get_border(&rect, 3);
1190 /* why readbuffer here? shouldn't be necessary (maybe a flush or so) */
1191 glReadBuffer(GL_BACK);
1193 glReadBuffer(GL_AUX0); /* apple only */
1197 selar= MEM_callocN(me->totface+1, "selar");
1199 sx= (rect.xmax-rect.xmin+1);
1200 sy= (rect.ymax-rect.ymin+1);
1201 if(sx*sy<=0) return;
1203 ibuf = IMB_allocImBuf(sx,sy,32,IB_rect,0);
1205 glReadPixels(rect.xmin+curarea->winrct.xmin, rect.ymin+curarea->winrct.ymin, sx, sy, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
1206 if(G.order==B_ENDIAN) IMB_convert_rgba_to_abgr(ibuf);
1211 index= framebuffer_to_index(*rt);
1212 if(index<=me->totface) selar[index]= 1;
1218 for(a=1; a<=me->totface; a++, mface++) {
1220 if(mface->flag & ME_HIDE);
1222 if(val==LEFTMOUSE) mface->flag |= ME_FACE_SEL;
1223 else mface->flag &= ~ME_FACE_SEL;
1228 IMB_freeImBuf(ibuf);
1231 BIF_undo_push("Border Select UV face");
1233 object_tface_flags_changed(OBACT, 0);
1236 glReadBuffer(GL_BACK);
1240 void uv_autocalc_tface()
1242 short mode, i=0, has_pymenu=0; /* pymenu must be bigger then UV_*_MAPPING */
1243 #ifndef DISABLE_PYTHON
1246 char menu_number[3];
1248 /* uvmenu, will add python items */
1249 char uvmenu[4096]=MENUTITLE("UV Calculation")
1250 MENUSTRING("Unwrap", UV_UNWRAP_MAPPING) "|%l|"
1252 MENUSTRING("Cube Projection", UV_CUBE_MAPPING) "|"
1253 MENUSTRING("Cylinder from View", UV_CYL_MAPPING) "|"
1254 MENUSTRING("Sphere from View", UV_SPHERE_MAPPING) "|%l|"
1256 MENUSTRING("Project From View", UV_WINDOW_MAPPING) "|"
1257 MENUSTRING("Project from View (Bounds)",UV_BOUNDS_MAPPING) "|%l|"
1259 MENUSTRING("Reset", UV_RESET_MAPPING);
1260 #ifndef DISABLE_PYTHON
1261 /* note that we account for the 10 previous entries with i+10: */
1262 for (pym = BPyMenuTable[PYMENU_UVCALCULATION]; pym; pym = pym->next, i++) {
1265 strcat(uvmenu, "|%l");
1269 strcat(uvmenu, "|");
1270 strcat(uvmenu, pym->name);
1271 strcat(uvmenu, " %x");
1272 sprintf(menu_number, "%d", i+10);
1273 strcat(uvmenu, menu_number);
1277 mode= pupmenu(uvmenu);
1278 #ifndef DISABLE_PYTHON
1280 BPY_menu_do_python(PYMENU_UVCALCULATION, mode - 10);
1285 case UV_CUBE_MAPPING:
1286 calculate_uv_map(B_UVAUTO_CUBE); break;
1287 case UV_CYL_MAPPING:
1288 calculate_uv_map(B_UVAUTO_CYLINDER); break;
1289 case UV_SPHERE_MAPPING:
1290 calculate_uv_map(B_UVAUTO_SPHERE); break;
1291 case UV_BOUNDS_MAPPING:
1292 calculate_uv_map(B_UVAUTO_BOUNDS); break;
1293 case UV_RESET_MAPPING:
1294 calculate_uv_map(B_UVAUTO_RESET); break;
1295 case UV_WINDOW_MAPPING:
1296 calculate_uv_map(B_UVAUTO_WINDOW); break;
1297 case UV_UNWRAP_MAPPING:
1298 unwrap_lscm(0); break;
1304 void set_texturepaint() /* toggle */
1309 scrarea_queue_headredraw(curarea);
1310 if(ob==NULL) return;
1312 if (object_data_is_libdata(ob)) {
1320 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
1322 if(G.f & G_TEXTUREPAINT) {
1323 G.f &= ~G_TEXTUREPAINT;
1324 GPU_paint_set_mipmap(1);
1327 G.f |= G_TEXTUREPAINT;
1329 if(me->mtface==NULL)
1332 brush_check_exists(&G.scene->toolsettings->imapaint.brush);
1333 GPU_paint_set_mipmap(0);
1336 allqueue(REDRAWVIEW3D, 0);
1337 allqueue(REDRAWBUTSEDIT, 0);
1340 static void texpaint_project(Object *ob, float *model, float *proj, float *co, float *pco)
1345 Mat4MulVecfl(ob->obmat, pco);
1346 Mat4MulVecfl((float(*)[4])model, pco);
1347 Mat4MulVec4fl((float(*)[4])proj, pco);
1350 static void texpaint_tri_weights(Object *ob, float *v1, float *v2, float *v3, float *co, float *w)
1352 float pv1[4], pv2[4], pv3[4], h[3], divw;
1353 float model[16], proj[16], wmat[3][3], invwmat[3][3];
1356 /* compute barycentric coordinates */
1358 /* get the needed opengl matrices */
1359 glGetIntegerv(GL_VIEWPORT, view);
1360 glGetFloatv(GL_MODELVIEW_MATRIX, model);
1361 glGetFloatv(GL_PROJECTION_MATRIX, proj);
1362 view[0] = view[1] = 0;
1364 /* project the verts */
1365 texpaint_project(ob, model, proj, v1, pv1);
1366 texpaint_project(ob, model, proj, v2, pv2);
1367 texpaint_project(ob, model, proj, v3, pv3);
1369 /* do inverse view mapping, see gluProject man page */
1370 h[0]= (co[0] - view[0])*2.0f/view[2] - 1;
1371 h[1]= (co[1] - view[1])*2.0f/view[3] - 1;
1374 /* solve for (w1,w2,w3)/perspdiv in:
1375 h*perspdiv = Project*Model*(w1*v1 + w2*v2 + w3*v3) */
1377 wmat[0][0]= pv1[0]; wmat[1][0]= pv2[0]; wmat[2][0]= pv3[0];
1378 wmat[0][1]= pv1[1]; wmat[1][1]= pv2[1]; wmat[2][1]= pv3[1];
1379 wmat[0][2]= pv1[3]; wmat[1][2]= pv2[3]; wmat[2][2]= pv3[3];
1381 Mat3Inv(invwmat, wmat);
1382 Mat3MulVecfl(invwmat, h);
1386 /* w is still divided by perspdiv, make it sum to one */
1387 divw= w[0] + w[1] + w[2];
1389 VecMulf(w, 1.0f/divw);
1392 /* compute uv coordinates of mouse in face */
1393 void texpaint_pick_uv(Object *ob, Mesh *mesh, unsigned int faceindex, short *xy, float *uv)
1395 DerivedMesh *dm = mesh_get_derived_final(ob, CD_MASK_BAREMESH);
1396 int *index = dm->getFaceDataArray(dm, CD_ORIGINDEX);
1397 MTFace *tface = dm->getFaceDataArray(dm, CD_MTFACE), *tf;
1398 int numfaces = dm->getNumFaces(dm), a;
1399 float p[2], w[3], absw, minabsw;
1404 uv[0] = uv[1] = 0.0;
1408 /* test all faces in the derivedmesh with the original index of the picked face */
1409 for (a = 0; a < numfaces; a++) {
1410 if (index[a] == faceindex) {
1411 dm->getFace(dm, a, &mf);
1413 dm->getVert(dm, mf.v1, &mv[0]);
1414 dm->getVert(dm, mf.v2, &mv[1]);
1415 dm->getVert(dm, mf.v3, &mv[2]);
1417 dm->getVert(dm, mf.v4, &mv[3]);
1425 /* the triangle with the largest absolute values is the one
1426 with the most negative weights */
1427 texpaint_tri_weights(ob, mv[0].co, mv[1].co, mv[3].co, p, w);
1428 absw= fabs(w[0]) + fabs(w[1]) + fabs(w[2]);
1429 if(absw < minabsw) {
1430 uv[0]= tf->uv[0][0]*w[0] + tf->uv[1][0]*w[1] + tf->uv[3][0]*w[2];
1431 uv[1]= tf->uv[0][1]*w[0] + tf->uv[1][1]*w[1] + tf->uv[3][1]*w[2];
1435 texpaint_tri_weights(ob, mv[1].co, mv[2].co, mv[3].co, p, w);
1436 absw= fabs(w[0]) + fabs(w[1]) + fabs(w[2]);
1437 if (absw < minabsw) {
1438 uv[0]= tf->uv[1][0]*w[0] + tf->uv[2][0]*w[1] + tf->uv[3][0]*w[2];
1439 uv[1]= tf->uv[1][1]*w[0] + tf->uv[2][1]*w[1] + tf->uv[3][1]*w[2];
1444 texpaint_tri_weights(ob, mv[0].co, mv[1].co, mv[2].co, p, w);
1445 absw= fabs(w[0]) + fabs(w[1]) + fabs(w[2]);
1446 if (absw < minabsw) {
1447 uv[0]= tf->uv[0][0]*w[0] + tf->uv[1][0]*w[1] + tf->uv[2][0]*w[2];
1448 uv[1]= tf->uv[0][1]*w[0] + tf->uv[1][1]*w[1] + tf->uv[2][1]*w[2];