void ResetEditMesh() { free_vertlist(&gEditMesh.verts); free_edgelist(&gEditMesh.edges); free_facelist(&gEditMesh.faces); if(gEditMesh.hashedgetab != NULL) { MEM_freeN(gEditMesh.hashedgetab); gEditMesh.hashedgetab = NULL; } if(VertsList != NULL) delete[] VertsList; VertsList = NULL; }
/* do not free editmesh itself here */ void free_editMesh(EditMesh *em) { if(em==NULL) return; if(em->verts.first) free_vertlist(em, &em->verts); if(em->edges.first) free_edgelist(em, &em->edges); if(em->faces.first) free_facelist(em, &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; } /* 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, NULL, 'e'); mesh_mirrtopo_table(NULL, 'e'); em->totvert= em->totedge= em->totface= 0; em->act_face = NULL; }
static Object* createRepresentation(bContext *C, struct recast_polyMesh *pmesh, struct recast_polyMeshDetail *dmesh, Base* base) { float co[3], rot[3]; EditMesh *em; int i,j, k; unsigned short* v; int face[3]; Scene *scene= CTX_data_scene(C); Object* obedit; int createob= base==NULL; int nverts, nmeshes, nvp; unsigned short *verts, *polys; unsigned int *meshes; float bmin[3], cs, ch, *dverts; unsigned char *tris; zero_v3(co); zero_v3(rot); if(createob) { /* create new object */ obedit= ED_object_add_type(C, OB_MESH, co, rot, FALSE, 1); } else { obedit= base->object; scene_select_base(scene, base); copy_v3_v3(obedit->loc, co); copy_v3_v3(obedit->rot, rot); } ED_object_enter_editmode(C, EM_DO_UNDO|EM_IGNORE_LAYER); em= BKE_mesh_get_editmesh(((Mesh *)obedit->data)); if(!createob) { /* clear */ if(em->verts.first) free_vertlist(em, &em->verts); if(em->edges.first) free_edgelist(em, &em->edges); if(em->faces.first) free_facelist(em, &em->faces); if(em->selected.first) BLI_freelistN(&(em->selected)); } /* create verts for polygon mesh */ verts= recast_polyMeshGetVerts(pmesh, &nverts); recast_polyMeshGetBoundbox(pmesh, bmin, NULL); recast_polyMeshGetCell(pmesh, &cs, &ch); for(i= 0; i<nverts; i++) { v= &verts[3*i]; co[0]= bmin[0] + v[0]*cs; co[1]= bmin[1] + v[1]*ch; co[2]= bmin[2] + v[2]*cs; SWAP(float, co[1], co[2]); addvertlist(em, co, NULL); } /* create custom data layer to save polygon idx */ CustomData_add_layer_named(&em->fdata, CD_RECAST, CD_CALLOC, NULL, 0, "createRepresentation recastData"); /* create verts and faces for detailed mesh */ meshes= recast_polyMeshDetailGetMeshes(dmesh, &nmeshes); polys= recast_polyMeshGetPolys(pmesh, NULL, &nvp); dverts= recast_polyMeshDetailGetVerts(dmesh, NULL); tris= recast_polyMeshDetailGetTris(dmesh, NULL); for(i= 0; i<nmeshes; i++) { int uniquevbase= em->totvert; unsigned int vbase= meshes[4*i+0]; unsigned short ndv= meshes[4*i+1]; unsigned short tribase= meshes[4*i+2]; unsigned short trinum= meshes[4*i+3]; const unsigned short* p= &polys[i*nvp*2]; int nv= 0; for(j= 0; j < nvp; ++j) { if(p[j]==0xffff) break; nv++; } /* create unique verts */ for(j= nv; j<ndv; j++) { copy_v3_v3(co, &dverts[3*(vbase + j)]); SWAP(float, co[1], co[2]); addvertlist(em, co, NULL); } EM_init_index_arrays(em, 1, 0, 0); /* create faces */ for(j= 0; j<trinum; j++) { unsigned char* tri= &tris[4*(tribase+j)]; EditFace* newFace; int* polygonIdx; for(k= 0; k<3; k++) { if(tri[k]<nv) face[k]= p[tri[k]]; /* shared vertex */ else face[k]= uniquevbase+tri[k]-nv; /* unique vertex */ } newFace= addfacelist(em, EM_get_vert_for_index(face[0]), EM_get_vert_for_index(face[2]), EM_get_vert_for_index(face[1]), NULL, NULL, NULL); /* set navigation polygon idx to the custom layer */ polygonIdx= (int*)CustomData_em_get(&em->fdata, newFace->data, CD_RECAST); *polygonIdx= i+1; /* add 1 to avoid zero idx */ } EM_free_index_arrays(); } recast_destroyPolyMesh(pmesh); recast_destroyPolyMeshDetail(dmesh); BKE_mesh_end_editmesh((Mesh*)obedit->data, em); DAG_id_tag_update((ID*)obedit->data, OB_RECALC_DATA); WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); ED_object_exit_editmode(C, EM_FREEDATA); WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, obedit); if(createob) { obedit->gameflag&= ~OB_COLLISION; obedit->gameflag|= OB_NAVMESH; obedit->body_type= OB_BODY_TYPE_NAVMESH; rename_id((ID *)obedit, "Navmesh"); } BKE_mesh_ensure_navmesh(obedit->data); return obedit; }