Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/src/editmesh.c')
-rw-r--r--source/blender/src/editmesh.c2374
1 files changed, 0 insertions, 2374 deletions
diff --git a/source/blender/src/editmesh.c b/source/blender/src/editmesh.c
deleted file mode 100644
index a573ea85ca8..00000000000
--- a/source/blender/src/editmesh.c
+++ /dev/null
@@ -1,2374 +0,0 @@
-/**
- * $Id$
- *
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "MEM_guardedalloc.h"
-
-#include "PIL_time.h"
-
-#include "DNA_customdata_types.h"
-#include "DNA_mesh_types.h"
-#include "DNA_meshdata_types.h"
-#include "DNA_object_types.h"
-#include "DNA_object_force.h"
-#include "DNA_screen_types.h"
-#include "DNA_key_types.h"
-#include "DNA_scene_types.h"
-#include "DNA_view3d_types.h"
-#include "DNA_material_types.h"
-#include "DNA_modifier_types.h"
-#include "DNA_texture_types.h"
-#include "DNA_userdef_types.h"
-
-#include "BLI_blenlib.h"
-#include "BLI_arithb.h"
-#include "BLI_editVert.h"
-#include "BLI_dynstr.h"
-#include "BLI_rand.h"
-
-#include "BKE_DerivedMesh.h"
-#include "BKE_depsgraph.h"
-#include "BKE_cloth.h"
-#include "BKE_customdata.h"
-#include "BKE_global.h"
-#include "BKE_key.h"
-#include "BKE_library.h"
-#include "BKE_main.h"
-#include "BKE_material.h"
-#include "BKE_mesh.h"
-#include "BKE_modifier.h"
-#include "BKE_multires.h"
-#include "BKE_object.h"
-#include "BKE_pointcache.h"
-#include "BKE_softbody.h"
-#include "BKE_texture.h"
-#include "BKE_utildefines.h"
-
-#ifdef WITH_VERSE
-#include "BKE_verse.h"
-#endif
-
-#include "BIF_editkey.h"
-#include "BIF_editmesh.h"
-#include "BIF_editmode_undo.h"
-#include "BIF_interface.h"
-#include "BIF_meshtools.h"
-#include "BIF_mywindow.h"
-#include "BIF_retopo.h"
-#include "BIF_space.h"
-#include "BIF_screen.h"
-#include "BIF_toolbox.h"
-
-#ifdef WITH_VERSE
-#include "BIF_verse.h"
-#endif
-
-#include "BSE_view.h"
-#include "BSE_edit.h"
-#include "BSE_trans_types.h"
-
-#include "BDR_drawobject.h"
-#include "BDR_editobject.h"
-#include "BDR_editface.h"
-#include "BDR_vpaint.h"
-
-#include "LBM_fluidsim.h"
-
-#include "multires.h"
-#include "mydevice.h"
-#include "blendef.h"
-
-/* own include */
-#include "editmesh.h"
-
-/*
-
-editmesh.c:
-- add/alloc/free data
-- hashtables
-- enter/exit editmode
-
-*/
-
-
-/* ***************** HASH ********************* */
-
-
-#define EDHASHSIZE (512*512)
-#define EDHASH(a, b) (a % EDHASHSIZE)
-
-
-/* ************ ADD / REMOVE / FIND ****************** */
-
-/* used to bypass normal calloc with fast one */
-static void *(*callocvert)(size_t, size_t) = calloc;
-static void *(*callocedge)(size_t, size_t) = calloc;
-static void *(*callocface)(size_t, size_t) = calloc;
-
-EditVert *addvertlist(float *vec, EditVert *example)
-{
- EditMesh *em = G.editMesh;
- EditVert *eve;
- static int hashnr= 0;
-
- eve= callocvert(sizeof(EditVert), 1);
- BLI_addtail(&em->verts, eve);
-
- if(vec) VECCOPY(eve->co, vec);
-
- eve->hash= hashnr++;
- if( hashnr>=EDHASHSIZE) hashnr= 0;
-
- /* new verts get keyindex of -1 since they did not
- * have a pre-editmode vertex order
- */
- eve->keyindex = -1;
-#ifdef WITH_VERSE
- createVerseVert(eve);
-#endif
-
- if(example) {
- CustomData_em_copy_data(&em->vdata, &em->vdata, example->data, &eve->data);
- eve->bweight = example->bweight;
- }
- else {
- CustomData_em_set_default(&em->vdata, &eve->data);
- }
-
- return eve;
-}
-
-void free_editvert (EditVert *eve)
-{
-#ifdef WITH_VERSE
- if(eve->vvert) {
- /* it prevents from removing all verse vertexes
- * during entering edit mode ... messy solution */
- if(G.editMesh->vnode)
- b_verse_send_vertex_delete(eve);
- else
- ((VerseVert*)eve->vvert)->vertex = NULL;
- }
-#endif
-
- EM_remove_selection(eve, EDITVERT);
- CustomData_em_free_block(&G.editMesh->vdata, &eve->data);
- if(eve->fast==0)
- free(eve);
-}
-
-
-EditEdge *findedgelist(EditVert *v1, EditVert *v2)
-{
- EditVert *v3;
- struct HashEdge *he;
-
- /* swap ? */
- if( v1 > v2) {
- v3= v2;
- v2= v1;
- v1= v3;
- }
-
- if(G.editMesh->hashedgetab==NULL)
- G.editMesh->hashedgetab= MEM_callocN(EDHASHSIZE*sizeof(struct HashEdge), "hashedgetab");
-
- he= G.editMesh->hashedgetab + EDHASH(v1->hash, v2->hash);
-
- while(he) {
-
- if(he->eed && he->eed->v1==v1 && he->eed->v2==v2) return he->eed;
-
- he= he->next;
- }
- return 0;
-}
-
-static void insert_hashedge(EditEdge *eed)
-{
- /* assuming that eed is not in the list yet, and that a find has been done before */
-
- struct HashEdge *first, *he;
-
- first= G.editMesh->hashedgetab + EDHASH(eed->v1->hash, eed->v2->hash);
-
- if( first->eed==0 ) {
- first->eed= eed;
- }
- else {
- he= &eed->hash;
- he->eed= eed;
- he->next= first->next;
- first->next= he;
- }
-}
-
-static void remove_hashedge(EditEdge *eed)
-{
- /* assuming eed is in the list */
-
- struct HashEdge *first, *he, *prev=NULL;
-
- he=first= G.editMesh->hashedgetab + EDHASH(eed->v1->hash, eed->v2->hash);
-
- while(he) {
- if(he->eed == eed) {
- /* remove from list */
- if(he==first) {
- if(first->next) {
- he= first->next;
- first->eed= he->eed;
- first->next= he->next;
- }
- else he->eed= 0;
- }
- else {
- prev->next= he->next;
- }
- return;
- }
- prev= he;
- he= he->next;
- }
-}
-
-EditEdge *addedgelist(EditVert *v1, EditVert *v2, EditEdge *example)
-{
- EditMesh *em = G.editMesh;
- EditVert *v3;
- EditEdge *eed;
- int swap= 0;
-
- if(v1==v2) return NULL;
- if(v1==NULL || v2==NULL) return NULL;
-
- /* swap ? */
- if(v1>v2) {
- v3= v2;
- v2= v1;
- v1= v3;
- swap= 1;
- }
-
- /* find in hashlist */
- eed= findedgelist(v1, v2);
-
- if(eed==NULL) {
-
- eed= (EditEdge *)callocedge(sizeof(EditEdge), 1);
- eed->v1= v1;
- eed->v2= v2;
- BLI_addtail(&em->edges, eed);
- eed->dir= swap;
- insert_hashedge(eed);
-
- /* copy edge data:
- rule is to do this with addedgelist call, before addfacelist */
- if(example) {
- eed->crease= example->crease;
- eed->bweight= example->bweight;
- eed->sharp = example->sharp;
- eed->seam = example->seam;
- eed->h |= (example->h & EM_FGON);
- }
- }
-
- return eed;
-}
-
-void remedge(EditEdge *eed)
-{
- EditMesh *em = G.editMesh;
-
- BLI_remlink(&em->edges, eed);
- remove_hashedge(eed);
-}
-
-void free_editedge(EditEdge *eed)
-{
- EM_remove_selection(eed, EDITEDGE);
- if(eed->fast==0){
- free(eed);
- }
-}
-
-void free_editface(EditFace *efa)
-{
-#ifdef WITH_VERSE
- if(efa->vface) {
- /* it prevents from removing all verse faces
- * during entering edit mode ... messy solution */
- if(G.editMesh->vnode)
- b_verse_send_face_delete(efa);
- else
- ((VerseFace*)efa->vface)->face = NULL;
- }
-#endif
- EM_remove_selection(efa, EDITFACE);
-
- if (G.editMesh->act_face==efa) {
- EM_set_actFace( G.editMesh->faces.first == efa ? NULL : G.editMesh->faces.first);
- }
-
- CustomData_em_free_block(&G.editMesh->fdata, &efa->data);
- if(efa->fast==0)
- free(efa);
-}
-
-void free_vertlist(ListBase *edve)
-{
- EditVert *eve, *next;
-
- if (!edve) return;
-
- eve= edve->first;
- while(eve) {
- next= eve->next;
- free_editvert(eve);
- eve= next;
- }
- edve->first= edve->last= NULL;
-}
-
-void free_edgelist(ListBase *lb)
-{
- EditEdge *eed, *next;
-
- eed= lb->first;
- while(eed) {
- next= eed->next;
- free_editedge(eed);
- eed= next;
- }
- lb->first= lb->last= NULL;
-}
-
-void free_facelist(ListBase *lb)
-{
- EditFace *efa, *next;
-
- efa= lb->first;
- while(efa) {
- next= efa->next;
- free_editface(efa);
- efa= next;
- }
- lb->first= lb->last= NULL;
-}
-
-EditFace *addfacelist(EditVert *v1, EditVert *v2, EditVert *v3, EditVert *v4, EditFace *example, EditFace *exampleEdges)
-{
- EditMesh *em = G.editMesh;
- EditFace *efa;
- EditEdge *e1, *e2=0, *e3=0, *e4=0;
-
- /* added sanity check... seems to happen for some tools, or for enter editmode for corrupted meshes */
- if(v1==v4 || v2==v4 || v3==v4) v4= NULL;
-
- /* add face to list and do the edges */
- if(exampleEdges) {
- e1= addedgelist(v1, v2, exampleEdges->e1);
- e2= addedgelist(v2, v3, exampleEdges->e2);
- if(v4) e3= addedgelist(v3, v4, exampleEdges->e3);
- else e3= addedgelist(v3, v1, exampleEdges->e3);
- if(v4) e4= addedgelist(v4, v1, exampleEdges->e4);
- }
- else {
- e1= addedgelist(v1, v2, NULL);
- e2= addedgelist(v2, v3, NULL);
- if(v4) e3= addedgelist(v3, v4, NULL);
- else e3= addedgelist(v3, v1, NULL);
- if(v4) e4= addedgelist(v4, v1, NULL);
- }
-
- if(v1==v2 || v2==v3 || v1==v3) return NULL;
- if(e2==0) return NULL;
-
- efa= (EditFace *)callocface(sizeof(EditFace), 1);
- efa->v1= v1;
- efa->v2= v2;
- efa->v3= v3;
- efa->v4= v4;
-
- efa->e1= e1;
- efa->e2= e2;
- efa->e3= e3;
- efa->e4= e4;
-
- if(example) {
- efa->mat_nr= example->mat_nr;
- efa->flag= example->flag;
- CustomData_em_copy_data(&em->fdata, &em->fdata, example->data, &efa->data);
- }
- else {
- if (G.obedit && G.obedit->actcol)
- efa->mat_nr= G.obedit->actcol-1;
-
- CustomData_em_set_default(&em->fdata, &efa->data);
- }
-
- BLI_addtail(&em->faces, efa);
-
- if(efa->v4) {
- CalcNormFloat4(efa->v1->co, efa->v2->co, efa->v3->co, efa->v4->co, efa->n);
- CalcCent4f(efa->cent, efa->v1->co, efa->v2->co, efa->v3->co, efa->v4->co);
- }
- else {
- CalcNormFloat(efa->v1->co, efa->v2->co, efa->v3->co, efa->n);
- CalcCent3f(efa->cent, efa->v1->co, efa->v2->co, efa->v3->co);
- }
-
-#ifdef WITH_VERSE
- createVerseFace(efa);
-#endif
-
- return efa;
-}
-
-/* ************************ end add/new/find ************ */
-
-/* ************************ Edit{Vert,Edge,Face} utilss ***************************** */
-
-/* some nice utility functions */
-
-EditVert *editedge_getOtherVert(EditEdge *eed, EditVert *eve)
-{
- if (eve==eed->v1) {
- return eed->v2;
- } else if (eve==eed->v2) {
- return eed->v1;
- } else {
- return NULL;
- }
-}
-
-EditVert *editedge_getSharedVert(EditEdge *eed, EditEdge *eed2)
-{
- if (eed->v1==eed2->v1 || eed->v1==eed2->v2) {
- return eed->v1;
- } else if (eed->v2==eed2->v1 || eed->v2==eed2->v2) {
- return eed->v2;
- } else {
- return NULL;
- }
-}
-
-int editedge_containsVert(EditEdge *eed, EditVert *eve)
-{
- return (eed->v1==eve || eed->v2==eve);
-}
-
-int editface_containsVert(EditFace *efa, EditVert *eve)
-{
- return (efa->v1==eve || efa->v2==eve || efa->v3==eve || (efa->v4 && efa->v4==eve));
-}
-
-int editface_containsEdge(EditFace *efa, EditEdge *eed)
-{
- return (efa->e1==eed || efa->e2==eed || efa->e3==eed || (efa->e4 && efa->e4==eed));
-}
-
-
-/* ************************ stuct EditMesh manipulation ***************************** */
-
-/* fake callocs for fastmalloc below */
-static void *calloc_fastvert(size_t size, size_t nr)
-{
- EditVert *eve= G.editMesh->curvert++;
- eve->fast= 1;
- return eve;
-}
-static void *calloc_fastedge(size_t size, size_t nr)
-{
- EditEdge *eed= G.editMesh->curedge++;
- eed->fast= 1;
- return eed;
-}
-static void *calloc_fastface(size_t size, size_t nr)
-{
- EditFace *efa= G.editMesh->curface++;
- efa->fast= 1;
- return efa;
-}
-
-/* allocate 1 chunk for all vertices, edges, faces. These get tagged to
- prevent it from being freed
-*/
-static void init_editmesh_fastmalloc(EditMesh *em, int totvert, int totedge, int totface)
-{
- if(totvert) em->allverts= MEM_callocN(totvert*sizeof(EditVert), "allverts");
- else em->allverts= NULL;
- em->curvert= em->allverts;
-
- if(totedge==0) totedge= 4*totface; // max possible
-
- if(totedge) em->alledges= MEM_callocN(totedge*sizeof(EditEdge), "alledges");
- else em->alledges= NULL;
- em->curedge= em->alledges;
-
- if(totface) em->allfaces= MEM_callocN(totface*sizeof(EditFace), "allfaces");
- else em->allfaces= NULL;
- em->curface= em->allfaces;
-
- callocvert= calloc_fastvert;
- callocedge= calloc_fastedge;
- callocface= calloc_fastface;
-}
-
-static void end_editmesh_fastmalloc(void)
-{
- callocvert= calloc;
- callocedge= calloc;
- callocface= calloc;
-}
-
-void free_editMesh(EditMesh *em)
-{
-#ifdef WITH_VERSE
- struct VNode *vnode=NULL;
-#endif
- if(em==NULL) return;
-
-#ifdef WITH_VERSE
- if(em->vnode) {
- vnode = (VNode*)em->vnode;
- em->vnode = NULL;
- }
-#endif
-
- if(em->verts.first) free_vertlist(&em->verts);
- if(em->edges.first) free_edgelist(&em->edges);
- if(em->faces.first) free_facelist(&em->faces);
- if(em->selected.first) BLI_freelistN(&(em->selected));
-
- CustomData_free(&em->vdata, 0);
- CustomData_free(&em->fdata, 0);
-
- if(em->derivedFinal) {
- if (em->derivedFinal!=em->derivedCage) {
- em->derivedFinal->needsFree= 1;
- em->derivedFinal->release(em->derivedFinal);
- }
- em->derivedFinal= NULL;
- }
- if(em->derivedCage) {
- em->derivedCage->needsFree= 1;
- em->derivedCage->release(em->derivedCage);
- em->derivedCage= NULL;
- }
-
-#ifdef WITH_VERSE
- if(vnode) {
- em->vnode = (void*)vnode;
- }
-#endif
-
- /* DEBUG: hashtabs are slowest part of enter/exit editmode. here a testprint */
-#if 0
- if(em->hashedgetab) {
- HashEdge *he, *hen;
- int a, used=0, max=0, nr;
- he= em->hashedgetab;
- for(a=0; a<EDHASHSIZE; a++, he++) {
- if(he->eed) used++;
- hen= he->next;
- nr= 0;
- while(hen) {
- nr++;
- hen= hen->next;
- }
- if(max<nr) max= nr;
- }
- printf("hastab used %d max %d\n", used, max);
- }
-#endif
- if(em->hashedgetab) MEM_freeN(em->hashedgetab);
- em->hashedgetab= NULL;
-
- if(em->allverts) MEM_freeN(em->allverts);
- if(em->alledges) MEM_freeN(em->alledges);
- if(em->allfaces) MEM_freeN(em->allfaces);
-
- em->allverts= em->curvert= NULL;
- em->alledges= em->curedge= NULL;
- em->allfaces= em->curface= NULL;
-
- mesh_octree_table(NULL, NULL, 'e');
-
- G.totvert= G.totface= 0;
-
- if(em->retopo_paint_data) retopo_free_paint_data(em->retopo_paint_data);
- em->retopo_paint_data= NULL;
- em->act_face = NULL;
-}
-
-/* on G.editMesh */
-static void editMesh_set_hash(void)
-{
- EditEdge *eed;
-
- G.editMesh->hashedgetab= NULL;
-
- for(eed=G.editMesh->edges.first; eed; eed= eed->next) {
- if( findedgelist(eed->v1, eed->v2)==NULL )
- insert_hashedge(eed);
- }
-
-}
-
-
-/* ************************ IN & OUT EDITMODE ***************************** */
-
-
-static void edge_normal_compare(EditEdge *eed, EditFace *efa1)
-{
- EditFace *efa2;
- float cent1[3], cent2[3];
- float inp;
-
- efa2 = eed->tmp.f;
- if(efa1==efa2) return;
-
- inp= efa1->n[0]*efa2->n[0] + efa1->n[1]*efa2->n[1] + efa1->n[2]*efa2->n[2];
- if(inp<0.999 && inp >-0.999) eed->f2= 1;
-
- if(efa1->v4) CalcCent4f(cent1, efa1->v1->co, efa1->v2->co, efa1->v3->co, efa1->v4->co);
- else CalcCent3f(cent1, efa1->v1->co, efa1->v2->co, efa1->v3->co);
- if(efa2->v4) CalcCent4f(cent2, efa2->v1->co, efa2->v2->co, efa2->v3->co, efa2->v4->co);
- else CalcCent3f(cent2, efa2->v1->co, efa2->v2->co, efa2->v3->co);
-
- VecSubf(cent1, cent2, cent1);
- Normalize(cent1);
- inp= cent1[0]*efa1->n[0] + cent1[1]*efa1->n[1] + cent1[2]*efa1->n[2];
-
- if(inp < -0.001 ) eed->f1= 1;
-}
-
-#if 0
-typedef struct {
- EditEdge *eed;
- float noLen,no[3];
- int adjCount;
-} EdgeDrawFlagInfo;
-
-static int edgeDrawFlagInfo_cmp(const void *av, const void *bv)
-{
- const EdgeDrawFlagInfo *a = av;
- const EdgeDrawFlagInfo *b = bv;
-
- if (a->noLen<b->noLen) return -1;
- else if (a->noLen>b->noLen) return 1;
- else return 0;
-}
-#endif
-
-static void edge_drawflags(void)
-{
- EditMesh *em = G.editMesh;
- EditVert *eve;
- EditEdge *eed, *e1, *e2, *e3, *e4;
- EditFace *efa;
-
- /* - count number of times edges are used in faces: 0 en 1 time means draw edge
- * - edges more than 1 time used: in *tmp.f is pointer to first face
- * - check all faces, when normal differs to much: draw (flag becomes 1)
- */
-
- /* later on: added flags for 'cylinder' and 'sphere' intersection tests in old
- game engine (2.04)
- */
-
- recalc_editnormals();
-
- /* init */
- eve= em->verts.first;
- while(eve) {
- eve->f1= 1; /* during test it's set at zero */
- eve= eve->next;
- }
- eed= em->edges.first;
- while(eed) {
- eed->f2= eed->f1= 0;
- eed->tmp.f = 0;
- eed= eed->next;
- }
-
- efa= em->faces.first;
- while(efa) {
- e1= efa->e1;
- e2= efa->e2;
- e3= efa->e3;
- e4= efa->e4;
- if(e1->f2<4) e1->f2+= 1;
- if(e2->f2<4) e2->f2+= 1;
- if(e3->f2<4) e3->f2+= 1;
- if(e4 && e4->f2<4) e4->f2+= 1;
-
- if(e1->tmp.f == 0) e1->tmp.f = (void *) efa;
- if(e2->tmp.f == 0) e2->tmp.f = (void *) efa;
- if(e3->tmp.f ==0) e3->tmp.f = (void *) efa;
- if(e4 && (e4->tmp.f == 0)) e4->tmp.f = (void *) efa;
-
- efa= efa->next;
- }
-
- if(G.f & G_ALLEDGES) {
- efa= em->faces.first;
- while(efa) {
- if(efa->e1->f2>=2) efa->e1->f2= 1;
- if(efa->e2->f2>=2) efa->e2->f2= 1;
- if(efa->e3->f2>=2) efa->e3->f2= 1;
- if(efa->e4 && efa->e4->f2>=2) efa->e4->f2= 1;
-
- efa= efa->next;
- }
- }
- else {
-
- /* handle single-edges for 'test cylinder flag' (old engine) */
-
- eed= em->edges.first;
- while(eed) {
- if(eed->f2==1) eed->f1= 1;
- eed= eed->next;
- }
-
- /* all faces, all edges with flag==2: compare normal */
- efa= em->faces.first;
- while(efa) {
- if(efa->e1->f2==2) edge_normal_compare(efa->e1, efa);
- else efa->e1->f2= 1;
- if(efa->e2->f2==2) edge_normal_compare(efa->e2, efa);
- else efa->e2->f2= 1;
- if(efa->e3->f2==2) edge_normal_compare(efa->e3, efa);
- else efa->e3->f2= 1;
- if(efa->e4) {
- if(efa->e4->f2==2) edge_normal_compare(efa->e4, efa);
- else efa->e4->f2= 1;
- }
- efa= efa->next;
- }
-
- /* sphere collision flag */
-
- eed= em->edges.first;
- while(eed) {
- if(eed->f1!=1) {
- eed->v1->f1= eed->v2->f1= 0;
- }
- eed= eed->next;
- }
-
- }
-}
-
-static int editmesh_pointcache_edit(Object *ob, int totvert, PTCacheID *pid_p, float mat[][4], int load)
-{
- Cloth *cloth;
- SoftBody *sb;
- ClothModifierData *clmd;
- PTCacheID pid, tmpid;
- int cfra= (int)G.scene->r.cfra, found= 0;
-
- pid.cache= NULL;
-
- /* check for cloth */
- if(modifiers_isClothEnabled(ob)) {
- clmd= (ClothModifierData*)modifiers_findByType(ob, eModifierType_Cloth);
- cloth= clmd->clothObject;
-
- BKE_ptcache_id_from_cloth(&tmpid, ob, clmd);
-
- /* verify vertex count and baked status */
- if(cloth && (totvert == cloth->numverts)) {
- if((tmpid.cache->flag & PTCACHE_BAKED) && (tmpid.cache->flag & PTCACHE_BAKE_EDIT)) {
- pid= tmpid;
-
- if(load && (pid.cache->flag & PTCACHE_BAKE_EDIT_ACTIVE))
- found= 1;
- }
- }
- }
-
- /* check for softbody */
- if(!found && ob->soft) {
- sb= ob->soft;
-
- BKE_ptcache_id_from_softbody(&tmpid, ob, sb);
-
- /* verify vertex count and baked status */
- if(sb->bpoint && (totvert == sb->totpoint)) {
- if((tmpid.cache->flag & PTCACHE_BAKED) && (tmpid.cache->flag & PTCACHE_BAKE_EDIT)) {
- pid= tmpid;
-
- if(load && (pid.cache->flag & PTCACHE_BAKE_EDIT_ACTIVE))
- found= 1;
- }
- }
- }
-
- /* if not making editmesh verify editing was active for this point cache */
- if(load) {
- if(found)
- pid.cache->flag &= ~PTCACHE_BAKE_EDIT_ACTIVE;
- else
- return 0;
- }
-
- /* check if we have cache for this frame */
- if(pid.cache && BKE_ptcache_id_exist(&pid, cfra)) {
- *pid_p = pid;
-
- if(load) {
- Mat4CpyMat4(mat, ob->obmat);
- }
- else {
- pid.cache->editframe= cfra;
- pid.cache->flag |= PTCACHE_BAKE_EDIT_ACTIVE;
- Mat4Invert(mat, ob->obmat); /* ob->imat is not up to date */
- }
-
- return 1;
- }
-
- return 0;
-}
-
-/* turns Mesh into editmesh */
-void make_editMesh()
-{
- Mesh *me= G.obedit->data;
- EditMesh *em= G.editMesh;
- MFace *mface;
- MVert *mvert;
- MSelect *mselect;
- KeyBlock *actkey;
- EditVert *eve, **evlist, *eve1, *eve2, *eve3, *eve4;
- EditFace *efa;
- EditEdge *eed;
- EditSelection *ese;
- PTCacheID pid;
- Cloth *cloth;
- SoftBody *sb;
- float cacheco[3], cachemat[4][4], *co;
- int tot, a, cacheedit= 0, eekadoodle= 0;
-
-#ifdef WITH_VERSE
- if(me->vnode){
- create_edit_mesh_from_geom_node(me->vnode);
- return;
- }
-#endif
-
- /* because of reload */
- free_editMesh(em);
-
- em->act_face = NULL;
- G.totvert= tot= me->totvert;
- G.totedge= me->totedge;
- G.totface= me->totface;
-
- if(tot==0) {
- countall();
- return;
- }
-
- /* initialize fastmalloc for editmesh */
- init_editmesh_fastmalloc(em, me->totvert, me->totedge, me->totface);
-
- actkey = ob_get_keyblock(G.obedit);
- if(actkey) {
- strcpy(G.editModeTitleExtra, "(Key) ");
- key_to_mesh(actkey, me);
- tot= actkey->totelem;
- /* undo-ing in past for previous editmode sessions gives corrupt 'keyindex' values */
- undo_editmode_clear();
- }
-
-
- /* make editverts */
- CustomData_copy(&me->vdata, &em->vdata, CD_MASK_EDITMESH, CD_CALLOC, 0);
- mvert= me->mvert;
-
- cacheedit= editmesh_pointcache_edit(G.obedit, tot, &pid, cachemat, 0);
-
- evlist= (EditVert **)MEM_mallocN(tot*sizeof(void *),"evlist");
- for(a=0; a<tot; a++, mvert++) {
-
- if(cacheedit) {
- if(pid.type == PTCACHE_TYPE_CLOTH) {
- cloth= ((ClothModifierData*)pid.data)->clothObject;
- VECCOPY(cacheco, cloth->verts[a].x)
- }
- else if(pid.type == PTCACHE_TYPE_SOFTBODY) {
- sb= (SoftBody*)pid.data;
- VECCOPY(cacheco, sb->bpoint[a].pos)
- }
-
- Mat4MulVecfl(cachemat, cacheco);
- co= cacheco;
- }
- else
- co= mvert->co;
-
- eve= addvertlist(co, NULL);
- evlist[a]= eve;
-
- // face select sets selection in next loop
- if( (FACESEL_PAINT_TEST)==0 )
- eve->f |= (mvert->flag & 1);
-
- if (mvert->flag & ME_HIDE) eve->h= 1;
- eve->no[0]= mvert->no[0]/32767.0;
- eve->no[1]= mvert->no[1]/32767.0;
- eve->no[2]= mvert->no[2]/32767.0;
-
- eve->bweight= ((float)mvert->bweight)/255.0f;
-
- /* lets overwrite the keyindex of the editvert
- * with the order it used to be in before
- * editmode
- */
- eve->keyindex = a;
-
- CustomData_to_em_block(&me->vdata, &em->vdata, a, &eve->data);
- }
-
- if(actkey && actkey->totelem!=me->totvert);
- else {
- MEdge *medge= me->medge;
-
- CustomData_copy(&me->edata, &em->edata, CD_MASK_EDITMESH, CD_CALLOC, 0);
- /* make edges */
- for(a=0; a<me->totedge; a++, medge++) {
- eed= addedgelist(evlist[medge->v1], evlist[medge->v2], NULL);
- /* eed can be zero when v1 and v2 are identical, dxf import does this... */
- if(eed) {
- eed->crease= ((float)medge->crease)/255.0f;
- eed->bweight= ((float)medge->bweight)/255.0f;
-
- if(medge->flag & ME_SEAM) eed->seam= 1;
- if(medge->flag & ME_SHARP) eed->sharp = 1;
- if(medge->flag & SELECT) eed->f |= SELECT;
- if(medge->flag & ME_FGON) eed->h= EM_FGON; // 2 different defines!
- if(medge->flag & ME_HIDE) eed->h |= 1;
- if(G.scene->selectmode==SCE_SELECT_EDGE)
- EM_select_edge(eed, eed->f & SELECT); // force edge selection to vertices, seems to be needed ...
- CustomData_to_em_block(&me->edata,&em->edata, a, &eed->data);
- }
- }
-
- CustomData_copy(&me->fdata, &em->fdata, CD_MASK_EDITMESH, CD_CALLOC, 0);
-
- /* make faces */
- mface= me->mface;
-
- for(a=0; a<me->totface; a++, mface++) {
- eve1= evlist[mface->v1];
- eve2= evlist[mface->v2];
- if(!mface->v3) eekadoodle= 1;
- eve3= evlist[mface->v3];
- if(mface->v4) eve4= evlist[mface->v4]; else eve4= NULL;
-
- efa= addfacelist(eve1, eve2, eve3, eve4, NULL, NULL);
-
- if(efa) {
- CustomData_to_em_block(&me->fdata, &em->fdata, a, &efa->data);
-
- efa->mat_nr= mface->mat_nr;
- efa->flag= mface->flag & ~ME_HIDE;
-
- /* select and hide face flag */
- if(mface->flag & ME_HIDE) {
- efa->h= 1;
- } else {
- if (a==me->act_face) {
- EM_set_actFace(efa);
- }
-
- /* dont allow hidden and selected */
- if(mface->flag & ME_FACE_SEL) {
- efa->f |= SELECT;
-
- if(FACESEL_PAINT_TEST) {
- EM_select_face(efa, 1); /* flush down */
- }
- }
- }
- }
- }
- }
-
- if(eekadoodle)
- error("This Mesh has old style edgecodes, please put it in the bugtracker!");
-
- MEM_freeN(evlist);
-
- end_editmesh_fastmalloc(); // resets global function pointers
-
- if(me->mselect){
- //restore editselections
- EM_init_index_arrays(1,1,1);
- mselect = me->mselect;
-
- for(a=0; a<me->totselect; a++, mselect++){
- /*check if recorded selection is still valid, if so copy into editmesh*/
- 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) ){
- ese = MEM_callocN(sizeof(EditSelection), "Edit Selection");
- ese->type = mselect->type;
- if(ese->type == EDITVERT) ese->data = EM_get_vert_for_index(mselect->index); else
- if(ese->type == EDITEDGE) ese->data = EM_get_edge_for_index(mselect->index); else
- if(ese->type == EDITFACE) ese->data = EM_get_face_for_index(mselect->index);
- BLI_addtail(&(em->selected),ese);
- }
- }
- EM_free_index_arrays();
- }
- /* this creates coherent selections. also needed for older files */
- EM_selectmode_set();
- /* paranoia check to enforce hide rules */
- EM_hide_reset();
- /* sets helper flags which arent saved */
- EM_fgon_flags();
-
- if (EM_get_actFace(0)==NULL) {
- EM_set_actFace( G.editMesh->faces.first ); /* will use the first face, this is so we alwats have an active face */
- }
-
- /* vertex coordinates change with cache edit, need to recalc */
- if(cacheedit)
- recalc_editnormals();
-
- countall();
-}
-
-/* makes Mesh out of editmesh */
-void load_editMesh(void)
-{
- EditMesh *em = G.editMesh;
- Mesh *me= G.obedit->data;
- MVert *mvert, *oldverts;
- MEdge *medge;
- MFace *mface;
- MSelect *mselect;
- EditVert *eve;
- EditFace *efa, *efa_act;
- EditEdge *eed;
- EditSelection *ese;
- SoftBody *sb;
- Cloth *cloth;
- ClothModifierData *clmd;
- PTCacheID pid;
- float *fp, *newkey, *oldkey, nor[3], cacheco[3], cachemat[4][4];
- int i, a, ototvert, totedge=0, cacheedit= 0;
-
-#ifdef WITH_VERSE
- if(em->vnode) {
- struct VNode *vnode = (VNode*)em->vnode;
- ((VGeomData*)vnode->data)->editmesh = NULL;
- em->vnode = NULL;
- }
-#endif
-
- countall();
-
- /* this one also tests of edges are not in faces: */
- /* eed->f2==0: not in face, f2==1: draw it */
- /* eed->f1 : flag for dynaface (cylindertest, old engine) */
- /* eve->f1 : flag for dynaface (sphere test, old engine) */
- /* eve->f2 : being used in vertexnormals */
- edge_drawflags();
-
- eed= em->edges.first;
- while(eed) {
- totedge++;
- eed= eed->next;
- }
-
- /* new Vertex block */
- if(G.totvert==0) mvert= NULL;
- else mvert= MEM_callocN(G.totvert*sizeof(MVert), "loadeditMesh vert");
-
- /* new Edge block */
- if(totedge==0) medge= NULL;
- else medge= MEM_callocN(totedge*sizeof(MEdge), "loadeditMesh edge");
-
- /* new Face block */
- if(G.totface==0) mface= NULL;
- else mface= MEM_callocN(G.totface*sizeof(MFace), "loadeditMesh face");
-
- /* lets save the old verts just in case we are actually working on
- * a key ... we now do processing of the keys at the end */
- oldverts= me->mvert;
- ototvert= me->totvert;
-
- /* don't free this yet */
- CustomData_set_layer(&me->vdata, CD_MVERT, NULL);
-
- /* free custom data */
- CustomData_free(&me->vdata, me->totvert);
- CustomData_free(&me->edata, me->totedge);
- CustomData_free(&me->fdata, me->totface);
-
- /* add new custom data */
- me->totvert= G.totvert;
- me->totedge= totedge;
- me->totface= G.totface;
-
- CustomData_copy(&em->vdata, &me->vdata, CD_MASK_MESH, CD_CALLOC, me->totvert);
- CustomData_copy(&em->edata, &me->edata, CD_MASK_MESH, CD_CALLOC, me->totedge);
- CustomData_copy(&em->fdata, &me->fdata, CD_MASK_MESH, CD_CALLOC, me->totface);
-
- CustomData_add_layer(&me->vdata, CD_MVERT, CD_ASSIGN, mvert, me->totvert);
- CustomData_add_layer(&me->edata, CD_MEDGE, CD_ASSIGN, medge, me->totedge);
- CustomData_add_layer(&me->fdata, CD_MFACE, CD_ASSIGN, mface, me->totface);
- mesh_update_customdata_pointers(me);
-
- /* the vertices, use ->tmp.l as counter */
- eve= em->verts.first;
- a= 0;
-
- /* check for point cache editing */
- cacheedit= editmesh_pointcache_edit(G.obedit, G.totvert, &pid, cachemat, 1);
-
- while(eve) {
- if(cacheedit) {
- if(pid.type == PTCACHE_TYPE_CLOTH) {
- clmd= (ClothModifierData*)pid.data;
- cloth= clmd->clothObject;
-
- /* assign position */
- VECCOPY(cacheco, cloth->verts[a].x)
- VECCOPY(cloth->verts[a].x, eve->co);
- Mat4MulVecfl(cachemat, cloth->verts[a].x);
-
- /* find plausible velocity, not physical correct but gives
- * nicer results when commented */
- VECSUB(cacheco, cloth->verts[a].x, cacheco);
- VecMulf(cacheco, clmd->sim_parms->stepsPerFrame*10.0f);
- VECADD(cloth->verts[a].v, cloth->verts[a].v, cacheco);
- }
- else if(pid.type == PTCACHE_TYPE_SOFTBODY) {
- sb= (SoftBody*)pid.data;
-
- /* assign position */
- VECCOPY(cacheco, sb->bpoint[a].pos)
- VECCOPY(sb->bpoint[a].pos, eve->co);
- Mat4MulVecfl(cachemat, sb->bpoint[a].pos);
-
- /* changing velocity for softbody doesn't seem to give
- * good results? */
-#if 0
- VECSUB(cacheco, sb->bpoint[a].pos, cacheco);
- VecMulf(cacheco, sb->minloops*10.0f);
- VECADD(sb->bpoint[a].vec, sb->bpoint[a].pos, cacheco);
-#endif
- }
-
- if(oldverts)
- VECCOPY(mvert->co, oldverts[a].co)
- }
- else
- VECCOPY(mvert->co, eve->co);
-
- mvert->mat_nr= 255; /* what was this for, halos? */
-
- /* vertex normal */
- VECCOPY(nor, eve->no);
- VecMulf(nor, 32767.0);
- VECCOPY(mvert->no, nor);
-
- /* note: it used to remove me->dvert when it was not in use, cancelled
- that... annoying when you have a fresh vgroup */
- CustomData_from_em_block(&em->vdata, &me->vdata, eve->data, a);
-
- eve->tmp.l = a++; /* counter */
-
- mvert->flag= 0;
- if(eve->f1==1) mvert->flag |= ME_SPHERETEST;
- mvert->flag |= (eve->f & SELECT);
- if (eve->h) mvert->flag |= ME_HIDE;
- mvert->bweight= (char)(255.0*eve->bweight);
-
-#ifdef WITH_VERSE
- if(eve->vvert) {
- ((VerseVert*)eve->vvert)->vertex = NULL;
- eve->vvert = NULL;
- }
-#endif
- eve= eve->next;
- mvert++;
- }
-
- /* write changes to cache */
- if(cacheedit) {
- if(pid.type == PTCACHE_TYPE_CLOTH)
- cloth_write_cache(G.obedit, pid.data, pid.cache->editframe);
- else if(pid.type == PTCACHE_TYPE_SOFTBODY)
- sbWriteCache(G.obedit, pid.cache->editframe);
- }
-
- /* the edges */
- a= 0;
- eed= em->edges.first;
- while(eed) {
- medge->v1= (unsigned int) eed->v1->tmp.l;
- medge->v2= (unsigned int) eed->v2->tmp.l;
-
- medge->flag= (eed->f & SELECT) | ME_EDGERENDER;
- if(eed->f2<2) medge->flag |= ME_EDGEDRAW;
- if(eed->f2==0) medge->flag |= ME_LOOSEEDGE;
- if(eed->sharp) medge->flag |= ME_SHARP;
- if(eed->seam) medge->flag |= ME_SEAM;
- if(eed->h & EM_FGON) medge->flag |= ME_FGON; // different defines yes
- if(eed->h & 1) medge->flag |= ME_HIDE;
-
- medge->crease= (char)(255.0*eed->crease);
- medge->bweight= (char)(255.0*eed->bweight);
- CustomData_from_em_block(&em->edata, &me->edata, eed->data, a);
-
- eed->tmp.l = a++;
-
- medge++;
- eed= eed->next;
- }
-
- /* the faces */
- a = 0;
- efa= em->faces.first;
- efa_act= EM_get_actFace(0);
- i = 0;
- me->act_face = -1;
- while(efa) {
- mface= &((MFace *) me->mface)[i];
-
- mface->v1= (unsigned int) efa->v1->tmp.l;
- mface->v2= (unsigned int) efa->v2->tmp.l;
- mface->v3= (unsigned int) efa->v3->tmp.l;
- if (efa->v4) mface->v4 = (unsigned int) efa->v4->tmp.l;
-
- mface->mat_nr= efa->mat_nr;
-
- mface->flag= efa->flag;
- /* bit 0 of flag is already taken for smooth... */
-
- if(efa->h) {
- mface->flag |= ME_HIDE;
- mface->flag &= ~ME_FACE_SEL;
- } else {
- if(efa->f & 1) mface->flag |= ME_FACE_SEL;
- else mface->flag &= ~ME_FACE_SEL;
- }
-
- /* mat_nr in vertex */
- if(me->totcol>1) {
- mvert= me->mvert+mface->v1;
- if(mvert->mat_nr == (char)255) mvert->mat_nr= mface->mat_nr;
- mvert= me->mvert+mface->v2;
- if(mvert->mat_nr == (char)255) mvert->mat_nr= mface->mat_nr;
- mvert= me->mvert+mface->v3;
- if(mvert->mat_nr == (char)255) mvert->mat_nr= mface->mat_nr;
- if(mface->v4) {
- mvert= me->mvert+mface->v4;
- if(mvert->mat_nr == (char)255) mvert->mat_nr= mface->mat_nr;
- }
- }
-
- /* watch: efa->e1->f2==0 means loose edge */
-
- if(efa->e1->f2==1) {
- efa->e1->f2= 2;
- }
- if(efa->e2->f2==1) {
- efa->e2->f2= 2;
- }
- if(efa->e3->f2==1) {
- efa->e3->f2= 2;
- }
- if(efa->e4 && efa->e4->f2==1) {
- efa->e4->f2= 2;
- }
-
- CustomData_from_em_block(&em->fdata, &me->fdata, efa->data, i);
-
- /* no index '0' at location 3 or 4 */
- test_index_face(mface, &me->fdata, i, efa->v4?4:3);
-
- if (efa_act == efa)
- me->act_face = a;
-
-#ifdef WITH_VERSE
- if(efa->vface) {
- ((VerseFace*)efa->vface)->face = NULL;
- efa->vface = NULL;
- }
-#endif
- efa->tmp.l = a++;
- i++;
- efa= efa->next;
- }
-
- /* patch hook indices and vertex parents */
- {
- Object *ob;
- ModifierData *md;
- EditVert **vertMap = NULL;
- int i,j;
-
- for (ob=G.main->object.first; ob; ob=ob->id.next) {
- if (ob->parent==G.obedit && ELEM(ob->partype, PARVERT1,PARVERT3)) {
-
- /* duplicate code from below, make it function later...? */
- if (!vertMap) {
- vertMap = MEM_callocN(sizeof(*vertMap)*ototvert, "vertMap");
-
- for (eve=em->verts.first; eve; eve=eve->next) {
- if (eve->keyindex!=-1)
- vertMap[eve->keyindex] = eve;
- }
- }
- if(ob->par1 < ototvert) {
- eve = vertMap[ob->par1];
- if(eve) ob->par1= eve->tmp.l;
- }
- if(ob->par2 < ototvert) {
- eve = vertMap[ob->par2];
- if(eve) ob->par2= eve->tmp.l;
- }
- if(ob->par3 < ototvert) {
- eve = vertMap[ob->par3];
- if(eve) ob->par3= eve->tmp.l;
- }
-
- }
- if (ob->data==me) {
- for (md=ob->modifiers.first; md; md=md->next) {
- if (md->type==eModifierType_Hook) {
- HookModifierData *hmd = (HookModifierData*) md;
-
- if (!vertMap) {
- vertMap = MEM_callocN(sizeof(*vertMap)*ototvert, "vertMap");
-
- for (eve=em->verts.first; eve; eve=eve->next) {
- if (eve->keyindex!=-1)
- vertMap[eve->keyindex] = eve;
- }
- }
-
- for (i=j=0; i<hmd->totindex; i++) {
- if(hmd->indexar[i] < ototvert) {
- eve = vertMap[hmd->indexar[i]];
-
- if (eve) {
- hmd->indexar[j++] = eve->tmp.l;
- }
- }
- else j++;
- }
-
- hmd->totindex = j;
- }
- }
- }
- }
-
- if (vertMap) MEM_freeN(vertMap);
- }
-
- /* are there keys? */
- if(me->key) {
- KeyBlock *currkey, *actkey = ob_get_keyblock(G.obedit);
-
- /* Lets reorder the key data so that things line up roughly
- * with the way things were before editmode */
- currkey = me->key->block.first;
- while(currkey) {
-
- fp= newkey= MEM_callocN(me->key->elemsize*G.totvert, "currkey->data");
- oldkey = currkey->data;
-
- eve= em->verts.first;
-
- i = 0;
- mvert = me->mvert;
- while(eve) {
- if (eve->keyindex >= 0 && eve->keyindex < currkey->totelem) { // valid old vertex
- if(currkey == actkey) {
- if (actkey == me->key->refkey) {
- VECCOPY(fp, mvert->co);
- }
- else {
- VECCOPY(fp, mvert->co);
- if(oldverts) {
- VECCOPY(mvert->co, oldverts[eve->keyindex].co);
- }
- }
- }
- else {
- if(oldkey) {
- VECCOPY(fp, oldkey + 3 * eve->keyindex);
- }
- }
- }
- else {
- VECCOPY(fp, mvert->co);
- }
- fp+= 3;
- ++i;
- ++mvert;
- eve= eve->next;
- }
- currkey->totelem= G.totvert;
- if(currkey->data) MEM_freeN(currkey->data);
- currkey->data = newkey;
-
- currkey= currkey->next;
- }
- }
-
- if(oldverts) MEM_freeN(oldverts);
-
- i = 0;
- for(ese=em->selected.first; ese; ese=ese->next) i++;
- me->totselect = i;
- if(i==0) mselect= NULL;
- else mselect= MEM_callocN(i*sizeof(MSelect), "loadeditMesh selections");
-
- if(me->mselect) MEM_freeN(me->mselect);
- me->mselect= mselect;
-
- for(ese=em->selected.first; ese; ese=ese->next){
- mselect->type = ese->type;
- if(ese->type == EDITVERT) mselect->index = ((EditVert*)ese->data)->tmp.l;
- else if(ese->type == EDITEDGE) mselect->index = ((EditEdge*)ese->data)->tmp.l;
- else if(ese->type == EDITFACE) mselect->index = ((EditFace*)ese->data)->tmp.l;
- mselect++;
- }
-
- /* to be sure: clear ->tmp.l pointers */
- eve= em->verts.first;
- while(eve) {
- eve->tmp.l = 0;
- eve= eve->next;
- }
-
- eed= em->edges.first;
- while(eed) {
- eed->tmp.l = 0;
- eed= eed->next;
- }
-
- efa= em->faces.first;
- while(efa) {
- efa->tmp.l = 0;
- efa= efa->next;
- }
-
- /* remake softbody of all users */
- if(me->id.us>1) {
- Base *base;
- for(base= G.scene->base.first; base; base= base->next)
- if(base->object->data==me)
- base->object->recalc |= OB_RECALC_DATA;
- }
-
- mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL);
-}
-
-void remake_editMesh(void)
-{
- make_editMesh();
- allqueue(REDRAWVIEW3D, 0);
- allqueue(REDRAWBUTSOBJECT, 0); /* needed to have nice cloth panels */
- DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
- BIF_undo_push("Undo all changes");
-}
-
-/* *************** (partial exit editmode) *************/
-
-
-void separatemenu(void)
-{
- short event;
-
- if(G.editMesh->verts.first==NULL) return;
-
- event = pupmenu("Separate %t|Selected%x1|All Loose Parts%x2|By Material%x3");
-
- if (event==0) return;
- waitcursor(1);
-
- switch (event) {
- case 1:
- separate_mesh();
- break;
- case 2:
- separate_mesh_loose();
- break;
- case 3:
- separate_material();
- break;
- }
- waitcursor(0);
-}
-
-void separate_material(void)
-{
- EditMesh *em = G.editMesh;
- unsigned char curr_mat;
- Mesh *me;
-
- if(multires_test()) return;
-
- me= get_mesh(G.obedit);
- if(me->key) {
- error("Can't separate with vertex keys");
- return;
- }
-
- if(G.obedit && em) {
- if(G.obedit->type == OB_MESH) {
- for (curr_mat = 1; curr_mat < G.obedit->totcol; ++curr_mat) {
- /* clear selection, we're going to use that to select material group */
- EM_clear_flag_all(SELECT);
- /* select the material */
- editmesh_select_by_material(curr_mat);
- /* and now separate */
- separate_mesh();
- }
- }
- }
-
- countall();
- allqueue(REDRAWVIEW3D, 0);
- DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
-
-}
-
-void separate_mesh(void)
-{
- EditMesh *em = G.editMesh;
- EditMesh emcopy;
- EditVert *eve, *v1;
- EditEdge *eed, *e1;
- EditFace *efa, *vl1;
- Object *oldob;
- Mesh *me, *men;
- Base *base, *oldbase;
- ListBase edve, eded, edvl;
-#ifdef WITH_VERSE
- struct VNode *vnode = NULL;
-#endif
-
- TEST_EDITMESH
- if(multires_test()) return;
-
- waitcursor(1);
-
- me= get_mesh(G.obedit);
- if(me->key) {
- error("Can't separate with vertex keys");
- return;
- }
-
- if(em->selected.first) BLI_freelistN(&(em->selected)); /* clear the selection order */
-
- EM_selectmode_set(); // enforce full consistant selection flags
-
- /* we are going to abuse the system as follows:
- * 1. add a duplicate object: this will be the new one, we remember old pointer
- * 2: then do a split if needed.
- * 3. put apart: all NOT selected verts, edges, faces
- * 4. call load_editMesh(): this will be the new object
- * 5. freelist and get back old verts, edges, facs
- */
-
- /* make only obedit selected */
- base= FIRSTBASE;
- while(base) {
- if(base->lay & G.vd->lay) {
- if(base->object==G.obedit) base->flag |= SELECT;
- else base->flag &= ~SELECT;
- }
- base= base->next;
- }
-
-#ifdef WITH_VERSE
- if(G.editMesh->vnode) {
- vnode = G.editMesh->vnode;
- G.editMesh->vnode = NULL;
- }
-#endif
- /* no test for split, split doesn't split when a loose part is selected */
- /* SPLIT: first make duplicate */
- adduplicateflag(SELECT);
-
-#ifdef WITH_VERSE
- if(vnode) {
- G.editMesh->vnode = vnode;
- }
-#endif
- /* SPLIT: old faces have 3x flag 128 set, delete these ones */
- delfaceflag(128);
-
- /* since we do tricky things with verts/edges/faces, this makes sure all is selected coherent */
- EM_selectmode_set();
-
- /* set apart: everything that is not selected */
- edve.first= edve.last= eded.first= eded.last= edvl.first= edvl.last= 0;
- eve= em->verts.first;
- while(eve) {
- v1= eve->next;
- if((eve->f & SELECT)==0) {
- BLI_remlink(&em->verts, eve);
- BLI_addtail(&edve, eve);
-#ifdef WITH_VERSE
- if(eve->vvert) {
- ((VerseVert*)eve->vvert)->vertex = NULL;
- eve->vvert = NULL;
- }
-#endif
- }
-
- eve= v1;
- }
- eed= em->edges.first;
- while(eed) {
- e1= eed->next;
- if((eed->f & SELECT)==0) {
- BLI_remlink(&em->edges, eed);
- BLI_addtail(&eded, eed);
- }
- eed= e1;
- }
- efa= em->faces.first;
- while(efa) {
- vl1= efa->next;
- if (efa == G.editMesh->act_face && (efa->f & SELECT)) {
- EM_set_actFace(NULL);
- }
-
- if((efa->f & SELECT)==0) {
- BLI_remlink(&em->faces, efa);
- BLI_addtail(&edvl, efa);
-#ifdef WITH_VERSE
- if(efa->vface) {
- ((VerseFace*)efa->vface)->face = NULL;
- efa->vface = NULL;
- }
-#endif
- }
- efa= vl1;
- }
-
- oldob= G.obedit;
- oldbase= BASACT;
-
-#ifdef WITH_VERSE
- if(G.obedit->vnode) {
- vnode = G.obedit->vnode;
- G.obedit->vnode = NULL;
- }
-#endif
- adduplicate(1, 0); /* notrans and a linked duplicate */
-
-#ifdef WITH_VERSE
- if(vnode) {
- G.obedit->vnode = vnode;
- }
-#endif
-
- G.obedit= BASACT->object; /* basact was set in adduplicate() */
-
- men= copy_mesh(me);
- set_mesh(G.obedit, men);
- /* because new mesh is a copy: reduce user count */
- men->id.us--;
-
- load_editMesh();
-
- BASACT->flag &= ~SELECT;
-
- /* we cannot free the original buffer... */
- emcopy= *G.editMesh;
- emcopy.allverts= NULL;
- emcopy.alledges= NULL;
- emcopy.allfaces= NULL;
- emcopy.derivedFinal= emcopy.derivedCage= NULL;
- memset(&emcopy.vdata, 0, sizeof(emcopy.vdata));
- memset(&emcopy.fdata, 0, sizeof(emcopy.fdata));
- free_editMesh(&emcopy);
-
- em->verts= edve;
- em->edges= eded;
- em->faces= edvl;
-
- /* hashedges are freed now, make new! */
- editMesh_set_hash();
-
- DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
- G.obedit= oldob;
- BASACT= oldbase;
- BASACT->flag |= SELECT;
-
- waitcursor(0);
-
- countall();
- allqueue(REDRAWVIEW3D, 0);
- DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
-
-}
-
-void separate_mesh_loose(void)
-{
- EditMesh *em = G.editMesh;
- EditMesh emcopy;
- EditVert *eve, *v1;
- EditEdge *eed, *e1;
- EditFace *efa, *vl1;
- Object *oldob=NULL;
- Mesh *me, *men;
- Base *base, *oldbase;
- ListBase edve, eded, edvl;
- int vertsep=0;
- short done=0, check=1;
-#ifdef WITH_VERSE
- struct VNode *vnode = NULL;
-#endif
-
- me= get_mesh(G.obedit);
-#ifdef WITH_VERSE
- if(me->vnode) {
- error("Can't separate a mesh shared at verse server");
- return;
- }
-#endif
- if(me->key) {
- error("Can't separate a mesh with vertex keys");
- return;
- }
-
- TEST_EDITMESH
- if(multires_test()) return;
- waitcursor(1);
-
- /* we are going to abuse the system as follows:
- * 1. add a duplicate object: this will be the new one, we remember old pointer
- * 2: then do a split if needed.
- * 3. put apart: all NOT selected verts, edges, faces
- * 4. call load_editMesh(): this will be the new object
- * 5. freelist and get back old verts, edges, facs
- */
-
- while(!done){
- vertsep=check=1;
-
- countall();
-
- /* make only obedit selected */
- base= FIRSTBASE;
- while(base) {
- if(base->lay & G.vd->lay) {
- if(base->object==G.obedit) base->flag |= SELECT;
- else base->flag &= ~SELECT;
- }
- base= base->next;
- }
-
- /*--------- Select connected-----------*/
-
- EM_clear_flag_all(SELECT);
-
- /* Select a random vert to start with */
- eve= em->verts.first;
- eve->f |= SELECT;
-
- while(check==1) {
- check= 0;
- eed= em->edges.first;
- while(eed) {
- if(eed->h==0) {
- if(eed->v1->f & SELECT) {
- if( (eed->v2->f & SELECT)==0 ) {
- eed->v2->f |= SELECT;
- vertsep++;
- check= 1;
- }
- }
- else if(eed->v2->f & SELECT) {
- if( (eed->v1->f & SELECT)==0 ) {
- eed->v1->f |= SELECT;
- vertsep++;
- check= SELECT;
- }
- }
- }
- eed= eed->next;
- }
- }
- /*----------End of select connected--------*/
-
-
- /* If the amount of vertices that is about to be split == the total amount
- of verts in the mesh, it means that there is only 1 unconnected object, so we don't have to separate
- */
- if(G.totvert==vertsep) done=1;
- else{
- /* No splitting: select connected goes fine */
-
- EM_select_flush(); // from verts->edges->faces
-
- /* set apart: everything that is not selected */
- edve.first= edve.last= eded.first= eded.last= edvl.first= edvl.last= 0;
- eve= em->verts.first;
- while(eve) {
- v1= eve->next;
- if((eve->f & SELECT)==0) {
- BLI_remlink(&em->verts, eve);
- BLI_addtail(&edve, eve);
-#ifdef WITH_VERSE
- if(eve->vvert) {
- b_verse_send_vertex_delete(eve);
- }
-#endif
- }
- eve= v1;
- }
- eed= em->edges.first;
- while(eed) {
- e1= eed->next;
- if( (eed->f & SELECT)==0 ) {
- BLI_remlink(&em->edges, eed);
- BLI_addtail(&eded, eed);
- }
- eed= e1;
- }
- efa= em->faces.first;
- while(efa) {
- vl1= efa->next;
- if( (efa->f & SELECT)==0 ) {
- BLI_remlink(&em->faces, efa);
- BLI_addtail(&edvl, efa);
-#ifdef WITH_VERSE
- if(efa->vface) {
- b_verse_send_face_delete(efa);
- }
-#endif
- }
- efa= vl1;
- }
-
- oldob= G.obedit;
- oldbase= BASACT;
-
-#ifdef WITH_VERSE
- if(G.obedit->vnode) {
- vnode = G.obedit->vnode;
- G.obedit->vnode = NULL;
- }
-#endif
- adduplicate(1, 0); /* notrans and a linked duplicate*/
-#ifdef WITH_VERSE
- if(vnode) {
- G.obedit->vnode = vnode;
- }
-#endif
-
- G.obedit= BASACT->object; /* basact was set in adduplicate() */
-
- men= copy_mesh(me);
- set_mesh(G.obedit, men);
- /* because new mesh is a copy: reduce user count */
- men->id.us--;
-
- load_editMesh();
-
- BASACT->flag &= ~SELECT;
-
- /* we cannot free the original buffer... */
- emcopy= *G.editMesh;
- emcopy.allverts= NULL;
- emcopy.alledges= NULL;
- emcopy.allfaces= NULL;
- emcopy.derivedFinal= emcopy.derivedCage= NULL;
- memset(&emcopy.vdata, 0, sizeof(emcopy.vdata));
- memset(&emcopy.fdata, 0, sizeof(emcopy.fdata));
- free_editMesh(&emcopy);
-
- em->verts= edve;
- em->edges= eded;
- em->faces= edvl;
-
- /* hashedges are freed now, make new! */
- editMesh_set_hash();
-
- G.obedit= oldob;
- BASACT= oldbase;
- BASACT->flag |= SELECT;
-
- }
- }
-
- /* unselect the vertices that we (ab)used for the separation*/
- EM_clear_flag_all(SELECT);
-
- waitcursor(0);
- countall();
- allqueue(REDRAWVIEW3D, 0);
- DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
-}
-
-/* ******************************************** */
-
-/* *************** UNDO ***************************** */
-/* new mesh undo, based on pushing editmesh data itself */
-/* reuses same code as for global and curve undo... unify that (ton) */
-
-/* only one 'hack', to save memory it doesn't store the first push, but does a remake editmesh */
-
-/* a compressed version of editmesh data */
-
-typedef struct EditVertC
-{
- float no[3];
- float co[3];
- unsigned char f, h;
- short bweight;
- int keyindex;
-} EditVertC;
-
-typedef struct EditEdgeC
-{
- int v1, v2;
- unsigned char f, h, seam, sharp, pad;
- short crease, bweight, fgoni;
-} EditEdgeC;
-
-typedef struct EditFaceC
-{
- int v1, v2, v3, v4;
- unsigned char mat_nr, flag, f, h, fgonf;
- short pad1;
-} EditFaceC;
-
-typedef struct EditSelectionC{
- short type;
- int index;
-}EditSelectionC;
-
-typedef struct EM_MultiresUndo {
- int users;
- Multires *mr;
-} EM_MultiresUndo;
-
-typedef struct UndoMesh {
- EditVertC *verts;
- EditEdgeC *edges;
- EditFaceC *faces;
- EditSelectionC *selected;
- int totvert, totedge, totface, totsel;
- short selectmode;
- RetopoPaintData *retopo_paint_data;
- char retopo_mode;
- CustomData vdata, edata, fdata;
- EM_MultiresUndo *mru;
-} UndoMesh;
-
-/* for callbacks */
-
-static void free_undoMesh(void *umv)
-{
- UndoMesh *um= umv;
-
- if(um->verts) MEM_freeN(um->verts);
- if(um->edges) MEM_freeN(um->edges);
- if(um->faces) MEM_freeN(um->faces);
- if(um->selected) MEM_freeN(um->selected);
- if(um->retopo_paint_data) retopo_free_paint_data(um->retopo_paint_data);
- CustomData_free(&um->vdata, um->totvert);
- CustomData_free(&um->edata, um->totedge);
- CustomData_free(&um->fdata, um->totface);
- if(um->mru) {
- --um->mru->users;
- if(um->mru->users==0) {
- multires_free(um->mru->mr);
- um->mru->mr= NULL;
- MEM_freeN(um->mru);
- }
- }
- MEM_freeN(um);
-}
-
-static void *editMesh_to_undoMesh(void)
-{
- EditMesh *em= G.editMesh;
- UndoMesh *um;
- EditVert *eve;
- EditEdge *eed;
- EditFace *efa;
- EditSelection *ese;
- EditVertC *evec=NULL;
- EditEdgeC *eedc=NULL;
- EditFaceC *efac=NULL;
- EditSelectionC *esec=NULL;
- int a;
-
- um= MEM_callocN(sizeof(UndoMesh), "undomesh");
-
- um->selectmode = G.scene->selectmode;
-
- for(eve=em->verts.first; eve; eve= eve->next) um->totvert++;
- for(eed=em->edges.first; eed; eed= eed->next) um->totedge++;
- for(efa=em->faces.first; efa; efa= efa->next) um->totface++;
- for(ese=em->selected.first; ese; ese=ese->next) um->totsel++;
- /* malloc blocks */
-
- if(um->totvert) evec= um->verts= MEM_callocN(um->totvert*sizeof(EditVertC), "allvertsC");
- if(um->totedge) eedc= um->edges= MEM_callocN(um->totedge*sizeof(EditEdgeC), "alledgesC");
- if(um->totface) efac= um->faces= MEM_callocN(um->totface*sizeof(EditFaceC), "allfacesC");
- if(um->totsel) esec= um->selected= MEM_callocN(um->totsel*sizeof(EditSelectionC), "allselections");
-
- if(um->totvert) CustomData_copy(&em->vdata, &um->vdata, CD_MASK_EDITMESH, CD_CALLOC, um->totvert);
- if(um->totedge) CustomData_copy(&em->edata, &um->edata, CD_MASK_EDITMESH, CD_CALLOC, um->totedge);
- if(um->totface) CustomData_copy(&em->fdata, &um->fdata, CD_MASK_EDITMESH, CD_CALLOC, um->totface);
-
- /* now copy vertices */
- a = 0;
- for(eve=em->verts.first; eve; eve= eve->next, evec++, a++) {
- VECCOPY(evec->co, eve->co);
- VECCOPY(evec->no, eve->no);
-
- evec->f= eve->f;
- evec->h= eve->h;
- evec->keyindex= eve->keyindex;
- eve->tmp.l = a; /*store index*/
- evec->bweight= (short)(eve->bweight*255.0);
-
- CustomData_from_em_block(&em->vdata, &um->vdata, eve->data, a);
- }
-
- /* copy edges */
- a = 0;
- for(eed=em->edges.first; eed; eed= eed->next, eedc++, a++) {
- eedc->v1= (int)eed->v1->tmp.l;
- eedc->v2= (int)eed->v2->tmp.l;
- eedc->f= eed->f;
- eedc->h= eed->h;
- eedc->seam= eed->seam;
- eedc->sharp= eed->sharp;
- eedc->crease= (short)(eed->crease*255.0);
- eedc->bweight= (short)(eed->bweight*255.0);
- eedc->fgoni= eed->fgoni;
- eed->tmp.l = a; /*store index*/
- CustomData_from_em_block(&em->edata, &um->edata, eed->data, a);
-
- }
-
- /* copy faces */
- a = 0;
- for(efa=em->faces.first; efa; efa= efa->next, efac++, a++) {
- efac->v1= (int)efa->v1->tmp.l;
- efac->v2= (int)efa->v2->tmp.l;
- efac->v3= (int)efa->v3->tmp.l;
- if(efa->v4) efac->v4= (int)efa->v4->tmp.l;
- else efac->v4= -1;
-
- efac->mat_nr= efa->mat_nr;
- efac->flag= efa->flag;
- efac->f= efa->f;
- efac->h= efa->h;
- efac->fgonf= efa->fgonf;
-
- efa->tmp.l = a; /*store index*/
-
- CustomData_from_em_block(&em->fdata, &um->fdata, efa->data, a);
- }
-
- a = 0;
- for(ese=em->selected.first; ese; ese=ese->next, esec++){
- esec->type = ese->type;
- if(ese->type == EDITVERT) a = esec->index = ((EditVert*)ese->data)->tmp.l;
- else if(ese->type == EDITEDGE) a = esec->index = ((EditEdge*)ese->data)->tmp.l;
- else if(ese->type == EDITFACE) a = esec->index = ((EditFace*)ese->data)->tmp.l;
- }
-
- um->retopo_paint_data= retopo_paint_data_copy(em->retopo_paint_data);
- um->retopo_mode= G.scene->toolsettings->retopo_mode;
-
- {
- Multires *mr= get_mesh(G.obedit)->mr;
- UndoMesh *prev= undo_editmode_get_prev(G.obedit);
-
- um->mru= NULL;
-
- if(mr) {
- if(prev && prev->mru && prev->mru->mr && prev->mru->mr->current == mr->current) {
- um->mru= prev->mru;
- ++um->mru->users;
- }
- else {
- um->mru= MEM_callocN(sizeof(EM_MultiresUndo), "EM_MultiresUndo");
- um->mru->users= 1;
- um->mru->mr= multires_copy(mr);
- }
- }
- }
-
- return um;
-}
-
-static void undoMesh_to_editMesh(void *umv)
-{
- UndoMesh *um= (UndoMesh*)umv;
- EditMesh *em= G.editMesh;
- EditVert *eve, **evar=NULL;
- EditEdge *eed;
- EditFace *efa;
- EditSelection *ese;
- EditVertC *evec;
- EditEdgeC *eedc;
- EditFaceC *efac;
- EditSelectionC *esec;
- int a=0;
-
-#ifdef WITH_VERSE
- struct VNode *vnode = G.editMesh->vnode;
- if(vnode) {
- /* send delete command to all verse vertexes and verse face ...
- * verse mesh will be recreated from new edit mesh */
- destroy_versemesh(vnode);
- }
-#endif
- G.scene->selectmode = um->selectmode;
-
- free_editMesh(G.editMesh);
-
- /* malloc blocks */
- memset(em, 0, sizeof(EditMesh));
-
- init_editmesh_fastmalloc(em, um->totvert, um->totedge, um->totface);
-
-#ifdef WITH_VERSE
- G.editMesh->vnode = vnode;
-#endif
-
- CustomData_free(&em->vdata, 0);
- CustomData_free(&em->edata, 0);
- CustomData_free(&em->fdata, 0);
-
- CustomData_copy(&um->vdata, &em->vdata, CD_MASK_EDITMESH, CD_CALLOC, 0);
- CustomData_copy(&um->edata, &em->edata, CD_MASK_EDITMESH, CD_CALLOC, 0);
- CustomData_copy(&um->fdata, &em->fdata, CD_MASK_EDITMESH, CD_CALLOC, 0);
-
- /* now copy vertices */
-
- if(um->totvert) evar= MEM_mallocN(um->totvert*sizeof(EditVert *), "vertex ar");
- for(a=0, evec= um->verts; a<um->totvert; a++, evec++) {
- eve= addvertlist(evec->co, NULL);
- evar[a]= eve;
-
- VECCOPY(eve->no, evec->no);
- eve->f= evec->f;
- eve->h= evec->h;
- eve->keyindex= evec->keyindex;
- eve->bweight= ((float)evec->bweight)/255.0f;
-
- CustomData_to_em_block(&um->vdata, &em->vdata, a, &eve->data);
- }
-
- /* copy edges */
- for(a=0, eedc= um->edges; a<um->totedge; a++, eedc++) {
- eed= addedgelist(evar[eedc->v1], evar[eedc->v2], NULL);
-
- eed->f= eedc->f;
- eed->h= eedc->h;
- eed->seam= eedc->seam;
- eed->sharp= eedc->sharp;
- eed->fgoni= eedc->fgoni;
- eed->crease= ((float)eedc->crease)/255.0f;
- eed->bweight= ((float)eedc->bweight)/255.0f;
- CustomData_to_em_block(&um->edata, &em->edata, a, &eed->data);
- }
-
- /* copy faces */
- for(a=0, efac= um->faces; a<um->totface; a++, efac++) {
- if(efac->v4 != -1)
- efa= addfacelist(evar[efac->v1], evar[efac->v2], evar[efac->v3], evar[efac->v4], NULL, NULL);
- else
- efa= addfacelist(evar[efac->v1], evar[efac->v2], evar[efac->v3], NULL, NULL ,NULL);
-
- efa->mat_nr= efac->mat_nr;
- efa->flag= efac->flag;
- efa->f= efac->f;
- efa->h= efac->h;
- efa->fgonf= efac->fgonf;
-
- CustomData_to_em_block(&um->fdata, &em->fdata, a, &efa->data);
- }
-
- end_editmesh_fastmalloc();
- if(evar) MEM_freeN(evar);
-
- G.totvert = um->totvert;
- G.totedge = um->totedge;
- G.totface = um->totface;
- /*restore stored editselections*/
- if(um->totsel){
- EM_init_index_arrays(1,1,1);
- for(a=0, esec= um->selected; a<um->totsel; a++, esec++){
- ese = MEM_callocN(sizeof(EditSelection), "Edit Selection");
- ese->type = esec->type;
- if(ese->type == EDITVERT) ese->data = EM_get_vert_for_index(esec->index); else
- if(ese->type == EDITEDGE) ese->data = EM_get_edge_for_index(esec->index); else
- if(ese->type == EDITFACE) ese->data = EM_get_face_for_index(esec->index);
- BLI_addtail(&(em->selected),ese);
- }
- EM_free_index_arrays();
- }
-
- retopo_free_paint();
- em->retopo_paint_data= retopo_paint_data_copy(um->retopo_paint_data);
- G.scene->toolsettings->retopo_mode= um->retopo_mode;
- if(G.scene->toolsettings->retopo_mode) {
- if(G.vd->depths) G.vd->depths->damaged= 1;
- retopo_queue_updates(G.vd);
- retopo_paint_view_update(G.vd);
- }
-
- {
- Mesh *me= get_mesh(G.obedit);
- multires_free(me->mr);
- me->mr= NULL;
- if(um->mru && um->mru->mr) me->mr= multires_copy(um->mru->mr);
- }
-}
-
-
-/* and this is all the undo system needs to know */
-void undo_push_mesh(char *name)
-{
- undo_editmode_push(name, free_undoMesh, undoMesh_to_editMesh, editMesh_to_undoMesh, NULL);
-}
-
-
-
-/* *************** END UNDO *************/
-
-static EditVert **g_em_vert_array = NULL;
-static EditEdge **g_em_edge_array = NULL;
-static EditFace **g_em_face_array = NULL;
-
-void EM_init_index_arrays(int forVert, int forEdge, int forFace)
-{
- EditVert *eve;
- EditEdge *eed;
- EditFace *efa;
- int i;
-
- if (forVert) {
- g_em_vert_array = MEM_mallocN(sizeof(*g_em_vert_array)*G.totvert, "em_v_arr");
-
- for (i=0,eve=G.editMesh->verts.first; eve; i++,eve=eve->next)
- g_em_vert_array[i] = eve;
- }
-
- if (forEdge) {
- g_em_edge_array = MEM_mallocN(sizeof(*g_em_edge_array)*G.totedge, "em_e_arr");
-
- for (i=0,eed=G.editMesh->edges.first; eed; i++,eed=eed->next)
- g_em_edge_array[i] = eed;
- }
-
- if (forFace) {
- g_em_face_array = MEM_mallocN(sizeof(*g_em_face_array)*G.totface, "em_f_arr");
-
- for (i=0,efa=G.editMesh->faces.first; efa; i++,efa=efa->next)
- g_em_face_array[i] = efa;
- }
-}
-
-void EM_free_index_arrays(void)
-{
- if (g_em_vert_array) MEM_freeN(g_em_vert_array);
- if (g_em_edge_array) MEM_freeN(g_em_edge_array);
- if (g_em_face_array) MEM_freeN(g_em_face_array);
- g_em_vert_array = NULL;
- g_em_edge_array = NULL;
- g_em_face_array = NULL;
-}
-
-EditVert *EM_get_vert_for_index(int index)
-{
- return g_em_vert_array?g_em_vert_array[index]:NULL;
-}
-
-EditEdge *EM_get_edge_for_index(int index)
-{
- return g_em_edge_array?g_em_edge_array[index]:NULL;
-}
-
-EditFace *EM_get_face_for_index(int index)
-{
- return g_em_face_array?g_em_face_array[index]:NULL;
-}
-
-/* can we edit UV's for this mesh?*/
-int EM_texFaceCheck(void)
-{
- /* some of these checks could be a touch overkill */
- if ( (G.obedit) &&
- (G.obedit->type == OB_MESH) &&
- (G.editMesh) &&
- (G.editMesh->faces.first) &&
- (CustomData_has_layer(&G.editMesh->fdata, CD_MTFACE)))
- return 1;
- return 0;
-}
-
-/* can we edit colors for this mesh?*/
-int EM_vertColorCheck(void)
-{
- /* some of these checks could be a touch overkill */
- if ( (G.obedit) &&
- (G.obedit->type == OB_MESH) &&
- (G.editMesh) &&
- (G.editMesh->faces.first) &&
- (CustomData_has_layer(&G.editMesh->fdata, CD_MCOL)))
- return 1;
- return 0;
-}
-