4 * ***** BEGIN GPL LICENSE BLOCK *****
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21 * All rights reserved.
23 * Contributor(s): Blender Foundation, full recode 2002-2008
25 * ***** END GPL LICENSE BLOCK *****
28 /** \file blender/editors/mesh/editmesh.c
38 #include "MEM_guardedalloc.h"
40 #include "DNA_scene_types.h"
41 #include "DNA_object_types.h"
42 #include "DNA_key_types.h"
43 #include "DNA_meshdata_types.h"
44 #include "DNA_modifier_types.h"
46 #include "BLI_blenlib.h"
48 #include "BLI_editVert.h"
49 #include "BLI_dynstr.h"
51 #include "BLI_utildefines.h"
53 #include "BKE_DerivedMesh.h"
54 #include "BKE_context.h"
55 #include "BKE_depsgraph.h"
56 #include "BKE_global.h"
59 #include "BKE_material.h"
61 #include "BKE_paint.h"
62 #include "BKE_report.h"
63 #include "BKE_multires.h"
66 #include "ED_object.h"
67 #include "ED_screen.h"
69 #include "ED_view3d.h"
71 #include "RNA_access.h"
72 #include "RNA_define.h"
78 #include "mesh_intern.h"
88 static void BIF_undo_push(const char *UNUSED(arg)) {}
89 static void error(const char *UNUSED(arg)) {}
92 /* ***************** HASH ********************* */
95 #define EDHASHSIZE (512*512)
96 #define EDHASH(a, b) (a % EDHASHSIZE)
99 /* ************ ADD / REMOVE / FIND ****************** */
101 static void *calloc_em(EditMesh *UNUSED(em), size_t size, size_t nr)
103 return calloc(size, nr);
106 /* used to bypass normal calloc with fast one */
107 static void *(*callocvert)(EditMesh *, size_t, size_t) = calloc_em;
108 static void *(*callocedge)(EditMesh *, size_t, size_t) = calloc_em;
109 static void *(*callocface)(EditMesh *, size_t, size_t) = calloc_em;
111 EditVert *addvertlist(EditMesh *em, float *vec, EditVert *example)
114 static int hashnr= 0;
116 eve= callocvert(em, sizeof(EditVert), 1);
117 BLI_addtail(&em->verts, eve);
120 if(vec) VECCOPY(eve->co, vec);
123 if( hashnr>=EDHASHSIZE) hashnr= 0;
125 /* new verts get keyindex of -1 since they did not
126 * have a pre-editmode vertex order
131 CustomData_em_copy_data(&em->vdata, &em->vdata, example->data, &eve->data);
132 eve->bweight = example->bweight;
135 CustomData_em_set_default(&em->vdata, &eve->data);
141 void free_editvert (EditMesh *em, EditVert *eve)
144 EM_remove_selection(em, eve, EDITVERT);
145 CustomData_em_free_block(&em->vdata, &eve->data);
153 EditEdge *findedgelist(EditMesh *em, EditVert *v1, EditVert *v2)
165 if(em->hashedgetab==NULL)
166 em->hashedgetab= MEM_callocN(EDHASHSIZE*sizeof(struct HashEdge), "hashedgetab");
168 he= em->hashedgetab + EDHASH(v1->hash, v2->hash);
172 if(he->eed && he->eed->v1==v1 && he->eed->v2==v2) return he->eed;
179 static void insert_hashedge(EditMesh *em, EditEdge *eed)
181 /* assuming that eed is not in the list yet, and that a find has been done before */
183 struct HashEdge *first, *he;
185 first= em->hashedgetab + EDHASH(eed->v1->hash, eed->v2->hash);
187 if( first->eed==0 ) {
193 he->next= first->next;
198 static void remove_hashedge(EditMesh *em, EditEdge *eed)
200 /* assuming eed is in the list */
202 struct HashEdge *first, *he, *prev=NULL;
204 he=first= em->hashedgetab + EDHASH(eed->v1->hash, eed->v2->hash);
208 /* remove from list */
213 first->next= he->next;
218 prev->next= he->next;
227 EditEdge *addedgelist(EditMesh *em, EditVert *v1, EditVert *v2, EditEdge *example)
233 if(v1==v2) return NULL;
234 if(v1==NULL || v2==NULL) return NULL;
244 /* find in hashlist */
245 eed= findedgelist(em, v1, v2);
249 eed= (EditEdge *)callocedge(em, sizeof(EditEdge), 1);
252 BLI_addtail(&em->edges, eed);
254 insert_hashedge(em, eed);
258 rule is to do this with addedgelist call, before addfacelist */
260 eed->crease= example->crease;
261 eed->bweight= example->bweight;
262 eed->sharp = example->sharp;
263 eed->seam = example->seam;
264 eed->h |= (example->h & EM_FGON);
271 void remedge(EditMesh *em, EditEdge *eed)
273 BLI_remlink(&em->edges, eed);
274 remove_hashedge(em, eed);
279 void free_editedge(EditMesh *em, EditEdge *eed)
281 EM_remove_selection(em, eed, EDITEDGE);
287 void free_editface(EditMesh *em, EditFace *efa)
289 EM_remove_selection(em, efa, EDITFACE);
291 if (em->act_face==efa) {
292 EM_set_actFace(em, em->faces.first == efa ? NULL : em->faces.first);
295 CustomData_em_free_block(&em->fdata, &efa->data);
302 void free_vertlist(EditMesh *em, ListBase *edve)
304 EditVert *eve, *next;
311 free_editvert(em, eve);
314 edve->first= edve->last= NULL;
315 em->totvert= em->totvertsel= 0;
318 void free_edgelist(EditMesh *em, ListBase *lb)
320 EditEdge *eed, *next;
325 free_editedge(em, eed);
328 lb->first= lb->last= NULL;
329 em->totedge= em->totedgesel= 0;
332 void free_facelist(EditMesh *em, ListBase *lb)
334 EditFace *efa, *next;
339 free_editface(em, efa);
342 lb->first= lb->last= NULL;
343 em->totface= em->totfacesel= 0;
346 EditFace *addfacelist(EditMesh *em, EditVert *v1, EditVert *v2, EditVert *v3, EditVert *v4, EditFace *example, EditFace *exampleEdges)
349 EditEdge *e1, *e2=0, *e3=0, *e4=0;
351 /* added sanity check... seems to happen for some tools, or for enter editmode for corrupted meshes */
352 if(v1==v4 || v2==v4 || v3==v4) v4= NULL;
354 /* add face to list and do the edges */
356 e1= addedgelist(em, v1, v2, exampleEdges->e1);
357 e2= addedgelist(em, v2, v3, exampleEdges->e2);
358 if(v4) e3= addedgelist(em, v3, v4, exampleEdges->e3);
359 else e3= addedgelist(em, v3, v1, exampleEdges->e3);
360 if(v4) e4= addedgelist(em, v4, v1, exampleEdges->e4);
363 e1= addedgelist(em, v1, v2, NULL);
364 e2= addedgelist(em, v2, v3, NULL);
365 if(v4) e3= addedgelist(em, v3, v4, NULL);
366 else e3= addedgelist(em, v3, v1, NULL);
367 if(v4) e4= addedgelist(em, v4, v1, NULL);
370 if(v1==v2 || v2==v3 || v1==v3) return NULL;
371 if(e2==0) return NULL;
373 efa= (EditFace *)callocface(em, sizeof(EditFace), 1);
385 efa->mat_nr= example->mat_nr;
386 efa->flag= example->flag;
387 CustomData_em_copy_data(&em->fdata, &em->fdata, example->data, &efa->data);
388 CustomData_em_validate_data(&em->fdata, efa->data, efa->v4 ? 4 : 3);
391 efa->mat_nr= em->mat_nr;
393 CustomData_em_set_default(&em->fdata, &efa->data);
396 BLI_addtail(&em->faces, efa);
400 normal_quad_v3( efa->n,efa->v1->co, efa->v2->co, efa->v3->co, efa->v4->co);
401 cent_quad_v3(efa->cent, efa->v1->co, efa->v2->co, efa->v3->co, efa->v4->co);
404 normal_tri_v3( efa->n,efa->v1->co, efa->v2->co, efa->v3->co);
405 cent_tri_v3(efa->cent, efa->v1->co, efa->v2->co, efa->v3->co);
411 /* ************************ end add/new/find ************ */
413 /* ************************ Edit{Vert,Edge,Face} utilss ***************************** */
415 /* some nice utility functions */
417 EditVert *editedge_getOtherVert(EditEdge *eed, EditVert *eve)
421 } else if (eve==eed->v2) {
428 EditVert *editedge_getSharedVert(EditEdge *eed, EditEdge *eed2)
430 if (eed->v1==eed2->v1 || eed->v1==eed2->v2) {
432 } else if (eed->v2==eed2->v1 || eed->v2==eed2->v2) {
439 int editedge_containsVert(EditEdge *eed, EditVert *eve)
441 return (eed->v1==eve || eed->v2==eve);
444 int editface_containsVert(EditFace *efa, EditVert *eve)
446 return (efa->v1==eve || efa->v2==eve || efa->v3==eve || (efa->v4 && efa->v4==eve));
449 int editface_containsEdge(EditFace *efa, EditEdge *eed)
451 return (efa->e1==eed || efa->e2==eed || efa->e3==eed || (efa->e4 && efa->e4==eed));
455 /* ************************ stuct EditMesh manipulation ***************************** */
457 /* fake callocs for fastmalloc below */
458 static void *calloc_fastvert(EditMesh *em, size_t UNUSED(size), size_t UNUSED(nr))
460 EditVert *eve= em->curvert++;
464 static void *calloc_fastedge(EditMesh *em, size_t UNUSED(size), size_t UNUSED(nr))
466 EditEdge *eed= em->curedge++;
470 static void *calloc_fastface(EditMesh *em, size_t UNUSED(size), size_t UNUSED(nr))
472 EditFace *efa= em->curface++;
477 /* allocate 1 chunk for all vertices, edges, faces. These get tagged to
478 prevent it from being freed
480 static void init_editmesh_fastmalloc(EditMesh *em, int totvert, int totedge, int totface)
482 if(totvert) em->allverts= MEM_callocN(totvert*sizeof(EditVert), "allverts");
483 else em->allverts= NULL;
484 em->curvert= em->allverts;
486 if(totedge==0) totedge= 4*totface; // max possible
488 if(totedge) em->alledges= MEM_callocN(totedge*sizeof(EditEdge), "alledges");
489 else em->alledges= NULL;
490 em->curedge= em->alledges;
492 if(totface) em->allfaces= MEM_callocN(totface*sizeof(EditFace), "allfaces");
493 else em->allfaces= NULL;
494 em->curface= em->allfaces;
496 callocvert= calloc_fastvert;
497 callocedge= calloc_fastedge;
498 callocface= calloc_fastface;
501 static void end_editmesh_fastmalloc(void)
503 callocvert= calloc_em;
504 callocedge= calloc_em;
505 callocface= calloc_em;
508 /* do not free editmesh itself here */
509 void free_editMesh(EditMesh *em)
513 if(em->verts.first) free_vertlist(em, &em->verts);
514 if(em->edges.first) free_edgelist(em, &em->edges);
515 if(em->faces.first) free_facelist(em, &em->faces);
516 if(em->selected.first) BLI_freelistN(&(em->selected));
518 CustomData_free(&em->vdata, 0);
519 CustomData_free(&em->fdata, 0);
521 if(em->derivedFinal) {
522 if (em->derivedFinal!=em->derivedCage) {
523 em->derivedFinal->needsFree= 1;
524 em->derivedFinal->release(em->derivedFinal);
526 em->derivedFinal= NULL;
528 if(em->derivedCage) {
529 em->derivedCage->needsFree= 1;
530 em->derivedCage->release(em->derivedCage);
531 em->derivedCage= NULL;
534 /* DEBUG: hashtabs are slowest part of enter/exit editmode. here a testprint */
536 if(em->hashedgetab) {
538 int a, used=0, max=0, nr;
540 for(a=0; a<EDHASHSIZE; a++, he++) {
550 printf("hastab used %d max %d\n", used, max);
553 if(em->hashedgetab) MEM_freeN(em->hashedgetab);
554 em->hashedgetab= NULL;
556 if(em->allverts) MEM_freeN(em->allverts);
557 if(em->alledges) MEM_freeN(em->alledges);
558 if(em->allfaces) MEM_freeN(em->allfaces);
560 em->allverts= em->curvert= NULL;
561 em->alledges= em->curedge= NULL;
562 em->allfaces= em->curface= NULL;
564 mesh_octree_table(NULL, NULL, NULL, 'e');
565 mesh_mirrtopo_table(NULL, 'e');
567 em->totvert= em->totedge= em->totface= 0;
569 // XXX if(em->retopo_paint_data) retopo_free_paint_data(em->retopo_paint_data);
570 em->retopo_paint_data= NULL;
574 static void editMesh_set_hash(EditMesh *em)
578 if(em->hashedgetab) MEM_freeN(em->hashedgetab);
579 em->hashedgetab= NULL;
581 for(eed=em->edges.first; eed; eed= eed->next) {
582 if( findedgelist(em, eed->v1, eed->v2)==NULL )
583 insert_hashedge(em, eed);
589 /* ************************ IN & OUT EDITMODE ***************************** */
592 static void edge_normal_compare(EditEdge *eed, EditFace *efa1)
595 float cent1[3], cent2[3];
599 if(efa1==efa2) return;
601 inp= efa1->n[0]*efa2->n[0] + efa1->n[1]*efa2->n[1] + efa1->n[2]*efa2->n[2];
602 if(inp<0.999f && inp >-0.999f) eed->f2= 1;
604 if(efa1->v4) cent_quad_v3(cent1, efa1->v1->co, efa1->v2->co, efa1->v3->co, efa1->v4->co);
605 else cent_tri_v3(cent1, efa1->v1->co, efa1->v2->co, efa1->v3->co);
606 if(efa2->v4) cent_quad_v3(cent2, efa2->v1->co, efa2->v2->co, efa2->v3->co, efa2->v4->co);
607 else cent_tri_v3(cent2, efa2->v1->co, efa2->v2->co, efa2->v3->co);
609 sub_v3_v3v3(cent1, cent2, cent1);
611 inp= cent1[0]*efa1->n[0] + cent1[1]*efa1->n[1] + cent1[2]*efa1->n[2];
613 if(inp < -0.001f) eed->f1= 1;
623 static int edgeDrawFlagInfo_cmp(const void *av, const void *bv)
625 const EdgeDrawFlagInfo *a = av;
626 const EdgeDrawFlagInfo *b = bv;
628 if (a->noLen<b->noLen) return -1;
629 else if (a->noLen>b->noLen) return 1;
634 static void edge_drawflags(Mesh *me, EditMesh *em)
637 EditEdge *eed, *e1, *e2, *e3, *e4;
640 /* - count number of times edges are used in faces: 0 en 1 time means draw edge
641 * - edges more than 1 time used: in *tmp.f is pointer to first face
642 * - check all faces, when normal differs to much: draw (flag becomes 1)
645 /* later on: added flags for 'cylinder' and 'sphere' intersection tests in old
649 recalc_editnormals(em);
652 eve= em->verts.first;
654 eve->f1= 1; /* during test it's set at zero */
657 eed= em->edges.first;
664 efa= em->faces.first;
670 if(e1->f2<4) e1->f2+= 1;
671 if(e2->f2<4) e2->f2+= 1;
672 if(e3->f2<4) e3->f2+= 1;
673 if(e4 && e4->f2<4) e4->f2+= 1;
675 if(e1->tmp.f == 0) e1->tmp.f = (void *) efa;
676 if(e2->tmp.f == 0) e2->tmp.f = (void *) efa;
677 if(e3->tmp.f ==0) e3->tmp.f = (void *) efa;
678 if(e4 && (e4->tmp.f == 0)) e4->tmp.f = (void *) efa;
683 if(me->drawflag & ME_ALLEDGES) {
684 efa= em->faces.first;
686 if(efa->e1->f2>=2) efa->e1->f2= 1;
687 if(efa->e2->f2>=2) efa->e2->f2= 1;
688 if(efa->e3->f2>=2) efa->e3->f2= 1;
689 if(efa->e4 && efa->e4->f2>=2) efa->e4->f2= 1;
696 /* handle single-edges for 'test cylinder flag' (old engine) */
698 eed= em->edges.first;
700 if(eed->f2==1) eed->f1= 1;
704 /* all faces, all edges with flag==2: compare normal */
705 efa= em->faces.first;
707 if(efa->e1->f2==2) edge_normal_compare(efa->e1, efa);
709 if(efa->e2->f2==2) edge_normal_compare(efa->e2, efa);
711 if(efa->e3->f2==2) edge_normal_compare(efa->e3, efa);
714 if(efa->e4->f2==2) edge_normal_compare(efa->e4, efa);
720 /* sphere collision flag */
722 eed= em->edges.first;
725 eed->v1->f1= eed->v2->f1= 0;
733 /* turns Mesh into editmesh */
734 void make_editMesh(Scene *scene, Object *ob)
742 EditVert *eve, **evlist, *eve1, *eve2, *eve3, *eve4;
743 EditFace *efa, *efa_last_sel= NULL;
746 float *co, (*keyco)[3]= NULL;
747 int tot, a, eekadoodle= 0;
748 const short is_paint_sel= paint_facesel_test(ob);
750 if(me->edit_mesh==NULL)
751 me->edit_mesh= MEM_callocN(sizeof(EditMesh), "editmesh");
753 /* because of reload */
754 free_editMesh(me->edit_mesh);
758 em->selectmode= scene->toolsettings->selectmode; // warning needs to be synced
760 em->totvert= tot= me->totvert;
761 em->totedge= me->totedge;
762 em->totface= me->totface;
769 em->mat_nr= ob->actcol-1;
771 /* initialize fastmalloc for editmesh */
772 init_editmesh_fastmalloc(em, me->totvert, me->totedge, me->totface);
774 actkey = ob_get_keyblock(ob);
776 /* undo-ing in past for previous editmode sessions gives corrupt 'keyindex' values */
777 undo_editmode_clear();
779 em->shapenr= ob->shapenr;
783 CustomData_copy(&me->vdata, &em->vdata, CD_MASK_EDITMESH, CD_CALLOC, 0);
786 evlist= (EditVert **)MEM_mallocN(tot*sizeof(void *),"evlist");
787 for(a=0; a<tot; a++, mvert++) {
791 /* edit the shape key coordinate if available */
792 if(keyco && a < actkey->totelem)
795 eve= addvertlist(em, co, NULL);
798 /* face select sets selection in next loop */
800 eve->f |= (mvert->flag & 1);
802 if (mvert->flag & ME_HIDE) eve->h= 1;
803 normal_short_to_float_v3(eve->no, mvert->no);
805 eve->bweight= ((float)mvert->bweight)/255.0f;
807 /* lets overwrite the keyindex of the editvert
808 * with the order it used to be in before
813 CustomData_to_em_block(&me->vdata, &em->vdata, a, &eve->data);
816 if(actkey && actkey->totelem!=me->totvert);
818 MEdge *medge= me->medge;
820 CustomData_copy(&me->edata, &em->edata, CD_MASK_EDITMESH, CD_CALLOC, 0);
822 for(a=0; a<me->totedge; a++, medge++) {
823 eed= addedgelist(em, evlist[medge->v1], evlist[medge->v2], NULL);
824 /* eed can be zero when v1 and v2 are identical, dxf import does this... */
826 eed->crease= ((float)medge->crease)/255.0f;
827 eed->bweight= ((float)medge->bweight)/255.0f;
829 if(medge->flag & ME_SEAM) eed->seam= 1;
830 if(medge->flag & ME_SHARP) eed->sharp = 1;
831 if(medge->flag & SELECT) eed->f |= SELECT;
832 if(medge->flag & ME_FGON) eed->h= EM_FGON; // 2 different defines!
833 if(medge->flag & ME_HIDE) eed->h |= 1;
834 if(em->selectmode==SCE_SELECT_EDGE)
835 EM_select_edge(eed, eed->f & SELECT); // force edge selection to vertices, seems to be needed ...
836 CustomData_to_em_block(&me->edata,&em->edata, a, &eed->data);
840 CustomData_copy(&me->fdata, &em->fdata, CD_MASK_EDITMESH, CD_CALLOC, 0);
845 for(a=0; a<me->totface; a++, mface++) {
846 eve1= evlist[mface->v1];
847 eve2= evlist[mface->v2];
848 if(!mface->v3) eekadoodle= 1;
849 eve3= evlist[mface->v3];
850 if(mface->v4) eve4= evlist[mface->v4]; else eve4= NULL;
852 efa= addfacelist(em, eve1, eve2, eve3, eve4, NULL, NULL);
855 CustomData_to_em_block(&me->fdata, &em->fdata, a, &efa->data);
857 efa->mat_nr= mface->mat_nr;
858 efa->flag= mface->flag & ~ME_HIDE;
860 /* select and hide face flag */
861 if(mface->flag & ME_HIDE) {
864 if (a==me->act_face) {
865 EM_set_actFace(em, efa);
868 /* dont allow hidden and selected */
869 if(mface->flag & ME_FACE_SEL) {
873 EM_select_face(efa, 1); /* flush down */
883 if(EM_get_actFace(em, 0)==NULL && efa_last_sel) {
884 EM_set_actFace(em, efa_last_sel);
888 error("This Mesh has old style edgecodes, please put it in the bugtracker!");
892 end_editmesh_fastmalloc(); // resets global function pointers
895 //restore editselections
896 EM_init_index_arrays(em, 1,1,1);
897 mselect = me->mselect;
899 for(a=0; a<me->totselect; a++, mselect++){
900 /*check if recorded selection is still valid, if so copy into editmesh*/
901 if( (mselect->type == EDITVERT && me->mvert[mselect->index].flag & SELECT) || (mselect->type == EDITEDGE && me->medge[mselect->index].flag & SELECT) || (mselect->type == EDITFACE && me->mface[mselect->index].flag & ME_FACE_SEL) ){
902 ese = MEM_callocN(sizeof(EditSelection), "Edit Selection");
903 ese->type = mselect->type;
904 if(ese->type == EDITVERT) ese->data = EM_get_vert_for_index(mselect->index); else
905 if(ese->type == EDITEDGE) ese->data = EM_get_edge_for_index(mselect->index); else
906 if(ese->type == EDITFACE) ese->data = EM_get_face_for_index(mselect->index);
907 BLI_addtail(&(em->selected),ese);
910 EM_free_index_arrays();
912 /* this creates coherent selections. also needed for older files */
913 EM_selectmode_set(em);
914 /* paranoia check to enforce hide rules */
916 /* sets helper flags which arent saved */
919 if (EM_get_actFace(em, 0)==NULL) {
920 EM_set_actFace(em, em->faces.first ); /* will use the first face, this is so we alwats have an active face */
924 /* makes Mesh out of editmesh */
925 void load_editMesh(Scene *scene, Object *obedit)
927 Mesh *me= obedit->data;
928 MVert *mvert, *oldverts;
932 EditMesh *em= me->edit_mesh;
934 EditFace *efa, *efa_act;
937 float *fp, *newkey, *oldkey;
940 /* this one also tests of edges are not in faces: */
941 /* eed->f2==0: not in face, f2==1: draw it */
942 /* eed->f1 : flag for dynaface (cylindertest, old engine) */
943 /* eve->f1 : flag for dynaface (sphere test, old engine) */
944 /* eve->f2 : being used in vertexnormals */
945 edge_drawflags(me, em);
949 /* new Vertex block */
950 if(em->totvert==0) mvert= NULL;
951 else mvert= MEM_callocN(em->totvert*sizeof(MVert), "loadeditMesh vert");
954 if(em->totedge==0) medge= NULL;
955 else medge= MEM_callocN(em->totedge*sizeof(MEdge), "loadeditMesh edge");
958 if(em->totface==0) mface= NULL;
959 else mface= MEM_callocN(em->totface*sizeof(MFace), "loadeditMesh face");
961 /* lets save the old verts just in case we are actually working on
962 * a key ... we now do processing of the keys at the end */
964 ototvert= me->totvert;
966 /* don't free this yet */
967 CustomData_set_layer(&me->vdata, CD_MVERT, NULL);
969 /* free custom data */
970 CustomData_free(&me->vdata, me->totvert);
971 CustomData_free(&me->edata, me->totedge);
972 CustomData_free(&me->fdata, me->totface);
974 /* add new custom data */
975 me->totvert= em->totvert;
976 me->totedge= em->totedge;
977 me->totface= em->totface;
979 CustomData_copy(&em->vdata, &me->vdata, CD_MASK_MESH, CD_CALLOC, me->totvert);
980 CustomData_copy(&em->edata, &me->edata, CD_MASK_MESH, CD_CALLOC, me->totedge);
981 CustomData_copy(&em->fdata, &me->fdata, CD_MASK_MESH, CD_CALLOC, me->totface);
983 CustomData_add_layer(&me->vdata, CD_MVERT, CD_ASSIGN, mvert, me->totvert);
984 CustomData_add_layer(&me->edata, CD_MEDGE, CD_ASSIGN, medge, me->totedge);
985 CustomData_add_layer(&me->fdata, CD_MFACE, CD_ASSIGN, mface, me->totface);
986 mesh_update_customdata_pointers(me);
988 /* the vertices, use ->tmp.l as counter */
989 eve= em->verts.first;
993 VECCOPY(mvert->co, eve->co);
996 normal_float_to_short_v3(mvert->no, eve->no);
998 /* note: it used to remove me->dvert when it was not in use, cancelled
999 that... annoying when you have a fresh vgroup */
1000 CustomData_from_em_block(&em->vdata, &me->vdata, eve->data, a);
1002 eve->tmp.l = a++; /* counter */
1005 mvert->flag |= (eve->f & SELECT);
1006 if (eve->h) mvert->flag |= ME_HIDE;
1008 mvert->bweight= (char)(255.0f*eve->bweight);
1016 eed= em->edges.first;
1018 medge->v1= (unsigned int) eed->v1->tmp.l;
1019 medge->v2= (unsigned int) eed->v2->tmp.l;
1021 medge->flag= (eed->f & SELECT) | ME_EDGERENDER;
1022 if(eed->f2<2) medge->flag |= ME_EDGEDRAW;
1023 if(eed->f2==0) medge->flag |= ME_LOOSEEDGE;
1024 if(eed->sharp) medge->flag |= ME_SHARP;
1025 if(eed->seam) medge->flag |= ME_SEAM;
1026 if(eed->h & EM_FGON) medge->flag |= ME_FGON; // different defines yes
1027 if(eed->h & 1) medge->flag |= ME_HIDE;
1029 medge->crease= (char)(255.0f*eed->crease);
1030 medge->bweight= (char)(255.0f*eed->bweight);
1031 CustomData_from_em_block(&em->edata, &me->edata, eed->data, a);
1041 efa= em->faces.first;
1042 efa_act= EM_get_actFace(em, 0);
1046 mface= &((MFace *) me->mface)[i];
1048 mface->v1= (unsigned int) efa->v1->tmp.l;
1049 mface->v2= (unsigned int) efa->v2->tmp.l;
1050 mface->v3= (unsigned int) efa->v3->tmp.l;
1051 if (efa->v4) mface->v4 = (unsigned int) efa->v4->tmp.l;
1053 mface->mat_nr= efa->mat_nr;
1055 mface->flag= efa->flag;
1056 /* bit 0 of flag is already taken for smooth... */
1059 mface->flag |= ME_HIDE;
1060 mface->flag &= ~ME_FACE_SEL;
1062 if(efa->f & 1) mface->flag |= ME_FACE_SEL;
1063 else mface->flag &= ~ME_FACE_SEL;
1066 /* watch: efa->e1->f2==0 means loose edge */
1068 if(efa->e1->f2==1) {
1071 if(efa->e2->f2==1) {
1074 if(efa->e3->f2==1) {
1077 if(efa->e4 && efa->e4->f2==1) {
1081 CustomData_from_em_block(&em->fdata, &me->fdata, efa->data, i);
1083 /* no index '0' at location 3 or 4 */
1084 test_index_face(mface, &me->fdata, i, efa->v4?4:3);
1094 /* patch hook indices and vertex parents */
1098 EditVert **vertMap = NULL;
1101 for (ob=G.main->object.first; ob; ob=ob->id.next) {
1102 if (ob->parent==obedit && ELEM(ob->partype, PARVERT1,PARVERT3)) {
1104 /* duplicate code from below, make it function later...? */
1106 vertMap = MEM_callocN(sizeof(*vertMap)*ototvert, "vertMap");
1108 for (eve=em->verts.first; eve; eve=eve->next) {
1109 if (eve->keyindex!=-1)
1110 vertMap[eve->keyindex] = eve;
1113 if(ob->par1 < ototvert) {
1114 eve = vertMap[ob->par1];
1115 if(eve) ob->par1= eve->tmp.l;
1117 if(ob->par2 < ototvert) {
1118 eve = vertMap[ob->par2];
1119 if(eve) ob->par2= eve->tmp.l;
1121 if(ob->par3 < ototvert) {
1122 eve = vertMap[ob->par3];
1123 if(eve) ob->par3= eve->tmp.l;
1128 for (md=ob->modifiers.first; md; md=md->next) {
1129 if (md->type==eModifierType_Hook) {
1130 HookModifierData *hmd = (HookModifierData*) md;
1133 vertMap = MEM_callocN(sizeof(*vertMap)*ototvert, "vertMap");
1135 for (eve=em->verts.first; eve; eve=eve->next) {
1136 if (eve->keyindex!=-1)
1137 vertMap[eve->keyindex] = eve;
1141 for (i=j=0; i<hmd->totindex; i++) {
1142 if(hmd->indexar[i] < ototvert) {
1143 eve = vertMap[hmd->indexar[i]];
1146 hmd->indexar[j++] = eve->tmp.l;
1158 if (vertMap) MEM_freeN(vertMap);
1161 /* are there keys? */
1164 KeyBlock *actkey= BLI_findlink(&me->key->block, em->shapenr-1);
1166 float (*ofs)[3] = NULL;
1168 /* editing the base key should update others */
1169 if(me->key->type==KEY_RELATIVE && oldverts) {
1170 int act_is_basis = 0;
1171 /* find if this key is a basis for any others */
1172 for(currkey = me->key->block.first; currkey; currkey= currkey->next) {
1173 if(em->shapenr-1 == currkey->relative) {
1179 if(act_is_basis) { /* active key is a base */
1180 float (*fp)[3]= actkey->data;
1182 ofs= MEM_callocN(sizeof(float) * 3 * em->totvert, "currkey->data");
1183 eve= em->verts.first;
1186 if(eve->keyindex>=0)
1187 VECSUB(ofs[i], mvert->co, fp[eve->keyindex]);
1197 /* Lets reorder the key data so that things line up roughly
1198 * with the way things were before editmode */
1199 currkey = me->key->block.first;
1201 int apply_offset = (ofs && (currkey != actkey) && (em->shapenr-1 == currkey->relative));
1203 fp= newkey= MEM_callocN(me->key->elemsize*em->totvert, "currkey->data");
1204 oldkey = currkey->data;
1206 eve= em->verts.first;
1211 if (eve->keyindex >= 0 && eve->keyindex < currkey->totelem) { // valid old vertex
1212 if(currkey == actkey) {
1213 if(actkey == me->key->refkey) {
1214 VECCOPY(fp, mvert->co);
1217 VECCOPY(fp, mvert->co);
1219 VECCOPY(mvert->co, oldverts[eve->keyindex].co);
1225 VECCOPY(fp, oldkey + 3 * eve->keyindex);
1230 VECCOPY(fp, mvert->co);
1233 /* propagate edited basis offsets to other shapes */
1235 VECADD(fp, fp, ofs[i]);
1243 currkey->totelem= em->totvert;
1244 if(currkey->data) MEM_freeN(currkey->data);
1245 currkey->data = newkey;
1247 currkey= currkey->next;
1250 if(ofs) MEM_freeN(ofs);
1253 if(oldverts) MEM_freeN(oldverts);
1256 for(ese=em->selected.first; ese; ese=ese->next) i++;
1258 if(i==0) mselect= NULL;
1259 else mselect= MEM_callocN(i*sizeof(MSelect), "loadeditMesh selections");
1261 if(me->mselect) MEM_freeN(me->mselect);
1262 me->mselect= mselect;
1264 for(ese=em->selected.first; ese; ese=ese->next){
1265 mselect->type = ese->type;
1266 if(ese->type == EDITVERT) mselect->index = ((EditVert*)ese->data)->tmp.l;
1267 else if(ese->type == EDITEDGE) mselect->index = ((EditEdge*)ese->data)->tmp.l;
1268 else if(ese->type == EDITFACE) mselect->index = ((EditFace*)ese->data)->tmp.l;
1272 /* to be sure: clear ->tmp.l pointers */
1273 eve= em->verts.first;
1279 eed= em->edges.first;
1285 efa= em->faces.first;
1291 /* remake softbody of all users */
1294 for(base= scene->base.first; base; base= base->next)
1295 if(base->object->data==me)
1296 base->object->recalc |= OB_RECALC_DATA;
1299 mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL);
1301 /* topology could be changed, ensure mdisps are ok */
1302 multires_topology_changed(scene, obedit);
1305 void remake_editMesh(Scene *scene, Object *ob)
1307 make_editMesh(scene, ob);
1308 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
1309 BIF_undo_push("Undo all changes");
1312 /* *************** Operator: separate parts *************/
1314 static EnumPropertyItem prop_separate_types[] = {
1315 {0, "SELECTED", 0, "Selection", ""},
1316 {1, "MATERIAL", 0, "By Material", ""},
1317 {2, "LOOSE", 0, "By loose parts", ""},
1318 {0, NULL, 0, NULL, NULL}
1321 /* return 1: success */
1322 static int mesh_separate_selected(wmOperator *op, Main *bmain, Scene *scene, Base *editbase)
1324 EditMesh *em, *emnew;
1332 if(editbase==NULL) return 0;
1334 obedit= editbase->object;
1336 em= BKE_mesh_get_editmesh(me);
1338 BKE_report(op->reports, RPT_WARNING, "Can't separate mesh with shape keys.");
1339 BKE_mesh_end_editmesh(me, em);
1343 if(em->selected.first)
1344 BLI_freelistN(&(em->selected)); /* clear the selection order */
1346 EM_selectmode_set(em); // enforce full consistent selection flags
1348 EM_stats_update(em);
1350 if(em->totvertsel==0) {
1351 BKE_mesh_end_editmesh(me, em);
1355 /* we are going to work as follows:
1356 * 1. add a linked duplicate object: this will be the new one, we remember old pointer
1357 * 2. give new object empty mesh and put in editmode
1358 * 3: do a split if needed on current editmesh.
1359 * 4. copy over: all NOT selected verts, edges, faces
1360 * 5. call load_editMesh() on the new object
1364 basenew= ED_object_add_duplicate(bmain, scene, editbase, 0); /* 0 = fully linked */
1365 ED_base_object_select(basenew, BA_DESELECT);
1368 basenew->object->data= menew= add_mesh(me->id.name+2); /* empty */
1369 assign_matarar(basenew->object, give_matarar(obedit), *give_totcolp(obedit)); /* new in 2.5 */
1371 make_editMesh(scene, basenew->object);
1372 emnew= menew->edit_mesh;
1373 CustomData_copy(&em->vdata, &emnew->vdata, CD_MASK_EDITMESH, CD_DEFAULT, 0);
1374 CustomData_copy(&em->edata, &emnew->edata, CD_MASK_EDITMESH, CD_DEFAULT, 0);
1375 CustomData_copy(&em->fdata, &emnew->fdata, CD_MASK_EDITMESH, CD_DEFAULT, 0);
1378 /* SPLIT: first make duplicate */
1379 adduplicateflag(em, SELECT);
1380 /* SPLIT: old faces have 3x flag 128 set, delete these ones */
1381 delfaceflag(em, 128);
1382 /* since we do tricky things with verts/edges/faces, this makes sure all is selected coherent */
1383 EM_selectmode_set(em);
1386 /* move over: everything that is selected */
1387 for(eve= em->verts.first; eve; eve= v1) {
1389 if(eve->f & SELECT) {
1390 BLI_remlink(&em->verts, eve);
1391 BLI_addtail(&emnew->verts, eve);
1395 for(eed= em->edges.first; eed; eed= e1) {
1397 if(eed->f & SELECT) {
1398 BLI_remlink(&em->edges, eed);
1399 BLI_addtail(&emnew->edges, eed);
1403 for(efa= em->faces.first; efa; efa= f1) {
1405 if (efa == em->act_face && (efa->f & SELECT)) {
1406 EM_set_actFace(em, NULL);
1409 if(efa->f & SELECT) {
1410 BLI_remlink(&em->faces, efa);
1411 BLI_addtail(&emnew->faces, efa);
1416 load_editMesh(scene, basenew->object);
1417 free_editMesh(emnew);
1418 MEM_freeN(menew->edit_mesh);
1419 menew->edit_mesh= NULL;
1422 menew->texflag= me->texflag;
1423 menew->drawflag= me->drawflag;
1424 menew->flag= me->flag;
1425 menew->editflag= me->editflag;
1426 menew->smoothresh= me->smoothresh;
1428 /* hashedges are invalid now, make new! */
1429 editMesh_set_hash(em);
1431 DAG_id_tag_update(&obedit->id, OB_RECALC_DATA);
1432 DAG_id_tag_update(&basenew->object->id, OB_RECALC_DATA);
1434 BKE_mesh_end_editmesh(me, em);
1439 /* return 1: success */
1440 static int mesh_separate_material(wmOperator *op, Main *bmain, Scene *scene, Base *editbase)
1442 Mesh *me= editbase->object->data;
1443 EditMesh *em= BKE_mesh_get_editmesh(me);
1444 unsigned char curr_mat;
1446 for (curr_mat = 1; curr_mat < editbase->object->totcol; ++curr_mat) {
1447 /* clear selection, we're going to use that to select material group */
1448 EM_clear_flag_all(em, SELECT);
1449 /* select the material */
1450 EM_select_by_material(em, curr_mat);
1451 /* and now separate */
1452 if(em->totfacesel > 0) {
1453 mesh_separate_selected(op, bmain, scene, editbase);
1457 BKE_mesh_end_editmesh(me, em);
1461 /* return 1: success */
1462 static int mesh_separate_loose(wmOperator *op, Main *bmain, Scene *scene, Base *editbase)
1468 me= editbase->object->data;
1469 em= BKE_mesh_get_editmesh(me);
1472 error("Can't separate with vertex keys");
1473 BKE_mesh_end_editmesh(me, em);
1477 EM_clear_flag_all(em, SELECT);
1480 /* Select a random vert to start with */
1484 /* check if all verts that are visible have been done */
1485 for(eve=em->verts.first; eve; eve= eve->next)
1487 if(eve==NULL) break; /* only hidden verts left, quit early */
1489 /* first non hidden vert */
1492 selectconnected_mesh_all(em);
1494 /* don't separate the very last part */
1495 for(eve=em->verts.first; eve; eve= eve->next)
1496 if((eve->f & SELECT)==0) break;
1497 if(eve==NULL) break;
1499 tot= BLI_countlist(&em->verts);
1501 /* and now separate */
1502 doit= mesh_separate_selected(op, bmain, scene, editbase);
1504 /* with hidden verts this can happen */
1505 if(tot == BLI_countlist(&em->verts))
1509 BKE_mesh_end_editmesh(me, em);
1514 static int mesh_separate_exec(bContext *C, wmOperator *op)
1516 Main *bmain= CTX_data_main(C);
1517 Scene *scene= CTX_data_scene(C);
1518 Base *base= CTX_data_active_base(C);
1519 int retval= 0, type= RNA_enum_get(op->ptr, "type");
1522 retval= mesh_separate_selected(op, bmain, scene, base);
1524 retval= mesh_separate_material(op, bmain, scene, base);
1526 retval= mesh_separate_loose(op, bmain, scene, base);
1529 WM_event_add_notifier(C, NC_GEOM|ND_DATA, base->object->data);
1531 // XXX: new object was created, but selection wasn't actually changed
1532 // need this for outliner update without adding new ND. nazgul.
1533 WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, scene);
1535 return OPERATOR_FINISHED;
1537 return OPERATOR_CANCELLED;
1540 void MESH_OT_separate(wmOperatorType *ot)
1543 ot->name= "Separate";
1544 ot->description= "Separate selected geometry into a new mesh";
1545 ot->idname= "MESH_OT_separate";
1548 ot->invoke= WM_menu_invoke;
1549 ot->exec= mesh_separate_exec;
1550 ot->poll= ED_operator_editmesh;
1553 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1555 ot->prop= RNA_def_enum(ot->srna, "type", prop_separate_types, 0, "Type", "");
1559 /* ******************************************** */
1561 /* *************** UNDO ***************************** */
1562 /* new mesh undo, based on pushing editmesh data itself */
1563 /* reuses same code as for global and curve undo... unify that (ton) */
1565 /* only one 'hack', to save memory it doesn't store the first push, but does a remake editmesh */
1567 /* a compressed version of editmesh data */
1569 typedef struct EditVertC
1578 typedef struct EditEdgeC
1581 unsigned char f, h, seam, sharp, pad;
1582 short crease, bweight, fgoni;
1585 typedef struct EditFaceC
1588 unsigned char flag, f, h, fgonf, pad1;
1592 typedef struct EditSelectionC{
1597 typedef struct UndoMesh {
1601 EditSelectionC *selected;
1602 int totvert, totedge, totface, totsel;
1603 int selectmode, shapenr;
1605 CustomData vdata, edata, fdata;
1610 static void free_undoMesh(void *umv)
1614 if(um->verts) MEM_freeN(um->verts);
1615 if(um->edges) MEM_freeN(um->edges);
1616 if(um->faces) MEM_freeN(um->faces);
1617 if(um->selected) MEM_freeN(um->selected);
1618 // XXX if(um->retopo_paint_data) retopo_free_paint_data(um->retopo_paint_data);
1619 CustomData_free(&um->vdata, um->totvert);
1620 CustomData_free(&um->edata, um->totedge);
1621 CustomData_free(&um->fdata, um->totface);
1625 static void *editMesh_to_undoMesh(void *emv)
1627 EditMesh *em= (EditMesh *)emv;
1633 EditVertC *evec=NULL;
1634 EditEdgeC *eedc=NULL;
1635 EditFaceC *efac=NULL;
1636 EditSelectionC *esec=NULL;
1639 um= MEM_callocN(sizeof(UndoMesh), "undomesh");
1641 um->selectmode = em->selectmode;
1642 um->shapenr = em->shapenr;
1644 for(eve=em->verts.first; eve; eve= eve->next) um->totvert++;
1645 for(eed=em->edges.first; eed; eed= eed->next) um->totedge++;
1646 for(efa=em->faces.first; efa; efa= efa->next) um->totface++;
1647 for(ese=em->selected.first; ese; ese=ese->next) um->totsel++;
1650 if(um->totvert) evec= um->verts= MEM_callocN(um->totvert*sizeof(EditVertC), "allvertsC");
1651 if(um->totedge) eedc= um->edges= MEM_callocN(um->totedge*sizeof(EditEdgeC), "alledgesC");
1652 if(um->totface) efac= um->faces= MEM_callocN(um->totface*sizeof(EditFaceC), "allfacesC");
1653 if(um->totsel) esec= um->selected= MEM_callocN(um->totsel*sizeof(EditSelectionC), "allselections");
1655 if(um->totvert) CustomData_copy(&em->vdata, &um->vdata, CD_MASK_EDITMESH, CD_CALLOC, um->totvert);
1656 if(um->totedge) CustomData_copy(&em->edata, &um->edata, CD_MASK_EDITMESH, CD_CALLOC, um->totedge);
1657 if(um->totface) CustomData_copy(&em->fdata, &um->fdata, CD_MASK_EDITMESH, CD_CALLOC, um->totface);
1659 /* now copy vertices */
1661 for(eve=em->verts.first; eve; eve= eve->next, evec++, a++) {
1662 copy_v3_v3(evec->co, eve->co);
1663 copy_v3_v3(evec->no, eve->no);
1667 evec->keyindex= eve->keyindex;
1668 eve->tmp.l = a; /*store index*/
1669 evec->bweight= (short)(eve->bweight*255.0f);
1671 CustomData_from_em_block(&em->vdata, &um->vdata, eve->data, a);
1676 for(eed=em->edges.first; eed; eed= eed->next, eedc++, a++) {
1677 eedc->v1= (int)eed->v1->tmp.l;
1678 eedc->v2= (int)eed->v2->tmp.l;
1681 eedc->seam= eed->seam;
1682 eedc->sharp= eed->sharp;
1683 eedc->crease= (short)(eed->crease*255.0f);
1684 eedc->bweight= (short)(eed->bweight*255.0f);
1685 eedc->fgoni= eed->fgoni;
1686 eed->tmp.l = a; /*store index*/
1687 CustomData_from_em_block(&em->edata, &um->edata, eed->data, a);
1693 for(efa=em->faces.first; efa; efa= efa->next, efac++, a++) {
1694 efac->v1= (int)efa->v1->tmp.l;
1695 efac->v2= (int)efa->v2->tmp.l;
1696 efac->v3= (int)efa->v3->tmp.l;
1697 if(efa->v4) efac->v4= (int)efa->v4->tmp.l;
1700 efac->mat_nr= efa->mat_nr;
1701 efac->flag= efa->flag;
1704 efac->fgonf= efa->fgonf;
1706 efa->tmp.l = a; /*store index*/
1708 CustomData_from_em_block(&em->fdata, &um->fdata, efa->data, a);
1712 for(ese=em->selected.first; ese; ese=ese->next, esec++){
1713 esec->type = ese->type;
1714 if(ese->type == EDITVERT) a = esec->index = ((EditVert*)ese->data)->tmp.l;
1715 else if(ese->type == EDITEDGE) a = esec->index = ((EditEdge*)ese->data)->tmp.l;
1716 else if(ese->type == EDITFACE) a = esec->index = ((EditFace*)ese->data)->tmp.l;
1719 // XXX um->retopo_paint_data= retopo_paint_data_copy(em->retopo_paint_data);
1720 // um->retopo_mode= scene->toolsettings->retopo_mode;
1725 static void undoMesh_to_editMesh(void *umv, void *emv)
1727 EditMesh *em= (EditMesh *)emv;
1728 UndoMesh *um= (UndoMesh *)umv;
1729 EditVert *eve, **evar=NULL;
1736 EditSelectionC *esec;
1742 memset(em, 0, sizeof(EditMesh));
1744 em->selectmode = um->selectmode;
1745 em->shapenr = um->shapenr;
1747 init_editmesh_fastmalloc(em, um->totvert, um->totedge, um->totface);
1749 CustomData_free(&em->vdata, 0);
1750 CustomData_free(&em->edata, 0);
1751 CustomData_free(&em->fdata, 0);
1753 CustomData_copy(&um->vdata, &em->vdata, CD_MASK_EDITMESH, CD_CALLOC, 0);
1754 CustomData_copy(&um->edata, &em->edata, CD_MASK_EDITMESH, CD_CALLOC, 0);
1755 CustomData_copy(&um->fdata, &em->fdata, CD_MASK_EDITMESH, CD_CALLOC, 0);
1757 /* now copy vertices */
1759 if(um->totvert) evar= MEM_mallocN(um->totvert*sizeof(EditVert *), "vertex ar");
1760 for(a=0, evec= um->verts; a<um->totvert; a++, evec++) {
1761 eve= addvertlist(em, evec->co, NULL);
1764 copy_v3_v3(eve->no, evec->no);
1767 eve->keyindex= evec->keyindex;
1768 eve->bweight= ((float)evec->bweight)/255.0f;
1770 CustomData_to_em_block(&um->vdata, &em->vdata, a, &eve->data);
1774 for(a=0, eedc= um->edges; a<um->totedge; a++, eedc++) {
1775 eed= addedgelist(em, evar[eedc->v1], evar[eedc->v2], NULL);
1779 eed->seam= eedc->seam;
1780 eed->sharp= eedc->sharp;
1781 eed->fgoni= eedc->fgoni;
1782 eed->crease= ((float)eedc->crease)/255.0f;
1783 eed->bweight= ((float)eedc->bweight)/255.0f;
1784 CustomData_to_em_block(&um->edata, &em->edata, a, &eed->data);
1788 for(a=0, efac= um->faces; a<um->totface; a++, efac++) {
1790 efa= addfacelist(em, evar[efac->v1], evar[efac->v2], evar[efac->v3], evar[efac->v4], NULL, NULL);
1792 efa= addfacelist(em, evar[efac->v1], evar[efac->v2], evar[efac->v3], NULL, NULL ,NULL);
1794 efa->mat_nr= efac->mat_nr;
1795 efa->flag= efac->flag;
1798 efa->fgonf= efac->fgonf;
1800 CustomData_to_em_block(&um->fdata, &em->fdata, a, &efa->data);
1803 end_editmesh_fastmalloc();
1804 if(evar) MEM_freeN(evar);
1806 em->totvert = um->totvert;
1807 em->totedge = um->totedge;
1808 em->totface = um->totface;
1809 /*restore stored editselections*/
1811 EM_init_index_arrays(em, 1,1,1);
1812 for(a=0, esec= um->selected; a<um->totsel; a++, esec++){
1813 ese = MEM_callocN(sizeof(EditSelection), "Edit Selection");
1814 ese->type = esec->type;
1815 if(ese->type == EDITVERT) ese->data = EM_get_vert_for_index(esec->index); else
1816 if(ese->type == EDITEDGE) ese->data = EM_get_edge_for_index(esec->index); else
1817 if(ese->type == EDITFACE) ese->data = EM_get_face_for_index(esec->index);
1818 BLI_addtail(&(em->selected),ese);
1820 EM_free_index_arrays();
1823 /* restore total selections */
1824 EM_nvertices_selected(em);
1825 EM_nedges_selected(em);
1826 EM_nfaces_selected(em);
1828 // XXX retopo_free_paint();
1829 // em->retopo_paint_data= retopo_paint_data_copy(um->retopo_paint_data);
1830 // scene->toolsettings->retopo_mode= um->retopo_mode;
1831 // if(scene->toolsettings->retopo_mode) {
1832 // XXX if(G.vd->depths) G.vd->depths->damaged= 1;
1833 // retopo_queue_updates(G.vd);
1834 // retopo_paint_view_update(G.vd);
1839 static void *getEditMesh(bContext *C)
1841 Object *obedit= CTX_data_edit_object(C);
1842 if(obedit && obedit->type==OB_MESH) {
1843 Mesh *me= obedit->data;
1844 return me->edit_mesh;
1849 /* and this is all the undo system needs to know */
1850 void undo_push_mesh(bContext *C, const char *name)
1852 undo_editmode_push(C, name, getEditMesh, free_undoMesh, undoMesh_to_editMesh, editMesh_to_undoMesh, NULL);
1857 /* *************** END UNDO *************/
1859 static EditVert **g_em_vert_array = NULL;
1860 static EditEdge **g_em_edge_array = NULL;
1861 static EditFace **g_em_face_array = NULL;
1863 void EM_init_index_arrays(EditMesh *em, int forVert, int forEdge, int forFace)
1871 em->totvert= BLI_countlist(&em->verts);
1874 g_em_vert_array = MEM_mallocN(sizeof(*g_em_vert_array)*em->totvert, "em_v_arr");
1876 for (i=0,eve=em->verts.first; eve; i++,eve=eve->next)
1877 g_em_vert_array[i] = eve;
1882 em->totedge= BLI_countlist(&em->edges);
1885 g_em_edge_array = MEM_mallocN(sizeof(*g_em_edge_array)*em->totedge, "em_e_arr");
1887 for (i=0,eed=em->edges.first; eed; i++,eed=eed->next)
1888 g_em_edge_array[i] = eed;
1893 em->totface= BLI_countlist(&em->faces);
1896 g_em_face_array = MEM_mallocN(sizeof(*g_em_face_array)*em->totface, "em_f_arr");
1898 for (i=0,efa=em->faces.first; efa; i++,efa=efa->next)
1899 g_em_face_array[i] = efa;
1904 void EM_free_index_arrays(void)
1906 if (g_em_vert_array) MEM_freeN(g_em_vert_array);
1907 if (g_em_edge_array) MEM_freeN(g_em_edge_array);
1908 if (g_em_face_array) MEM_freeN(g_em_face_array);
1909 g_em_vert_array = NULL;
1910 g_em_edge_array = NULL;
1911 g_em_face_array = NULL;
1914 EditVert *EM_get_vert_for_index(int index)
1916 return g_em_vert_array?g_em_vert_array[index]:NULL;
1919 EditEdge *EM_get_edge_for_index(int index)
1921 return g_em_edge_array?g_em_edge_array[index]:NULL;
1924 EditFace *EM_get_face_for_index(int index)
1926 return g_em_face_array?g_em_face_array[index]:NULL;
1929 /* can we edit UV's for this mesh?*/
1930 int EM_texFaceCheck(EditMesh *em)
1932 /* some of these checks could be a touch overkill */
1934 (em->faces.first) &&
1935 (CustomData_has_layer(&em->fdata, CD_MTFACE)))
1940 /* can we edit colors for this mesh?*/
1941 int EM_vertColorCheck(EditMesh *em)
1943 /* some of these checks could be a touch overkill */
1945 (em->faces.first) &&
1946 (CustomData_has_layer(&em->fdata, CD_MCOL)))
1952 void em_setup_viewcontext(bContext *C, ViewContext *vc)
1954 view3d_set_viewcontext(C, vc);
1957 Mesh *me= vc->obedit->data;
1958 vc->em= me->edit_mesh;
1963 /* Jason (similar to void paintface_flush_flags(Object *ob))
1964 * copy the vertex flags, most importantly selection from the mesh to the final derived mesh,
1965 * use in object mode when selecting vertices (while painting) */
1966 void paintvert_flush_flags(Object *ob)
1968 Mesh *me= get_mesh(ob);
1969 DerivedMesh *dm= ob->derivedFinal;
1970 MVert *verts, *mv, *mv_orig;
1971 int *index_array = NULL;
1975 if(me==NULL || dm==NULL)
1978 index_array = dm->getVertDataArray(dm, CD_ORIGINDEX);
1980 verts = dm->getVertArray(dm);
1981 totvert = dm->getNumVerts(dm);
1985 for (i= 0; i<totvert; i++, mv++) { /* loop over derived mesh faces */
1987 mv_orig= me->mvert + index_array[i];
1988 mv->flag= mv_orig->flag;
1990 mv_orig= me->mvert + i;
1991 mv->flag= mv_orig->flag;
1995 /* Jason note: if the caller passes FALSE to flush_flags, then they will need to run paintvert_flush_flags(ob) themselves */
1996 void paintvert_deselect_all_visible(Object *ob, int action, short flush_flags)
2003 if(me==NULL) return;
2005 if(action == SEL_INVERT) {
2009 if((mvert->flag & ME_HIDE) == 0) {
2010 mvert->flag ^= SELECT;
2016 if (action == SEL_TOGGLE) {
2017 action = SEL_SELECT;
2022 if((mvert->flag & ME_HIDE) == 0 && mvert->flag & SELECT) {
2023 action = SEL_DESELECT;
2033 if((mvert->flag & ME_HIDE) == 0) {
2036 mvert->flag |= SELECT;
2039 mvert->flag &= ~SELECT;
2042 mvert->flag ^= SELECT;
2051 paintvert_flush_flags(ob);