4 * ***** BEGIN GPL LICENSE BLOCK *****
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21 * All rights reserved.
23 * Contributor(s): Blender Foundation, full recode 2002-2008
25 * ***** END GPL LICENSE BLOCK *****
33 #include "MEM_guardedalloc.h"
37 #include "DNA_customdata_types.h"
38 #include "DNA_mesh_types.h"
39 #include "DNA_meshdata_types.h"
40 #include "DNA_object_types.h"
41 #include "DNA_object_force.h"
42 #include "DNA_screen_types.h"
43 #include "DNA_key_types.h"
44 #include "DNA_scene_types.h"
45 #include "DNA_view3d_types.h"
46 #include "DNA_material_types.h"
47 #include "DNA_modifier_types.h"
48 #include "DNA_texture_types.h"
49 #include "DNA_userdef_types.h"
51 #include "BLI_blenlib.h"
52 #include "BLI_arithb.h"
53 #include "BLI_editVert.h"
54 #include "BLI_dynstr.h"
57 #include "BKE_cloth.h"
58 #include "BKE_context.h"
59 #include "BKE_customdata.h"
60 #include "BKE_depsgraph.h"
61 #include "BKE_DerivedMesh.h"
62 #include "BKE_global.h"
64 #include "BKE_library.h"
66 #include "BKE_material.h"
68 #include "BKE_modifier.h"
69 #include "BKE_object.h"
70 #include "BKE_paint.h"
71 #include "BKE_pointcache.h"
72 #include "BKE_softbody.h"
73 #include "BKE_texture.h"
74 #include "BKE_utildefines.h"
76 #include "LBM_fluidsim.h"
80 #include "ED_object.h"
81 #include "ED_retopo.h"
82 #include "ED_screen.h"
84 #include "ED_view3d.h"
86 #include "RNA_access.h"
87 #include "RNA_define.h"
93 #include "mesh_intern.h"
103 static void BIF_undo_push() {}
104 static void error() {}
107 /* ***************** HASH ********************* */
110 #define EDHASHSIZE (512*512)
111 #define EDHASH(a, b) (a % EDHASHSIZE)
114 /* ************ ADD / REMOVE / FIND ****************** */
116 static void *calloc_em(EditMesh *em, size_t size, size_t nr)
118 return calloc(size, nr);
121 /* used to bypass normal calloc with fast one */
122 static void *(*callocvert)(EditMesh *, size_t, size_t) = calloc_em;
123 static void *(*callocedge)(EditMesh *, size_t, size_t) = calloc_em;
124 static void *(*callocface)(EditMesh *, size_t, size_t) = calloc_em;
126 EditVert *addvertlist(EditMesh *em, float *vec, EditVert *example)
129 static int hashnr= 0;
131 eve= callocvert(em, sizeof(EditVert), 1);
132 BLI_addtail(&em->verts, eve);
135 if(vec) VECCOPY(eve->co, vec);
138 if( hashnr>=EDHASHSIZE) hashnr= 0;
140 /* new verts get keyindex of -1 since they did not
141 * have a pre-editmode vertex order
146 CustomData_em_copy_data(&em->vdata, &em->vdata, example->data, &eve->data);
147 eve->bweight = example->bweight;
150 CustomData_em_set_default(&em->vdata, &eve->data);
156 void free_editvert (EditMesh *em, EditVert *eve)
159 EM_remove_selection(em, eve, EDITVERT);
160 CustomData_em_free_block(&em->vdata, &eve->data);
168 EditEdge *findedgelist(EditMesh *em, EditVert *v1, EditVert *v2)
180 if(em->hashedgetab==NULL)
181 em->hashedgetab= MEM_callocN(EDHASHSIZE*sizeof(struct HashEdge), "hashedgetab");
183 he= em->hashedgetab + EDHASH(v1->hash, v2->hash);
187 if(he->eed && he->eed->v1==v1 && he->eed->v2==v2) return he->eed;
194 static void insert_hashedge(EditMesh *em, EditEdge *eed)
196 /* assuming that eed is not in the list yet, and that a find has been done before */
198 struct HashEdge *first, *he;
200 first= em->hashedgetab + EDHASH(eed->v1->hash, eed->v2->hash);
202 if( first->eed==0 ) {
208 he->next= first->next;
213 static void remove_hashedge(EditMesh *em, EditEdge *eed)
215 /* assuming eed is in the list */
217 struct HashEdge *first, *he, *prev=NULL;
219 he=first= em->hashedgetab + EDHASH(eed->v1->hash, eed->v2->hash);
223 /* remove from list */
228 first->next= he->next;
233 prev->next= he->next;
242 EditEdge *addedgelist(EditMesh *em, EditVert *v1, EditVert *v2, EditEdge *example)
248 if(v1==v2) return NULL;
249 if(v1==NULL || v2==NULL) return NULL;
259 /* find in hashlist */
260 eed= findedgelist(em, v1, v2);
264 eed= (EditEdge *)callocedge(em, sizeof(EditEdge), 1);
267 BLI_addtail(&em->edges, eed);
269 insert_hashedge(em, eed);
273 rule is to do this with addedgelist call, before addfacelist */
275 eed->crease= example->crease;
276 eed->bweight= example->bweight;
277 eed->sharp = example->sharp;
278 eed->seam = example->seam;
279 eed->h |= (example->h & EM_FGON);
286 void remedge(EditMesh *em, EditEdge *eed)
288 BLI_remlink(&em->edges, eed);
289 remove_hashedge(em, eed);
294 void free_editedge(EditMesh *em, EditEdge *eed)
296 EM_remove_selection(em, eed, EDITEDGE);
302 void free_editface(EditMesh *em, EditFace *efa)
304 EM_remove_selection(em, efa, EDITFACE);
306 if (em->act_face==efa) {
307 EM_set_actFace(em, em->faces.first == efa ? NULL : em->faces.first);
310 CustomData_em_free_block(&em->fdata, &efa->data);
317 void free_vertlist(EditMesh *em, ListBase *edve)
319 EditVert *eve, *next;
326 free_editvert(em, eve);
329 edve->first= edve->last= NULL;
330 em->totvert= em->totvertsel= 0;
333 void free_edgelist(EditMesh *em, ListBase *lb)
335 EditEdge *eed, *next;
340 free_editedge(em, eed);
343 lb->first= lb->last= NULL;
344 em->totedge= em->totedgesel= 0;
347 void free_facelist(EditMesh *em, ListBase *lb)
349 EditFace *efa, *next;
354 free_editface(em, efa);
357 lb->first= lb->last= NULL;
358 em->totface= em->totfacesel= 0;
361 EditFace *addfacelist(EditMesh *em, EditVert *v1, EditVert *v2, EditVert *v3, EditVert *v4, EditFace *example, EditFace *exampleEdges)
364 EditEdge *e1, *e2=0, *e3=0, *e4=0;
366 /* added sanity check... seems to happen for some tools, or for enter editmode for corrupted meshes */
367 if(v1==v4 || v2==v4 || v3==v4) v4= NULL;
369 /* add face to list and do the edges */
371 e1= addedgelist(em, v1, v2, exampleEdges->e1);
372 e2= addedgelist(em, v2, v3, exampleEdges->e2);
373 if(v4) e3= addedgelist(em, v3, v4, exampleEdges->e3);
374 else e3= addedgelist(em, v3, v1, exampleEdges->e3);
375 if(v4) e4= addedgelist(em, v4, v1, exampleEdges->e4);
378 e1= addedgelist(em, v1, v2, NULL);
379 e2= addedgelist(em, v2, v3, NULL);
380 if(v4) e3= addedgelist(em, v3, v4, NULL);
381 else e3= addedgelist(em, v3, v1, NULL);
382 if(v4) e4= addedgelist(em, v4, v1, NULL);
385 if(v1==v2 || v2==v3 || v1==v3) return NULL;
386 if(e2==0) return NULL;
388 efa= (EditFace *)callocface(em, sizeof(EditFace), 1);
400 efa->mat_nr= example->mat_nr;
401 efa->flag= example->flag;
402 CustomData_em_copy_data(&em->fdata, &em->fdata, example->data, &efa->data);
405 efa->mat_nr= em->mat_nr;
407 CustomData_em_set_default(&em->fdata, &efa->data);
410 BLI_addtail(&em->faces, efa);
414 CalcNormFloat4(efa->v1->co, efa->v2->co, efa->v3->co, efa->v4->co, efa->n);
415 CalcCent4f(efa->cent, efa->v1->co, efa->v2->co, efa->v3->co, efa->v4->co);
418 CalcNormFloat(efa->v1->co, efa->v2->co, efa->v3->co, efa->n);
419 CalcCent3f(efa->cent, efa->v1->co, efa->v2->co, efa->v3->co);
425 /* ************************ end add/new/find ************ */
427 /* ************************ Edit{Vert,Edge,Face} utilss ***************************** */
429 /* some nice utility functions */
431 EditVert *editedge_getOtherVert(EditEdge *eed, EditVert *eve)
435 } else if (eve==eed->v2) {
442 EditVert *editedge_getSharedVert(EditEdge *eed, EditEdge *eed2)
444 if (eed->v1==eed2->v1 || eed->v1==eed2->v2) {
446 } else if (eed->v2==eed2->v1 || eed->v2==eed2->v2) {
453 int editedge_containsVert(EditEdge *eed, EditVert *eve)
455 return (eed->v1==eve || eed->v2==eve);
458 int editface_containsVert(EditFace *efa, EditVert *eve)
460 return (efa->v1==eve || efa->v2==eve || efa->v3==eve || (efa->v4 && efa->v4==eve));
463 int editface_containsEdge(EditFace *efa, EditEdge *eed)
465 return (efa->e1==eed || efa->e2==eed || efa->e3==eed || (efa->e4 && efa->e4==eed));
469 /* ************************ stuct EditMesh manipulation ***************************** */
471 /* fake callocs for fastmalloc below */
472 static void *calloc_fastvert(EditMesh *em, size_t size, size_t nr)
474 EditVert *eve= em->curvert++;
478 static void *calloc_fastedge(EditMesh *em, size_t size, size_t nr)
480 EditEdge *eed= em->curedge++;
484 static void *calloc_fastface(EditMesh *em, size_t size, size_t nr)
486 EditFace *efa= em->curface++;
491 /* allocate 1 chunk for all vertices, edges, faces. These get tagged to
492 prevent it from being freed
494 static void init_editmesh_fastmalloc(EditMesh *em, int totvert, int totedge, int totface)
496 if(totvert) em->allverts= MEM_callocN(totvert*sizeof(EditVert), "allverts");
497 else em->allverts= NULL;
498 em->curvert= em->allverts;
500 if(totedge==0) totedge= 4*totface; // max possible
502 if(totedge) em->alledges= MEM_callocN(totedge*sizeof(EditEdge), "alledges");
503 else em->alledges= NULL;
504 em->curedge= em->alledges;
506 if(totface) em->allfaces= MEM_callocN(totface*sizeof(EditFace), "allfaces");
507 else em->allfaces= NULL;
508 em->curface= em->allfaces;
510 callocvert= calloc_fastvert;
511 callocedge= calloc_fastedge;
512 callocface= calloc_fastface;
515 static void end_editmesh_fastmalloc(void)
517 callocvert= calloc_em;
518 callocedge= calloc_em;
519 callocface= calloc_em;
522 /* do not free editmesh itself here */
523 void free_editMesh(EditMesh *em)
527 if(em->verts.first) free_vertlist(em, &em->verts);
528 if(em->edges.first) free_edgelist(em, &em->edges);
529 if(em->faces.first) free_facelist(em, &em->faces);
530 if(em->selected.first) BLI_freelistN(&(em->selected));
532 CustomData_free(&em->vdata, 0);
533 CustomData_free(&em->fdata, 0);
535 if(em->derivedFinal) {
536 if (em->derivedFinal!=em->derivedCage) {
537 em->derivedFinal->needsFree= 1;
538 em->derivedFinal->release(em->derivedFinal);
540 em->derivedFinal= NULL;
542 if(em->derivedCage) {
543 em->derivedCage->needsFree= 1;
544 em->derivedCage->release(em->derivedCage);
545 em->derivedCage= NULL;
548 /* DEBUG: hashtabs are slowest part of enter/exit editmode. here a testprint */
550 if(em->hashedgetab) {
552 int a, used=0, max=0, nr;
554 for(a=0; a<EDHASHSIZE; a++, he++) {
564 printf("hastab used %d max %d\n", used, max);
567 if(em->hashedgetab) MEM_freeN(em->hashedgetab);
568 em->hashedgetab= NULL;
570 if(em->allverts) MEM_freeN(em->allverts);
571 if(em->alledges) MEM_freeN(em->alledges);
572 if(em->allfaces) MEM_freeN(em->allfaces);
574 em->allverts= em->curvert= NULL;
575 em->alledges= em->curedge= NULL;
576 em->allfaces= em->curface= NULL;
578 mesh_octree_table(NULL, NULL, NULL, 'e');
580 em->totvert= em->totedge= em->totface= 0;
582 // XXX if(em->retopo_paint_data) retopo_free_paint_data(em->retopo_paint_data);
583 em->retopo_paint_data= NULL;
587 static void editMesh_set_hash(EditMesh *em)
591 if(em->hashedgetab) MEM_freeN(em->hashedgetab);
592 em->hashedgetab= NULL;
594 for(eed=em->edges.first; eed; eed= eed->next) {
595 if( findedgelist(em, eed->v1, eed->v2)==NULL )
596 insert_hashedge(em, eed);
602 /* ************************ IN & OUT EDITMODE ***************************** */
605 static void edge_normal_compare(EditEdge *eed, EditFace *efa1)
608 float cent1[3], cent2[3];
612 if(efa1==efa2) return;
614 inp= efa1->n[0]*efa2->n[0] + efa1->n[1]*efa2->n[1] + efa1->n[2]*efa2->n[2];
615 if(inp<0.999 && inp >-0.999) eed->f2= 1;
617 if(efa1->v4) CalcCent4f(cent1, efa1->v1->co, efa1->v2->co, efa1->v3->co, efa1->v4->co);
618 else CalcCent3f(cent1, efa1->v1->co, efa1->v2->co, efa1->v3->co);
619 if(efa2->v4) CalcCent4f(cent2, efa2->v1->co, efa2->v2->co, efa2->v3->co, efa2->v4->co);
620 else CalcCent3f(cent2, efa2->v1->co, efa2->v2->co, efa2->v3->co);
622 VecSubf(cent1, cent2, cent1);
624 inp= cent1[0]*efa1->n[0] + cent1[1]*efa1->n[1] + cent1[2]*efa1->n[2];
626 if(inp < -0.001 ) eed->f1= 1;
636 static int edgeDrawFlagInfo_cmp(const void *av, const void *bv)
638 const EdgeDrawFlagInfo *a = av;
639 const EdgeDrawFlagInfo *b = bv;
641 if (a->noLen<b->noLen) return -1;
642 else if (a->noLen>b->noLen) return 1;
647 static void edge_drawflags(Mesh *me, EditMesh *em)
650 EditEdge *eed, *e1, *e2, *e3, *e4;
653 /* - count number of times edges are used in faces: 0 en 1 time means draw edge
654 * - edges more than 1 time used: in *tmp.f is pointer to first face
655 * - check all faces, when normal differs to much: draw (flag becomes 1)
658 /* later on: added flags for 'cylinder' and 'sphere' intersection tests in old
662 recalc_editnormals(em);
665 eve= em->verts.first;
667 eve->f1= 1; /* during test it's set at zero */
670 eed= em->edges.first;
677 efa= em->faces.first;
683 if(e1->f2<4) e1->f2+= 1;
684 if(e2->f2<4) e2->f2+= 1;
685 if(e3->f2<4) e3->f2+= 1;
686 if(e4 && e4->f2<4) e4->f2+= 1;
688 if(e1->tmp.f == 0) e1->tmp.f = (void *) efa;
689 if(e2->tmp.f == 0) e2->tmp.f = (void *) efa;
690 if(e3->tmp.f ==0) e3->tmp.f = (void *) efa;
691 if(e4 && (e4->tmp.f == 0)) e4->tmp.f = (void *) efa;
696 if(me->drawflag & ME_ALLEDGES) {
697 efa= em->faces.first;
699 if(efa->e1->f2>=2) efa->e1->f2= 1;
700 if(efa->e2->f2>=2) efa->e2->f2= 1;
701 if(efa->e3->f2>=2) efa->e3->f2= 1;
702 if(efa->e4 && efa->e4->f2>=2) efa->e4->f2= 1;
709 /* handle single-edges for 'test cylinder flag' (old engine) */
711 eed= em->edges.first;
713 if(eed->f2==1) eed->f1= 1;
717 /* all faces, all edges with flag==2: compare normal */
718 efa= em->faces.first;
720 if(efa->e1->f2==2) edge_normal_compare(efa->e1, efa);
722 if(efa->e2->f2==2) edge_normal_compare(efa->e2, efa);
724 if(efa->e3->f2==2) edge_normal_compare(efa->e3, efa);
727 if(efa->e4->f2==2) edge_normal_compare(efa->e4, efa);
733 /* sphere collision flag */
735 eed= em->edges.first;
738 eed->v1->f1= eed->v2->f1= 0;
746 static int editmesh_pointcache_edit(Scene *scene, Object *ob, int totvert, PTCacheID *pid_p, float mat[][4], int load)
750 ClothModifierData *clmd;
751 PTCacheID pid, tmpid;
752 int cfra= (int)scene->r.cfra, found= 0;
756 /* check for cloth */
757 if(modifiers_isClothEnabled(ob)) {
758 clmd= (ClothModifierData*)modifiers_findByType(ob, eModifierType_Cloth);
759 cloth= clmd->clothObject;
761 BKE_ptcache_id_from_cloth(&tmpid, ob, clmd);
763 /* verify vertex count and baked status */
764 if(cloth && (totvert == cloth->numverts)) {
765 if((tmpid.cache->flag & PTCACHE_BAKED) && (tmpid.cache->flag & PTCACHE_BAKE_EDIT)) {
768 if(load && (pid.cache->flag & PTCACHE_BAKE_EDIT_ACTIVE))
774 /* check for softbody */
775 if(!found && ob->soft) {
778 BKE_ptcache_id_from_softbody(&tmpid, ob, sb);
780 /* verify vertex count and baked status */
781 if(sb->bpoint && (totvert == sb->totpoint)) {
782 if((tmpid.cache->flag & PTCACHE_BAKED) && (tmpid.cache->flag & PTCACHE_BAKE_EDIT)) {
785 if(load && (pid.cache->flag & PTCACHE_BAKE_EDIT_ACTIVE))
791 /* if not making editmesh verify editing was active for this point cache */
794 pid.cache->flag &= ~PTCACHE_BAKE_EDIT_ACTIVE;
799 /* check if we have cache for this frame */
800 if(pid.cache && BKE_ptcache_id_exist(&pid, cfra)) {
804 Mat4CpyMat4(mat, ob->obmat);
807 pid.cache->editframe= cfra;
808 pid.cache->flag |= PTCACHE_BAKE_EDIT_ACTIVE;
809 Mat4Invert(mat, ob->obmat); /* ob->imat is not up to date */
818 /* turns Mesh into editmesh */
819 void make_editMesh(Scene *scene, Object *ob)
827 EditVert *eve, **evlist, *eve1, *eve2, *eve3, *eve4;
834 float cacheco[3], cachemat[4][4], *co;
835 int tot, a, cacheedit= 0, eekadoodle= 0;
837 if(me->edit_mesh==NULL)
838 me->edit_mesh= MEM_callocN(sizeof(EditMesh), "editmesh");
840 /* because of reload */
841 free_editMesh(me->edit_mesh);
845 em->selectmode= scene->toolsettings->selectmode; // warning needs to be synced
847 em->totvert= tot= me->totvert;
848 em->totedge= me->totedge;
849 em->totface= me->totface;
855 /* initialize fastmalloc for editmesh */
856 init_editmesh_fastmalloc(em, me->totvert, me->totedge, me->totface);
858 actkey = ob_get_keyblock(ob);
860 tot= actkey->totelem;
861 /* undo-ing in past for previous editmode sessions gives corrupt 'keyindex' values */
862 undo_editmode_clear();
867 CustomData_copy(&me->vdata, &em->vdata, CD_MASK_EDITMESH, CD_CALLOC, 0);
870 cacheedit= editmesh_pointcache_edit(scene, ob, tot, &pid, cachemat, 0);
872 evlist= (EditVert **)MEM_mallocN(tot*sizeof(void *),"evlist");
873 for(a=0; a<tot; a++, mvert++) {
876 if(pid.type == PTCACHE_TYPE_CLOTH) {
877 cloth= ((ClothModifierData*)pid.calldata)->clothObject;
878 VECCOPY(cacheco, cloth->verts[a].x)
880 else if(pid.type == PTCACHE_TYPE_SOFTBODY) {
881 sb= (SoftBody*)pid.calldata;
882 VECCOPY(cacheco, sb->bpoint[a].pos)
885 Mat4MulVecfl(cachemat, cacheco);
891 eve= addvertlist(em, co, NULL);
894 // face select sets selection in next loop
895 if(!paint_facesel_test(ob))
896 eve->f |= (mvert->flag & 1);
898 if (mvert->flag & ME_HIDE) eve->h= 1;
899 eve->no[0]= mvert->no[0]/32767.0;
900 eve->no[1]= mvert->no[1]/32767.0;
901 eve->no[2]= mvert->no[2]/32767.0;
903 eve->bweight= ((float)mvert->bweight)/255.0f;
905 /* lets overwrite the keyindex of the editvert
906 * with the order it used to be in before
911 CustomData_to_em_block(&me->vdata, &em->vdata, a, &eve->data);
914 if(actkey && actkey->totelem!=me->totvert);
916 MEdge *medge= me->medge;
918 CustomData_copy(&me->edata, &em->edata, CD_MASK_EDITMESH, CD_CALLOC, 0);
920 for(a=0; a<me->totedge; a++, medge++) {
921 eed= addedgelist(em, evlist[medge->v1], evlist[medge->v2], NULL);
922 /* eed can be zero when v1 and v2 are identical, dxf import does this... */
924 eed->crease= ((float)medge->crease)/255.0f;
925 eed->bweight= ((float)medge->bweight)/255.0f;
927 if(medge->flag & ME_SEAM) eed->seam= 1;
928 if(medge->flag & ME_SHARP) eed->sharp = 1;
929 if(medge->flag & SELECT) eed->f |= SELECT;
930 if(medge->flag & ME_FGON) eed->h= EM_FGON; // 2 different defines!
931 if(medge->flag & ME_HIDE) eed->h |= 1;
932 if(em->selectmode==SCE_SELECT_EDGE)
933 EM_select_edge(eed, eed->f & SELECT); // force edge selection to vertices, seems to be needed ...
934 CustomData_to_em_block(&me->edata,&em->edata, a, &eed->data);
938 CustomData_copy(&me->fdata, &em->fdata, CD_MASK_EDITMESH, CD_CALLOC, 0);
943 for(a=0; a<me->totface; a++, mface++) {
944 eve1= evlist[mface->v1];
945 eve2= evlist[mface->v2];
946 if(!mface->v3) eekadoodle= 1;
947 eve3= evlist[mface->v3];
948 if(mface->v4) eve4= evlist[mface->v4]; else eve4= NULL;
950 efa= addfacelist(em, eve1, eve2, eve3, eve4, NULL, NULL);
953 CustomData_to_em_block(&me->fdata, &em->fdata, a, &efa->data);
955 efa->mat_nr= mface->mat_nr;
956 efa->flag= mface->flag & ~ME_HIDE;
958 /* select and hide face flag */
959 if(mface->flag & ME_HIDE) {
962 if (a==me->act_face) {
963 EM_set_actFace(em, efa);
966 /* dont allow hidden and selected */
967 if(mface->flag & ME_FACE_SEL) {
970 if(paint_facesel_test(ob)) {
971 EM_select_face(efa, 1); /* flush down */
980 error("This Mesh has old style edgecodes, please put it in the bugtracker!");
984 end_editmesh_fastmalloc(); // resets global function pointers
987 //restore editselections
988 EM_init_index_arrays(em, 1,1,1);
989 mselect = me->mselect;
991 for(a=0; a<me->totselect; a++, mselect++){
992 /*check if recorded selection is still valid, if so copy into editmesh*/
993 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) ){
994 ese = MEM_callocN(sizeof(EditSelection), "Edit Selection");
995 ese->type = mselect->type;
996 if(ese->type == EDITVERT) ese->data = EM_get_vert_for_index(mselect->index); else
997 if(ese->type == EDITEDGE) ese->data = EM_get_edge_for_index(mselect->index); else
998 if(ese->type == EDITFACE) ese->data = EM_get_face_for_index(mselect->index);
999 BLI_addtail(&(em->selected),ese);
1002 EM_free_index_arrays();
1004 /* this creates coherent selections. also needed for older files */
1005 EM_selectmode_set(em);
1006 /* paranoia check to enforce hide rules */
1008 /* sets helper flags which arent saved */
1011 if (EM_get_actFace(em, 0)==NULL) {
1012 EM_set_actFace(em, em->faces.first ); /* will use the first face, this is so we alwats have an active face */
1015 /* vertex coordinates change with cache edit, need to recalc */
1017 recalc_editnormals(em);
1021 /* makes Mesh out of editmesh */
1022 void load_editMesh(Scene *scene, Object *ob)
1025 MVert *mvert, *oldverts;
1029 EditMesh *em= me->edit_mesh;
1031 EditFace *efa, *efa_act;
1036 ClothModifierData *clmd;
1038 float *fp, *newkey, *oldkey, nor[3], cacheco[3], cachemat[4][4];
1039 int i, a, ototvert, cacheedit= 0;
1041 /* this one also tests of edges are not in faces: */
1042 /* eed->f2==0: not in face, f2==1: draw it */
1043 /* eed->f1 : flag for dynaface (cylindertest, old engine) */
1044 /* eve->f1 : flag for dynaface (sphere test, old engine) */
1045 /* eve->f2 : being used in vertexnormals */
1046 edge_drawflags(me, em);
1048 EM_stats_update(em);
1050 /* new Vertex block */
1051 if(em->totvert==0) mvert= NULL;
1052 else mvert= MEM_callocN(em->totvert*sizeof(MVert), "loadeditMesh vert");
1054 /* new Edge block */
1055 if(em->totedge==0) medge= NULL;
1056 else medge= MEM_callocN(em->totedge*sizeof(MEdge), "loadeditMesh edge");
1058 /* new Face block */
1059 if(em->totface==0) mface= NULL;
1060 else mface= MEM_callocN(em->totface*sizeof(MFace), "loadeditMesh face");
1062 /* lets save the old verts just in case we are actually working on
1063 * a key ... we now do processing of the keys at the end */
1064 oldverts= me->mvert;
1065 ototvert= me->totvert;
1067 /* don't free this yet */
1068 CustomData_set_layer(&me->vdata, CD_MVERT, NULL);
1070 /* free custom data */
1071 CustomData_free(&me->vdata, me->totvert);
1072 CustomData_free(&me->edata, me->totedge);
1073 CustomData_free(&me->fdata, me->totface);
1075 /* add new custom data */
1076 me->totvert= em->totvert;
1077 me->totedge= em->totedge;
1078 me->totface= em->totface;
1080 CustomData_copy(&em->vdata, &me->vdata, CD_MASK_MESH, CD_CALLOC, me->totvert);
1081 CustomData_copy(&em->edata, &me->edata, CD_MASK_MESH, CD_CALLOC, me->totedge);
1082 CustomData_copy(&em->fdata, &me->fdata, CD_MASK_MESH, CD_CALLOC, me->totface);
1084 CustomData_add_layer(&me->vdata, CD_MVERT, CD_ASSIGN, mvert, me->totvert);
1085 CustomData_add_layer(&me->edata, CD_MEDGE, CD_ASSIGN, medge, me->totedge);
1086 CustomData_add_layer(&me->fdata, CD_MFACE, CD_ASSIGN, mface, me->totface);
1087 mesh_update_customdata_pointers(me);
1089 /* the vertices, use ->tmp.l as counter */
1090 eve= em->verts.first;
1093 /* check for point cache editing */
1094 cacheedit= editmesh_pointcache_edit(scene, ob, em->totvert, &pid, cachemat, 1);
1098 if(pid.type == PTCACHE_TYPE_CLOTH) {
1099 clmd= (ClothModifierData*)pid.calldata;
1100 cloth= clmd->clothObject;
1102 /* assign position */
1103 VECCOPY(cacheco, cloth->verts[a].x)
1104 VECCOPY(cloth->verts[a].x, eve->co);
1105 Mat4MulVecfl(cachemat, cloth->verts[a].x);
1107 /* find plausible velocity, not physical correct but gives
1108 * nicer results when commented */
1109 VECSUB(cacheco, cloth->verts[a].x, cacheco);
1110 VecMulf(cacheco, clmd->sim_parms->stepsPerFrame*10.0f);
1111 VECADD(cloth->verts[a].v, cloth->verts[a].v, cacheco);
1113 else if(pid.type == PTCACHE_TYPE_SOFTBODY) {
1114 sb= (SoftBody*)pid.calldata;
1116 /* assign position */
1117 VECCOPY(cacheco, sb->bpoint[a].pos)
1118 VECCOPY(sb->bpoint[a].pos, eve->co);
1119 Mat4MulVecfl(cachemat, sb->bpoint[a].pos);
1121 /* changing velocity for softbody doesn't seem to give
1124 VECSUB(cacheco, sb->bpoint[a].pos, cacheco);
1125 VecMulf(cacheco, sb->minloops*10.0f);
1126 VECADD(sb->bpoint[a].vec, sb->bpoint[a].pos, cacheco);
1131 VECCOPY(mvert->co, oldverts[a].co)
1134 VECCOPY(mvert->co, eve->co);
1136 mvert->mat_nr= 32767; /* what was this for, halos? */
1139 VECCOPY(nor, eve->no);
1140 VecMulf(nor, 32767.0);
1141 VECCOPY(mvert->no, nor);
1143 /* note: it used to remove me->dvert when it was not in use, cancelled
1144 that... annoying when you have a fresh vgroup */
1145 CustomData_from_em_block(&em->vdata, &me->vdata, eve->data, a);
1147 eve->tmp.l = a++; /* counter */
1150 mvert->flag |= (eve->f & SELECT);
1151 if (eve->h) mvert->flag |= ME_HIDE;
1153 mvert->bweight= (char)(255.0*eve->bweight);
1159 /* write changes to cache */
1161 BKE_ptcache_write_cache(&pid, pid.cache->editframe);
1165 eed= em->edges.first;
1167 medge->v1= (unsigned int) eed->v1->tmp.l;
1168 medge->v2= (unsigned int) eed->v2->tmp.l;
1170 medge->flag= (eed->f & SELECT) | ME_EDGERENDER;
1171 if(eed->f2<2) medge->flag |= ME_EDGEDRAW;
1172 if(eed->f2==0) medge->flag |= ME_LOOSEEDGE;
1173 if(eed->sharp) medge->flag |= ME_SHARP;
1174 if(eed->seam) medge->flag |= ME_SEAM;
1175 if(eed->h & EM_FGON) medge->flag |= ME_FGON; // different defines yes
1176 if(eed->h & 1) medge->flag |= ME_HIDE;
1178 medge->crease= (char)(255.0*eed->crease);
1179 medge->bweight= (char)(255.0*eed->bweight);
1180 CustomData_from_em_block(&em->edata, &me->edata, eed->data, a);
1190 efa= em->faces.first;
1191 efa_act= EM_get_actFace(em, 0);
1195 mface= &((MFace *) me->mface)[i];
1197 mface->v1= (unsigned int) efa->v1->tmp.l;
1198 mface->v2= (unsigned int) efa->v2->tmp.l;
1199 mface->v3= (unsigned int) efa->v3->tmp.l;
1200 if (efa->v4) mface->v4 = (unsigned int) efa->v4->tmp.l;
1202 mface->mat_nr= efa->mat_nr;
1204 mface->flag= efa->flag;
1205 /* bit 0 of flag is already taken for smooth... */
1208 mface->flag |= ME_HIDE;
1209 mface->flag &= ~ME_FACE_SEL;
1211 if(efa->f & 1) mface->flag |= ME_FACE_SEL;
1212 else mface->flag &= ~ME_FACE_SEL;
1215 /* mat_nr in vertex */
1217 mvert= me->mvert+mface->v1;
1218 if(mvert->mat_nr == (char)32767) mvert->mat_nr= mface->mat_nr;
1219 mvert= me->mvert+mface->v2;
1220 if(mvert->mat_nr == (char)32767) mvert->mat_nr= mface->mat_nr;
1221 mvert= me->mvert+mface->v3;
1222 if(mvert->mat_nr == (char)32767) mvert->mat_nr= mface->mat_nr;
1224 mvert= me->mvert+mface->v4;
1225 if(mvert->mat_nr == (char)32767) mvert->mat_nr= mface->mat_nr;
1229 /* watch: efa->e1->f2==0 means loose edge */
1231 if(efa->e1->f2==1) {
1234 if(efa->e2->f2==1) {
1237 if(efa->e3->f2==1) {
1240 if(efa->e4 && efa->e4->f2==1) {
1244 CustomData_from_em_block(&em->fdata, &me->fdata, efa->data, i);
1246 /* no index '0' at location 3 or 4 */
1247 test_index_face(mface, &me->fdata, i, efa->v4?4:3);
1257 /* patch hook indices and vertex parents */
1261 EditVert **vertMap = NULL;
1264 for (ob=G.main->object.first; ob; ob=ob->id.next) {
1265 if (ob->parent==ob && ELEM(ob->partype, PARVERT1,PARVERT3)) {
1267 /* duplicate code from below, make it function later...? */
1269 vertMap = MEM_callocN(sizeof(*vertMap)*ototvert, "vertMap");
1271 for (eve=em->verts.first; eve; eve=eve->next) {
1272 if (eve->keyindex!=-1)
1273 vertMap[eve->keyindex] = eve;
1276 if(ob->par1 < ototvert) {
1277 eve = vertMap[ob->par1];
1278 if(eve) ob->par1= eve->tmp.l;
1280 if(ob->par2 < ototvert) {
1281 eve = vertMap[ob->par2];
1282 if(eve) ob->par2= eve->tmp.l;
1284 if(ob->par3 < ototvert) {
1285 eve = vertMap[ob->par3];
1286 if(eve) ob->par3= eve->tmp.l;
1291 for (md=ob->modifiers.first; md; md=md->next) {
1292 if (md->type==eModifierType_Hook) {
1293 HookModifierData *hmd = (HookModifierData*) md;
1296 vertMap = MEM_callocN(sizeof(*vertMap)*ototvert, "vertMap");
1298 for (eve=em->verts.first; eve; eve=eve->next) {
1299 if (eve->keyindex!=-1)
1300 vertMap[eve->keyindex] = eve;
1304 for (i=j=0; i<hmd->totindex; i++) {
1305 if(hmd->indexar[i] < ototvert) {
1306 eve = vertMap[hmd->indexar[i]];
1309 hmd->indexar[j++] = eve->tmp.l;
1321 if (vertMap) MEM_freeN(vertMap);
1324 /* are there keys? */
1326 KeyBlock *currkey, *actkey = ob_get_keyblock(ob);
1328 /* Lets reorder the key data so that things line up roughly
1329 * with the way things were before editmode */
1330 currkey = me->key->block.first;
1333 fp= newkey= MEM_callocN(me->key->elemsize*em->totvert, "currkey->data");
1334 oldkey = currkey->data;
1336 eve= em->verts.first;
1341 if (eve->keyindex >= 0 && eve->keyindex < currkey->totelem) { // valid old vertex
1342 if(currkey == actkey) {
1343 if (actkey == me->key->refkey) {
1344 VECCOPY(fp, mvert->co);
1347 VECCOPY(fp, mvert->co);
1349 VECCOPY(mvert->co, oldverts[eve->keyindex].co);
1355 VECCOPY(fp, oldkey + 3 * eve->keyindex);
1360 VECCOPY(fp, mvert->co);
1367 currkey->totelem= em->totvert;
1368 if(currkey->data) MEM_freeN(currkey->data);
1369 currkey->data = newkey;
1371 currkey= currkey->next;
1375 if(oldverts) MEM_freeN(oldverts);
1378 for(ese=em->selected.first; ese; ese=ese->next) i++;
1380 if(i==0) mselect= NULL;
1381 else mselect= MEM_callocN(i*sizeof(MSelect), "loadeditMesh selections");
1383 if(me->mselect) MEM_freeN(me->mselect);
1384 me->mselect= mselect;
1386 for(ese=em->selected.first; ese; ese=ese->next){
1387 mselect->type = ese->type;
1388 if(ese->type == EDITVERT) mselect->index = ((EditVert*)ese->data)->tmp.l;
1389 else if(ese->type == EDITEDGE) mselect->index = ((EditEdge*)ese->data)->tmp.l;
1390 else if(ese->type == EDITFACE) mselect->index = ((EditFace*)ese->data)->tmp.l;
1394 /* to be sure: clear ->tmp.l pointers */
1395 eve= em->verts.first;
1401 eed= em->edges.first;
1407 efa= em->faces.first;
1413 /* remake softbody of all users */
1416 for(base= scene->base.first; base; base= base->next)
1417 if(base->object->data==me)
1418 base->object->recalc |= OB_RECALC_DATA;
1421 mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL);
1424 void remake_editMesh(Scene *scene, Object *ob)
1426 make_editMesh(scene, ob);
1427 DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
1428 BIF_undo_push("Undo all changes");
1431 /* *************** Operator: separate parts *************/
1433 static EnumPropertyItem prop_separate_types[] = {
1434 {0, "SELECTED", 0, "Selection", ""},
1435 {1, "MATERIAL", 0, "By Material", ""},
1436 {2, "LOOSE", 0, "By loose parts", ""},
1437 {0, NULL, 0, NULL, NULL}
1440 /* return 1: success */
1441 static int mesh_separate_selected(Scene *scene, Base *editbase)
1443 EditMesh *em, *emnew;
1451 if(editbase==NULL) return 0;
1453 obedit= editbase->object;
1455 em= BKE_mesh_get_editmesh(me);
1457 error("Can't separate with vertex keys");
1458 BKE_mesh_end_editmesh(me, em);
1462 if(em->selected.first)
1463 BLI_freelistN(&(em->selected)); /* clear the selection order */
1465 EM_selectmode_set(em); // enforce full consistent selection flags
1467 EM_stats_update(em);
1469 if(em->totvertsel==0) {
1470 BKE_mesh_end_editmesh(me, em);
1474 /* we are going to work as follows:
1475 * 1. add a linked duplicate object: this will be the new one, we remember old pointer
1476 * 2. give new object empty mesh and put in editmode
1477 * 3: do a split if needed on current editmesh.
1478 * 4. copy over: all NOT selected verts, edges, faces
1479 * 5. call load_editMesh() on the new object
1483 basenew= ED_object_add_duplicate(scene, editbase, 0); /* 0 = fully linked */
1484 ED_base_object_select(basenew, BA_DESELECT);
1487 basenew->object->data= menew= add_mesh(me->id.name); /* empty */
1489 make_editMesh(scene, basenew->object);
1490 emnew= menew->edit_mesh;
1493 /* SPLIT: first make duplicate */
1494 adduplicateflag(em, SELECT);
1495 /* SPLIT: old faces have 3x flag 128 set, delete these ones */
1496 delfaceflag(em, 128);
1497 /* since we do tricky things with verts/edges/faces, this makes sure all is selected coherent */
1498 EM_selectmode_set(em);
1501 /* move over: everything that is selected */
1502 for(eve= em->verts.first; eve; eve= v1) {
1504 if(eve->f & SELECT) {
1505 BLI_remlink(&em->verts, eve);
1506 BLI_addtail(&emnew->verts, eve);
1510 for(eed= em->edges.first; eed; eed= e1) {
1512 if(eed->f & SELECT) {
1513 BLI_remlink(&em->edges, eed);
1514 BLI_addtail(&emnew->edges, eed);
1518 for(efa= em->faces.first; efa; efa= f1) {
1520 if (efa == em->act_face && (efa->f & SELECT)) {
1521 EM_set_actFace(em, NULL);
1524 if(efa->f & SELECT) {
1525 BLI_remlink(&em->faces, efa);
1526 BLI_addtail(&emnew->faces, efa);
1531 load_editMesh(scene, basenew->object);
1532 free_editMesh(emnew);
1534 /* hashedges are invalid now, make new! */
1535 editMesh_set_hash(em);
1537 DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
1538 DAG_object_flush_update(scene, basenew->object, OB_RECALC_DATA);
1540 BKE_mesh_end_editmesh(me, em);
1545 /* return 1: success */
1546 static int mesh_separate_material(Scene *scene, Base *editbase)
1548 Mesh *me= editbase->object->data;
1549 EditMesh *em= BKE_mesh_get_editmesh(me);
1550 unsigned char curr_mat;
1552 for (curr_mat = 1; curr_mat < editbase->object->totcol; ++curr_mat) {
1553 /* clear selection, we're going to use that to select material group */
1554 EM_clear_flag_all(em, SELECT);
1555 /* select the material */
1556 EM_select_by_material(em, curr_mat);
1557 /* and now separate */
1558 if(0==mesh_separate_selected(scene, editbase)) {
1559 BKE_mesh_end_editmesh(me, em);
1564 BKE_mesh_end_editmesh(me, em);
1568 /* return 1: success */
1569 static int mesh_separate_loose(Scene *scene, Base *editbase)
1575 me= editbase->object->data;
1576 em= BKE_mesh_get_editmesh(me);
1579 error("Can't separate with vertex keys");
1580 BKE_mesh_end_editmesh(me, em);
1584 EM_clear_flag_all(em, SELECT);
1586 while(doit && em->verts.first) {
1587 /* Select a random vert to start with */
1588 EditVert *eve= em->verts.first;
1591 selectconnected_mesh_all(em);
1593 /* and now separate */
1594 doit= mesh_separate_selected(scene, editbase);
1597 BKE_mesh_end_editmesh(me, em);
1602 static int mesh_separate_exec(bContext *C, wmOperator *op)
1604 Scene *scene= CTX_data_scene(C);
1605 Base *base= CTX_data_active_base(C);
1606 int retval= 0, type= RNA_enum_get(op->ptr, "type");
1609 retval= mesh_separate_selected(scene, base);
1611 retval= mesh_separate_material (scene, base);
1613 retval= mesh_separate_loose(scene, base);
1616 WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, base->object);
1617 return OPERATOR_FINISHED;
1619 return OPERATOR_CANCELLED;
1622 void MESH_OT_separate(wmOperatorType *ot)
1625 ot->name= "Separate";
1626 ot->description= "Separate selected geometry into a new mesh.";
1627 ot->idname= "MESH_OT_separate";
1630 ot->invoke= WM_menu_invoke;
1631 ot->exec= mesh_separate_exec;
1632 ot->poll= ED_operator_editmesh;
1635 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1637 RNA_def_enum(ot->srna, "type", prop_separate_types, 0, "Type", "");
1641 /* ******************************************** */
1643 /* *************** UNDO ***************************** */
1644 /* new mesh undo, based on pushing editmesh data itself */
1645 /* reuses same code as for global and curve undo... unify that (ton) */
1647 /* only one 'hack', to save memory it doesn't store the first push, but does a remake editmesh */
1649 /* a compressed version of editmesh data */
1651 typedef struct EditVertC
1660 typedef struct EditEdgeC
1663 unsigned char f, h, seam, sharp, pad;
1664 short crease, bweight, fgoni;
1667 typedef struct EditFaceC
1670 unsigned char flag, f, h, fgonf, pad1;
1674 typedef struct EditSelectionC{
1679 typedef struct UndoMesh {
1683 EditSelectionC *selected;
1684 int totvert, totedge, totface, totsel;
1686 RetopoPaintData *retopo_paint_data;
1688 CustomData vdata, edata, fdata;
1693 static void free_undoMesh(void *umv)
1697 if(um->verts) MEM_freeN(um->verts);
1698 if(um->edges) MEM_freeN(um->edges);
1699 if(um->faces) MEM_freeN(um->faces);
1700 if(um->selected) MEM_freeN(um->selected);
1701 // XXX if(um->retopo_paint_data) retopo_free_paint_data(um->retopo_paint_data);
1702 CustomData_free(&um->vdata, um->totvert);
1703 CustomData_free(&um->edata, um->totedge);
1704 CustomData_free(&um->fdata, um->totface);
1708 static void *editMesh_to_undoMesh(void *emv)
1710 EditMesh *em= (EditMesh *)emv;
1716 EditVertC *evec=NULL;
1717 EditEdgeC *eedc=NULL;
1718 EditFaceC *efac=NULL;
1719 EditSelectionC *esec=NULL;
1722 um= MEM_callocN(sizeof(UndoMesh), "undomesh");
1724 um->selectmode = em->selectmode;
1726 for(eve=em->verts.first; eve; eve= eve->next) um->totvert++;
1727 for(eed=em->edges.first; eed; eed= eed->next) um->totedge++;
1728 for(efa=em->faces.first; efa; efa= efa->next) um->totface++;
1729 for(ese=em->selected.first; ese; ese=ese->next) um->totsel++;
1732 if(um->totvert) evec= um->verts= MEM_callocN(um->totvert*sizeof(EditVertC), "allvertsC");
1733 if(um->totedge) eedc= um->edges= MEM_callocN(um->totedge*sizeof(EditEdgeC), "alledgesC");
1734 if(um->totface) efac= um->faces= MEM_callocN(um->totface*sizeof(EditFaceC), "allfacesC");
1735 if(um->totsel) esec= um->selected= MEM_callocN(um->totsel*sizeof(EditSelectionC), "allselections");
1737 if(um->totvert) CustomData_copy(&em->vdata, &um->vdata, CD_MASK_EDITMESH, CD_CALLOC, um->totvert);
1738 if(um->totedge) CustomData_copy(&em->edata, &um->edata, CD_MASK_EDITMESH, CD_CALLOC, um->totedge);
1739 if(um->totface) CustomData_copy(&em->fdata, &um->fdata, CD_MASK_EDITMESH, CD_CALLOC, um->totface);
1741 /* now copy vertices */
1743 for(eve=em->verts.first; eve; eve= eve->next, evec++, a++) {
1744 VECCOPY(evec->co, eve->co);
1745 VECCOPY(evec->no, eve->no);
1749 evec->keyindex= eve->keyindex;
1750 eve->tmp.l = a; /*store index*/
1751 evec->bweight= (short)(eve->bweight*255.0);
1753 CustomData_from_em_block(&em->vdata, &um->vdata, eve->data, a);
1758 for(eed=em->edges.first; eed; eed= eed->next, eedc++, a++) {
1759 eedc->v1= (int)eed->v1->tmp.l;
1760 eedc->v2= (int)eed->v2->tmp.l;
1763 eedc->seam= eed->seam;
1764 eedc->sharp= eed->sharp;
1765 eedc->crease= (short)(eed->crease*255.0);
1766 eedc->bweight= (short)(eed->bweight*255.0);
1767 eedc->fgoni= eed->fgoni;
1768 eed->tmp.l = a; /*store index*/
1769 CustomData_from_em_block(&em->edata, &um->edata, eed->data, a);
1775 for(efa=em->faces.first; efa; efa= efa->next, efac++, a++) {
1776 efac->v1= (int)efa->v1->tmp.l;
1777 efac->v2= (int)efa->v2->tmp.l;
1778 efac->v3= (int)efa->v3->tmp.l;
1779 if(efa->v4) efac->v4= (int)efa->v4->tmp.l;
1782 efac->mat_nr= efa->mat_nr;
1783 efac->flag= efa->flag;
1786 efac->fgonf= efa->fgonf;
1788 efa->tmp.l = a; /*store index*/
1790 CustomData_from_em_block(&em->fdata, &um->fdata, efa->data, a);
1794 for(ese=em->selected.first; ese; ese=ese->next, esec++){
1795 esec->type = ese->type;
1796 if(ese->type == EDITVERT) a = esec->index = ((EditVert*)ese->data)->tmp.l;
1797 else if(ese->type == EDITEDGE) a = esec->index = ((EditEdge*)ese->data)->tmp.l;
1798 else if(ese->type == EDITFACE) a = esec->index = ((EditFace*)ese->data)->tmp.l;
1801 // XXX um->retopo_paint_data= retopo_paint_data_copy(em->retopo_paint_data);
1802 // um->retopo_mode= scene->toolsettings->retopo_mode;
1807 static void undoMesh_to_editMesh(void *umv, void *emv)
1809 EditMesh *em= (EditMesh *)emv;
1810 UndoMesh *um= (UndoMesh *)umv;
1811 EditVert *eve, **evar=NULL;
1818 EditSelectionC *esec;
1824 memset(em, 0, sizeof(EditMesh));
1826 em->selectmode = um->selectmode;
1828 init_editmesh_fastmalloc(em, um->totvert, um->totedge, um->totface);
1830 CustomData_free(&em->vdata, 0);
1831 CustomData_free(&em->edata, 0);
1832 CustomData_free(&em->fdata, 0);
1834 CustomData_copy(&um->vdata, &em->vdata, CD_MASK_EDITMESH, CD_CALLOC, 0);
1835 CustomData_copy(&um->edata, &em->edata, CD_MASK_EDITMESH, CD_CALLOC, 0);
1836 CustomData_copy(&um->fdata, &em->fdata, CD_MASK_EDITMESH, CD_CALLOC, 0);
1838 /* now copy vertices */
1840 if(um->totvert) evar= MEM_mallocN(um->totvert*sizeof(EditVert *), "vertex ar");
1841 for(a=0, evec= um->verts; a<um->totvert; a++, evec++) {
1842 eve= addvertlist(em, evec->co, NULL);
1845 VECCOPY(eve->no, evec->no);
1848 eve->keyindex= evec->keyindex;
1849 eve->bweight= ((float)evec->bweight)/255.0f;
1851 CustomData_to_em_block(&um->vdata, &em->vdata, a, &eve->data);
1855 for(a=0, eedc= um->edges; a<um->totedge; a++, eedc++) {
1856 eed= addedgelist(em, evar[eedc->v1], evar[eedc->v2], NULL);
1860 eed->seam= eedc->seam;
1861 eed->sharp= eedc->sharp;
1862 eed->fgoni= eedc->fgoni;
1863 eed->crease= ((float)eedc->crease)/255.0f;
1864 eed->bweight= ((float)eedc->bweight)/255.0f;
1865 CustomData_to_em_block(&um->edata, &em->edata, a, &eed->data);
1869 for(a=0, efac= um->faces; a<um->totface; a++, efac++) {
1871 efa= addfacelist(em, evar[efac->v1], evar[efac->v2], evar[efac->v3], evar[efac->v4], NULL, NULL);
1873 efa= addfacelist(em, evar[efac->v1], evar[efac->v2], evar[efac->v3], NULL, NULL ,NULL);
1875 efa->mat_nr= efac->mat_nr;
1876 efa->flag= efac->flag;
1879 efa->fgonf= efac->fgonf;
1881 CustomData_to_em_block(&um->fdata, &em->fdata, a, &efa->data);
1884 end_editmesh_fastmalloc();
1885 if(evar) MEM_freeN(evar);
1887 em->totvert = um->totvert;
1888 em->totedge = um->totedge;
1889 em->totface = um->totface;
1890 /*restore stored editselections*/
1892 EM_init_index_arrays(em, 1,1,1);
1893 for(a=0, esec= um->selected; a<um->totsel; a++, esec++){
1894 ese = MEM_callocN(sizeof(EditSelection), "Edit Selection");
1895 ese->type = esec->type;
1896 if(ese->type == EDITVERT) ese->data = EM_get_vert_for_index(esec->index); else
1897 if(ese->type == EDITEDGE) ese->data = EM_get_edge_for_index(esec->index); else
1898 if(ese->type == EDITFACE) ese->data = EM_get_face_for_index(esec->index);
1899 BLI_addtail(&(em->selected),ese);
1901 EM_free_index_arrays();
1904 // XXX retopo_free_paint();
1905 // em->retopo_paint_data= retopo_paint_data_copy(um->retopo_paint_data);
1906 // scene->toolsettings->retopo_mode= um->retopo_mode;
1907 // if(scene->toolsettings->retopo_mode) {
1908 // XXX if(G.vd->depths) G.vd->depths->damaged= 1;
1909 // retopo_queue_updates(G.vd);
1910 // retopo_paint_view_update(G.vd);
1915 static void *getEditMesh(bContext *C)
1917 Object *obedit= CTX_data_edit_object(C);
1918 if(obedit && obedit->type==OB_MESH) {
1919 Mesh *me= obedit->data;
1920 return me->edit_mesh;
1925 /* and this is all the undo system needs to know */
1926 void undo_push_mesh(bContext *C, char *name)
1928 undo_editmode_push(C, name, getEditMesh, free_undoMesh, undoMesh_to_editMesh, editMesh_to_undoMesh, NULL);
1933 /* *************** END UNDO *************/
1935 static EditVert **g_em_vert_array = NULL;
1936 static EditEdge **g_em_edge_array = NULL;
1937 static EditFace **g_em_face_array = NULL;
1939 void EM_init_index_arrays(EditMesh *em, int forVert, int forEdge, int forFace)
1947 em->totvert= BLI_countlist(&em->verts);
1950 g_em_vert_array = MEM_mallocN(sizeof(*g_em_vert_array)*em->totvert, "em_v_arr");
1952 for (i=0,eve=em->verts.first; eve; i++,eve=eve->next)
1953 g_em_vert_array[i] = eve;
1958 em->totedge= BLI_countlist(&em->edges);
1961 g_em_edge_array = MEM_mallocN(sizeof(*g_em_edge_array)*em->totedge, "em_e_arr");
1963 for (i=0,eed=em->edges.first; eed; i++,eed=eed->next)
1964 g_em_edge_array[i] = eed;
1969 em->totface= BLI_countlist(&em->faces);
1972 g_em_face_array = MEM_mallocN(sizeof(*g_em_face_array)*em->totface, "em_f_arr");
1974 for (i=0,efa=em->faces.first; efa; i++,efa=efa->next)
1975 g_em_face_array[i] = efa;
1980 void EM_free_index_arrays(void)
1982 if (g_em_vert_array) MEM_freeN(g_em_vert_array);
1983 if (g_em_edge_array) MEM_freeN(g_em_edge_array);
1984 if (g_em_face_array) MEM_freeN(g_em_face_array);
1985 g_em_vert_array = NULL;
1986 g_em_edge_array = NULL;
1987 g_em_face_array = NULL;
1990 EditVert *EM_get_vert_for_index(int index)
1992 return g_em_vert_array?g_em_vert_array[index]:NULL;
1995 EditEdge *EM_get_edge_for_index(int index)
1997 return g_em_edge_array?g_em_edge_array[index]:NULL;
2000 EditFace *EM_get_face_for_index(int index)
2002 return g_em_face_array?g_em_face_array[index]:NULL;
2005 /* can we edit UV's for this mesh?*/
2006 int EM_texFaceCheck(EditMesh *em)
2008 /* some of these checks could be a touch overkill */
2010 (em->faces.first) &&
2011 (CustomData_has_layer(&em->fdata, CD_MTFACE)))
2016 /* can we edit colors for this mesh?*/
2017 int EM_vertColorCheck(EditMesh *em)
2019 /* some of these checks could be a touch overkill */
2021 (em->faces.first) &&
2022 (CustomData_has_layer(&em->fdata, CD_MCOL)))
2028 void em_setup_viewcontext(bContext *C, ViewContext *vc)
2030 view3d_set_viewcontext(C, vc);
2033 Mesh *me= vc->obedit->data;
2034 vc->em= me->edit_mesh;