Blender  V2.59
mesh_data.c
Go to the documentation of this file.
00001 /*
00002  * $Id: mesh_data.c 37504 2011-06-15 10:17:06Z blendix $
00003  *
00004  * ***** BEGIN GPL LICENSE BLOCK *****
00005  *
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU General Public License
00008  * as published by the Free Software Foundation; either version 2
00009  * of the License, or (at your option) any later version. 
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software Foundation,
00018  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00019  *
00020  * The Original Code is Copyright (C) 2009 Blender Foundation.
00021  * All rights reserved.
00022  *
00023  * 
00024  * Contributor(s): Blender Foundation
00025  *
00026  * ***** END GPL LICENSE BLOCK *****
00027  */
00028 
00034 #include <math.h>
00035 #include <stdlib.h>
00036 #include <string.h>
00037 
00038 #include "MEM_guardedalloc.h"
00039 
00040 #include "DNA_material_types.h"
00041 #include "DNA_meshdata_types.h"
00042 #include "DNA_object_types.h"
00043 #include "DNA_scene_types.h"
00044 #include "DNA_view3d_types.h"
00045 
00046 #include "BLI_math.h"
00047 #include "BLI_editVert.h"
00048 #include "BLI_edgehash.h"
00049 #include "BLI_utildefines.h"
00050 
00051 #include "BKE_context.h"
00052 #include "BKE_depsgraph.h"
00053 #include "BKE_displist.h"
00054 #include "BKE_image.h"
00055 #include "BKE_library.h"
00056 #include "BKE_material.h"
00057 #include "BKE_mesh.h"
00058 #include "BKE_report.h"
00059 
00060 #include "RNA_access.h"
00061 #include "RNA_define.h"
00062 
00063 #include "WM_api.h"
00064 #include "WM_types.h"
00065 
00066 #include "ED_mesh.h"
00067 #include "ED_object.h"
00068 #include "ED_uvedit.h"
00069 #include "ED_view3d.h"
00070 
00071 #include "RE_render_ext.h"
00072 
00073 #include "mesh_intern.h"
00074 
00075 static void delete_customdata_layer(bContext *C, Object *ob, CustomDataLayer *layer)
00076 {
00077         Mesh *me = ob->data;
00078         CustomData *data= (me->edit_mesh)? &me->edit_mesh->fdata: &me->fdata;
00079         void *actlayerdata, *rndlayerdata, *clonelayerdata, *stencillayerdata, *layerdata=layer->data;
00080         int type= layer->type;
00081         int index= CustomData_get_layer_index(data, type);
00082         int i, actindex, rndindex, cloneindex, stencilindex;
00083         
00084         /* ok, deleting a non-active layer needs to preserve the active layer indices.
00085           to do this, we store a pointer to the .data member of both layer and the active layer,
00086           (to detect if we're deleting the active layer or not), then use the active
00087           layer data pointer to find where the active layer has ended up.
00088           
00089           this is necassary because the deletion functions only support deleting the active
00090           layer. */
00091         actlayerdata = data->layers[CustomData_get_active_layer_index(data, type)].data;
00092         rndlayerdata = data->layers[CustomData_get_render_layer_index(data, type)].data;
00093         clonelayerdata = data->layers[CustomData_get_clone_layer_index(data, type)].data;
00094         stencillayerdata = data->layers[CustomData_get_stencil_layer_index(data, type)].data;
00095         CustomData_set_layer_active(data, type, layer - &data->layers[index]);
00096 
00097         if(me->edit_mesh) {
00098                 EM_free_data_layer(me->edit_mesh, data, type);
00099         }
00100         else {
00101                 CustomData_free_layer_active(data, type, me->totface);
00102                 mesh_update_customdata_pointers(me);
00103         }
00104 
00105         if(!CustomData_has_layer(data, type) && (type == CD_MCOL && (ob->mode & OB_MODE_VERTEX_PAINT)))
00106                 ED_object_toggle_modes(C, OB_MODE_VERTEX_PAINT);
00107 
00108         /* reconstruct active layer */
00109         if (actlayerdata != layerdata) {
00110                 /* find index */
00111                 actindex = CustomData_get_layer_index(data, type);
00112                 for (i=actindex; i<data->totlayer; i++) {
00113                         if (data->layers[i].data == actlayerdata) {
00114                                 actindex = i - actindex;
00115                                 break;
00116                         }
00117                 }
00118                 
00119                 /* set index */
00120                 CustomData_set_layer_active(data, type, actindex);
00121         }
00122         
00123         if (rndlayerdata != layerdata) {
00124                 /* find index */
00125                 rndindex = CustomData_get_layer_index(data, type);
00126                 for (i=rndindex; i<data->totlayer; i++) {
00127                         if (data->layers[i].data == rndlayerdata) {
00128                                 rndindex = i - rndindex;
00129                                 break;
00130                         }
00131                 }
00132                 
00133                 /* set index */
00134                 CustomData_set_layer_render(data, type, rndindex);
00135         }
00136         
00137         if (clonelayerdata != layerdata) {
00138                 /* find index */
00139                 cloneindex = CustomData_get_layer_index(data, type);
00140                 for (i=cloneindex; i<data->totlayer; i++) {
00141                         if (data->layers[i].data == clonelayerdata) {
00142                                 cloneindex = i - cloneindex;
00143                                 break;
00144                         }
00145                 }
00146                 
00147                 /* set index */
00148                 CustomData_set_layer_clone(data, type, cloneindex);
00149         }
00150         
00151         if (stencillayerdata != layerdata) {
00152                 /* find index */
00153                 stencilindex = CustomData_get_layer_index(data, type);
00154                 for (i=stencilindex; i<data->totlayer; i++) {
00155                         if (data->layers[i].data == stencillayerdata) {
00156                                 stencilindex = i - stencilindex;
00157                                 break;
00158                         }
00159                 }
00160                 
00161                 /* set index */
00162                 CustomData_set_layer_stencil(data, type, stencilindex);
00163         }
00164 }
00165 
00166 static void copy_editface_active_customdata(EditMesh *em, int type, int index)
00167 {
00168         EditFace *efa;
00169         int n= CustomData_get_active_layer(&em->fdata, type);
00170 
00171         for(efa= em->faces.first; efa; efa= efa->next) {
00172                 void *data= CustomData_em_get_n(&em->fdata, efa->data, type, n);
00173                 CustomData_em_set_n(&em->fdata, efa->data, type, index, data);
00174         }
00175 }
00176 
00177 int ED_mesh_uv_texture_add(bContext *C, Mesh *me, const char *name, int active_set)
00178 {
00179         EditMesh *em;
00180         int layernum;
00181 
00182         if(me->edit_mesh) {
00183                 em= me->edit_mesh;
00184 
00185                 layernum= CustomData_number_of_layers(&em->fdata, CD_MTFACE);
00186                 if(layernum >= MAX_MTFACE)
00187                         return 0;
00188 
00189                 EM_add_data_layer(em, &em->fdata, CD_MTFACE, name);
00190 
00191                 if(layernum) /* copy data from active UV */
00192                         copy_editface_active_customdata(em, CD_MTFACE, layernum);
00193 
00194                 if(active_set || layernum==0)
00195                         CustomData_set_layer_active(&em->fdata, CD_MTFACE, layernum);
00196         }
00197         else {
00198                 layernum= CustomData_number_of_layers(&me->fdata, CD_MTFACE);
00199                 if(layernum >= MAX_MTFACE)
00200                         return 0;
00201 
00202                 if(me->mtface)
00203                         CustomData_add_layer_named(&me->fdata, CD_MTFACE, CD_DUPLICATE, me->mtface, me->totface, name);
00204                 else
00205                         CustomData_add_layer_named(&me->fdata, CD_MTFACE, CD_DEFAULT, NULL, me->totface, name);
00206 
00207                 if(active_set || layernum==0)
00208                         CustomData_set_layer_active(&me->fdata, CD_MTFACE, layernum);
00209 
00210                 mesh_update_customdata_pointers(me);
00211         }
00212 
00213         DAG_id_tag_update(&me->id, 0);
00214         WM_event_add_notifier(C, NC_GEOM|ND_DATA, me);
00215 
00216         return 1;
00217 }
00218 
00219 int ED_mesh_uv_texture_remove(bContext *C, Object *ob, Mesh *me)
00220 {
00221         CustomData *data= (me->edit_mesh)? &me->edit_mesh->fdata: &me->fdata;
00222         CustomDataLayer *cdl;
00223         int index;
00224 
00225         index= CustomData_get_active_layer_index(data, CD_MTFACE);
00226         cdl= (index == -1) ? NULL: &data->layers[index];
00227 
00228         if(!cdl)
00229                 return 0;
00230 
00231         delete_customdata_layer(C, ob, cdl);
00232         DAG_id_tag_update(&me->id, 0);
00233         WM_event_add_notifier(C, NC_GEOM|ND_DATA, me);
00234 
00235         return 1;
00236 }
00237 
00238 int ED_mesh_color_add(bContext *C, Scene *UNUSED(scene), Object *UNUSED(ob), Mesh *me, const char *name, int active_set)
00239 {
00240         EditMesh *em;
00241         MCol *mcol;
00242         int layernum;
00243 
00244         if(me->edit_mesh) {
00245                 em= me->edit_mesh;
00246 
00247                 layernum= CustomData_number_of_layers(&em->fdata, CD_MCOL);
00248                 if(layernum >= MAX_MCOL)
00249                         return 0;
00250 
00251                 EM_add_data_layer(em, &em->fdata, CD_MCOL, name);
00252 
00253                 if(layernum) /* copy data from active vertex color layer */
00254                         copy_editface_active_customdata(em, CD_MCOL, layernum);
00255 
00256                 if(active_set || layernum==0)
00257                         CustomData_set_layer_active(&em->fdata, CD_MCOL, layernum);
00258         }
00259         else {
00260                 layernum= CustomData_number_of_layers(&me->fdata, CD_MCOL);
00261                 if(layernum >= MAX_MCOL)
00262                         return 0;
00263 
00264                 mcol= me->mcol;
00265 
00266                 if(me->mcol)
00267                         CustomData_add_layer_named(&me->fdata, CD_MCOL, CD_DUPLICATE, me->mcol, me->totface, name);
00268                 else
00269                         CustomData_add_layer_named(&me->fdata, CD_MCOL, CD_DEFAULT, NULL, me->totface, name);
00270 
00271                 if(active_set || layernum==0)
00272                         CustomData_set_layer_active(&me->fdata, CD_MCOL, layernum);
00273 
00274                 mesh_update_customdata_pointers(me);
00275         }
00276 
00277         DAG_id_tag_update(&me->id, 0);
00278         WM_event_add_notifier(C, NC_GEOM|ND_DATA, me);
00279 
00280         return 1;
00281 }
00282 
00283 int ED_mesh_color_remove(bContext *C, Object *ob, Mesh *me)
00284 {
00285         CustomData *data= (me->edit_mesh)? &me->edit_mesh->fdata: &me->fdata;
00286         CustomDataLayer *cdl;
00287         int index;
00288 
00289          index= CustomData_get_active_layer_index(data, CD_MCOL);
00290         cdl= (index == -1)? NULL: &data->layers[index];
00291 
00292         if(!cdl)
00293                 return 0;
00294 
00295         delete_customdata_layer(C, ob, cdl);
00296         DAG_id_tag_update(&me->id, 0);
00297         WM_event_add_notifier(C, NC_GEOM|ND_DATA, me);
00298 
00299         return 1;
00300 }
00301 
00302 /*********************** UV texture operators ************************/
00303 
00304 static int layers_poll(bContext *C)
00305 {
00306         Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
00307         ID *data= (ob)? ob->data: NULL;
00308         return (ob && !ob->id.lib && ob->type==OB_MESH && data && !data->lib);
00309 }
00310 
00311 static int uv_texture_add_exec(bContext *C, wmOperator *UNUSED(op))
00312 {
00313         Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
00314         Mesh *me= ob->data;
00315 
00316         if(!ED_mesh_uv_texture_add(C, me, NULL, TRUE))
00317                 return OPERATOR_CANCELLED;
00318 
00319         return OPERATOR_FINISHED;
00320 }
00321 
00322 void MESH_OT_uv_texture_add(wmOperatorType *ot)
00323 {
00324         /* identifiers */
00325         ot->name= "Add UV Texture";
00326         ot->description= "Add UV texture layer";
00327         ot->idname= "MESH_OT_uv_texture_add";
00328         
00329         /* api callbacks */
00330         ot->poll= layers_poll;
00331         ot->exec= uv_texture_add_exec;
00332 
00333         /* flags */
00334         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
00335 }
00336 
00337 static int drop_named_image_invoke(bContext *C, wmOperator *op, wmEvent *event)
00338 {
00339         Scene *scene= CTX_data_scene(C);
00340         View3D *v3d= CTX_wm_view3d(C);
00341         Base *base= ED_view3d_give_base_under_cursor(C, event->mval);
00342         Image *ima= NULL;
00343         Mesh *me;
00344         Object *obedit;
00345         int exitmode= 0;
00346         char name[32];
00347         
00348         /* Check context */
00349         if(base==NULL || base->object->type!=OB_MESH) {
00350                 BKE_report(op->reports, RPT_ERROR, "Not an Object or Mesh");
00351                 return OPERATOR_CANCELLED;
00352         }
00353         
00354         /* check input variables */
00355         if(RNA_property_is_set(op->ptr, "filepath")) {
00356                 char path[FILE_MAX];
00357                 
00358                 RNA_string_get(op->ptr, "filepath", path);
00359                 ima= BKE_add_image_file(path);
00360         }
00361         else {
00362                 RNA_string_get(op->ptr, "name", name);
00363                 ima= (Image *)find_id("IM", name);
00364         }
00365         
00366         if(!ima) {
00367                 BKE_report(op->reports, RPT_ERROR, "Not an Image.");
00368                 return OPERATOR_CANCELLED;
00369         }
00370         
00371         /* turn mesh in editmode */
00372         /* BKE_mesh_get/end_editmesh: ED_uvedit_assign_image also calls this */
00373 
00374         obedit= base->object;
00375         me= obedit->data;
00376         if(me->edit_mesh==NULL) {
00377                 make_editMesh(scene, obedit);
00378                 exitmode= 1;
00379         }
00380         if(me->edit_mesh==NULL)
00381                 return OPERATOR_CANCELLED;
00382         
00383         ED_uvedit_assign_image(scene, obedit, ima, NULL);
00384 
00385         if(exitmode) {
00386                 load_editMesh(scene, obedit);
00387                 free_editMesh(me->edit_mesh);
00388                 MEM_freeN(me->edit_mesh);
00389                 me->edit_mesh= NULL;
00390         }
00391 
00392         /* dummie drop support; ensure view shows a result :) */
00393         if(v3d)
00394                 v3d->flag2 |= V3D_SOLID_TEX;
00395         
00396         WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
00397         
00398         return OPERATOR_FINISHED;
00399 }
00400 
00401 void MESH_OT_drop_named_image(wmOperatorType *ot)
00402 {
00403         /* identifiers */
00404         ot->name= "Assign Image to UV Texture";
00405         ot->description= "Assigns Image to active UV layer, or creates a UV layer";
00406         ot->idname= "MESH_OT_drop_named_image";
00407         
00408         /* api callbacks */
00409         ot->poll= layers_poll;
00410         ot->invoke= drop_named_image_invoke;
00411         
00412         /* flags */
00413         ot->flag= OPTYPE_UNDO;
00414         
00415         /* properties */
00416         RNA_def_string(ot->srna, "name", "Image", 24, "Name", "Image name to assign.");
00417         RNA_def_string(ot->srna, "filepath", "Path", FILE_MAX, "Filepath", "Path to image file");
00418 }
00419 
00420 static int uv_texture_remove_exec(bContext *C, wmOperator *UNUSED(op))
00421 {
00422         Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
00423         Mesh *me= ob->data;
00424 
00425         if(!ED_mesh_uv_texture_remove(C, ob, me))
00426                 return OPERATOR_CANCELLED;
00427 
00428         return OPERATOR_FINISHED;
00429 }
00430 
00431 void MESH_OT_uv_texture_remove(wmOperatorType *ot)
00432 {
00433         /* identifiers */
00434         ot->name= "Remove UV Texture";
00435         ot->description= "Remove UV texture layer";
00436         ot->idname= "MESH_OT_uv_texture_remove";
00437         
00438         /* api callbacks */
00439         ot->poll= layers_poll;
00440         ot->exec= uv_texture_remove_exec;
00441 
00442         /* flags */
00443         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
00444 }
00445 
00446 /*********************** vertex color operators ************************/
00447 
00448 static int vertex_color_add_exec(bContext *C, wmOperator *UNUSED(op))
00449 {
00450         Scene *scene= CTX_data_scene(C);
00451         Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
00452         Mesh *me= ob->data;
00453 
00454         if(!ED_mesh_color_add(C, scene, ob, me, NULL, TRUE))
00455                 return OPERATOR_CANCELLED;
00456 
00457         return OPERATOR_FINISHED;
00458 }
00459 
00460 void MESH_OT_vertex_color_add(wmOperatorType *ot)
00461 {
00462         /* identifiers */
00463         ot->name= "Add Vertex Color";
00464         ot->description= "Add vertex color layer";
00465         ot->idname= "MESH_OT_vertex_color_add";
00466         
00467         /* api callbacks */
00468         ot->poll= layers_poll;
00469         ot->exec= vertex_color_add_exec;
00470 
00471         /* flags */
00472         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
00473 }
00474 
00475 static int vertex_color_remove_exec(bContext *C, wmOperator *UNUSED(op))
00476 {
00477         Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
00478         Mesh *me= ob->data;
00479 
00480         if(!ED_mesh_color_remove(C, ob, me))
00481                 return OPERATOR_CANCELLED;
00482 
00483         return OPERATOR_FINISHED;
00484 }
00485 
00486 void MESH_OT_vertex_color_remove(wmOperatorType *ot)
00487 {
00488         /* identifiers */
00489         ot->name= "Remove Vertex Color";
00490         ot->description= "Remove vertex color layer";
00491         ot->idname= "MESH_OT_vertex_color_remove";
00492         
00493         /* api callbacks */
00494         ot->exec= vertex_color_remove_exec;
00495         ot->poll= layers_poll;
00496 
00497         /* flags */
00498         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
00499 }
00500 
00501 /*********************** sticky operators ************************/
00502 
00503 static int sticky_add_exec(bContext *C, wmOperator *UNUSED(op))
00504 {
00505         Scene *scene= CTX_data_scene(C);
00506         View3D *v3d= CTX_wm_view3d(C);
00507         Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
00508         Mesh *me= ob->data;
00509 
00510         /*if(me->msticky)
00511                 return OPERATOR_CANCELLED;*/
00512 
00513         RE_make_sticky(scene, v3d);
00514 
00515         DAG_id_tag_update(&me->id, 0);
00516         WM_event_add_notifier(C, NC_GEOM|ND_DATA, me);
00517 
00518         return OPERATOR_FINISHED;
00519 }
00520 
00521 void MESH_OT_sticky_add(wmOperatorType *ot)
00522 {
00523         /* identifiers */
00524         ot->name= "Add Sticky";
00525         ot->description= "Add sticky UV texture layer";
00526         ot->idname= "MESH_OT_sticky_add";
00527         
00528         /* api callbacks */
00529         ot->poll= layers_poll;
00530         ot->exec= sticky_add_exec;
00531 
00532         /* flags */
00533         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
00534 }
00535 
00536 static int sticky_remove_exec(bContext *C, wmOperator *UNUSED(op))
00537 {
00538         Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
00539         Mesh *me= ob->data;
00540 
00541         if(!me->msticky)
00542                 return OPERATOR_CANCELLED;
00543 
00544         CustomData_free_layer_active(&me->vdata, CD_MSTICKY, me->totvert);
00545         me->msticky= NULL;
00546 
00547         DAG_id_tag_update(&me->id, 0);
00548         WM_event_add_notifier(C, NC_GEOM|ND_DATA, me);
00549 
00550         return OPERATOR_FINISHED;
00551 }
00552 
00553 void MESH_OT_sticky_remove(wmOperatorType *ot)
00554 {
00555         /* identifiers */
00556         ot->name= "Remove Sticky";
00557         ot->description= "Remove sticky UV texture layer";
00558         ot->idname= "MESH_OT_sticky_remove";
00559         
00560         /* api callbacks */
00561         ot->poll= layers_poll;
00562         ot->exec= sticky_remove_exec;
00563 
00564         /* flags */
00565         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
00566 }
00567 
00568 /************************** Add Geometry Layers *************************/
00569 
00570 void ED_mesh_update(Mesh *mesh, bContext *C, int calc_edges)
00571 {
00572         if(calc_edges || (mesh->totface && mesh->totedge == 0))
00573                 BKE_mesh_calc_edges(mesh, calc_edges);
00574 
00575         mesh_calc_normals(mesh->mvert, mesh->totvert, mesh->mface, mesh->totface, NULL);
00576 
00577         DAG_id_tag_update(&mesh->id, 0);
00578         WM_event_add_notifier(C, NC_GEOM|ND_DATA, mesh);
00579 }
00580 
00581 static void mesh_add_verts(Mesh *mesh, int len)
00582 {
00583         CustomData vdata;
00584         MVert *mvert;
00585         int i, totvert;
00586 
00587         if(len == 0)
00588                 return;
00589 
00590         totvert= mesh->totvert + len;
00591         CustomData_copy(&mesh->vdata, &vdata, CD_MASK_MESH, CD_DEFAULT, totvert);
00592         CustomData_copy_data(&mesh->vdata, &vdata, 0, 0, mesh->totvert);
00593 
00594         if(!CustomData_has_layer(&vdata, CD_MVERT))
00595                 CustomData_add_layer(&vdata, CD_MVERT, CD_CALLOC, NULL, totvert);
00596 
00597         CustomData_free(&mesh->vdata, mesh->totvert);
00598         mesh->vdata= vdata;
00599         mesh_update_customdata_pointers(mesh);
00600 
00601         /* scan the input list and insert the new vertices */
00602 
00603         mvert= &mesh->mvert[mesh->totvert];
00604         for(i=0; i<len; i++, mvert++)
00605                 mvert->flag |= SELECT;
00606 
00607         /* set final vertex list size */
00608         mesh->totvert= totvert;
00609 }
00610 
00611 void ED_mesh_transform(Mesh *me, float *mat)
00612 {
00613         int i;
00614         MVert *mvert= me->mvert;
00615 
00616         for(i= 0; i < me->totvert; i++, mvert++)
00617                 mul_m4_v3((float (*)[4])mat, mvert->co);
00618 
00619         mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL);
00620 }
00621 
00622 static void mesh_add_edges(Mesh *mesh, int len)
00623 {
00624         CustomData edata;
00625         MEdge *medge;
00626         int i, totedge;
00627 
00628         if(len == 0)
00629                 return;
00630 
00631         totedge= mesh->totedge+len;
00632 
00633         /* update customdata  */
00634         CustomData_copy(&mesh->edata, &edata, CD_MASK_MESH, CD_DEFAULT, totedge);
00635         CustomData_copy_data(&mesh->edata, &edata, 0, 0, mesh->totedge);
00636 
00637         if(!CustomData_has_layer(&edata, CD_MEDGE))
00638                 CustomData_add_layer(&edata, CD_MEDGE, CD_CALLOC, NULL, totedge);
00639 
00640         CustomData_free(&mesh->edata, mesh->totedge);
00641         mesh->edata= edata;
00642         mesh_update_customdata_pointers(mesh);
00643 
00644         /* set default flags */
00645         medge= &mesh->medge[mesh->totedge];
00646         for(i=0; i<len; i++, medge++)
00647                 medge->flag= ME_EDGEDRAW|ME_EDGERENDER|SELECT;
00648 
00649         mesh->totedge= totedge;
00650 }
00651 
00652 static void mesh_add_faces(Mesh *mesh, int len)
00653 {
00654         CustomData fdata;
00655         MFace *mface;
00656         int i, totface;
00657 
00658         if(len == 0)
00659                 return;
00660 
00661         totface= mesh->totface + len;   /* new face count */
00662 
00663         /* update customdata */
00664         CustomData_copy(&mesh->fdata, &fdata, CD_MASK_MESH, CD_DEFAULT, totface);
00665         CustomData_copy_data(&mesh->fdata, &fdata, 0, 0, mesh->totface);
00666 
00667         if(!CustomData_has_layer(&fdata, CD_MFACE))
00668                 CustomData_add_layer(&fdata, CD_MFACE, CD_CALLOC, NULL, totface);
00669 
00670         CustomData_free(&mesh->fdata, mesh->totface);
00671         mesh->fdata= fdata;
00672         mesh_update_customdata_pointers(mesh);
00673 
00674         /* set default flags */
00675         mface= &mesh->mface[mesh->totface];
00676         for(i=0; i<len; i++, mface++)
00677                 mface->flag= ME_FACE_SEL;
00678 
00679         mesh->totface= totface;
00680 }
00681 
00682 /*
00683 void ED_mesh_geometry_add(Mesh *mesh, ReportList *reports, int verts, int edges, int faces)
00684 {
00685         if(mesh->edit_mesh) {
00686                 BKE_report(reports, RPT_ERROR, "Can't add geometry in edit mode.");
00687                 return;
00688         }
00689 
00690         if(verts)
00691                 mesh_add_verts(mesh, verts);
00692         if(edges)
00693                 mesh_add_edges(mesh, edges);
00694         if(faces)
00695                 mesh_add_faces(mesh, faces);
00696 }
00697 */
00698 
00699 void ED_mesh_faces_add(Mesh *mesh, ReportList *reports, int count)
00700 {
00701         if(mesh->edit_mesh) {
00702                 BKE_report(reports, RPT_ERROR, "Can't add faces in edit mode.");
00703                 return;
00704         }
00705 
00706         mesh_add_faces(mesh, count);
00707 }
00708 
00709 void ED_mesh_edges_add(Mesh *mesh, ReportList *reports, int count)
00710 {
00711         if(mesh->edit_mesh) {
00712                 BKE_report(reports, RPT_ERROR, "Can't add edges in edit mode.");
00713                 return;
00714         }
00715 
00716         mesh_add_edges(mesh, count);
00717 }
00718 
00719 void ED_mesh_vertices_add(Mesh *mesh, ReportList *reports, int count)
00720 {
00721         if(mesh->edit_mesh) {
00722                 BKE_report(reports, RPT_ERROR, "Can't add vertices in edit mode.");
00723                 return;
00724         }
00725 
00726         mesh_add_verts(mesh, count);
00727 }
00728 
00729 void ED_mesh_calc_normals(Mesh *me)
00730 {
00731         mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL);
00732 }