Blender V2.61 - r43446

mesh_data.c

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