Blender  V2.59
editmesh_lib.c
Go to the documentation of this file.
00001 /*
00002  * $Id: editmesh_lib.c 36007 2011-04-04 17:28:31Z blendix $
00003  *
00004  * ***** BEGIN GPL LICENSE BLOCK *****
00005  *
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU General Public License
00008  * as published by the Free Software Foundation; either version 2
00009  * of the License, or (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software Foundation,
00018  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00019  *
00020  * The Original Code is Copyright (C) 2004 by Blender Foundation
00021  * All rights reserved.
00022  *
00023  * The Original Code is: all of this file.
00024  *
00025  * Contributor(s): none yet.
00026  *
00027  * ***** END GPL LICENSE BLOCK *****
00028  */
00029 
00035 /*
00036 
00037 editmesh_lib: generic (no UI, no menus) operations/evaluators for editmesh data
00038 
00039 */
00040 
00041 #include <stdlib.h>
00042 #include <string.h>
00043 #include <math.h>
00044 
00045 #include "MEM_guardedalloc.h"
00046 
00047 #include "DNA_meshdata_types.h"
00048 #include "DNA_modifier_types.h"
00049 #include "DNA_object_types.h"
00050 #include "DNA_scene_types.h"
00051 
00052 #include "BLI_blenlib.h"
00053 #include "BLI_math.h"
00054 #include "BLI_editVert.h"
00055 #include "BLI_edgehash.h"
00056 #include "BLI_utildefines.h"
00057 
00058 #include "BKE_customdata.h"
00059 #include "BKE_context.h"
00060 #include "BKE_global.h"
00061 #include "BKE_mesh.h"
00062 
00063 
00064 #include "ED_mesh.h"
00065 #include "ED_screen.h"
00066 #include "ED_view3d.h"
00067 #include "ED_transform.h"
00068 
00069 #include "mesh_intern.h"
00070 
00071 /* Helpers for EM_set_flag_all_selectmode */
00072 #define SET_EVE_FLAG(eve, flag) \
00073         if (eve->h==0) { \
00074                 if (flag & SELECT && !(eve->f & SELECT)) { \
00075                         ++selvert; \
00076                 } \
00077                 eve->f |= flag; \
00078         }
00079 
00080 #define SET_EED_FLAG(eed, flag) \
00081         if (eed->h==0) { \
00082                 if (flag & SELECT && !(eed->f & SELECT)) { \
00083                         ++seledge; \
00084                 } \
00085                 eed->f |= flag; \
00086                 SET_EVE_FLAG(eed->v1, flag); \
00087                 SET_EVE_FLAG(eed->v2, flag); \
00088         }
00089 
00090 
00091 /* ****************** stats *************** */
00092 
00093 int EM_nfaces_selected(EditMesh *em)
00094 {
00095         EditFace *efa;
00096         int count= 0;
00097         
00098         for (efa= em->faces.first; efa; efa= efa->next)
00099                 if (efa->f & SELECT)
00100                         count++;
00101         
00102         em->totfacesel= count;
00103         
00104         return count;
00105 }
00106 
00107 int EM_nedges_selected(EditMesh *em)
00108 {
00109         EditEdge *eed;
00110         int count= 0;
00111         
00112         for (eed= em->edges.first; eed; eed= eed->next) 
00113                 if(eed->f & SELECT)
00114                         count++;
00115         
00116         em->totedgesel= count;
00117         
00118         return count;
00119 }
00120 
00121 int EM_nvertices_selected(EditMesh *em)
00122 {
00123         EditVert *eve;
00124         int count= 0;
00125         
00126         for (eve= em->verts.first; eve; eve= eve->next)
00127                 if (eve->f & SELECT)
00128                         count++;
00129         
00130         em->totvertsel= count;
00131         
00132         return count;
00133 }
00134 
00135 void EM_stats_update(EditMesh *em)
00136 {
00137         
00138         em->totvert= BLI_countlist(&em->verts);
00139         em->totedge= BLI_countlist(&em->edges);
00140         em->totface= BLI_countlist(&em->faces);
00141         
00142         EM_nvertices_selected(em);
00143         EM_nedges_selected(em);
00144         EM_nfaces_selected(em);
00145 }
00146 
00147 /* ************************************** */
00148 
00149 /* this replaces the active flag used in uv/face mode */
00150 void EM_set_actFace(EditMesh *em, EditFace *efa)
00151 {
00152         em->act_face = efa;
00153 }
00154 
00155 EditFace *EM_get_actFace(EditMesh *em, int sloppy)
00156 {
00157         if (em->act_face) {
00158                 return em->act_face;
00159         } else if (sloppy) {
00160                 EditFace *efa= NULL;
00161                 EditSelection *ese;
00162                 
00163                 ese = em->selected.last;
00164                 for (; ese; ese=ese->prev){
00165                         if(ese->type == EDITFACE) {
00166                                 efa = (EditFace *)ese->data;
00167                                 
00168                                 if (efa->h)     efa= NULL;
00169                                 else            break;
00170                         }
00171                 }
00172                 if (efa==NULL) {
00173                         for (efa= em->faces.first; efa; efa= efa->next) {
00174                                 if (efa->f & SELECT)
00175                                         break;
00176                         }
00177                 }
00178                 return efa; /* can still be null */
00179         }
00180         return NULL;
00181 }
00182 
00183 int EM_get_actSelection(EditMesh *em, EditSelection *ese)
00184 {
00185         EditSelection *ese_last = em->selected.last;
00186         EditFace *efa = EM_get_actFace(em, 0);
00187 
00188         ese->next = ese->prev = NULL;
00189         
00190         if (ese_last) {
00191                 if (ese_last->type == EDITFACE) { /* if there is an active face, use it over the last selected face */
00192                         if (efa) {
00193                                 ese->data = (void *)efa;
00194                         } else {
00195                                 ese->data = ese_last->data;
00196                         }
00197                         ese->type = EDITFACE;
00198                 } else {
00199                         ese->data = ese_last->data;
00200                         ese->type = ese_last->type;
00201                 }
00202         } else if (efa) { /* no */
00203                 ese->data = (void *)efa;
00204                 ese->type = EDITFACE;
00205         } else {
00206                 ese->data = NULL;
00207                 return 0;
00208         }
00209         return 1;
00210 }
00211 
00212 /* ********* Selection History ************ */
00213 static int EM_check_selection(EditMesh *em, void *data)
00214 {
00215         EditSelection *ese;
00216         
00217         for(ese = em->selected.first; ese; ese = ese->next){
00218                 if(ese->data == data) return 1;
00219         }
00220         
00221         return 0;
00222 }
00223 
00224 void EM_remove_selection(EditMesh *em, void *data, int UNUSED(type))
00225 {
00226         EditSelection *ese;
00227         for(ese=em->selected.first; ese; ese = ese->next){
00228                 if(ese->data == data){
00229                         BLI_freelinkN(&(em->selected),ese);
00230                         break;
00231                 }
00232         }
00233 }
00234 
00235 void EM_store_selection(EditMesh *em, void *data, int type)
00236 {
00237         EditSelection *ese;
00238         if(!EM_check_selection(em, data)){
00239                 ese = (EditSelection*) MEM_callocN( sizeof(EditSelection), "Edit Selection");
00240                 ese->type = type;
00241                 ese->data = data;
00242                 BLI_addtail(&(em->selected),ese);
00243         }
00244 }
00245 
00246 void EM_validate_selections(EditMesh *em)
00247 {
00248         EditSelection *ese, *nextese;
00249 
00250         ese = em->selected.first;
00251 
00252         while(ese){
00253                 nextese = ese->next;
00254                 if(ese->type == EDITVERT && !(((EditVert*)ese->data)->f & SELECT)) BLI_freelinkN(&(em->selected), ese);
00255                 else if(ese->type == EDITEDGE && !(((EditEdge*)ese->data)->f & SELECT)) BLI_freelinkN(&(em->selected), ese);
00256                 else if(ese->type == EDITFACE && !(((EditFace*)ese->data)->f & SELECT)) BLI_freelinkN(&(em->selected), ese);
00257                 ese = nextese;
00258         }
00259 }
00260 
00261 static void EM_strip_selections(EditMesh *em)
00262 {
00263         EditSelection *ese, *nextese;
00264         if(!(em->selectmode & SCE_SELECT_VERTEX)){
00265                 ese = em->selected.first;
00266                 while(ese){
00267                         nextese = ese->next; 
00268                         if(ese->type == EDITVERT) BLI_freelinkN(&(em->selected),ese);
00269                         ese = nextese;
00270                 }
00271         }
00272         if(!(em->selectmode & SCE_SELECT_EDGE)){
00273                 ese=em->selected.first;
00274                 while(ese){
00275                         nextese = ese->next;
00276                         if(ese->type == EDITEDGE) BLI_freelinkN(&(em->selected), ese);
00277                         ese = nextese;
00278                 }
00279         }
00280         if(!(em->selectmode & SCE_SELECT_FACE)){
00281                 ese=em->selected.first;
00282                 while(ese){
00283                         nextese = ese->next;
00284                         if(ese->type == EDITFACE) BLI_freelinkN(&(em->selected), ese);
00285                         ese = nextese;
00286                 }
00287         }
00288 }
00289 
00290 /* generic way to get data from an EditSelection type 
00291 These functions were written to be used by the Modifier widget when in Rotate about active mode,
00292 but can be used anywhere.
00293 EM_editselection_center
00294 EM_editselection_normal
00295 EM_editselection_plane
00296 */
00297 void EM_editselection_center(float *center, EditSelection *ese)
00298 {
00299         if (ese->type==EDITVERT) {
00300                 EditVert *eve= ese->data;
00301                 copy_v3_v3(center, eve->co);
00302         } else if (ese->type==EDITEDGE) {
00303                 EditEdge *eed= ese->data;
00304                 add_v3_v3v3(center, eed->v1->co, eed->v2->co);
00305                 mul_v3_fl(center, 0.5);
00306         } else if (ese->type==EDITFACE) {
00307                 EditFace *efa= ese->data;
00308                 copy_v3_v3(center, efa->cent);
00309         }
00310 }
00311 
00312 void EM_editselection_normal(float *normal, EditSelection *ese)
00313 {
00314         if (ese->type==EDITVERT) {
00315                 EditVert *eve= ese->data;
00316                 copy_v3_v3(normal, eve->no);
00317         } else if (ese->type==EDITEDGE) {
00318                 EditEdge *eed= ese->data;
00319                 float plane[3]; /* need a plane to correct the normal */
00320                 float vec[3]; /* temp vec storage */
00321                 
00322                 add_v3_v3v3(normal, eed->v1->no, eed->v2->no);
00323                 sub_v3_v3v3(plane, eed->v2->co, eed->v1->co);
00324                 
00325                 /* the 2 vertex normals will be close but not at rightangles to the edge
00326                 for rotate about edge we want them to be at right angles, so we need to
00327                 do some extra colculation to correct the vert normals,
00328                 we need the plane for this */
00329                 cross_v3_v3v3(vec, normal, plane);
00330                 cross_v3_v3v3(normal, plane, vec); 
00331                 normalize_v3(normal);
00332                 
00333         } else if (ese->type==EDITFACE) {
00334                 EditFace *efa= ese->data;
00335                 copy_v3_v3(normal, efa->n);
00336         }
00337 }
00338 
00339 /* Calculate a plane that is rightangles to the edge/vert/faces normal
00340 also make the plane run allong an axis that is related to the geometry,
00341 because this is used for the manipulators Y axis.*/
00342 void EM_editselection_plane(float *plane, EditSelection *ese)
00343 {
00344         if (ese->type==EDITVERT) {
00345                 EditVert *eve= ese->data;
00346                 float vec[3]={0,0,0};
00347                 
00348                 if (ese->prev) { /*use previously selected data to make a usefull vertex plane */
00349                         EM_editselection_center(vec, ese->prev);
00350                         sub_v3_v3v3(plane, vec, eve->co);
00351                 } else {
00352                         /* make a fake  plane thats at rightangles to the normal
00353                         we cant make a crossvec from a vec thats the same as the vec
00354                         unlikely but possible, so make sure if the normal is (0,0,1)
00355                         that vec isnt the same or in the same direction even.*/
00356                         if (eve->no[0]<0.5f)            vec[0]=1;
00357                         else if (eve->no[1]<0.5f)       vec[1]=1;
00358                         else                                            vec[2]=1;
00359                         cross_v3_v3v3(plane, eve->no, vec);
00360                 }
00361         } else if (ese->type==EDITEDGE) {
00362                 EditEdge *eed= ese->data;
00363 
00364                 /*the plane is simple, it runs allong the edge
00365                 however selecting different edges can swap the direction of the y axis.
00366                 this makes it less likely for the y axis of the manipulator
00367                 (running along the edge).. to flip less often.
00368                 at least its more predictable */
00369                 if (eed->v2->co[1] > eed->v1->co[1]) /*check which to do first */
00370                         sub_v3_v3v3(plane, eed->v2->co, eed->v1->co);
00371                 else
00372                         sub_v3_v3v3(plane, eed->v1->co, eed->v2->co);
00373                 
00374         } else if (ese->type==EDITFACE) {
00375                 EditFace *efa= ese->data;
00376                 float vec[3];
00377                 if (efa->v4) { /*if its a quad- set the plane along the 2 longest edges.*/
00378                         float vecA[3], vecB[3];
00379                         sub_v3_v3v3(vecA, efa->v4->co, efa->v3->co);
00380                         sub_v3_v3v3(vecB, efa->v1->co, efa->v2->co);
00381                         add_v3_v3v3(plane, vecA, vecB);
00382                         
00383                         sub_v3_v3v3(vecA, efa->v1->co, efa->v4->co);
00384                         sub_v3_v3v3(vecB, efa->v2->co, efa->v3->co);
00385                         add_v3_v3v3(vec, vecA, vecB);                                           
00386                         /*use the biggest edge length*/
00387                         if (plane[0]*plane[0]+plane[1]*plane[1]+plane[2]*plane[2] < vec[0]*vec[0]+vec[1]*vec[1]+vec[2]*vec[2])
00388                                 copy_v3_v3(plane, vec);
00389                 } else {
00390                         /*start with v1-2 */
00391                         sub_v3_v3v3(plane, efa->v1->co, efa->v2->co);
00392                         
00393                         /*test the edge between v2-3, use if longer */
00394                         sub_v3_v3v3(vec, efa->v2->co, efa->v3->co);
00395                         if (plane[0]*plane[0]+plane[1]*plane[1]+plane[2]*plane[2] < vec[0]*vec[0]+vec[1]*vec[1]+vec[2]*vec[2])
00396                                 copy_v3_v3(plane, vec);
00397                         
00398                         /*test the edge between v1-3, use if longer */
00399                         sub_v3_v3v3(vec, efa->v3->co, efa->v1->co);
00400                         if (plane[0]*plane[0]+plane[1]*plane[1]+plane[2]*plane[2] < vec[0]*vec[0]+vec[1]*vec[1]+vec[2]*vec[2])
00401                                 copy_v3_v3(plane, vec);
00402                 }
00403         }
00404         normalize_v3(plane);
00405 }
00406 
00407 
00408 
00409 void EM_select_face(EditFace *efa, int sel)
00410 {
00411         if(sel) {
00412                 efa->f |= SELECT;
00413                 efa->e1->f |= SELECT;
00414                 efa->e2->f |= SELECT;
00415                 efa->e3->f |= SELECT;
00416                 if(efa->e4) efa->e4->f |= SELECT;
00417                 efa->v1->f |= SELECT;
00418                 efa->v2->f |= SELECT;
00419                 efa->v3->f |= SELECT;
00420                 if(efa->v4) efa->v4->f |= SELECT;
00421         }
00422         else {
00423                 efa->f &= ~SELECT;
00424                 efa->e1->f &= ~SELECT;
00425                 efa->e2->f &= ~SELECT;
00426                 efa->e3->f &= ~SELECT;
00427                 if(efa->e4) efa->e4->f &= ~SELECT;
00428                 efa->v1->f &= ~SELECT;
00429                 efa->v2->f &= ~SELECT;
00430                 efa->v3->f &= ~SELECT;
00431                 if(efa->v4) efa->v4->f &= ~SELECT;
00432         }
00433 }
00434 
00435 void EM_select_edge(EditEdge *eed, int sel)
00436 {
00437         if(sel) {
00438                 eed->f |= SELECT;
00439                 eed->v1->f |= SELECT;
00440                 eed->v2->f |= SELECT;
00441         }
00442         else {
00443                 eed->f &= ~SELECT;
00444                 eed->v1->f &= ~SELECT;
00445                 eed->v2->f &= ~SELECT;
00446         }
00447 }
00448 
00449 void EM_select_face_fgon(EditMesh *em, EditFace *efa, int val)
00450 {
00451         short index=0;
00452         
00453         if(efa->fgonf==0) EM_select_face(efa, val);
00454         else {
00455                 if(efa->e1->fgoni) index= efa->e1->fgoni;
00456                 if(efa->e2->fgoni) index= efa->e2->fgoni;
00457                 if(efa->e3->fgoni) index= efa->e3->fgoni;
00458                 if(efa->v4 && efa->e4->fgoni) index= efa->e4->fgoni;
00459                 
00460                 if((index==0) && (G.f & G_DEBUG))printf("wrong fgon select\n");
00461                 
00462                 // select all ngon faces with index
00463                 for(efa= em->faces.first; efa; efa= efa->next) {
00464                         if(efa->fgonf) {
00465                                 if(efa->e1->fgoni==index || efa->e2->fgoni==index || 
00466                                    efa->e3->fgoni==index || (efa->e4 && efa->e4->fgoni==index) ) {
00467                                         EM_select_face(efa, val);
00468                                 }
00469                         }
00470                 }
00471         }
00472 }
00473 
00474 
00475 /* only vertices */
00476 int faceselectedOR(EditFace *efa, int flag)
00477 {
00478         if ((efa->v1->f | efa->v2->f | efa->v3->f | (efa->v4?efa->v4->f:0))&flag) {
00479                 return 1;
00480         } else {
00481                 return 0;
00482         }
00483 }
00484 
00485 // replace with (efa->f & SELECT)
00486 int faceselectedAND(EditFace *efa, int flag)
00487 {
00488         if ((efa->v1->f & efa->v2->f & efa->v3->f & (efa->v4?efa->v4->f:flag))&flag) {
00489                 return 1;
00490         } else {
00491                 return 0;
00492         }
00493 }
00494 
00495 void EM_clear_flag_all(EditMesh *em, int flag)
00496 {
00497         EditVert *eve;
00498         EditEdge *eed;
00499         EditFace *efa;
00500         
00501         for (eve= em->verts.first; eve; eve= eve->next) eve->f &= ~flag;
00502         for (eed= em->edges.first; eed; eed= eed->next) eed->f &= ~flag;
00503         for (efa= em->faces.first; efa; efa= efa->next) efa->f &= ~flag;
00504         
00505         if(flag & SELECT) {
00506                 BLI_freelistN(&(em->selected));
00507                 em->totvertsel= em->totedgesel= em->totfacesel= 0;
00508         }
00509 }
00510 
00511 void EM_set_flag_all(EditMesh *em, int flag)
00512 {
00513         EditVert *eve;
00514         EditEdge *eed;
00515         EditFace *efa;
00516         
00517         for (eve= em->verts.first; eve; eve= eve->next) if(eve->h==0) eve->f |= flag;
00518         for (eed= em->edges.first; eed; eed= eed->next) if(eed->h==0) eed->f |= flag;
00519         for (efa= em->faces.first; efa; efa= efa->next) if(efa->h==0) efa->f |= flag;
00520         
00521         if(flag & SELECT) {
00522                 em->totvertsel= em->totvert;
00523                 em->totedgesel= em->totedge;
00524                 em->totfacesel= em->totface;
00525         }
00526 }
00527 
00528 void EM_set_flag_all_selectmode(EditMesh *em, int flag)
00529 {
00530          EditVert *eve;
00531          EditEdge *eed;
00532          EditFace *efa;
00533 
00534         int selvert= 0, seledge= 0, selface= 0;
00535 
00536         if (em->selectmode & SCE_SELECT_VERTEX) {
00537                 /* If vertex select mode enabled all the data could be affected */
00538                 for (eve= em->verts.first; eve; eve= eve->next) if(eve->h==0) eve->f |= flag;
00539                 for (eed= em->edges.first; eed; eed= eed->next) if(eed->h==0) eed->f |= flag;
00540                 for (efa= em->faces.first; efa; efa= efa->next) if(efa->h==0) efa->f |= flag;
00541 
00542                 if (flag & SELECT) {
00543                         selvert= em->totvert;
00544                         seledge= em->totedge;
00545                         selface= em->totface;
00546                 }
00547         } else if (em->selectmode & SCE_SELECT_EDGE) {
00548                 /* If edge select mode is enabled we should affect on all edges, faces and */
00549                 /* vertices, connected to them */
00550 
00551                 for (eed= em->edges.first; eed; eed= eed->next) {
00552                         SET_EED_FLAG(eed, flag)
00553                 }
00554 
00555                 for (efa= em->faces.first; efa; efa= efa->next) {
00556                         if(efa->h==0) {
00557                                 efa->f |= flag;
00558 
00559                                 if (flag & SELECT) {
00560                                         ++selface;
00561                                 }
00562                         }
00563                 }
00564         } else if (em->selectmode & SCE_SELECT_FACE) {
00565                 /* No vertex and edge select mode, only face selection */
00566                 /* In face select mode only edges and vertices belongs to faces should be affected */
00567 
00568                 for (efa= em->faces.first; efa; efa= efa->next) {
00569                         if(efa->h==0) {
00570                                 efa->f |= flag;
00571                                 SET_EED_FLAG(efa->e1, flag);
00572                                 SET_EED_FLAG(efa->e2, flag);
00573                                 SET_EED_FLAG(efa->e3, flag);
00574 
00575                                 if (efa->e4) {
00576                                         SET_EED_FLAG(efa->e4, flag);
00577                                 }
00578 
00579                                 if (flag & SELECT) {
00580                                         ++selface;
00581                                 }
00582                         }
00583                 }
00584         }
00585 
00586         if(flag & SELECT) {
00587                 em->totvertsel= selvert;
00588                 em->totedgesel= seledge;
00589                 em->totfacesel= selface;
00590          }
00591  }
00592 /* flush for changes in vertices only */
00593 void EM_deselect_flush(EditMesh *em)
00594 {
00595         EditEdge *eed;
00596         EditFace *efa;
00597         
00598         for(eed= em->edges.first; eed; eed= eed->next) {
00599                 if(eed->v1->f & eed->v2->f & SELECT);
00600                 else eed->f &= ~SELECT;
00601         }
00602         for(efa= em->faces.first; efa; efa= efa->next) {
00603                 if(efa->v4) {
00604                         if(efa->v1->f & efa->v2->f & efa->v3->f & efa->v4->f & SELECT );
00605                         else efa->f &= ~SELECT;
00606                 }
00607                 else {
00608                         if(efa->v1->f & efa->v2->f & efa->v3->f & SELECT );
00609                         else efa->f &= ~SELECT;
00610                 }
00611         }
00612         EM_nedges_selected(em);
00613         EM_nfaces_selected(em);
00614 }
00615 
00616 
00617 /* flush selection to edges & faces */
00618 
00619 /*  this only based on coherent selected vertices, for example when adding new
00620         objects. call clear_flag_all() before you select vertices to be sure it ends OK!
00621         
00622 */
00623 
00624 void EM_select_flush(EditMesh *em)
00625 {
00626         EditEdge *eed;
00627         EditFace *efa;
00628         
00629         for(eed= em->edges.first; eed; eed= eed->next) {
00630                 if(eed->v1->f & eed->v2->f & SELECT) eed->f |= SELECT;
00631         }
00632         for(efa= em->faces.first; efa; efa= efa->next) {
00633                 if(efa->v4) {
00634                         if(efa->v1->f & efa->v2->f & efa->v3->f & efa->v4->f & SELECT ) efa->f |= SELECT;
00635                 }
00636                 else {
00637                         if(efa->v1->f & efa->v2->f & efa->v3->f & SELECT ) efa->f |= SELECT;
00638                 }
00639         }
00640         EM_nedges_selected(em);
00641         EM_nfaces_selected(em);
00642 }
00643 
00644 /* when vertices or edges can be selected, also make fgon consistent */
00645 static void check_fgons_selection(EditMesh *em)
00646 {
00647         EditFace *efa, *efan;
00648         EditEdge *eed;
00649         ListBase *lbar;
00650         int sel, desel, index, totfgon= 0;
00651         
00652         /* count amount of fgons */
00653         for(eed= em->edges.first; eed; eed= eed->next) 
00654                 if(eed->fgoni>totfgon) totfgon= eed->fgoni;
00655         
00656         if(totfgon==0) return;
00657         
00658         lbar= MEM_callocN((totfgon+1)*sizeof(ListBase), "listbase array");
00659         
00660         /* put all fgons in lbar */
00661         for(efa= em->faces.first; efa; efa= efan) {
00662                 efan= efa->next;
00663                 index= efa->e1->fgoni;
00664                 if(index==0) index= efa->e2->fgoni;
00665                 if(index==0) index= efa->e3->fgoni;
00666                 if(index==0 && efa->e4) index= efa->e4->fgoni;
00667                 if(index) {
00668                         BLI_remlink(&em->faces, efa);
00669                         BLI_addtail(&lbar[index], efa);
00670                 }
00671         }
00672         
00673         /* now check the fgons */
00674         for(index=1; index<=totfgon; index++) {
00675                 /* we count on vertices/faces/edges being set OK, so we only have to set ngon itself */
00676                 sel= desel= 0;
00677                 for(efa= lbar[index].first; efa; efa= efa->next) {
00678                         if(efa->e1->fgoni==0) {
00679                                 if(efa->e1->f & SELECT) sel++;
00680                                 else desel++;
00681                         }
00682                         if(efa->e2->fgoni==0) {
00683                                 if(efa->e2->f & SELECT) sel++;
00684                                 else desel++;
00685                         }
00686                         if(efa->e3->fgoni==0) {
00687                                 if(efa->e3->f & SELECT) sel++;
00688                                 else desel++;
00689                         }
00690                         if(efa->e4 && efa->e4->fgoni==0) {
00691                                 if(efa->e4->f & SELECT) sel++;
00692                                 else desel++;
00693                         }
00694                         
00695                         if(sel && desel) break;
00696                 }
00697 
00698                 if(sel && desel) sel= 0;
00699                 else if(sel) sel= 1;
00700                 else sel= 0;
00701                 
00702                 /* select/deselect and put back */
00703                 for(efa= lbar[index].first; efa; efa= efa->next) {
00704                         if(sel) efa->f |= SELECT;
00705                         else efa->f &= ~SELECT;
00706                 }
00707                 BLI_movelisttolist(&em->faces, &lbar[index]);
00708         }
00709         
00710         MEM_freeN(lbar);
00711 }
00712 
00713 
00714 /* flush to edges & faces */
00715 
00716 /* based on select mode it selects edges/faces 
00717    assumed is that verts/edges/faces were properly selected themselves
00718    with the calls above
00719 */
00720 
00721 void EM_selectmode_flush(EditMesh *em)
00722 {
00723         EditEdge *eed;
00724         EditFace *efa;
00725         
00726         // flush to edges & faces
00727         if(em->selectmode & SCE_SELECT_VERTEX) {
00728                 for(eed= em->edges.first; eed; eed= eed->next) {
00729                         if(eed->v1->f & eed->v2->f & SELECT) eed->f |= SELECT;
00730                         else eed->f &= ~SELECT;
00731                 }
00732                 for(efa= em->faces.first; efa; efa= efa->next) {
00733                         if(efa->v4) {
00734                                 if(efa->v1->f & efa->v2->f & efa->v3->f & efa->v4->f & SELECT) efa->f |= SELECT;
00735                                 else efa->f &= ~SELECT;
00736                         }
00737                         else {
00738                                 if(efa->v1->f & efa->v2->f & efa->v3->f & SELECT) efa->f |= SELECT;
00739                                 else efa->f &= ~SELECT;
00740                         }
00741                 }
00742         }
00743         // flush to faces
00744         else if(em->selectmode & SCE_SELECT_EDGE) {
00745                 for(efa= em->faces.first; efa; efa= efa->next) {
00746                         if(efa->e4) {
00747                                 if(efa->e1->f & efa->e2->f & efa->e3->f & efa->e4->f & SELECT) efa->f |= SELECT;
00748                                 else efa->f &= ~SELECT;
00749                         }
00750                         else {
00751                                 if(efa->e1->f & efa->e2->f & efa->e3->f & SELECT) efa->f |= SELECT;
00752                                 else efa->f &= ~SELECT;
00753                         }
00754                 }
00755         }       
00756         // make sure selected faces have selected edges too, for extrude (hack?)
00757         else if(em->selectmode & SCE_SELECT_FACE) {
00758                 for(efa= em->faces.first; efa; efa= efa->next) {
00759                         if(efa->f & SELECT) EM_select_face(efa, 1);
00760                 }
00761         }
00762         
00763         if(!(em->selectmode & SCE_SELECT_FACE))
00764                 check_fgons_selection(em);
00765 
00766         EM_nvertices_selected(em);
00767         EM_nedges_selected(em);
00768         EM_nfaces_selected(em);
00769 }
00770 
00771 void EM_convertsel(EditMesh *em, short oldmode, short selectmode)
00772 {
00773         EditVert *eve;
00774         EditEdge *eed;
00775         EditFace *efa;
00776         /*clear flags*/
00777         for(eve= em->verts.first; eve; eve= eve->next) eve->f1 = 0;
00778         for(eed= em->edges.first; eed; eed= eed->next) eed->f1 = 0;
00779         for(efa= em->faces.first; efa; efa= efa->next) efa->f1 = 0;
00780         
00781         /*have to find out what the selectionmode was previously*/
00782         if(oldmode == SCE_SELECT_VERTEX) {
00783                 if(selectmode == SCE_SELECT_EDGE){
00784                         /*select all edges associated with every selected vertex*/
00785                         for(eed= em->edges.first; eed; eed= eed->next){
00786                                 if(eed->v1->f&SELECT) eed->f1 = 1;
00787                                 else if(eed->v2->f&SELECT) eed->f1 = 1;
00788                         }
00789                         
00790                         for(eed= em->edges.first; eed; eed= eed->next){
00791                                 if(eed->f1 == 1) EM_select_edge(eed,1); 
00792                         }
00793                 }               
00794                 else if(selectmode == SCE_SELECT_FACE){
00795                         /*select all faces associated with every selected vertex*/
00796                         for(efa= em->faces.first; efa; efa= efa->next){
00797                                 if(efa->v1->f&SELECT) efa->f1 = 1;
00798                                 else if(efa->v2->f&SELECT) efa->f1 = 1;
00799                                 else if(efa->v3->f&SELECT) efa->f1 = 1;
00800                                 else{ 
00801                                         if(efa->v4){
00802                                                 if(efa->v4->f&SELECT) efa->f1 =1;
00803                                         }
00804                                 }
00805                         }
00806                         for(efa= em->faces.first; efa; efa= efa->next){
00807                                 if(efa->f1 == 1) EM_select_face(efa,1);
00808                         }
00809                 }
00810         }
00811         
00812         if(oldmode == SCE_SELECT_EDGE){
00813                 if(selectmode == SCE_SELECT_FACE){
00814                         for(efa= em->faces.first; efa; efa= efa->next){
00815                                 if(efa->e1->f&SELECT) efa->f1 = 1;
00816                                 else if(efa->e2->f&SELECT) efa->f1 = 1;
00817                                 else if(efa->e3->f&SELECT) efa->f1 = 1;
00818                                 else if(efa->e4){
00819                                         if(efa->e4->f&SELECT) efa->f1 = 1;
00820                                 }
00821                         }
00822                         for(efa= em->faces.first; efa; efa= efa->next){
00823                                 if(efa->f1 == 1) EM_select_face(efa,1);
00824                         }
00825                 }
00826         }
00827         
00828         check_fgons_selection(em);
00829 
00830         EM_nvertices_selected(em);
00831         EM_nedges_selected(em);
00832         EM_nfaces_selected(em);
00833 }
00834 
00835 void EM_selectmode_to_scene(struct Scene *scene, struct Object *obedit)
00836 {
00837         scene->toolsettings->selectmode= get_mesh(obedit)->edit_mesh->selectmode;
00838 }
00839 
00840 /* when switching select mode, makes sure selection is consistent for editing */
00841 /* also for paranoia checks to make sure edge or face mode works */
00842 void EM_selectmode_set(EditMesh *em)
00843 {
00844         EditVert *eve;
00845         EditEdge *eed;
00846         EditFace *efa;
00847         
00848         EM_strip_selections(em); /*strip EditSelections from em->selected that are not relevant to new mode*/
00849         
00850         if(em->selectmode & SCE_SELECT_VERTEX) {
00851                 /* vertices -> edges -> faces */
00852                 for (eed= em->edges.first; eed; eed= eed->next) eed->f &= ~SELECT;
00853                 for (efa= em->faces.first; efa; efa= efa->next) efa->f &= ~SELECT;
00854                 
00855                 EM_select_flush(em);
00856         }
00857         else if(em->selectmode & SCE_SELECT_EDGE) {
00858                 /* deselect vertices, and select again based on edge select */
00859                 for(eve= em->verts.first; eve; eve= eve->next) eve->f &= ~SELECT;
00860                 for(eed= em->edges.first; eed; eed= eed->next) 
00861                         if(eed->f & SELECT) EM_select_edge(eed, 1);
00862                 /* selects faces based on edge status */
00863                 EM_selectmode_flush(em);
00864         }
00865         else if(em->selectmode & SCE_SELECT_FACE) {
00866                 /* deselect eges, and select again based on face select */
00867                 for(eed= em->edges.first; eed; eed= eed->next) EM_select_edge(eed, 0);
00868                 
00869                 for(efa= em->faces.first; efa; efa= efa->next) 
00870                         if(efa->f & SELECT) EM_select_face(efa, 1);
00871         }
00872 
00873         EM_nvertices_selected(em);
00874         EM_nedges_selected(em);
00875         EM_nfaces_selected(em);
00876 }
00877 
00878 /* paranoia check, actually only for entering editmode. rule:
00879 - vertex hidden, always means edge is hidden too
00880 - edge hidden, always means face is hidden too
00881 - face hidden, dont change anything
00882 */
00883 void EM_hide_reset(EditMesh *em)
00884 {
00885         EditEdge *eed;
00886         EditFace *efa;
00887         
00888         for(eed= em->edges.first; eed; eed= eed->next) 
00889                 if(eed->v1->h || eed->v2->h) eed->h |= 1;
00890                 
00891         for(efa= em->faces.first; efa; efa= efa->next) 
00892                 if((efa->e1->h & 1) || (efa->e2->h & 1) || (efa->e3->h & 1) || (efa->e4 && (efa->e4->h & 1)))
00893                         efa->h= 1;
00894                 
00895 }
00896 
00897 void EM_data_interp_from_verts(EditMesh *em, EditVert *v1, EditVert *v2, EditVert *eve, float fac)
00898 {
00899         void *src[2];
00900         float w[2];
00901 
00902         if (v1->data && v2->data) {
00903                 src[0]= v1->data;
00904                 src[1]= v2->data;
00905                 w[0] = 1.0f-fac;
00906                 w[1] = fac;
00907 
00908                 CustomData_em_interp(&em->vdata, src, w, NULL, 2, eve->data);
00909         }
00910 }
00911 
00912 void EM_data_interp_from_faces(EditMesh *em, EditFace *efa1, EditFace *efa2, EditFace *efan, int i1, int i2, int i3, int i4)
00913 {
00914         float w[2][4][4];
00915         void *src[2];
00916         int count = (efa2)? 2: 1;
00917 
00918         if (efa1->data) {
00919                 /* set weights for copying from corners directly to other corners */
00920                 memset(w, 0, sizeof(w));
00921 
00922                 w[i1/4][0][i1%4]= 1.0f;
00923                 w[i2/4][1][i2%4]= 1.0f;
00924                 w[i3/4][2][i3%4]= 1.0f;
00925                 if (i4 != -1)
00926                         w[i4/4][3][i4%4]= 1.0f;
00927 
00928                 src[0]= efa1->data;
00929                 src[1]= (efa2)? efa2->data: NULL;
00930 
00931                 CustomData_em_interp(&em->fdata, src, NULL, (float*)w, count, efan->data);
00932         }
00933 }
00934 
00935 EditFace *EM_face_from_faces(EditMesh *em, EditFace *efa1, EditFace *efa2, int i1, int i2, int i3, int i4)
00936 {
00937         EditFace *efan;
00938         EditVert **v[2];
00939         
00940         v[0]= &efa1->v1;
00941         v[1]= (efa2)? &efa2->v1: NULL;
00942 
00943         efan= addfacelist(em, v[i1/4][i1%4], v[i2/4][i2%4], v[i3/4][i3%4],
00944                 (i4 == -1)? 0: v[i4/4][i4%4], efa1, NULL);
00945 
00946         EM_data_interp_from_faces(em, efa1, efa2, efan, i1, i2, i3, i4);
00947         
00948         return efan;
00949 }
00950 
00951 static void update_data_blocks(EditMesh *em, CustomData *olddata, CustomData *data)
00952 {
00953         EditFace *efa;
00954         EditVert *eve;
00955         void *block;
00956 
00957         if (data == &em->vdata) {
00958                 for(eve= em->verts.first; eve; eve= eve->next) {
00959                         block = NULL;
00960                         CustomData_em_set_default(data, &block);
00961                         CustomData_em_copy_data(olddata, data, eve->data, &block);
00962                         CustomData_em_free_block(olddata, &eve->data);
00963                         eve->data= block;
00964                 }
00965         }
00966         else if (data == &em->fdata) {
00967                 for(efa= em->faces.first; efa; efa= efa->next) {
00968                         block = NULL;
00969                         CustomData_em_set_default(data, &block);
00970                         CustomData_em_copy_data(olddata, data, efa->data, &block);
00971                         CustomData_em_free_block(olddata, &efa->data);
00972                         efa->data= block;
00973                 }
00974         }
00975 }
00976 
00977 void EM_add_data_layer(EditMesh *em, CustomData *data, int type, const char *name)
00978 {
00979         CustomData olddata;
00980 
00981         olddata= *data;
00982         olddata.layers= (olddata.layers)? MEM_dupallocN(olddata.layers): NULL;
00983         CustomData_add_layer_named(data, type, CD_CALLOC, NULL, 0, name);
00984 
00985         update_data_blocks(em, &olddata, data);
00986         if (olddata.layers) MEM_freeN(olddata.layers);
00987 }
00988 
00989 void EM_free_data_layer(EditMesh *em, CustomData *data, int type)
00990 {
00991         CustomData olddata;
00992 
00993         olddata= *data;
00994         olddata.layers= (olddata.layers)? MEM_dupallocN(olddata.layers): NULL;
00995         CustomData_free_layer_active(data, type, 0);
00996 
00997         update_data_blocks(em, &olddata, data);
00998         if (olddata.layers) MEM_freeN(olddata.layers);
00999 }
01000 
01001 /* ********  EXTRUDE ********* */
01002 
01003 static void add_normal_aligned(float *nor, float *add)
01004 {
01005         if( INPR(nor, add) < -0.9999f)
01006                 sub_v3_v3(nor, add);
01007         else
01008                 add_v3_v3(nor, add);
01009 }
01010 
01011 static void set_edge_directions_f2(EditMesh *em, int val)
01012 {
01013         EditFace *efa;
01014         int do_all= 1;
01015         
01016         /* edge directions are used for extrude, to detect direction of edges that make new faces */
01017         /* we have set 'f2' flags in edges that need to get a direction set (e.g. get new face) */
01018         /* the val argument differs... so we need it as arg */
01019         
01020         for(efa= em->faces.first; efa; efa= efa->next) {
01021                 if(efa->f & SELECT) {
01022                         do_all= 0;
01023                         if(efa->e1->f2<val) {
01024                                 if(efa->e1->v1 == efa->v1) efa->e1->dir= 0;
01025                                 else efa->e1->dir= 1;
01026                         }
01027                         if(efa->e2->f2<val) {
01028                                 if(efa->e2->v1 == efa->v2) efa->e2->dir= 0;
01029                                 else efa->e2->dir= 1;
01030                         }
01031                         if(efa->e3->f2<val) {
01032                                 if(efa->e3->v1 == efa->v3) efa->e3->dir= 0;
01033                                 else efa->e3->dir= 1;
01034                         }
01035                         if(efa->e4 && efa->e4->f2<val) {
01036                                 if(efa->e4->v1 == efa->v4) efa->e4->dir= 0;
01037                                 else efa->e4->dir= 1;
01038                         }
01039                 }
01040         }       
01041         /* ok, no faces done... then we at least set it for exterior edges */
01042         if(do_all) {
01043                 for(efa= em->faces.first; efa; efa= efa->next) {
01044                         if(efa->e1->v1 == efa->v1) efa->e1->dir= 0;
01045                         else efa->e1->dir= 1;
01046                         if(efa->e2->v1 == efa->v2) efa->e2->dir= 0;
01047                         else efa->e2->dir= 1;
01048                         if(efa->e3->v1 == efa->v3) efa->e3->dir= 0;
01049                         else efa->e3->dir= 1;
01050                         if(efa->e4) {
01051                                 if(efa->e4->v1 == efa->v4) efa->e4->dir= 0;
01052                                 else efa->e4->dir= 1;
01053                         }
01054                 }       
01055         }
01056 }
01057 
01058 /* individual face extrude */
01059 /* will use vertex normals for extrusion directions, so *nor is unaffected */
01060 short extrudeflag_face_indiv(EditMesh *em, short UNUSED(flag), float *UNUSED(nor))
01061 {
01062         EditVert *eve, *v1, *v2, *v3, *v4;
01063         EditEdge *eed;
01064         EditFace *efa, *nextfa;
01065         
01066         if(em==NULL) return 0;
01067         
01068         /* selected edges with 1 or more selected face become faces */
01069         /* selected faces each makes new faces */
01070         /* always remove old faces, keeps volumes manifold */
01071         /* select the new extrusion, deselect old */
01072         
01073         /* step 1; init, count faces in edges */
01074         recalc_editnormals(em);
01075         
01076         for(eve= em->verts.first; eve; eve= eve->next) eve->f1= 0;      // new select flag
01077 
01078         for(eed= em->edges.first; eed; eed= eed->next) {
01079                 eed->f2= 0; // amount of unselected faces
01080         }
01081         for(efa= em->faces.first; efa; efa= efa->next) {
01082                 if(efa->f & SELECT);
01083                 else {
01084                         efa->e1->f2++;
01085                         efa->e2->f2++;
01086                         efa->e3->f2++;
01087                         if(efa->e4) efa->e4->f2++;
01088                 }
01089         }
01090 
01091         /* step 2: make new faces from faces */
01092         for(efa= em->faces.last; efa; efa= efa->prev) {
01093                 if(efa->f & SELECT) {
01094                         v1= addvertlist(em, efa->v1->co, efa->v1);
01095                         v2= addvertlist(em, efa->v2->co, efa->v2);
01096                         v3= addvertlist(em, efa->v3->co, efa->v3);
01097                         
01098                         v1->f1= v2->f1= v3->f1= 1;
01099                         VECCOPY(v1->no, efa->n);
01100                         VECCOPY(v2->no, efa->n);
01101                         VECCOPY(v3->no, efa->n);
01102                         if(efa->v4) {
01103                                 v4= addvertlist(em, efa->v4->co, efa->v4); 
01104                                 v4->f1= 1;
01105                                 VECCOPY(v4->no, efa->n);
01106                         }
01107                         else v4= NULL;
01108                         
01109                         /* side faces, clockwise */
01110                         addfacelist(em, efa->v2, v2, v1, efa->v1, efa, NULL);
01111                         addfacelist(em, efa->v3, v3, v2, efa->v2, efa, NULL);
01112                         if(efa->v4) {
01113                                 addfacelist(em, efa->v4, v4, v3, efa->v3, efa, NULL);
01114                                 addfacelist(em, efa->v1, v1, v4, efa->v4, efa, NULL);
01115                         }
01116                         else {
01117                                 addfacelist(em, efa->v1, v1, v3, efa->v3, efa, NULL);
01118                         }
01119                         /* top face */
01120                         addfacelist(em, v1, v2, v3, v4, efa, NULL);
01121                 }
01122         }
01123         
01124         /* step 3: remove old faces */
01125         efa= em->faces.first;
01126         while(efa) {
01127                 nextfa= efa->next;
01128                 if(efa->f & SELECT) {
01129                         BLI_remlink(&em->faces, efa);
01130                         free_editface(em, efa);
01131                 }
01132                 efa= nextfa;
01133         }
01134 
01135         /* step 4: redo selection */
01136         EM_clear_flag_all(em, SELECT);
01137         
01138         for(eve= em->verts.first; eve; eve= eve->next) {
01139                 if(eve->f1)  eve->f |= SELECT;
01140         }
01141         
01142         EM_select_flush(em);
01143         
01144         return 'n';
01145 }
01146 
01147 
01148 /* extrudes individual edges */
01149 /* nor is filled with constraint vector */
01150 short extrudeflag_edges_indiv(EditMesh *em, short flag, float *nor) 
01151 {
01152         EditVert *eve;
01153         EditEdge *eed;
01154         EditFace *efa;
01155         
01156         for(eve= em->verts.first; eve; eve= eve->next) eve->tmp.v = NULL;
01157         for(eed= em->edges.first; eed; eed= eed->next) {
01158                 eed->tmp.f = NULL;
01159                 eed->f2= ((eed->f & flag)!=0);
01160         }
01161         
01162         set_edge_directions_f2(em, 2);
01163 
01164         /* sample for next loop */
01165         for(efa= em->faces.first; efa; efa= efa->next) {
01166                 efa->e1->tmp.f = efa;
01167                 efa->e2->tmp.f = efa;
01168                 efa->e3->tmp.f = efa;
01169                 if(efa->e4) efa->e4->tmp.f = efa;
01170         }
01171         /* make the faces */
01172         for(eed= em->edges.first; eed; eed= eed->next) {
01173                 if(eed->f & flag) {
01174                         if(eed->v1->tmp.v == NULL)
01175                                 eed->v1->tmp.v = addvertlist(em, eed->v1->co, eed->v1);
01176                         if(eed->v2->tmp.v == NULL)
01177                                 eed->v2->tmp.v = addvertlist(em, eed->v2->co, eed->v2);
01178 
01179                         if(eed->dir==1) 
01180                                 addfacelist(em, eed->v1, eed->v2, 
01181                                                         eed->v2->tmp.v, eed->v1->tmp.v, 
01182                                                         eed->tmp.f, NULL);
01183                         else 
01184                                 addfacelist(em, eed->v2, eed->v1, 
01185                                                         eed->v1->tmp.v, eed->v2->tmp.v, 
01186                                                         eed->tmp.f, NULL);
01187 
01188                         /* for transform */
01189                         if(eed->tmp.f) {
01190                                 efa = eed->tmp.f;
01191                                 if (efa->f & SELECT) add_normal_aligned(nor, efa->n);
01192                         }
01193                 }
01194         }
01195         normalize_v3(nor);
01196         
01197         /* set correct selection */
01198         EM_clear_flag_all(em, SELECT);
01199         for(eve= em->verts.last; eve; eve= eve->prev) {
01200                 if(eve->tmp.v) {
01201                         eve->tmp.v->f |= flag;
01202                 }
01203         }
01204 
01205         for(eed= em->edges.first; eed; eed= eed->next) {
01206                 if(eed->v1->f & eed->v2->f & flag) eed->f |= flag;
01207         }
01208         
01209         if(is_zero_v3(nor)) return 'g'; // g is grab
01210         return 'n';  // n is for normal constraint
01211 }
01212 
01213 /* extrudes individual vertices */
01214 short extrudeflag_verts_indiv(EditMesh *em, short flag, float *UNUSED(nor)) 
01215 {
01216         EditVert *eve;
01217         
01218         /* make the edges */
01219         for(eve= em->verts.first; eve; eve= eve->next) {
01220                 if(eve->f & flag) {
01221                         eve->tmp.v = addvertlist(em, eve->co, eve);
01222                         addedgelist(em, eve, eve->tmp.v, NULL);
01223                 }
01224                 else eve->tmp.v = NULL;
01225         }
01226         
01227         /* set correct selection */
01228         EM_clear_flag_all(em, SELECT);
01229 
01230         for(eve= em->verts.last; eve; eve= eve->prev) 
01231                 if (eve->tmp.v) 
01232                         eve->tmp.v->f |= flag;
01233 
01234         return 'g';     // g is grab
01235 }
01236 
01237 
01238 /* this is actually a recode of extrudeflag(), using proper edge/face select */
01239 /* hurms, doesnt use 'flag' yet, but its not called by primitive making stuff anyway */
01240 static short extrudeflag_edge(Object *obedit, EditMesh *em, short UNUSED(flag), float *nor, int all)
01241 {
01242         /* all select edges/faces: extrude */
01243         /* old select is cleared, in new ones it is set */
01244         EditVert *eve, *nextve;
01245         EditEdge *eed, *nexted;
01246         EditFace *efa, *nextfa, *efan;
01247         short del_old= 0;
01248         ModifierData *md;
01249         
01250         if(em==NULL) return 0;
01251 
01252         md = obedit->modifiers.first;
01253         
01254         /* selected edges with 0 or 1 selected face become faces */
01255         /* selected faces generate new faces */
01256 
01257         /* if *one* selected face has edge with unselected face; remove old selected faces */
01258         
01259         /* if selected edge is not used anymore; remove */
01260         /* if selected vertex is not used anymore: remove */
01261         
01262         /* select the new extrusion, deselect old */
01263         
01264         
01265         /* step 1; init, count faces in edges */
01266         recalc_editnormals(em);
01267         
01268         for(eve= em->verts.first; eve; eve= eve->next) {
01269                 eve->tmp.v = NULL;
01270                 eve->f1= 0;
01271         }
01272 
01273         for(eed= em->edges.first; eed; eed= eed->next) {
01274                 eed->f1= 0; // amount of unselected faces
01275                 eed->f2= 0; // amount of selected faces
01276                 if(eed->f & SELECT) {
01277                         eed->v1->f1= 1; // we call this 'selected vertex' now
01278                         eed->v2->f1= 1;
01279                 }
01280                 eed->tmp.f = NULL;              // here we tuck face pointer, as sample
01281         }
01282         for(efa= em->faces.first; efa; efa= efa->next) {
01283                 if(efa->f & SELECT) {
01284                         efa->e1->f2++;
01285                         efa->e2->f2++;
01286                         efa->e3->f2++;
01287                         if(efa->e4) efa->e4->f2++;
01288                         
01289                         // sample for next loop
01290                         efa->e1->tmp.f = efa;
01291                         efa->e2->tmp.f = efa;
01292                         efa->e3->tmp.f = efa;
01293                         if(efa->e4) efa->e4->tmp.f = efa;
01294                 }
01295                 else {
01296                         efa->e1->f1++;
01297                         efa->e2->f1++;
01298                         efa->e3->f1++;
01299                         if(efa->e4) efa->e4->f1++;
01300                 }
01301         }
01302         
01303         /* If a mirror modifier with clipping is on, we need to adjust some 
01304          * of the cases above to handle edges on the line of symmetry.
01305          */
01306         for (; md; md=md->next) {
01307                 if (md->type==eModifierType_Mirror) {
01308                         MirrorModifierData *mmd = (MirrorModifierData*) md;     
01309                 
01310                         if(mmd->flag & MOD_MIR_CLIPPING) {
01311                                 float mtx[4][4];
01312                                 if (mmd->mirror_ob) {
01313                                         float imtx[4][4];
01314                                         invert_m4_m4(imtx, mmd->mirror_ob->obmat);
01315                                         mul_m4_m4m4(mtx, obedit->obmat, imtx);
01316                                 }
01317 
01318                                 for (eed= em->edges.first; eed; eed= eed->next) {
01319                                         if(eed->f2 == 1) {
01320                                                 float co1[3], co2[3];
01321 
01322                                                 copy_v3_v3(co1, eed->v1->co);
01323                                                 copy_v3_v3(co2, eed->v2->co);
01324 
01325                                                 if (mmd->mirror_ob) {
01326                                                         mul_m4_v3(mtx, co1);
01327                                                         mul_m4_v3(mtx, co2);
01328                                                 }
01329 
01330                                                 if (mmd->flag & MOD_MIR_AXIS_X)
01331                                                         if ( (fabsf(co1[0]) < mmd->tolerance) &&
01332                                                                  (fabsf(co2[0]) < mmd->tolerance) )
01333                                                                 ++eed->f2;
01334 
01335                                                 if (mmd->flag & MOD_MIR_AXIS_Y)
01336                                                         if ( (fabsf(co1[1]) < mmd->tolerance) &&
01337                                                                  (fabsf(co2[1]) < mmd->tolerance) )
01338                                                                 ++eed->f2;
01339 
01340                                                 if (mmd->flag & MOD_MIR_AXIS_Z)
01341                                                         if ( (fabsf(co1[2]) < mmd->tolerance) &&
01342                                                                  (fabsf(co2[2]) < mmd->tolerance) )
01343                                                                 ++eed->f2;
01344                                         }
01345                                 }
01346                         }
01347                 }
01348         }
01349 
01350         set_edge_directions_f2(em, 2);
01351         
01352         /* step 1.5: if *one* selected face has edge with unselected face; remove old selected faces */
01353         if(all == 0) {
01354                 for(efa= em->faces.last; efa; efa= efa->prev) {
01355                         if(efa->f & SELECT) {
01356                                 if(efa->e1->f1 || efa->e2->f1 || efa->e3->f1 || (efa->e4 && efa->e4->f1)) {
01357                                         del_old= 1;
01358                                         break;
01359                                 }
01360                         }
01361                 }
01362         }
01363                                 
01364         /* step 2: make new faces from edges */
01365         for(eed= em->edges.last; eed; eed= eed->prev) {
01366                 if(eed->f & SELECT) {
01367                         if(eed->f2<2) {
01368                                 if(eed->v1->tmp.v == NULL)
01369                                         eed->v1->tmp.v = addvertlist(em, eed->v1->co, eed->v1);
01370                                 if(eed->v2->tmp.v == NULL)
01371                                         eed->v2->tmp.v = addvertlist(em, eed->v2->co, eed->v2);
01372 
01373                                 /* if del_old, the preferred normal direction is exact 
01374                                  * opposite as for keep old faces
01375                                  */
01376                                 if(eed->dir!=del_old) 
01377                                         addfacelist(em, eed->v1, eed->v2, 
01378                                                                 eed->v2->tmp.v, eed->v1->tmp.v, 
01379                                                                 eed->tmp.f, NULL);
01380                                 else 
01381                                         addfacelist(em, eed->v2, eed->v1, 
01382                                                                 eed->v1->tmp.v, eed->v2->tmp.v,
01383                                                                 eed->tmp.f, NULL);
01384                         }
01385                 }
01386         }
01387         
01388         /* step 3: make new faces from faces */
01389         for(efa= em->faces.last; efa; efa= efa->prev) {
01390                 if(efa->f & SELECT) {
01391                         if (efa->v1->tmp.v == NULL)
01392                                 efa->v1->tmp.v = addvertlist(em, efa->v1->co, efa->v1);
01393                         if (efa->v2->tmp.v ==NULL)
01394                                 efa->v2->tmp.v = addvertlist(em, efa->v2->co, efa->v2);
01395                         if (efa->v3->tmp.v ==NULL)
01396                                 efa->v3->tmp.v = addvertlist(em, efa->v3->co, efa->v3);
01397                         if (efa->v4 && (efa->v4->tmp.v == NULL))
01398                                 efa->v4->tmp.v = addvertlist(em, efa->v4->co, efa->v4);
01399                         
01400                         if(efa->v4)
01401                                 efan = addfacelist(em, efa->v1->tmp.v, efa->v2->tmp.v,
01402                                                         efa->v3->tmp.v, efa->v4->tmp.v, efa, efa);
01403                         else
01404                                 efan = addfacelist(em, efa->v1->tmp.v, efa->v2->tmp.v,
01405                                                         efa->v3->tmp.v, NULL, efa, efa);
01406 
01407                         /* keep old faces means flipping normal, reverse vertex order gives bad UV's & VCols etc - [#25260] */
01408                         if(del_old==0) {
01409                                 flipface(em, efan);
01410                         }
01411 
01412                         if (em->act_face == efa) {
01413                                 em->act_face = efan; 
01414                         }
01415 
01416                         /* for transform */
01417                         add_normal_aligned(nor, efa->n);
01418                 }
01419         }
01420         
01421         if(del_old) {
01422                 
01423                 /* step 4: remove old faces, if del_old */
01424                 efa= em->faces.first;
01425                 while(efa) {
01426                         nextfa= efa->next;
01427                         if(efa->f & SELECT) {
01428                                 BLI_remlink(&em->faces, efa);
01429                                 free_editface(em, efa);
01430                         }
01431                         efa= nextfa;
01432                 }
01433                 
01434                 
01435                 /* step 5: remove selected unused edges */
01436                 /* start tagging again */
01437                 for(eed= em->edges.first; eed; eed= eed->next) eed->f1=0;
01438                 for(efa= em->faces.first; efa; efa= efa->next) {
01439                         efa->e1->f1= 1;
01440                         efa->e2->f1= 1;
01441                         efa->e3->f1= 1;
01442                         if(efa->e4) efa->e4->f1= 1;
01443                 }
01444                 /* remove */
01445                 eed= em->edges.first; 
01446                 while(eed) {
01447                         nexted= eed->next;
01448                         if(eed->f & SELECT) {
01449                                 if(eed->f1==0) {
01450                                         remedge(em, eed);
01451                                         free_editedge(em, eed);
01452                                 }
01453                         }
01454                         eed= nexted;
01455                 }
01456         
01457                 /* step 6: remove selected unused vertices */
01458                 for(eed= em->edges.first; eed; eed= eed->next) 
01459                         eed->v1->f1= eed->v2->f1= 0;
01460                 
01461                 eve= em->verts.first;
01462                 while(eve) {
01463                         nextve= eve->next;
01464                         if(eve->f1) {
01465                                 // hack... but we need it for step 7, redoing selection
01466                                 if(eve->tmp.v) eve->tmp.v->tmp.v= eve->tmp.v;
01467                                 
01468                                 BLI_remlink(&em->verts, eve);
01469                                 free_editvert(em, eve);
01470                         }
01471                         eve= nextve;
01472                 }
01473         }
01474         
01475         normalize_v3(nor);      // translation normal grab
01476         
01477         /* step 7: redo selection */
01478         EM_clear_flag_all(em, SELECT);
01479 
01480         for(eve= em->verts.first; eve; eve= eve->next) {
01481                 if(eve->tmp.v) {
01482                         eve->tmp.v->f |= SELECT;
01483                 }
01484         }
01485 
01486         EM_select_flush(em);
01487 
01488         if(is_zero_v3(nor)) return 'g'; // grab
01489         return 'n'; // normal constraint 
01490 }
01491 
01492 short extrudeflag_vert(Object *obedit, EditMesh *em, short flag, float *nor, int all)
01493 {
01494         /* all verts/edges/faces with (f & 'flag'): extrude */
01495         /* from old verts, 'flag' is cleared, in new ones it is set */
01496         EditVert *eve, *v1, *v2, *v3, *v4, *nextve;
01497         EditEdge *eed, *e1, *e2, *e3, *e4, *nexted;
01498         EditFace *efa, *efa2, *nextvl;
01499         short sel=0, del_old= 0, is_face_sel=0;
01500         ModifierData *md;
01501 
01502         if(em==NULL) return 0;
01503 
01504         md = obedit->modifiers.first;
01505 
01506         /* clear vert flag f1, we use this to detect a loose selected vertice */
01507         eve= em->verts.first;
01508         while(eve) {
01509                 if(eve->f & flag) eve->f1= 1;
01510                 else eve->f1= 0;
01511                 eve= eve->next;
01512         }
01513         /* clear edges counter flag, if selected we set it at 1 */
01514         eed= em->edges.first;
01515         while(eed) {
01516                 if( (eed->v1->f & flag) && (eed->v2->f & flag) ) {
01517                         eed->f2= 1;
01518                         eed->v1->f1= 0;
01519                         eed->v2->f1= 0;
01520                 }
01521                 else eed->f2= 0;
01522                 
01523                 eed->f1= 1;             /* this indicates it is an 'old' edge (in this routine we make new ones) */
01524                 eed->tmp.f = NULL;      /* used as sample */
01525                 
01526                 eed= eed->next;
01527         }
01528 
01529         /* we set a flag in all selected faces, and increase the associated edge counters */
01530 
01531         efa= em->faces.first;
01532         while(efa) {
01533                 efa->f1= 0;
01534 
01535                 if(faceselectedAND(efa, flag)) {
01536                         e1= efa->e1;
01537                         e2= efa->e2;
01538                         e3= efa->e3;
01539                         e4= efa->e4;
01540 
01541                         if(e1->f2 < 3) e1->f2++;
01542                         if(e2->f2 < 3) e2->f2++;
01543                         if(e3->f2 < 3) e3->f2++;
01544                         if(e4 && e4->f2 < 3) e4->f2++;
01545                         
01546                         efa->f1= 1;
01547                         is_face_sel= 1; // for del_old
01548                 }
01549                 else if(faceselectedOR(efa, flag)) {
01550                         e1= efa->e1;
01551                         e2= efa->e2;
01552                         e3= efa->e3;
01553                         e4= efa->e4;
01554                         
01555                         if( (e1->v1->f & flag) && (e1->v2->f & flag) ) e1->f1= 2;
01556                         if( (e2->v1->f & flag) && (e2->v2->f & flag) ) e2->f1= 2;
01557                         if( (e3->v1->f & flag) && (e3->v2->f & flag) ) e3->f1= 2;
01558                         if( e4 && (e4->v1->f & flag) && (e4->v2->f & flag) ) e4->f1= 2;
01559                 }
01560                 
01561                 // sample for next loop
01562                 efa->e1->tmp.f = efa;
01563                 efa->e2->tmp.f = efa;
01564                 efa->e3->tmp.f = efa;
01565                 if(efa->e4) efa->e4->tmp.f = efa;
01566 
01567                 efa= efa->next;
01568         }
01569 
01570         set_edge_directions_f2(em, 3);
01571 
01572         /* the current state now is:
01573                 eve->f1==1: loose selected vertex 
01574 
01575                 eed->f2==0 : edge is not selected, no extrude
01576                 eed->f2==1 : edge selected, is not part of a face, extrude
01577                 eed->f2==2 : edge selected, is part of 1 face, extrude
01578                 eed->f2==3 : edge selected, is part of more faces, no extrude
01579                 
01580                 eed->f1==0: new edge
01581                 eed->f1==1: edge selected, is part of selected face, when eed->f==3: remove
01582                 eed->f1==2: edge selected, part of a partially selected face
01583                                         
01584                 efa->f1==1 : duplicate this face
01585         */
01586 
01587         /* If a mirror modifier with clipping is on, we need to adjust some 
01588          * of the cases above to handle edges on the line of symmetry.
01589          */
01590         for (; md; md=md->next) {
01591                 if (md->type==eModifierType_Mirror) {
01592                         MirrorModifierData *mmd = (MirrorModifierData*) md;     
01593                 
01594                         if(mmd->flag & MOD_MIR_CLIPPING) {
01595                                 float mtx[4][4];
01596                                 if (mmd->mirror_ob) {
01597                                         float imtx[4][4];
01598                                         invert_m4_m4(imtx, mmd->mirror_ob->obmat);
01599                                         mul_m4_m4m4(mtx, obedit->obmat, imtx);
01600                                 }
01601 
01602                                 for (eed= em->edges.first; eed; eed= eed->next) {
01603                                         if(eed->f2 == 2) {
01604                                                 float co1[3], co2[3];
01605 
01606                                                 copy_v3_v3(co1, eed->v1->co);
01607                                                 copy_v3_v3(co2, eed->v2->co);
01608 
01609                                                 if (mmd->mirror_ob) {
01610                                                         mul_m4_v3(mtx, co1);
01611                                                         mul_m4_v3(mtx, co2);
01612                                                 }
01613 
01614                                                 if (mmd->flag & MOD_MIR_AXIS_X)
01615                                                         if ( (fabsf(co1[0]) < mmd->tolerance) &&
01616                                                                  (fabsf(co2[0]) < mmd->tolerance) )
01617                                                                 ++eed->f2;
01618 
01619                                                 if (mmd->flag & MOD_MIR_AXIS_Y)
01620                                                         if ( (fabsf(co1[1]) < mmd->tolerance) &&
01621                                                                  (fabsf(co2[1]) < mmd->tolerance) )
01622                                                                 ++eed->f2;
01623                                                 if (mmd->flag & MOD_MIR_AXIS_Z)
01624                                                         if ( (fabsf(co1[2]) < mmd->tolerance) &&
01625                                                                  (fabsf(co2[2]) < mmd->tolerance) )
01626                                                                 ++eed->f2;
01627                                         }
01628                                 }
01629                         }
01630                 }
01631         }
01632 
01633         /* copy all selected vertices, */
01634         /* write pointer to new vert in old struct at eve->tmp.v */
01635         eve= em->verts.last;
01636         while(eve) {
01637                 eve->f &= ~128;  /* clear, for later test for loose verts */
01638                 if(eve->f & flag) {
01639                         sel= 1;
01640                         v1= addvertlist(em, 0, NULL);
01641                         
01642                         VECCOPY(v1->co, eve->co);
01643                         VECCOPY(v1->no, eve->no);
01644                         v1->f= eve->f;
01645                         eve->f &= ~flag;
01646                         eve->tmp.v = v1;
01647                 }
01648                 else eve->tmp.v = NULL;
01649                 eve= eve->prev;
01650         }
01651 
01652         if(sel==0) return 0;
01653 
01654         /* all edges with eed->f2==1 or eed->f2==2 become faces */
01655         
01656         /* if del_old==1 then extrude is in partial geometry, to keep it manifold.
01657                                          verts with f1==0 and (eve->f & 128)==0) are removed
01658                                          edges with eed->f2>2 are removed
01659                                          faces with efa->f1 are removed
01660            if del_old==0 the extrude creates a volume.
01661         */
01662         
01663          /* find if we delete old faces */
01664         if(is_face_sel && all==0) {
01665                 for(eed= em->edges.first; eed; eed= eed->next) {
01666                         if( (eed->f2==1 || eed->f2==2) ) {
01667                                 if(eed->f1==2) {
01668                                         del_old= 1;
01669                                         break;
01670                                 }
01671                         }
01672                 }
01673         }
01674         
01675         eed= em->edges.last;
01676         while(eed) {
01677                 nexted= eed->prev;
01678                 if( eed->f2<3) {
01679                         eed->v1->f |= 128;  /* = no loose vert! */
01680                         eed->v2->f |= 128;
01681                 }
01682                 if( (eed->f2==1 || eed->f2==2) ) {
01683         
01684                         /* if del_old, the preferred normal direction is exact opposite as for keep old faces */
01685                         if(eed->dir != del_old) 
01686                                 efa2 = addfacelist(em, eed->v1, eed->v2, 
01687                                                                   eed->v2->tmp.v, eed->v1->tmp.v, 
01688                                                                   eed->tmp.f, NULL);
01689                         else 
01690                                 efa2 = addfacelist(em, eed->v2, eed->v1, 
01691                                                                    eed->v1->tmp.v, eed->v2->tmp.v, 
01692                                                                    eed->tmp.f, NULL);
01693                         
01694                         /* Needs smarter adaption of existing creases.
01695                          * If addedgelist is used, make sure seams are set to 0 on these
01696                          * new edges, since we do not want to add any seams on extrusion.
01697                          */
01698                         efa2->e1->crease= eed->crease;
01699                         efa2->e2->crease= eed->crease;
01700                         efa2->e3->crease= eed->crease;
01701                         if(efa2->e4) efa2->e4->crease= eed->crease;
01702                 }
01703 
01704                 eed= nexted;
01705         }
01706         
01707         /* duplicate faces, if necessary remove old ones  */
01708         efa= em->faces.first;
01709         while(efa) {
01710                 nextvl= efa->next;
01711                 if(efa->f1 & 1) {
01712                 
01713                         v1 = efa->v1->tmp.v;
01714                         v2 = efa->v2->tmp.v;
01715                         v3 = efa->v3->tmp.v;
01716                         if(efa->v4) 
01717                                 v4 = efa->v4->tmp.v; 
01718                         else
01719                                 v4= NULL;
01720 
01721                         /* hmm .. not sure about edges here */
01722                         if(del_old==0)  // if we keep old, we flip normal
01723                                 efa2= addfacelist(em, v3, v2, v1, v4, efa, efa); 
01724                         else
01725                                 efa2= addfacelist(em, v1, v2, v3, v4, efa, efa);
01726                         
01727                         /* for transform */
01728                         add_normal_aligned(nor, efa->n);
01729 
01730                         if(del_old) {
01731                                 BLI_remlink(&em->faces, efa);
01732                                 free_editface(em, efa);
01733                         }
01734                 }
01735                 efa= nextvl;
01736         }
01737         /* delete edges after copying edges above! */
01738         if(del_old) {
01739                 eed= em->edges.first;
01740                 while(eed) {
01741                         nexted= eed->next;
01742                         if(eed->f2==3 && eed->f1==1) {
01743                                 remedge(em, eed);
01744                                 free_editedge(em, eed);
01745                         }
01746                         eed= nexted;
01747                 }
01748         }
01749         
01750         normalize_v3(nor);      // for grab
01751         
01752         /* for all vertices with eve->tmp.v!=0 
01753                 if eve->f1==1: make edge
01754                 if flag!=128 : if del_old==1: remove
01755         */
01756         eve= em->verts.last;
01757         while(eve) {
01758                 nextve= eve->prev;
01759                 if(eve->tmp.v) {
01760                         if(eve->f1==1) addedgelist(em, eve, eve->tmp.v, NULL);
01761                         else if( (eve->f & 128)==0) {
01762                                 if(del_old) {
01763                                         BLI_remlink(&em->verts,eve);
01764                                         free_editvert(em, eve);
01765                                         eve= NULL;
01766                                 }
01767                         }
01768                 }
01769                 if(eve) {
01770                         eve->f &= ~128;
01771                 }
01772                 eve= nextve;
01773         }
01774         // since its vertex select mode now, it also deselects higher order
01775         EM_selectmode_flush(em);
01776 
01777         if(is_zero_v3(nor)) return 'g'; // g is grab, for correct undo print
01778         return 'n';
01779 }
01780 
01781 /* generic extrude */
01782 short extrudeflag(Object *obedit, EditMesh *em, short flag, float *nor, int all)
01783 {
01784         if(em->selectmode & SCE_SELECT_VERTEX)
01785                 return extrudeflag_vert(obedit, em, flag, nor, all);
01786         else 
01787                 return extrudeflag_edge(obedit, em, flag, nor, all);
01788                 
01789 }
01790 
01791 void rotateflag(EditMesh *em, short flag, float *cent, float rotmat[][3])
01792 {
01793         /* all verts with (flag & 'flag') rotate */
01794         EditVert *eve;
01795 
01796         eve= em->verts.first;
01797         while(eve) {
01798                 if(eve->f & flag) {
01799                         eve->co[0]-=cent[0];
01800                         eve->co[1]-=cent[1];
01801                         eve->co[2]-=cent[2];
01802                         mul_m3_v3(rotmat,eve->co);
01803                         eve->co[0]+=cent[0];
01804                         eve->co[1]+=cent[1];
01805                         eve->co[2]+=cent[2];
01806                 }
01807                 eve= eve->next;
01808         }
01809 }
01810 
01811 void translateflag(EditMesh *em, short flag, float *vec)
01812 {
01813         /* all verts with (flag & 'flag') translate */
01814         EditVert *eve;
01815 
01816         eve= em->verts.first;
01817         while(eve) {
01818                 if(eve->f & flag) {
01819                         eve->co[0]+=vec[0];
01820                         eve->co[1]+=vec[1];
01821                         eve->co[2]+=vec[2];
01822                 }
01823                 eve= eve->next;
01824         }
01825 }
01826 
01827 /* helper call for below */
01828 static EditVert *adduplicate_vertex(EditMesh *em, EditVert *eve, int flag)
01829 {
01830         /* FIXME: copy deformation weight from eve ok here? */
01831         EditVert *v1= addvertlist(em, eve->co, eve);
01832         
01833         v1->f= eve->f;
01834         eve->f &= ~flag;
01835         eve->f|= 128;
01836         
01837         eve->tmp.v = v1;
01838         
01839         return v1;
01840 }
01841 
01842 /* old selection has flag 128 set, and flag 'flag' cleared
01843 new selection has flag 'flag' set */
01844 void adduplicateflag(EditMesh *em, int flag)
01845 {
01846         EditVert *eve, *v1, *v2, *v3, *v4;
01847         EditEdge *eed, *newed;
01848         EditFace *efa, *newfa, *act_efa = EM_get_actFace(em, 0);
01849 
01850         EM_clear_flag_all(em, 128);
01851         EM_selectmode_set(em);  // paranoia check, selection now is consistent
01852 
01853         /* vertices first */
01854         for(eve= em->verts.last; eve; eve= eve->prev) {
01855 
01856                 if(eve->f & flag)
01857                         adduplicate_vertex(em, eve, flag);
01858                 else 
01859                         eve->tmp.v = NULL;
01860         }
01861         
01862         /* copy edges, note that vertex selection can be independent of edge */
01863         for(eed= em->edges.last; eed; eed= eed->prev) {
01864                 if( eed->f & flag ) {
01865                         v1 = eed->v1->tmp.v;
01866                         if(v1==NULL) v1= adduplicate_vertex(em, eed->v1, flag);
01867                         v2 = eed->v2->tmp.v;
01868                         if(v2==NULL) v2= adduplicate_vertex(em, eed->v2, flag);
01869                         
01870                         newed= addedgelist(em, v1, v2, eed);
01871                         
01872                         newed->f= eed->f;
01873                         eed->f &= ~flag;
01874                         eed->f |= 128;
01875                 }
01876         }
01877 
01878         /* then duplicate faces, again create new vertices if needed */
01879         for(efa= em->faces.last; efa; efa= efa->prev) {
01880                 if(efa->f & flag) {
01881                         v1 = efa->v1->tmp.v;
01882                         if(v1==NULL) v1= adduplicate_vertex(em, efa->v1, flag);
01883                         v2 = efa->v2->tmp.v;
01884                         if(v2==NULL) v2= adduplicate_vertex(em, efa->v2, flag);
01885                         v3 = efa->v3->tmp.v;
01886                         if(v3==NULL) v3= adduplicate_vertex(em, efa->v3, flag);
01887                         if(efa->v4) {
01888                                 v4 = efa->v4->tmp.v; 
01889                                 if(v4==NULL) v4= adduplicate_vertex(em, efa->v4, flag);
01890                         }
01891                         else v4= NULL;
01892                         
01893                         newfa= addfacelist(em, v1, v2, v3, v4, efa, efa); 
01894                         
01895                         if (efa==act_efa) {
01896                                 EM_set_actFace(em, newfa);
01897                         }
01898                         
01899                         newfa->f= efa->f;
01900                         efa->f &= ~flag;
01901                         efa->f |= 128;
01902                 }
01903         }
01904         
01905         EM_fgon_flags(em);      // redo flags and indices for fgons
01906 }
01907 
01908 void delfaceflag(EditMesh *em, int flag)
01909 {
01910         /* delete all faces with 'flag', including loose edges and loose vertices */
01911         /* this is maybe a bit weird, but this function is used for 'split' and 'separate' */
01912         /* in remaining vertices/edges 'flag' is cleared */
01913         EditVert *eve,*nextve;
01914         EditEdge *eed, *nexted;
01915         EditFace *efa,*nextvl;
01916 
01917         /* to detect loose edges, we put f2 flag on 1 */
01918         for(eed= em->edges.first; eed; eed= eed->next) {
01919                 if(eed->f & flag) eed->f2= 1;
01920                 else eed->f2= 0;
01921         }
01922         
01923         /* delete faces */
01924         efa= em->faces.first;
01925         while(efa) {
01926                 nextvl= efa->next;
01927                 if(efa->f & flag) {
01928                         
01929                         efa->e1->f2= 1;
01930                         efa->e2->f2= 1;
01931                         efa->e3->f2= 1;
01932                         if(efa->e4) {
01933                                 efa->e4->f2= 1;
01934                         }
01935                                                                 
01936                         BLI_remlink(&em->faces, efa);
01937                         free_editface(em, efa);
01938                 }
01939                 efa= nextvl;
01940         }
01941         
01942         /* all remaining faces: make sure we keep the edges */
01943         for(efa= em->faces.first; efa; efa= efa->next) {
01944                 efa->e1->f2= 0;
01945                 efa->e2->f2= 0;
01946                 efa->e3->f2= 0;
01947                 if(efa->e4) {
01948                         efa->e4->f2= 0;
01949                 }
01950         }
01951         
01952         /* remove tagged edges, and clear remaining ones */
01953         eed= em->edges.first;
01954         while(eed) {
01955                 nexted= eed->next;
01956                 
01957                 if(eed->f2==1) {
01958                         remedge(em, eed);
01959                         free_editedge(em, eed);
01960                 }
01961                 else {
01962                         eed->f &= ~flag;
01963                         eed->v1->f &= ~flag;
01964                         eed->v2->f &= ~flag;
01965                 }
01966                 eed= nexted;
01967         }
01968         
01969         /* vertices with 'flag' now are the loose ones, and will be removed */
01970         eve= em->verts.first;
01971         while(eve) {
01972                 nextve= eve->next;
01973                 if(eve->f & flag) {
01974                         BLI_remlink(&em->verts, eve);
01975                         free_editvert(em, eve);
01976                 }
01977                 eve= nextve;
01978         }
01979 
01980 }
01981 
01982 /* ********************* */
01983 #if 0
01984 static int check_vnormal_flip(float *n, float *vnorm) 
01985 {
01986         float inp;
01987 
01988         inp= n[0]*vnorm[0]+n[1]*vnorm[1]+n[2]*vnorm[2];
01989 
01990         /* angles 90 degrees: dont flip */
01991         if(inp> -0.000001) return 0;
01992 
01993         return 1;
01994 }
01995 #endif
01996 
01997 
01998 
01999 /* does face centers too */
02000 void recalc_editnormals(EditMesh *em)
02001 {
02002         EditFace *efa;
02003         EditVert *eve;
02004 
02005         for(eve= em->verts.first; eve; eve=eve->next)
02006                 zero_v3(eve->no);
02007 
02008         for(efa= em->faces.first; efa; efa=efa->next) {
02009                 float *n4= (efa->v4)? efa->v4->no: NULL;
02010                 float *c4= (efa->v4)? efa->v4->co: NULL;
02011 
02012                 if(efa->v4) {
02013                         normal_quad_v3(efa->n, efa->v1->co, efa->v2->co, efa->v3->co, efa->v4->co);
02014                         cent_quad_v3(efa->cent, efa->v1->co, efa->v2->co, efa->v3->co, efa->v4->co);
02015                 }
02016                 else {
02017                         normal_tri_v3(efa->n, efa->v1->co, efa->v2->co, efa->v3->co);
02018                         cent_tri_v3(efa->cent, efa->v1->co, efa->v2->co, efa->v3->co);
02019                 }
02020 
02021                 accumulate_vertex_normals(efa->v1->no, efa->v2->no, efa->v3->no, n4,
02022                         efa->n, efa->v1->co, efa->v2->co, efa->v3->co, c4);
02023         }
02024 
02025         /* following Mesh convention; we use vertex coordinate itself for normal in this case */
02026         for(eve= em->verts.first; eve; eve=eve->next) {
02027                 if(normalize_v3(eve->no) == 0.0f) {
02028                         copy_v3_v3(eve->no, eve->co);
02029                         normalize_v3(eve->no);
02030                 }
02031         }
02032 }
02033 
02034 int compareface(EditFace *vl1, EditFace *vl2)
02035 {
02036         EditVert *v1, *v2, *v3, *v4;
02037         
02038         if(vl1->v4 && vl2->v4) {
02039                 v1= vl2->v1;
02040                 v2= vl2->v2;
02041                 v3= vl2->v3;
02042                 v4= vl2->v4;
02043                 
02044                 if(vl1->v1==v1 || vl1->v2==v1 || vl1->v3==v1 || vl1->v4==v1) {
02045                         if(vl1->v1==v2 || vl1->v2==v2 || vl1->v3==v2 || vl1->v4==v2) {
02046                                 if(vl1->v1==v3 || vl1->v2==v3 || vl1->v3==v3 || vl1->v4==v3) {
02047                                         if(vl1->v1==v4 || vl1->v2==v4 || vl1->v3==v4 || vl1->v4==v4) {
02048                                                 return 1;
02049                                         }
02050                                 }
02051                         }
02052                 }
02053         }
02054         else if(vl1->v4==0 && vl2->v4==0) {
02055                 v1= vl2->v1;
02056                 v2= vl2->v2;
02057                 v3= vl2->v3;
02058                 
02059                 if(vl1->v1==v1 || vl1->v2==v1 || vl1->v3==v1) {
02060                         if(vl1->v1==v2 || vl1->v2==v2 || vl1->v3==v2) {
02061                                 if(vl1->v1==v3 || vl1->v2==v3 || vl1->v3==v3) {
02062                                         return 1;
02063                                 }
02064                         }
02065                 }
02066         }
02067         
02068         return 0;
02069 }
02070 
02071 /* checks for existence, not tria overlapping inside quad */
02072 EditFace *exist_face(EditMesh *em, EditVert *v1, EditVert *v2, EditVert *v3, EditVert *v4)
02073 {
02074         EditFace *efa, efatest;
02075         
02076         efatest.v1= v1;
02077         efatest.v2= v2;
02078         efatest.v3= v3;
02079         efatest.v4= v4;
02080         
02081         efa= em->faces.first;
02082         while(efa) {
02083                 if(compareface(&efatest, efa)) return efa;
02084                 efa= efa->next;
02085         }
02086         return NULL;
02087 }
02088 
02089 /* evaluate if entire quad is a proper convex quad */
02090 int convex(float *v1, float *v2, float *v3, float *v4)
02091 {
02092         float nor[3], nor1[3], nor2[3], vec[4][2];
02093         
02094         /* define projection, do both trias apart, quad is undefined! */
02095         normal_tri_v3( nor1,v1, v2, v3);
02096         normal_tri_v3( nor2,v1, v3, v4);
02097         nor[0]= ABS(nor1[0]) + ABS(nor2[0]);
02098         nor[1]= ABS(nor1[1]) + ABS(nor2[1]);
02099         nor[2]= ABS(nor1[2]) + ABS(nor2[2]);
02100 
02101         if(nor[2] >= nor[0] && nor[2] >= nor[1]) {
02102                 vec[0][0]= v1[0]; vec[0][1]= v1[1];
02103                 vec[1][0]= v2[0]; vec[1][1]= v2[1];
02104                 vec[2][0]= v3[0]; vec[2][1]= v3[1];
02105                 vec[3][0]= v4[0]; vec[3][1]= v4[1];
02106         }
02107         else if(nor[1] >= nor[0] && nor[1]>= nor[2]) {
02108                 vec[0][0]= v1[0]; vec[0][1]= v1[2];
02109                 vec[1][0]= v2[0]; vec[1][1]= v2[2];
02110                 vec[2][0]= v3[0]; vec[2][1]= v3[2];
02111                 vec[3][0]= v4[0]; vec[3][1]= v4[2];
02112         }
02113         else {
02114                 vec[0][0]= v1[1]; vec[0][1]= v1[2];
02115                 vec[1][0]= v2[1]; vec[1][1]= v2[2];
02116                 vec[2][0]= v3[1]; vec[2][1]= v3[2];
02117                 vec[3][0]= v4[1]; vec[3][1]= v4[2];
02118         }
02119         
02120         /* linetests, the 2 diagonals have to instersect to be convex */
02121         if( isect_line_line_v2(vec[0], vec[2], vec[1], vec[3]) > 0 ) return 1;
02122         return 0;
02123 }
02124 
02125 
02126 /* ********************* Fake Polgon support (FGon) ***************** */
02127 
02128 
02129 /* results in:
02130    - faces having ->fgonf flag set (also for draw)
02131    - edges having ->fgoni index set (for select)
02132 */
02133 
02134 float EM_face_area(EditFace *efa)
02135 {
02136         if(efa->v4) return area_quad_v3(efa->v1->co, efa->v2->co, efa->v3->co, efa->v4->co);
02137         else return area_tri_v3(efa->v1->co, efa->v2->co, efa->v3->co);
02138 }
02139 
02140 float EM_face_perimeter(EditFace *efa)
02141 {       
02142         if(efa->v4) return
02143                 len_v3v3(efa->v1->co, efa->v2->co)+
02144                 len_v3v3(efa->v2->co, efa->v3->co)+
02145                 len_v3v3(efa->v3->co, efa->v4->co)+
02146                 len_v3v3(efa->v4->co, efa->v1->co);
02147         
02148         else return
02149                 len_v3v3(efa->v1->co, efa->v2->co)+
02150                 len_v3v3(efa->v2->co, efa->v3->co)+
02151                 len_v3v3(efa->v3->co, efa->v1->co);
02152 }
02153 
02154 void EM_fgon_flags(EditMesh *em)
02155 {
02156         EditFace *efa, *efan, *efamax;
02157         EditEdge *eed;
02158         ListBase listb={NULL, NULL};
02159         float size, maxsize;
02160         short done, curindex= 1;
02161         
02162         // for each face with fgon edge AND not fgon flag set
02163         for(eed= em->edges.first; eed; eed= eed->next) eed->fgoni= 0;  // index
02164         for(efa= em->faces.first; efa; efa= efa->next) efa->fgonf= 0;  // flag
02165         
02166         // for speed & simplicity, put fgon face candidates in new listbase
02167         efa= em->faces.first;
02168         while(efa) {
02169                 efan= efa->next;
02170                 if( (efa->e1->h & EM_FGON) || (efa->e2->h & EM_FGON) || 
02171                         (efa->e3->h & EM_FGON) || (efa->e4 && (efa->e4->h & EM_FGON)) ) {
02172                         BLI_remlink(&em->faces, efa);
02173                         BLI_addtail(&listb, efa);
02174                 }
02175                 efa= efan;
02176         }
02177         
02178         // find an undone face with fgon edge
02179         for(efa= listb.first; efa; efa= efa->next) {
02180                 if(efa->fgonf==0) {
02181                         
02182                         // init this face
02183                         efa->fgonf= EM_FGON;
02184                         if(efa->e1->h & EM_FGON) efa->e1->fgoni= curindex;
02185                         if(efa->e2->h & EM_FGON) efa->e2->fgoni= curindex;
02186                         if(efa->e3->h & EM_FGON) efa->e3->fgoni= curindex;
02187                         if(efa->e4 && (efa->e4->h & EM_FGON)) efa->e4->fgoni= curindex;
02188                         
02189                         // we search for largest face, to give facedot drawing rights
02190                         maxsize= EM_face_area(efa);
02191                         efamax= efa;
02192                         
02193                         // now flush curendex over edges and set faceflags
02194                         done= 1;
02195                         while(done==1) {
02196                                 done= 0;
02197                                 
02198                                 for(efan= listb.first; efan; efan= efan->next) {
02199                                         if(efan->fgonf==0) {
02200                                                 // if one if its edges has index set, do other too
02201                                                 if( (efan->e1->fgoni==curindex) || (efan->e2->fgoni==curindex) ||
02202                                                         (efan->e3->fgoni==curindex) || (efan->e4 && (efan->e4->fgoni==curindex)) ) {
02203                                                         
02204                                                         efan->fgonf= EM_FGON;
02205                                                         if(efan->e1->h & EM_FGON) efan->e1->fgoni= curindex;
02206                                                         if(efan->e2->h & EM_FGON) efan->e2->fgoni= curindex;
02207                                                         if(efan->e3->h & EM_FGON) efan->e3->fgoni= curindex;
02208                                                         if(efan->e4 && (efan->e4->h & EM_FGON)) efan->e4->fgoni= curindex;
02209                                                         
02210                                                         size= EM_face_area(efan);
02211                                                         if(size>maxsize) {
02212                                                                 efamax= efan;
02213                                                                 maxsize= size;
02214                                                         }
02215                                                         done= 1;
02216                                                 }
02217                                         }
02218                                 }
02219                         }
02220                         
02221                         efamax->fgonf |= EM_FGON_DRAW;
02222                         curindex++;
02223 
02224                 }
02225         }
02226 
02227         // put fgon face candidates back in listbase
02228         efa= listb.first;
02229         while(efa) {
02230                 efan= efa->next;
02231                 BLI_remlink(&listb, efa);
02232                 BLI_addtail(&em->faces, efa);
02233                 efa= efan;
02234         }
02235         
02236         // remove fgon flags when edge not in fgon (anymore)
02237         for(eed= em->edges.first; eed; eed= eed->next) {
02238                 if(eed->fgoni==0) eed->h &= ~EM_FGON;
02239         }
02240         
02241 }
02242 
02243 /* editmesh vertmap, copied from intern.mesh.c
02244  * if do_face_idx_array is 0 it means we need to run it as well as freeing
02245  * */
02246 
02247 UvVertMap *EM_make_uv_vert_map(EditMesh *em, int selected, int do_face_idx_array, float *limit)
02248 {
02249         EditVert *ev;
02250         EditFace *efa;
02251         int totverts;
02252         
02253         /* vars from original func */
02254         UvVertMap *vmap;
02255         UvMapVert *buf;
02256         MTFace *tf;
02257         unsigned int a;
02258         int     i, totuv, nverts;
02259         
02260         if (do_face_idx_array)
02261                 EM_init_index_arrays(em, 0, 0, 1);
02262         
02263         /* we need the vert */
02264         for (ev= em->verts.first, totverts=0; ev; ev= ev->next, totverts++) {
02265                 ev->tmp.l = totverts;
02266         }
02267         
02268         totuv = 0;
02269 
02270         /* generate UvMapVert array */
02271         for (efa= em->faces.first; efa; efa= efa->next)
02272                 if(!selected || ((!efa->h) && (efa->f & SELECT)))
02273                         totuv += (efa->v4)? 4: 3;
02274                 
02275         if(totuv==0) {
02276                 if (do_face_idx_array)
02277                         EM_free_index_arrays();
02278                 return NULL;
02279         }
02280         vmap= (UvVertMap*)MEM_callocN(sizeof(*vmap), "UvVertMap");
02281         if (!vmap) {
02282                 if (do_face_idx_array)
02283                         EM_free_index_arrays();
02284                 return NULL;
02285         }
02286 
02287         vmap->vert= (UvMapVert**)MEM_callocN(sizeof(*vmap->vert)*totverts, "UvMapVert*");
02288         buf= vmap->buf= (UvMapVert*)MEM_callocN(sizeof(*vmap->buf)*totuv, "UvMapVert");
02289 
02290         if (!vmap->vert || !vmap->buf) {
02291                 free_uv_vert_map(vmap);
02292                 if (do_face_idx_array)
02293                         EM_free_index_arrays();
02294                 return NULL;
02295         }
02296 
02297         for (a=0, efa= em->faces.first; efa; a++, efa= efa->next) {
02298                 if(!selected || ((!efa->h) && (efa->f & SELECT))) {
02299                         nverts= (efa->v4)? 4: 3;
02300                         
02301                         for(i=0; i<nverts; i++) {
02302                                 buf->tfindex= i;
02303                                 buf->f= a;
02304                                 buf->separate = 0;
02305                                 
02306                                 buf->next= vmap->vert[(*(&efa->v1 + i))->tmp.l];
02307                                 vmap->vert[(*(&efa->v1 + i))->tmp.l]= buf;
02308                                 
02309                                 buf++;
02310                         }
02311                 }
02312         }
02313         
02314         /* sort individual uvs for each vert */
02315         for(a=0, ev=em->verts.first; ev; a++, ev= ev->next) {
02316                 UvMapVert *newvlist= NULL, *vlist=vmap->vert[a];
02317                 UvMapVert *iterv, *v, *lastv, *next;
02318                 float *uv, *uv2, uvdiff[2];
02319 
02320                 while(vlist) {
02321                         v= vlist;
02322                         vlist= vlist->next;
02323                         v->next= newvlist;
02324                         newvlist= v;
02325 
02326                         efa = EM_get_face_for_index(v->f);
02327                         tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
02328                         uv = tf->uv[v->tfindex]; 
02329                         
02330                         lastv= NULL;
02331                         iterv= vlist;
02332 
02333                         while(iterv) {
02334                                 next= iterv->next;
02335                                 efa = EM_get_face_for_index(iterv->f);
02336                                 tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
02337                                 uv2 = tf->uv[iterv->tfindex];
02338                                 
02339                                 sub_v2_v2v2(uvdiff, uv2, uv);
02340 
02341                                 if(fabsf(uv[0]-uv2[0]) < limit[0] && fabsf(uv[1]-uv2[1]) < limit[1]) {
02342                                         if(lastv) lastv->next= next;
02343                                         else vlist= next;
02344                                         iterv->next= newvlist;
02345                                         newvlist= iterv;
02346                                 }
02347                                 else
02348                                         lastv=iterv;
02349 
02350                                 iterv= next;
02351                         }
02352 
02353                         newvlist->separate = 1;
02354                 }
02355 
02356                 vmap->vert[a]= newvlist;
02357         }
02358         
02359         if (do_face_idx_array)
02360                 EM_free_index_arrays();
02361         
02362         return vmap;
02363 }
02364 
02365 UvMapVert *EM_get_uv_map_vert(UvVertMap *vmap, unsigned int v)
02366 {
02367         return vmap->vert[v];
02368 }
02369 
02370 void EM_free_uv_vert_map(UvVertMap *vmap)
02371 {
02372         if (vmap) {
02373                 if (vmap->vert) MEM_freeN(vmap->vert);
02374                 if (vmap->buf) MEM_freeN(vmap->buf);
02375                 MEM_freeN(vmap);
02376         }
02377 }
02378 
02379 /* poll call for mesh operators requiring a view3d context */
02380 int EM_view3d_poll(bContext *C)
02381 {
02382         if(ED_operator_editmesh(C) && ED_operator_view3d_active(C))
02383                 return 1;
02384         return 0;
02385 }
02386 
02387 /* higher quality normals */
02388 
02389 /* NormalCalc */
02390 /* NormalCalc modifier: calculates higher quality normals
02391 */
02392 
02393 /* each edge uses this to  */
02394 typedef struct EdgeFaceRef {
02395         int f1; /* init as -1 */
02396         int f2;
02397 } EdgeFaceRef;
02398 
02399 void EM_make_hq_normals(EditMesh *em)
02400 {
02401         EditFace *efa;
02402         EditVert *eve;
02403         int i;
02404 
02405         EdgeHash *edge_hash = BLI_edgehash_new();
02406         EdgeHashIterator *edge_iter;
02407         int edge_ref_count = 0;
02408         int ed_v1, ed_v2; /* use when getting the key */
02409         EdgeFaceRef *edge_ref_array = MEM_callocN(em->totedge * sizeof(EdgeFaceRef), "Edge Connectivity");
02410         EdgeFaceRef *edge_ref;
02411         float edge_normal[3];
02412 
02413         EM_init_index_arrays(em, 1, 1, 1);
02414 
02415         for(eve= em->verts.first, i=0; eve; eve= eve->next, i++) {
02416                 zero_v3(eve->no);
02417                 eve->tmp.l= i;
02418         }
02419 
02420         /* This function adds an edge hash if its not there, and adds the face index */
02421 #define NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(EDV1, EDV2); \
02422                         edge_ref = (EdgeFaceRef *)BLI_edgehash_lookup(edge_hash, EDV1, EDV2); \
02423                         if (!edge_ref) { \
02424                                 edge_ref = &edge_ref_array[edge_ref_count]; edge_ref_count++; \
02425                                 edge_ref->f1=i; \
02426                                 edge_ref->f2=-1; \
02427                                 BLI_edgehash_insert(edge_hash, EDV1, EDV2, edge_ref); \
02428                         } else { \
02429                                 edge_ref->f2=i; \
02430                         }
02431 
02432 
02433         efa= em->faces.first;
02434         for(i = 0; i < em->totface; i++, efa= efa->next) {
02435                 if(efa->v4) {
02436                         NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(efa->v1->tmp.l, efa->v2->tmp.l);
02437                         NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(efa->v2->tmp.l, efa->v3->tmp.l);
02438                         NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(efa->v3->tmp.l, efa->v4->tmp.l);
02439                         NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(efa->v4->tmp.l, efa->v1->tmp.l);
02440                 } else {
02441                         NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(efa->v1->tmp.l, efa->v2->tmp.l);
02442                         NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(efa->v2->tmp.l, efa->v3->tmp.l);
02443                         NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(efa->v3->tmp.l, efa->v1->tmp.l);
02444                 }
02445         }
02446 
02447 #undef NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE
02448 
02449 
02450         for(edge_iter = BLI_edgehashIterator_new(edge_hash); !BLI_edgehashIterator_isDone(edge_iter); BLI_edgehashIterator_step(edge_iter)) {
02451                 /* Get the edge vert indices, and edge value (the face indices that use it)*/
02452                 BLI_edgehashIterator_getKey(edge_iter, (int*)&ed_v1, (int*)&ed_v2);
02453                 edge_ref = BLI_edgehashIterator_getValue(edge_iter);
02454 
02455                 if (edge_ref->f2 != -1) {
02456                         EditFace *ef1= EM_get_face_for_index(edge_ref->f1), *ef2= EM_get_face_for_index(edge_ref->f2);
02457                         float angle= angle_normalized_v3v3(ef1->n, ef2->n);
02458                         if(angle > 0.0f) {
02459                                 /* We have 2 faces using this edge, calculate the edges normal
02460                                  * using the angle between the 2 faces as a weighting */
02461                                 add_v3_v3v3(edge_normal, ef1->n, ef2->n);
02462                                 normalize_v3(edge_normal);
02463                                 mul_v3_fl(edge_normal, angle);
02464                         }
02465                         else {
02466                                 /* cant do anything useful here!
02467                                    Set the face index for a vert incase it gets a zero normal */
02468                                 EM_get_vert_for_index(ed_v1)->tmp.l=
02469                                 EM_get_vert_for_index(ed_v2)->tmp.l= -(edge_ref->f1 + 1);
02470                                 continue;
02471                         }
02472                 } else {
02473                         /* only one face attached to that edge */
02474                         /* an edge without another attached- the weight on this is
02475                          * undefined, M_PI/2 is 90d in radians and that seems good enough */
02476                         VECCOPY(edge_normal, EM_get_face_for_index(edge_ref->f1)->n)
02477                         mul_v3_fl(edge_normal, M_PI/2);
02478                 }
02479                 add_v3_v3(EM_get_vert_for_index(ed_v1)->no, edge_normal );
02480                 add_v3_v3(EM_get_vert_for_index(ed_v2)->no, edge_normal );
02481 
02482 
02483         }
02484         BLI_edgehashIterator_free(edge_iter);
02485         BLI_edgehash_free(edge_hash, NULL);
02486         MEM_freeN(edge_ref_array);
02487 
02488         /* normalize vertex normals and assign */
02489         for(eve= em->verts.first; eve; eve= eve->next) {
02490                 if(normalize_v3(eve->no) == 0.0f && eve->tmp.l < 0) {
02491                         /* exceptional case, totally flat */
02492                         efa= EM_get_face_for_index(-(eve->tmp.l) - 1);
02493                         VECCOPY(eve->no, efa->n);
02494                 }       
02495         }
02496 
02497         EM_free_index_arrays();
02498 }
02499 
02500 void EM_solidify(EditMesh *em, float dist)
02501 {
02502         EditFace *efa;
02503         EditVert *eve;
02504         float *vert_angles= MEM_callocN(sizeof(float) * em->totvert * 2, "EM_solidify"); /* 2 in 1 */
02505         float *vert_accum= vert_angles + em->totvert;
02506         float face_angles[4];
02507         int i, j;
02508 
02509         for(eve= em->verts.first, i=0; eve; eve= eve->next, i++) {
02510                 eve->tmp.l= i;
02511         }
02512 
02513         efa= em->faces.first;
02514         for(i = 0; i < em->totface; i++, efa= efa->next) {
02515 
02516                 if(!(efa->f & SELECT))
02517                         continue;
02518 
02519                 if(efa->v4) {
02520                         angle_quad_v3(face_angles, efa->v1->co, efa->v2->co, efa->v3->co, efa->v4->co);
02521                         j= 3;
02522                 }
02523                 else {
02524                         angle_tri_v3(face_angles, efa->v1->co, efa->v2->co, efa->v3->co);
02525                         j= 2;
02526                 }
02527 
02528                 for(; j>=0; j--) {
02529                         eve= *(&efa->v1 + j);
02530                         vert_accum[eve->tmp.l] += face_angles[j];
02531                         vert_angles[eve->tmp.l]+= shell_angle_to_dist(angle_normalized_v3v3(eve->no, efa->n)) * face_angles[j];
02532                 }
02533         }
02534 
02535         for(eve= em->verts.first, i=0; eve; eve= eve->next, i++) {
02536                 if(vert_accum[i]) { /* zero if unselected */
02537                         madd_v3_v3fl(eve->co, eve->no, dist * vert_angles[i] / vert_accum[i]);
02538                 }
02539         }
02540 
02541         MEM_freeN(vert_angles);
02542 }
02543 
02544 /* not that optimal!, should be nicer with bmesh */
02545 static void tag_face_edges(EditFace *efa)
02546 {
02547         if(efa->v4)
02548                 efa->e1->tmp.l= efa->e2->tmp.l= efa->e3->tmp.l= efa->e4->tmp.l= 1;
02549         else
02550                 efa->e1->tmp.l= efa->e2->tmp.l= efa->e3->tmp.l= 1;
02551 }
02552 static int tag_face_edges_test(EditFace *efa)
02553 {
02554         if(efa->v4)
02555                 return (efa->e1->tmp.l || efa->e2->tmp.l || efa->e3->tmp.l || efa->e4->tmp.l) ? 1:0;
02556         else
02557                 return (efa->e1->tmp.l || efa->e2->tmp.l || efa->e3->tmp.l) ? 1:0;
02558 }
02559 
02560 static void em_deselect_nth_face(EditMesh *em, int nth, EditFace *efa_act)
02561 {
02562         EditFace *efa;
02563         EditEdge *eed;
02564         int ok= 1;
02565 
02566         if(efa_act==NULL) {
02567                 return;
02568         }
02569 
02570         /* to detect loose edges, we put f2 flag on 1 */
02571         for(eed= em->edges.first; eed; eed= eed->next) {
02572                 eed->tmp.l= 0;
02573         }
02574 
02575         for (efa= em->faces.first; efa; efa= efa->next) {
02576                 efa->tmp.l = 0;
02577         }
02578 
02579         efa_act->tmp.l = 1;
02580 
02581         while(ok) {
02582                 ok = 0;
02583 
02584                 for (efa= em->faces.first; efa; efa= efa->next) {
02585                         if(efa->f & SELECT) {
02586                                 if(efa->tmp.l==1) { /* initialize */
02587                                         tag_face_edges(efa);
02588                                 }
02589         
02590                                 if(efa->tmp.l) {
02591                                         efa->tmp.l++;
02592                                 }
02593                         }
02594                 }
02595 
02596                 for (efa= em->faces.first; efa; efa= efa->next) {
02597                         if(efa->f & SELECT) {
02598                                 if(efa->tmp.l==0 && tag_face_edges_test(efa)) {
02599                                         efa->tmp.l= 1;
02600                                         ok = 1; /* keep looping */
02601                                 }
02602                         }
02603                 }
02604         }
02605 
02606         for (efa= em->faces.first; efa; efa= efa->next) {
02607                 if(efa->tmp.l > 0 && efa->tmp.l % nth) {
02608                         EM_select_face(efa, 0);
02609                 }
02610         }
02611         for (efa= em->faces.first; efa; efa= efa->next) {
02612                 if(efa->f & SELECT) {
02613                         EM_select_face(efa, 1);
02614                 }
02615         }
02616 
02617         EM_nvertices_selected(em);
02618         EM_nedges_selected(em);
02619         EM_nfaces_selected(em);
02620 }
02621 
02622 /* not that optimal!, should be nicer with bmesh */
02623 static void tag_edge_verts(EditEdge *eed)
02624 {
02625         eed->v1->tmp.l= eed->v2->tmp.l= 1;
02626 }
02627 static int tag_edge_verts_test(EditEdge *eed)
02628 {
02629         return (eed->v1->tmp.l || eed->v2->tmp.l) ? 1:0;
02630 }
02631 
02632 static void em_deselect_nth_edge(EditMesh *em, int nth, EditEdge *eed_act)
02633 {
02634         EditEdge *eed;
02635         EditVert *eve;
02636         int ok= 1;
02637 
02638         if(eed_act==NULL) {
02639                 return;
02640         }
02641 
02642         for(eve= em->verts.first; eve; eve= eve->next) {
02643                 eve->tmp.l= 0;
02644         }
02645 
02646         for (eed= em->edges.first; eed; eed= eed->next) {
02647                 eed->tmp.l = 0;
02648         }
02649 
02650         eed_act->tmp.l = 1;
02651 
02652         while(ok) {
02653                 ok = 0;
02654 
02655                 for (eed= em->edges.first; eed; eed= eed->next) {
02656                         if(eed->f & SELECT) {
02657                                 if(eed->tmp.l==1) { /* initialize */
02658                                         tag_edge_verts(eed);
02659                                 }
02660         
02661                                 if(eed->tmp.l) {
02662                                         eed->tmp.l++;
02663                                 }
02664                         }
02665                 }
02666 
02667                 for (eed= em->edges.first; eed; eed= eed->next) {
02668                         if(eed->f & SELECT) {
02669                                 if(eed->tmp.l==0 && tag_edge_verts_test(eed)) {
02670                                         eed->tmp.l= 1;
02671                                         ok = 1; /* keep looping */
02672                                 }
02673                         }
02674                 }
02675         }
02676 
02677         for (eed= em->edges.first; eed; eed= eed->next) {
02678                 if(eed->tmp.l > 0 && eed->tmp.l % nth) {
02679                         EM_select_edge(eed, 0);
02680                 }
02681         }
02682         for (eed= em->edges.first; eed; eed= eed->next) {
02683                 if(eed->f & SELECT) {
02684                         EM_select_edge(eed, 1);
02685                 }
02686         }
02687 
02688         {
02689                 /* grr, should be a function */
02690                 EditFace *efa;
02691                 for (efa= em->faces.first; efa; efa= efa->next) {
02692                         if(efa->v4) {
02693                                 if(efa->e1->f & efa->e2->f & efa->e3->f & efa->e4->f & SELECT );
02694                                 else efa->f &= ~SELECT;
02695                         }
02696                         else {
02697                                 if(efa->e1->f & efa->e2->f & efa->e3->f & SELECT );
02698                                 else efa->f &= ~SELECT;
02699                         }
02700                 }
02701         }
02702 
02703         EM_nvertices_selected(em);
02704         EM_nedges_selected(em);
02705         EM_nfaces_selected(em);
02706 }
02707 
02708 static void em_deselect_nth_vert(EditMesh *em, int nth, EditVert *eve_act)
02709 {
02710         EditVert *eve;
02711         EditEdge *eed;
02712         int ok= 1;
02713 
02714         if(eve_act==NULL) {
02715                 return;
02716         }
02717 
02718         for (eve= em->verts.first; eve; eve= eve->next) {
02719                 eve->tmp.l = 0;
02720         }
02721 
02722         eve_act->tmp.l = 1;
02723 
02724         while(ok) {
02725                 ok = 0;
02726 
02727                 for (eve= em->verts.first; eve; eve= eve->next) {
02728                         if(eve->f & SELECT) {
02729                                 if(eve->tmp.l)
02730                                         eve->tmp.l++;
02731                         }
02732                 }
02733 
02734                 for (eed= em->edges.first; eed; eed= eed->next) {
02735                         if(eed->f & SELECT) {
02736                                 if(eed->v1->tmp.l==2 && eed->v2->tmp.l==0) { /* initialize */
02737                                         eed->v2->tmp.l= 1;
02738                                         ok = 1; /* keep looping */
02739                                 }
02740                                 else if(eed->v2->tmp.l==2 && eed->v1->tmp.l==0) { /* initialize */
02741                                         eed->v1->tmp.l= 1;
02742                                         ok = 1; /* keep looping */
02743                                 }
02744                         }
02745                 }
02746         }
02747 
02748         for (eve= em->verts.first; eve; eve= eve->next) {
02749                 if(eve->tmp.l > 0 && eve->tmp.l % nth) {
02750                         eve->f &= ~SELECT;
02751                 }
02752         }
02753 
02754         EM_deselect_flush(em);
02755 
02756         EM_nvertices_selected(em);
02757         // EM_nedges_selected(em); // flush does these
02758         // EM_nfaces_selected(em); // flush does these
02759 }
02760 
02761 static void deselect_nth_active(EditMesh *em, EditVert **eve_p, EditEdge **eed_p, EditFace **efa_p)
02762 {
02763         EditSelection *ese;
02764 
02765         *eve_p= NULL;
02766         *eed_p= NULL;
02767         *efa_p= NULL;
02768 
02769         ese= (EditSelection*)em->selected.last;
02770 
02771         if(ese) {
02772                 switch(ese->type) {
02773                 case EDITVERT:
02774                         *eve_p= (EditVert *)ese->data;
02775                         return;
02776                 case EDITEDGE:
02777                         *eed_p= (EditEdge *)ese->data;
02778                         return;
02779                 case EDITFACE:
02780                         *efa_p= (EditFace *)ese->data;
02781                         return;
02782                 }
02783         }
02784 
02785         if(em->selectmode & SCE_SELECT_VERTEX) {
02786                 EditVert *eve;
02787                 for (eve= em->verts.first; eve; eve= eve->next) {
02788                         if(eve->f & SELECT) {
02789                                 *eve_p= eve;
02790                                 return;
02791                         }
02792                 }
02793         }
02794 
02795         if(em->selectmode & SCE_SELECT_EDGE) {
02796                 EditEdge *eed;
02797                 for (eed= em->edges.first; eed; eed= eed->next) {
02798                         if(eed->f & SELECT) {
02799                                 *eed_p= eed;
02800                                 return;
02801                         }
02802                 }
02803         }
02804 
02805         if(em->selectmode & SCE_SELECT_FACE) {
02806                 EditFace *efa= EM_get_actFace(em, 1);
02807                 if(efa) {
02808                         *efa_p= efa;
02809                         return;
02810                 }
02811         }
02812 }
02813 
02814 int EM_deselect_nth(EditMesh *em, int nth)
02815 {
02816         EditVert *eve;
02817         EditEdge *eed;
02818         EditFace *efa;
02819 
02820         deselect_nth_active(em, &eve, &eed, &efa);
02821 
02822         if(eve)
02823                 em_deselect_nth_vert(em, nth, eve);
02824         else if (eed)
02825                 em_deselect_nth_edge(em, nth, eed);
02826         else if (efa)
02827                 em_deselect_nth_face(em, nth, efa);
02828         else
02829                 return 0;
02830         
02831         return 1;
02832 }
02833 
02834 void EM_project_snap_verts(bContext *C, ARegion *ar, Object *obedit, EditMesh *em)
02835 {
02836         EditVert *eve;
02837         for(eve= em->verts.first;eve; eve=eve->next) {
02838                 if(eve->f & SELECT) {
02839                         float mval[2], vec[3], no_dummy[3];
02840                         int dist_dummy;
02841                         mul_v3_m4v3(vec, obedit->obmat, eve->co);
02842                         project_float_noclip(ar, vec, mval);
02843                         if(snapObjectsContext(C, mval, &dist_dummy, vec, no_dummy, SNAP_NOT_OBEDIT)) {
02844                                 mul_v3_m4v3(eve->co, obedit->imat, vec);
02845                         }
02846                 }
02847         }
02848 }