Blender  V2.59
object_modifier.c
Go to the documentation of this file.
00001 /*
00002  * $Id: object_modifier.c 38115 2011-07-05 10:35:48Z 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) 2001-2002 by NaN Holding BV.
00021  * All rights reserved.
00022  *
00023  * Contributor(s): Blender Foundation, 2009
00024  *
00025  * ***** END GPL LICENSE BLOCK *****
00026  */
00027 
00033 #include <math.h>
00034 #include <stdio.h>
00035 #include <stdlib.h>
00036 
00037 #include "MEM_guardedalloc.h"
00038 
00039 #include "DNA_curve_types.h"
00040 #include "DNA_key_types.h"
00041 #include "DNA_mesh_types.h"
00042 #include "DNA_meshdata_types.h"
00043 #include "DNA_object_force.h"
00044 #include "DNA_scene_types.h"
00045 
00046 #include "BLI_math.h"
00047 #include "BLI_listbase.h"
00048 #include "BLI_string.h"
00049 #include "BLI_path_util.h"
00050 #include "BLI_editVert.h"
00051 #include "BLI_utildefines.h"
00052 
00053 #include "BKE_curve.h"
00054 #include "BKE_context.h"
00055 #include "BKE_depsgraph.h"
00056 #include "BKE_displist.h"
00057 #include "BKE_DerivedMesh.h"
00058 #include "BKE_effect.h"
00059 #include "BKE_global.h"
00060 #include "BKE_key.h"
00061 #include "BKE_lattice.h"
00062 #include "BKE_main.h"
00063 #include "BKE_mesh.h"
00064 #include "BKE_modifier.h"
00065 #include "BKE_multires.h"
00066 #include "BKE_report.h"
00067 #include "BKE_object.h"
00068 #include "BKE_particle.h"
00069 #include "BKE_softbody.h"
00070 
00071 #include "RNA_access.h"
00072 #include "RNA_define.h"
00073 #include "RNA_enum_types.h"
00074 
00075 #include "ED_armature.h"
00076 #include "ED_object.h"
00077 #include "ED_screen.h"
00078 #include "ED_mesh.h"
00079 
00080 #include "WM_api.h"
00081 #include "WM_types.h"
00082 
00083 #include "object_intern.h"
00084 
00085 /******************************** API ****************************/
00086 
00087 ModifierData *ED_object_modifier_add(ReportList *reports, Main *bmain, Scene *scene, Object *ob, const char *name, int type)
00088 {
00089         ModifierData *md=NULL, *new_md=NULL;
00090         ModifierTypeInfo *mti = modifierType_getInfo(type);
00091         
00092         /* only geometry objects should be able to get modifiers [#25291] */
00093         if(!ELEM5(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_LATTICE)) {
00094                 BKE_reportf(reports, RPT_WARNING, "Modifiers cannot be added to Object '%s'", ob->id.name+2);
00095                 return NULL;
00096         }
00097         
00098         if(mti->flags&eModifierTypeFlag_Single) {
00099                 if(modifiers_findByType(ob, type)) {
00100                         BKE_report(reports, RPT_WARNING, "Only one modifier of this type allowed.");
00101                         return NULL;
00102                 }
00103         }
00104         
00105         if(type == eModifierType_ParticleSystem) {
00106                 /* don't need to worry about the new modifier's name, since that is set to the number
00107                  * of particle systems which shouldn't have too many duplicates 
00108                  */
00109                 new_md = object_add_particle_system(scene, ob, name);
00110         }
00111         else {
00112                 /* get new modifier data to add */
00113                 new_md= modifier_new(type);
00114                 
00115                 if(mti->flags&eModifierTypeFlag_RequiresOriginalData) {
00116                         md = ob->modifiers.first;
00117                         
00118                         while(md && modifierType_getInfo(md->type)->type==eModifierTypeType_OnlyDeform)
00119                                 md = md->next;
00120                         
00121                         BLI_insertlinkbefore(&ob->modifiers, md, new_md);
00122                 }
00123                 else
00124                         BLI_addtail(&ob->modifiers, new_md);
00125 
00126                 if(name)
00127                         BLI_strncpy(new_md->name, name, sizeof(new_md->name));
00128 
00129                 /* make sure modifier data has unique name */
00130 
00131                 modifier_unique_name(&ob->modifiers, new_md);
00132                 
00133                 /* special cases */
00134                 if(type == eModifierType_Softbody) {
00135                         if(!ob->soft) {
00136                                 ob->soft= sbNew(scene);
00137                                 ob->softflag |= OB_SB_GOAL|OB_SB_EDGES;
00138                         }
00139                 }
00140                 else if(type == eModifierType_Collision) {
00141                         if(!ob->pd)
00142                                 ob->pd= object_add_collision_fields(0);
00143                         
00144                         ob->pd->deflect= 1;
00145                         DAG_scene_sort(bmain, scene);
00146                 }
00147                 else if(type == eModifierType_Surface)
00148                         DAG_scene_sort(bmain, scene);
00149                 else if(type == eModifierType_Multires)
00150                         /* set totlvl from existing MDISPS layer if object already had it */
00151                         multiresModifier_set_levels_from_disps((MultiresModifierData *)new_md, ob);
00152         }
00153 
00154         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
00155 
00156         return new_md;
00157 }
00158 
00159 int ED_object_modifier_remove(ReportList *reports, Main *bmain, Scene *scene, Object *ob, ModifierData *md)
00160 {
00161         ModifierData *obmd;
00162         int sort_depsgraph = 0;
00163 
00164         /* It seems on rapid delete it is possible to
00165          * get called twice on same modifier, so make
00166          * sure it is in list. */
00167         for(obmd=ob->modifiers.first; obmd; obmd=obmd->next)
00168                 if(obmd==md)
00169                         break;
00170         
00171         if(!obmd) {
00172                 BKE_reportf(reports, RPT_ERROR, "Modifier '%s' not in object '%s'.", ob->id.name, md->name);
00173                 return 0;
00174         }
00175 
00176         /* special cases */
00177         if(md->type == eModifierType_ParticleSystem) {
00178                 ParticleSystemModifierData *psmd=(ParticleSystemModifierData*)md;
00179 
00180                 BLI_remlink(&ob->particlesystem, psmd->psys);
00181                 psys_free(ob, psmd->psys);
00182                 psmd->psys= NULL;
00183         }
00184         else if(md->type == eModifierType_Softbody) {
00185                 if(ob->soft) {
00186                         sbFree(ob->soft);
00187                         ob->soft= NULL;
00188                         ob->softflag= 0;
00189                 }
00190         }
00191         else if(md->type == eModifierType_Collision) {
00192                 if(ob->pd)
00193                         ob->pd->deflect= 0;
00194 
00195                 sort_depsgraph = 1;
00196         }
00197         else if(md->type == eModifierType_Surface) {
00198                 if(ob->pd && ob->pd->shape == PFIELD_SHAPE_SURFACE)
00199                         ob->pd->shape = PFIELD_SHAPE_PLANE;
00200 
00201                 sort_depsgraph = 1;
00202         }
00203         else if(md->type == eModifierType_Smoke) {
00204                 ob->dt = OB_TEXTURE;
00205         }
00206         else if(md->type == eModifierType_Multires) {
00207                 int ok= 1;
00208                 Mesh *me= ob->data;
00209                 ModifierData *tmpmd;
00210 
00211                 /* ensure MDISPS CustomData layer is't used by another multires modifiers */
00212                 for(tmpmd= ob->modifiers.first; tmpmd; tmpmd= tmpmd->next)
00213                         if(tmpmd!=md && tmpmd->type == eModifierType_Multires) {
00214                                 ok= 0;
00215                                 break;
00216                         }
00217 
00218                 if(ok) {
00219                         if(me->edit_mesh) {
00220                                 EditMesh *em= me->edit_mesh;
00221                                 /* CustomData_external_remove is used here only to mark layer as non-external
00222                                    for further free-ing, so zero element count looks safer than em->totface */
00223                                 CustomData_external_remove(&em->fdata, &me->id, CD_MDISPS, 0);
00224                                 EM_free_data_layer(em, &em->fdata, CD_MDISPS);
00225                         } else {
00226                                 CustomData_external_remove(&me->fdata, &me->id, CD_MDISPS, me->totface);
00227                                 CustomData_free_layer_active(&me->fdata, CD_MDISPS, me->totface);
00228                         }
00229                 }
00230         }
00231 
00232         if(ELEM(md->type, eModifierType_Softbody, eModifierType_Cloth) &&
00233                 ob->particlesystem.first == NULL) {
00234                 ob->mode &= ~OB_MODE_PARTICLE_EDIT;
00235         }
00236 
00237         BLI_remlink(&ob->modifiers, md);
00238         modifier_free(md);
00239 
00240         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
00241 
00242         /* sorting has to be done after the update so that dynamic systems can react properly */
00243         if(sort_depsgraph)
00244                 DAG_scene_sort(bmain, scene);
00245 
00246         return 1;
00247 }
00248 
00249 int ED_object_modifier_move_up(ReportList *reports, Object *ob, ModifierData *md)
00250 {
00251         if(md->prev) {
00252                 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
00253 
00254                 if(mti->type!=eModifierTypeType_OnlyDeform) {
00255                         ModifierTypeInfo *nmti = modifierType_getInfo(md->prev->type);
00256 
00257                         if(nmti->flags&eModifierTypeFlag_RequiresOriginalData) {
00258                                 BKE_report(reports, RPT_WARNING, "Cannot move above a modifier requiring original data.");
00259                                 return 0;
00260                         }
00261                 }
00262 
00263                 BLI_remlink(&ob->modifiers, md);
00264                 BLI_insertlink(&ob->modifiers, md->prev->prev, md);
00265         }
00266 
00267         return 1;
00268 }
00269 
00270 int ED_object_modifier_move_down(ReportList *reports, Object *ob, ModifierData *md)
00271 {
00272         if(md->next) {
00273                 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
00274 
00275                 if(mti->flags&eModifierTypeFlag_RequiresOriginalData) {
00276                         ModifierTypeInfo *nmti = modifierType_getInfo(md->next->type);
00277 
00278                         if(nmti->type!=eModifierTypeType_OnlyDeform) {
00279                                 BKE_report(reports, RPT_WARNING, "Cannot move beyond a non-deforming modifier.");
00280                                 return 0;
00281                         }
00282                 }
00283 
00284                 BLI_remlink(&ob->modifiers, md);
00285                 BLI_insertlink(&ob->modifiers, md->next, md);
00286         }
00287 
00288         return 1;
00289 }
00290 
00291 int ED_object_modifier_convert(ReportList *UNUSED(reports), Main *bmain, Scene *scene, Object *ob, ModifierData *md)
00292 {
00293         Object *obn;
00294         ParticleSystem *psys;
00295         ParticleCacheKey *key, **cache;
00296         ParticleSettings *part;
00297         Mesh *me;
00298         MVert *mvert;
00299         MEdge *medge;
00300         int a, k, kmax;
00301         int totvert=0, totedge=0, cvert=0;
00302         int totpart=0, totchild=0;
00303 
00304         if(md->type != eModifierType_ParticleSystem) return 0;
00305         if(ob && ob->mode & OB_MODE_PARTICLE_EDIT) return 0;
00306 
00307         psys=((ParticleSystemModifierData *)md)->psys;
00308         part= psys->part;
00309 
00310         if(part->ren_as != PART_DRAW_PATH || psys->pathcache == NULL)
00311                 return 0;
00312 
00313         totpart= psys->totcached;
00314         totchild= psys->totchildcache;
00315 
00316         if(totchild && (part->draw&PART_DRAW_PARENT)==0)
00317                 totpart= 0;
00318 
00319         /* count */
00320         cache= psys->pathcache;
00321         for(a=0; a<totpart; a++) {
00322                 key= cache[a];
00323 
00324                 if(key->steps > 0) {
00325                         totvert+= key->steps+1;
00326                         totedge+= key->steps;
00327                 }
00328         }
00329 
00330         cache= psys->childcache;
00331         for(a=0; a<totchild; a++) {
00332                 key= cache[a];
00333 
00334                 if(key->steps > 0) {
00335                         totvert+= key->steps+1;
00336                         totedge+= key->steps;
00337                 }
00338         }
00339 
00340         if(totvert==0) return 0;
00341 
00342         /* add new mesh */
00343         obn= add_object(scene, OB_MESH);
00344         me= obn->data;
00345         
00346         me->totvert= totvert;
00347         me->totedge= totedge;
00348         
00349         me->mvert= CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, totvert);
00350         me->medge= CustomData_add_layer(&me->edata, CD_MEDGE, CD_CALLOC, NULL, totedge);
00351         me->mface= CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, 0);
00352         
00353         mvert= me->mvert;
00354         medge= me->medge;
00355 
00356         /* copy coordinates */
00357         cache= psys->pathcache;
00358         for(a=0; a<totpart; a++) {
00359                 key= cache[a];
00360                 kmax= key->steps;
00361                 for(k=0; k<=kmax; k++,key++,cvert++,mvert++) {
00362                         VECCOPY(mvert->co,key->co);
00363                         if(k) {
00364                                 medge->v1= cvert-1;
00365                                 medge->v2= cvert;
00366                                 medge->flag= ME_EDGEDRAW|ME_EDGERENDER|ME_LOOSEEDGE;
00367                                 medge++;
00368                         }
00369                         else {
00370                                 /* cheap trick to select the roots */
00371                                 mvert->flag |= SELECT;
00372                         }
00373                 }
00374         }
00375 
00376         cache=psys->childcache;
00377         for(a=0; a<totchild; a++) {
00378                 key=cache[a];
00379                 kmax=key->steps;
00380                 for(k=0; k<=kmax; k++,key++,cvert++,mvert++) {
00381                         VECCOPY(mvert->co,key->co);
00382                         if(k) {
00383                                 medge->v1=cvert-1;
00384                                 medge->v2=cvert;
00385                                 medge->flag= ME_EDGEDRAW|ME_EDGERENDER|ME_LOOSEEDGE;
00386                                 medge++;
00387                         }
00388                         else {
00389                                 /* cheap trick to select the roots */
00390                                 mvert->flag |= SELECT;
00391                         }
00392                 }
00393         }
00394 
00395         DAG_scene_sort(bmain, scene);
00396 
00397         return 1;
00398 }
00399 
00400 static int modifier_apply_shape(ReportList *reports, Scene *scene, Object *ob, ModifierData *md)
00401 {
00402         ModifierTypeInfo *mti= modifierType_getInfo(md->type);
00403 
00404         md->scene= scene;
00405 
00406         if (mti->isDisabled && mti->isDisabled(md, 0)) {
00407                 BKE_report(reports, RPT_ERROR, "Modifier is disabled, skipping apply");
00408                 return 0;
00409         }
00410 
00411         if (ob->type==OB_MESH) {
00412                 DerivedMesh *dm;
00413                 Mesh *me= ob->data;
00414                 Key *key=me->key;
00415                 KeyBlock *kb;
00416                 
00417                 if(!modifier_sameTopology(md)) {
00418                         BKE_report(reports, RPT_ERROR, "Only deforming modifiers can be applied to Shapes");
00419                         return 0;
00420                 }
00421                 mesh_pmv_off(me);
00422                 
00423                 dm = mesh_create_derived_for_modifier(scene, ob, md);
00424                 if (!dm) {
00425                         BKE_report(reports, RPT_ERROR, "Modifier is disabled or returned error, skipping apply");
00426                         return 0;
00427                 }
00428                 
00429                 if(key == NULL) {
00430                         key= me->key= add_key((ID *)me);
00431                         key->type= KEY_RELATIVE;
00432                         /* if that was the first key block added, then it was the basis.
00433                          * Initialise it with the mesh, and add another for the modifier */
00434                         kb= add_keyblock(key, NULL);
00435                         mesh_to_key(me, kb);
00436                 }
00437 
00438                 kb= add_keyblock(key, md->name);
00439                 DM_to_meshkey(dm, me, kb);
00440                 
00441                 dm->release(dm);
00442         }
00443         else {
00444                 BKE_report(reports, RPT_ERROR, "Cannot apply modifier for this object type");
00445                 return 0;
00446         }
00447         return 1;
00448 }
00449 
00450 static int modifier_apply_obdata(ReportList *reports, Scene *scene, Object *ob, ModifierData *md)
00451 {
00452         ModifierTypeInfo *mti= modifierType_getInfo(md->type);
00453 
00454         md->scene= scene;
00455 
00456         if (mti->isDisabled && mti->isDisabled(md, 0)) {
00457                 BKE_report(reports, RPT_ERROR, "Modifier is disabled, skipping apply");
00458                 return 0;
00459         }
00460 
00461         if (ob->type==OB_MESH) {
00462                 DerivedMesh *dm;
00463                 Mesh *me = ob->data;
00464                 MultiresModifierData *mmd= find_multires_modifier_before(scene, md);
00465 
00466                 if( me->key) {
00467                         BKE_report(reports, RPT_ERROR, "Modifier cannot be applied to Mesh with Shape Keys");
00468                         return 0;
00469                 }
00470 
00471                 mesh_pmv_off(me);
00472 
00473                 /* Multires: ensure that recent sculpting is applied */
00474                 if(md->type == eModifierType_Multires)
00475                         multires_force_update(ob);
00476 
00477                 if (mmd && mmd->totlvl && mti->type==eModifierTypeType_OnlyDeform) {
00478                         if(!multiresModifier_reshapeFromDeformMod (scene, mmd, ob, md)) {
00479                                 BKE_report(reports, RPT_ERROR, "Multires modifier returned error, skipping apply");
00480                                 return 0;
00481                         }
00482                 } else {
00483                         dm = mesh_create_derived_for_modifier(scene, ob, md);
00484                         if (!dm) {
00485                                 BKE_report(reports, RPT_ERROR, "Modifier returned error, skipping apply");
00486                                 return 0;
00487                         }
00488 
00489                         DM_to_mesh(dm, me);
00490 
00491                         dm->release(dm);
00492 
00493                         if(md->type == eModifierType_Multires) {
00494                                 CustomData_external_remove(&me->fdata, &me->id, CD_MDISPS, me->totface);
00495                                 CustomData_free_layer_active(&me->fdata, CD_MDISPS, me->totface);
00496                         }
00497                 }
00498         }
00499         else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
00500                 Curve *cu;
00501                 int numVerts;
00502                 float (*vertexCos)[3];
00503 
00504                 if (mti->type==eModifierTypeType_Constructive) {
00505                         BKE_report(reports, RPT_ERROR, "Cannot apply constructive modifiers on curve");
00506                         return 0;
00507                 }
00508 
00509                 cu = ob->data;
00510                 BKE_report(reports, RPT_INFO, "Applied modifier only changed CV points, not tesselated/bevel vertices");
00511 
00512                 vertexCos = curve_getVertexCos(cu, &cu->nurb, &numVerts);
00513                 mti->deformVerts(md, ob, NULL, vertexCos, numVerts, 0, 0);
00514                 curve_applyVertexCos(cu, &cu->nurb, vertexCos);
00515 
00516                 MEM_freeN(vertexCos);
00517 
00518                 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
00519         }
00520         else {
00521                 BKE_report(reports, RPT_ERROR, "Cannot apply modifier for this object type");
00522                 return 0;
00523         }
00524 
00525         /* lattice modifier can be applied to particle system too */
00526         if(ob->particlesystem.first) {
00527 
00528                 ParticleSystem *psys = ob->particlesystem.first;
00529 
00530                 for(; psys; psys=psys->next) {
00531                         
00532                         if(psys->part->type != PART_HAIR)
00533                                 continue;
00534 
00535                         psys_apply_hair_lattice(scene, ob, psys);
00536                 }
00537         }
00538 
00539         return 1;
00540 }
00541 
00542 int ED_object_modifier_apply(ReportList *reports, Scene *scene, Object *ob, ModifierData *md, int mode)
00543 {
00544         int prev_mode;
00545 
00546         if (scene->obedit) {
00547                 BKE_report(reports, RPT_ERROR, "Modifiers cannot be applied in editmode");
00548                 return 0;
00549         } else if (((ID*) ob->data)->us>1) {
00550                 BKE_report(reports, RPT_ERROR, "Modifiers cannot be applied to multi-user data");
00551                 return 0;
00552         }
00553 
00554         if (md!=ob->modifiers.first)
00555                 BKE_report(reports, RPT_INFO, "Applied modifier was not first, result may not be as expected.");
00556 
00557         /* allow apply of a not-realtime modifier, by first re-enabling realtime. */
00558         prev_mode= md->mode;
00559         md->mode |= eModifierMode_Realtime;
00560 
00561         if (mode == MODIFIER_APPLY_SHAPE) {
00562                 if (!modifier_apply_shape(reports, scene, ob, md)) {
00563                         md->mode= prev_mode;
00564                         return 0;
00565                 }
00566         } else {
00567                 if (!modifier_apply_obdata(reports, scene, ob, md)) {
00568                         md->mode= prev_mode;
00569                         return 0;
00570                 }
00571         }
00572 
00573         BLI_remlink(&ob->modifiers, md);
00574         modifier_free(md);
00575 
00576         return 1;
00577 }
00578 
00579 int ED_object_modifier_copy(ReportList *UNUSED(reports), Object *ob, ModifierData *md)
00580 {
00581         ModifierData *nmd;
00582         
00583         nmd = modifier_new(md->type);
00584         modifier_copyData(md, nmd);
00585         BLI_insertlink(&ob->modifiers, md, nmd);
00586         modifier_unique_name(&ob->modifiers, nmd);
00587 
00588         return 1;
00589 }
00590 
00591 /************************ add modifier operator *********************/
00592 
00593 static int modifier_add_exec(bContext *C, wmOperator *op)
00594 {
00595         Main *bmain= CTX_data_main(C);
00596         Scene *scene= CTX_data_scene(C);
00597         Object *ob = ED_object_active_context(C);
00598         int type= RNA_enum_get(op->ptr, "type");
00599 
00600         if(!ED_object_modifier_add(op->reports, bmain, scene, ob, NULL, type))
00601                 return OPERATOR_CANCELLED;
00602 
00603         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
00604         
00605         return OPERATOR_FINISHED;
00606 }
00607 
00608 static EnumPropertyItem *modifier_add_itemf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), int *free)
00609 {       
00610         Object *ob= ED_object_active_context(C);
00611         EnumPropertyItem *item= NULL, *md_item;
00612         ModifierTypeInfo *mti;
00613         int totitem= 0, a;
00614         
00615         if(!ob)
00616                 return modifier_type_items;
00617 
00618         for(a=0; modifier_type_items[a].identifier; a++) {
00619                 md_item= &modifier_type_items[a];
00620 
00621                 if(md_item->identifier[0]) {
00622                         mti= modifierType_getInfo(md_item->value);
00623 
00624                         if(mti->flags & eModifierTypeFlag_NoUserAdd)
00625                                 continue;
00626 
00627                         if(!((mti->flags & eModifierTypeFlag_AcceptsCVs) ||
00628                            (ob->type==OB_MESH && (mti->flags & eModifierTypeFlag_AcceptsMesh))))
00629                                 continue;
00630                 }
00631 
00632                 RNA_enum_item_add(&item, &totitem, md_item);
00633         }
00634 
00635         RNA_enum_item_end(&item, &totitem);
00636         *free= 1;
00637 
00638         return item;
00639 }
00640 
00641 void OBJECT_OT_modifier_add(wmOperatorType *ot)
00642 {
00643         PropertyRNA *prop;
00644 
00645         /* identifiers */
00646         ot->name= "Add Modifier";
00647         ot->description = "Add a modifier to the active object";
00648         ot->idname= "OBJECT_OT_modifier_add";
00649         
00650         /* api callbacks */
00651         ot->invoke= WM_menu_invoke;
00652         ot->exec= modifier_add_exec;
00653         ot->poll= ED_operator_object_active_editable;
00654         
00655         /* flags */
00656         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
00657         
00658         /* properties */
00659         prop= RNA_def_enum(ot->srna, "type", modifier_type_items, eModifierType_Subsurf, "Type", "");
00660         RNA_def_enum_funcs(prop, modifier_add_itemf);
00661         ot->prop= prop;
00662 }
00663 
00664 /************************ generic functions for operators using mod names and data context *********************/
00665 
00666 static int edit_modifier_poll_generic(bContext *C, StructRNA *rna_type, int obtype_flag)
00667 {
00668         PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", rna_type);
00669         Object *ob= (ptr.id.data)?ptr.id.data:ED_object_active_context(C);
00670         
00671         if (!ob || ob->id.lib) return 0;
00672         if (obtype_flag && ((1<<ob->type) & obtype_flag)==0) return 0;
00673         if (ptr.id.data && ((ID*)ptr.id.data)->lib) return 0;
00674         
00675         return 1;
00676 }
00677 
00678 static int edit_modifier_poll(bContext *C)
00679 {
00680         return edit_modifier_poll_generic(C, &RNA_Modifier, 0);
00681 }
00682 
00683 static void edit_modifier_properties(wmOperatorType *ot)
00684 {
00685         RNA_def_string(ot->srna, "modifier", "", 32, "Modifier", "Name of the modifier to edit");
00686 }
00687 
00688 static int edit_modifier_invoke_properties(bContext *C, wmOperator *op)
00689 {
00690         PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier);
00691         ModifierData *md;
00692         
00693         if (RNA_property_is_set(op->ptr, "modifier"))
00694                 return 1;
00695         
00696         if (ptr.data) {
00697                 md = ptr.data;
00698                 RNA_string_set(op->ptr, "modifier", md->name);
00699                 return 1;
00700         }
00701         
00702         return 0;
00703 }
00704 
00705 static ModifierData *edit_modifier_property_get(wmOperator *op, Object *ob, int type)
00706 {
00707         char modifier_name[32];
00708         ModifierData *md;
00709         RNA_string_get(op->ptr, "modifier", modifier_name);
00710         
00711         md = modifiers_findByName(ob, modifier_name);
00712         
00713         if (md && type != 0 && md->type != type)
00714                 md = NULL;
00715 
00716         return md;
00717 }
00718 
00719 /************************ remove modifier operator *********************/
00720 
00721 static int modifier_remove_exec(bContext *C, wmOperator *op)
00722 {
00723         Main *bmain= CTX_data_main(C);
00724         Scene *scene= CTX_data_scene(C);
00725         Object *ob = ED_object_active_context(C);
00726         ModifierData *md = edit_modifier_property_get(op, ob, 0);
00727         int mode_orig = ob->mode;
00728         
00729         if(!ob || !md || !ED_object_modifier_remove(op->reports, bmain, scene, ob, md))
00730                 return OPERATOR_CANCELLED;
00731 
00732         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
00733 
00734         /* if cloth/softbody was removed, particle mode could be cleared */
00735         if(mode_orig & OB_MODE_PARTICLE_EDIT)
00736                 if((ob->mode & OB_MODE_PARTICLE_EDIT)==0)
00737                         if(scene->basact && scene->basact->object==ob)
00738                                 WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_OBJECT, NULL);
00739         
00740         return OPERATOR_FINISHED;
00741 }
00742 
00743 static int modifier_remove_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
00744 {
00745         if (edit_modifier_invoke_properties(C, op))
00746                 return modifier_remove_exec(C, op);
00747         else
00748                 return OPERATOR_CANCELLED;
00749 }
00750 
00751 void OBJECT_OT_modifier_remove(wmOperatorType *ot)
00752 {
00753         ot->name= "Remove Modifier";
00754         ot->description= "Remove a modifier from the active object";
00755         ot->idname= "OBJECT_OT_modifier_remove";
00756 
00757         ot->invoke= modifier_remove_invoke;
00758         ot->exec= modifier_remove_exec;
00759         ot->poll= edit_modifier_poll;
00760         
00761         /* flags */
00762         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
00763         edit_modifier_properties(ot);
00764 }
00765 
00766 /************************ move up modifier operator *********************/
00767 
00768 static int modifier_move_up_exec(bContext *C, wmOperator *op)
00769 {
00770         Object *ob = ED_object_active_context(C);
00771         ModifierData *md = edit_modifier_property_get(op, ob, 0);
00772 
00773         if(!ob || !md || !ED_object_modifier_move_up(op->reports, ob, md))
00774                 return OPERATOR_CANCELLED;
00775 
00776         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
00777         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
00778         
00779         return OPERATOR_FINISHED;
00780 }
00781 
00782 static int modifier_move_up_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
00783 {
00784         if (edit_modifier_invoke_properties(C, op))
00785                 return modifier_move_up_exec(C, op);
00786         else
00787                 return OPERATOR_CANCELLED;
00788 }
00789 
00790 void OBJECT_OT_modifier_move_up(wmOperatorType *ot)
00791 {
00792         ot->name= "Move Up Modifier";
00793         ot->description= "Move modifier up in the stack";
00794         ot->idname= "OBJECT_OT_modifier_move_up";
00795 
00796         ot->invoke= modifier_move_up_invoke;
00797         ot->exec= modifier_move_up_exec;
00798         ot->poll= edit_modifier_poll;
00799         
00800         /* flags */
00801         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
00802         edit_modifier_properties(ot);
00803 }
00804 
00805 /************************ move down modifier operator *********************/
00806 
00807 static int modifier_move_down_exec(bContext *C, wmOperator *op)
00808 {
00809         Object *ob = ED_object_active_context(C);
00810         ModifierData *md = edit_modifier_property_get(op, ob, 0);
00811 
00812         if(!ob || !md || !ED_object_modifier_move_down(op->reports, ob, md))
00813                 return OPERATOR_CANCELLED;
00814 
00815         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
00816         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
00817         
00818         return OPERATOR_FINISHED;
00819 }
00820 
00821 static int modifier_move_down_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
00822 {
00823         if (edit_modifier_invoke_properties(C, op))
00824                 return modifier_move_down_exec(C, op);
00825         else
00826                 return OPERATOR_CANCELLED;
00827 }
00828 
00829 void OBJECT_OT_modifier_move_down(wmOperatorType *ot)
00830 {
00831         ot->name= "Move Down Modifier";
00832         ot->description= "Move modifier down in the stack";
00833         ot->idname= "OBJECT_OT_modifier_move_down";
00834 
00835         ot->invoke= modifier_move_down_invoke;
00836         ot->exec= modifier_move_down_exec;
00837         ot->poll= edit_modifier_poll;
00838         
00839         /* flags */
00840         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
00841         edit_modifier_properties(ot);
00842 }
00843 
00844 /************************ apply modifier operator *********************/
00845 
00846 static int modifier_apply_exec(bContext *C, wmOperator *op)
00847 {
00848         Scene *scene= CTX_data_scene(C);
00849         Object *ob = ED_object_active_context(C);
00850         ModifierData *md = edit_modifier_property_get(op, ob, 0);
00851         int apply_as= RNA_enum_get(op->ptr, "apply_as");
00852         
00853         if(!ob || !md || !ED_object_modifier_apply(op->reports, scene, ob, md, apply_as)) {
00854                 return OPERATOR_CANCELLED;
00855         }
00856 
00857         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
00858         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
00859         
00860         return OPERATOR_FINISHED;
00861 }
00862 
00863 static int modifier_apply_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
00864 {
00865         if (edit_modifier_invoke_properties(C, op))
00866                 return modifier_apply_exec(C, op);
00867         else
00868                 return OPERATOR_CANCELLED;
00869 }
00870 
00871 static EnumPropertyItem modifier_apply_as_items[] = {
00872         {MODIFIER_APPLY_DATA, "DATA", 0, "Object Data", "Apply modifier to the object's data"},
00873         {MODIFIER_APPLY_SHAPE, "SHAPE", 0, "New Shape", "Apply deform-only modifier to a new shape on this object"},
00874         {0, NULL, 0, NULL, NULL}};
00875 
00876 void OBJECT_OT_modifier_apply(wmOperatorType *ot)
00877 {
00878         ot->name= "Apply Modifier";
00879         ot->description= "Apply modifier and remove from the stack";
00880         ot->idname= "OBJECT_OT_modifier_apply";
00881 
00882         ot->invoke= modifier_apply_invoke;
00883         ot->exec= modifier_apply_exec;
00884         ot->poll= edit_modifier_poll;
00885         
00886         /* flags */
00887         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
00888         
00889         RNA_def_enum(ot->srna, "apply_as", modifier_apply_as_items, MODIFIER_APPLY_DATA, "Apply as", "How to apply the modifier to the geometry");
00890         edit_modifier_properties(ot);
00891 }
00892 
00893 /************************ convert modifier operator *********************/
00894 
00895 static int modifier_convert_exec(bContext *C, wmOperator *op)
00896 {
00897         Main *bmain= CTX_data_main(C);
00898         Scene *scene= CTX_data_scene(C);
00899         Object *ob = ED_object_active_context(C);
00900         ModifierData *md = edit_modifier_property_get(op, ob, 0);
00901         
00902         if(!ob || !md || !ED_object_modifier_convert(op->reports, bmain, scene, ob, md))
00903                 return OPERATOR_CANCELLED;
00904 
00905         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
00906         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
00907         
00908         return OPERATOR_FINISHED;
00909 }
00910 
00911 static int modifier_convert_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
00912 {
00913         if (edit_modifier_invoke_properties(C, op))
00914                 return modifier_convert_exec(C, op);
00915         else
00916                 return OPERATOR_CANCELLED;
00917 }
00918 
00919 void OBJECT_OT_modifier_convert(wmOperatorType *ot)
00920 {
00921         ot->name= "Convert Modifier";
00922         ot->description= "Convert particles to a mesh object";
00923         ot->idname= "OBJECT_OT_modifier_convert";
00924 
00925         ot->invoke= modifier_convert_invoke;
00926         ot->exec= modifier_convert_exec;
00927         ot->poll= edit_modifier_poll;
00928         
00929         /* flags */
00930         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
00931         edit_modifier_properties(ot);
00932 }
00933 
00934 /************************ copy modifier operator *********************/
00935 
00936 static int modifier_copy_exec(bContext *C, wmOperator *op)
00937 {
00938         Object *ob = ED_object_active_context(C);
00939         ModifierData *md = edit_modifier_property_get(op, ob, 0);
00940 
00941         if(!ob || !md || !ED_object_modifier_copy(op->reports, ob, md))
00942                 return OPERATOR_CANCELLED;
00943 
00944         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
00945         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
00946         
00947         return OPERATOR_FINISHED;
00948 }
00949 
00950 static int modifier_copy_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
00951 {
00952         if (edit_modifier_invoke_properties(C, op))
00953                 return modifier_copy_exec(C, op);
00954         else
00955                 return OPERATOR_CANCELLED;
00956 }
00957 
00958 void OBJECT_OT_modifier_copy(wmOperatorType *ot)
00959 {
00960         ot->name= "Copy Modifier";
00961         ot->description= "Duplicate modifier at the same position in the stack";
00962         ot->idname= "OBJECT_OT_modifier_copy";
00963 
00964         ot->invoke= modifier_copy_invoke;
00965         ot->exec= modifier_copy_exec;
00966         ot->poll= edit_modifier_poll;
00967         
00968         /* flags */
00969         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
00970         edit_modifier_properties(ot);
00971 }
00972 
00973 /************* multires delete higher levels operator ****************/
00974 
00975 static int multires_poll(bContext *C)
00976 {
00977         return edit_modifier_poll_generic(C, &RNA_MultiresModifier, (1<<OB_MESH));
00978 }
00979 
00980 static int multires_higher_levels_delete_exec(bContext *C, wmOperator *op)
00981 {
00982         Object *ob = ED_object_active_context(C);
00983         MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get(op, ob, eModifierType_Multires);
00984         
00985         if (!mmd)
00986                 return OPERATOR_CANCELLED;
00987         
00988         multiresModifier_del_levels(mmd, ob, 1);
00989         
00990         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
00991         
00992         return OPERATOR_FINISHED;
00993 }
00994 
00995 static int multires_higher_levels_delete_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
00996 {
00997         if (edit_modifier_invoke_properties(C, op))
00998                 return multires_higher_levels_delete_exec(C, op);
00999         else
01000                 return OPERATOR_CANCELLED;
01001 }
01002 
01003 void OBJECT_OT_multires_higher_levels_delete(wmOperatorType *ot)
01004 {
01005         ot->name= "Delete Higher Levels";
01006         ot->description= "Deletes the higher resolution mesh, potential loss of detail";
01007         ot->idname= "OBJECT_OT_multires_higher_levels_delete";
01008 
01009         ot->poll= multires_poll;
01010         ot->invoke= multires_higher_levels_delete_invoke;
01011         ot->exec= multires_higher_levels_delete_exec;
01012         
01013         /* flags */
01014         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
01015         edit_modifier_properties(ot);
01016 }
01017 
01018 /****************** multires subdivide operator *********************/
01019 
01020 static int multires_subdivide_exec(bContext *C, wmOperator *op)
01021 {
01022         Object *ob = ED_object_active_context(C);
01023         MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get(op, ob, eModifierType_Multires);
01024         
01025         if (!mmd)
01026                 return OPERATOR_CANCELLED;
01027         
01028         multiresModifier_subdivide(mmd, ob, 0, mmd->simple);
01029 
01030         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
01031         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
01032         
01033         return OPERATOR_FINISHED;
01034 }
01035 
01036 static int multires_subdivide_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
01037 {
01038         if (edit_modifier_invoke_properties(C, op))
01039                 return multires_subdivide_exec(C, op);
01040         else
01041                 return OPERATOR_CANCELLED;
01042 }
01043 
01044 void OBJECT_OT_multires_subdivide(wmOperatorType *ot)
01045 {
01046         ot->name= "Multires Subdivide";
01047         ot->description= "Add a new level of subdivision";
01048         ot->idname= "OBJECT_OT_multires_subdivide";
01049 
01050         ot->poll= multires_poll;
01051         ot->invoke= multires_subdivide_invoke;
01052         ot->exec= multires_subdivide_exec;
01053         
01054         /* flags */
01055         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
01056         edit_modifier_properties(ot);
01057 }
01058 
01059 /****************** multires reshape operator *********************/
01060 
01061 static int multires_reshape_exec(bContext *C, wmOperator *op)
01062 {
01063         Object *ob= ED_object_active_context(C), *secondob= NULL;
01064         Scene *scene= CTX_data_scene(C);
01065         MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get(op, ob, eModifierType_Multires);
01066 
01067         if (!mmd)
01068                 return OPERATOR_CANCELLED;
01069         
01070         CTX_DATA_BEGIN(C, Object*, selob, selected_editable_objects) {
01071                 if(selob->type == OB_MESH && selob != ob) {
01072                         secondob= selob;
01073                         break;
01074                 }
01075         }
01076         CTX_DATA_END;
01077 
01078         if(!secondob) {
01079                 BKE_report(op->reports, RPT_ERROR, "Second selected mesh object require to copy shape from.");
01080                 return OPERATOR_CANCELLED;
01081         }
01082 
01083         if(!multiresModifier_reshape(scene, mmd, ob, secondob)) {
01084                 BKE_report(op->reports, RPT_ERROR, "Objects do not have the same number of vertices.");
01085                 return OPERATOR_CANCELLED;
01086         }
01087 
01088         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
01089         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
01090 
01091         return OPERATOR_FINISHED;
01092 }
01093 
01094 static int multires_reshape_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
01095 {
01096         if (edit_modifier_invoke_properties(C, op))
01097                 return multires_reshape_exec(C, op);
01098         else
01099                 return OPERATOR_CANCELLED;
01100 }
01101 
01102 void OBJECT_OT_multires_reshape(wmOperatorType *ot)
01103 {
01104         ot->name= "Multires Reshape";
01105         ot->description= "Copy vertex coordinates from other object";
01106         ot->idname= "OBJECT_OT_multires_reshape";
01107 
01108         ot->poll= multires_poll;
01109         ot->invoke= multires_reshape_invoke;
01110         ot->exec= multires_reshape_exec;
01111         
01112         /* flags */
01113         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
01114         edit_modifier_properties(ot);
01115 }
01116 
01117 /****************** multires save external operator *********************/
01118 
01119 static int multires_external_save_exec(bContext *C, wmOperator *op)
01120 {
01121         Object *ob = ED_object_active_context(C);
01122         Mesh *me= (ob)? ob->data: op->customdata;
01123         char path[FILE_MAX];
01124         int relative= RNA_boolean_get(op->ptr, "relative_path");
01125 
01126         if(!me)
01127                 return OPERATOR_CANCELLED;
01128 
01129         if(CustomData_external_test(&me->fdata, CD_MDISPS))
01130                 return OPERATOR_CANCELLED;
01131         
01132         RNA_string_get(op->ptr, "filepath", path);
01133 
01134         if(relative)
01135                 BLI_path_rel(path, G.main->name);
01136 
01137         CustomData_external_add(&me->fdata, &me->id, CD_MDISPS, me->totface, path);
01138         CustomData_external_write(&me->fdata, &me->id, CD_MASK_MESH, me->totface, 0);
01139         
01140         return OPERATOR_FINISHED;
01141 }
01142 
01143 static int multires_external_save_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
01144 {
01145         Object *ob = ED_object_active_context(C);
01146         MultiresModifierData *mmd;
01147         Mesh *me= ob->data;
01148         char path[FILE_MAX];
01149 
01150         if (!edit_modifier_invoke_properties(C, op))
01151                 return OPERATOR_CANCELLED;
01152         
01153         mmd = (MultiresModifierData *)edit_modifier_property_get(op, ob, eModifierType_Multires);
01154         
01155         if (!mmd)
01156                 return OPERATOR_CANCELLED;
01157         
01158         if(CustomData_external_test(&me->fdata, CD_MDISPS))
01159                 return OPERATOR_CANCELLED;
01160 
01161         if(!RNA_property_is_set(op->ptr, "relative_path"))
01162                 RNA_boolean_set(op->ptr, "relative_path", U.flag & USER_RELPATHS);
01163 
01164         if(RNA_property_is_set(op->ptr, "filepath"))
01165                 return multires_external_save_exec(C, op);
01166         
01167         op->customdata= me;
01168 
01169         BLI_snprintf(path, sizeof(path), "//%s.btx", me->id.name+2);
01170         RNA_string_set(op->ptr, "filepath", path);
01171         
01172         WM_event_add_fileselect(C, op);
01173 
01174         return OPERATOR_RUNNING_MODAL;
01175 }
01176 
01177 void OBJECT_OT_multires_external_save(wmOperatorType *ot)
01178 {
01179         ot->name= "Multires Save External";
01180         ot->description= "Save displacements to an external file";
01181         ot->idname= "OBJECT_OT_multires_external_save";
01182 
01183         // XXX modifier no longer in context after file browser .. ot->poll= multires_poll;
01184         ot->exec= multires_external_save_exec;
01185         ot->invoke= multires_external_save_invoke;
01186         ot->poll= multires_poll;
01187         
01188         /* flags */
01189         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
01190 
01191         WM_operator_properties_filesel(ot, FOLDERFILE|BTXFILE, FILE_SPECIAL, FILE_SAVE, WM_FILESEL_FILEPATH|WM_FILESEL_RELPATH);
01192         edit_modifier_properties(ot);
01193 }
01194 
01195 /****************** multires pack operator *********************/
01196 
01197 static int multires_external_pack_exec(bContext *C, wmOperator *UNUSED(op))
01198 {
01199         Object *ob = ED_object_active_context(C);
01200         Mesh *me= ob->data;
01201 
01202         if(!CustomData_external_test(&me->fdata, CD_MDISPS))
01203                 return OPERATOR_CANCELLED;
01204 
01205         // XXX don't remove..
01206         CustomData_external_remove(&me->fdata, &me->id, CD_MDISPS, me->totface);
01207         
01208         return OPERATOR_FINISHED;
01209 }
01210 
01211 void OBJECT_OT_multires_external_pack(wmOperatorType *ot)
01212 {
01213         ot->name= "Multires Pack External";
01214         ot->description= "Pack displacements from an external file";
01215         ot->idname= "OBJECT_OT_multires_external_pack";
01216 
01217         ot->poll= multires_poll;
01218         ot->exec= multires_external_pack_exec;
01219         
01220         /* flags */
01221         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
01222 }
01223 
01224 /********************* multires apply base ***********************/
01225 static int multires_base_apply_exec(bContext *C, wmOperator *op)
01226 {
01227         Object *ob = ED_object_active_context(C);
01228         MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get(op, ob, eModifierType_Multires);
01229         
01230         if (!mmd)
01231                 return OPERATOR_CANCELLED;
01232         
01233         multiresModifier_base_apply(mmd, ob);
01234 
01235         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
01236         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
01237         
01238         return OPERATOR_FINISHED;
01239 }
01240 
01241 static int multires_base_apply_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
01242 {
01243         if (edit_modifier_invoke_properties(C, op))
01244                 return multires_base_apply_exec(C, op);
01245         else
01246                 return OPERATOR_CANCELLED;
01247 }
01248 
01249 
01250 void OBJECT_OT_multires_base_apply(wmOperatorType *ot)
01251 {
01252         ot->name= "Multires Apply Base";
01253         ot->description= "Modify the base mesh to conform to the displaced mesh";
01254         ot->idname= "OBJECT_OT_multires_base_apply";
01255 
01256         ot->poll= multires_poll;
01257         ot->invoke= multires_base_apply_invoke;
01258         ot->exec= multires_base_apply_exec;
01259         
01260         /* flags */
01261         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
01262         edit_modifier_properties(ot);
01263 }
01264 
01265 
01266 /************************ mdef bind operator *********************/
01267 
01268 static int meshdeform_poll(bContext *C)
01269 {
01270         return edit_modifier_poll_generic(C, &RNA_MeshDeformModifier, (1<<OB_MESH));
01271 }
01272 
01273 static int meshdeform_bind_exec(bContext *C, wmOperator *op)
01274 {
01275         Scene *scene= CTX_data_scene(C);
01276         Object *ob = ED_object_active_context(C);
01277         MeshDeformModifierData *mmd = (MeshDeformModifierData *)edit_modifier_property_get(op, ob, eModifierType_MeshDeform);
01278         
01279         if (!mmd)
01280                 return OPERATOR_CANCELLED;
01281 
01282         if(mmd->bindcagecos) {
01283                 if(mmd->bindcagecos) MEM_freeN(mmd->bindcagecos);
01284                 if(mmd->dyngrid) MEM_freeN(mmd->dyngrid);
01285                 if(mmd->dyninfluences) MEM_freeN(mmd->dyninfluences);
01286                 if(mmd->bindinfluences) MEM_freeN(mmd->bindinfluences);
01287                 if(mmd->bindoffsets) MEM_freeN(mmd->bindoffsets);
01288                 if(mmd->dynverts) MEM_freeN(mmd->dynverts);
01289                 if(mmd->bindweights) MEM_freeN(mmd->bindweights); /* deprecated */
01290                 if(mmd->bindcos) MEM_freeN(mmd->bindcos); /* deprecated */
01291 
01292                 mmd->bindcagecos= NULL;
01293                 mmd->dyngrid= NULL;
01294                 mmd->dyninfluences= NULL;
01295                 mmd->bindoffsets= NULL;
01296                 mmd->dynverts= NULL;
01297                 mmd->bindweights= NULL; /* deprecated */
01298                 mmd->bindcos= NULL; /* deprecated */
01299                 mmd->totvert= 0;
01300                 mmd->totcagevert= 0;
01301                 mmd->totinfluence= 0;
01302                 
01303                 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
01304                 WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
01305         }
01306         else {
01307                 DerivedMesh *dm;
01308                 int mode= mmd->modifier.mode;
01309 
01310                 /* force modifier to run, it will call binding routine */
01311                 mmd->bindfunc= mesh_deform_bind;
01312                 mmd->modifier.mode |= eModifierMode_Realtime;
01313 
01314                 if(ob->type == OB_MESH) {
01315                         dm= mesh_create_derived_view(scene, ob, 0);
01316                         dm->release(dm);
01317                 }
01318                 else if(ob->type == OB_LATTICE) {
01319                         lattice_calc_modifiers(scene, ob);
01320                 }
01321                 else if(ob->type==OB_MBALL) {
01322                         makeDispListMBall(scene, ob);
01323                 }
01324                 else if(ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT)) {
01325                         makeDispListCurveTypes(scene, ob, 0);
01326                 }
01327 
01328                 mmd->bindfunc= NULL;
01329                 mmd->modifier.mode= mode;
01330         }
01331         
01332         return OPERATOR_FINISHED;
01333 }
01334 
01335 static int meshdeform_bind_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
01336 {
01337         if (edit_modifier_invoke_properties(C, op))
01338                 return meshdeform_bind_exec(C, op);
01339         else 
01340                 return OPERATOR_CANCELLED;
01341 }
01342 
01343 void OBJECT_OT_meshdeform_bind(wmOperatorType *ot)
01344 {
01345         /* identifiers */
01346         ot->name= "Mesh Deform Bind";
01347         ot->description = "Bind mesh to cage in mesh deform modifier";
01348         ot->idname= "OBJECT_OT_meshdeform_bind";
01349         
01350         /* api callbacks */
01351         ot->poll= meshdeform_poll;
01352         ot->invoke= meshdeform_bind_invoke;
01353         ot->exec= meshdeform_bind_exec;
01354         
01355         /* flags */
01356         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
01357         edit_modifier_properties(ot);
01358 }
01359 
01360 /****************** explode refresh operator *********************/
01361 
01362 static int explode_poll(bContext *C)
01363 {
01364         return edit_modifier_poll_generic(C, &RNA_ExplodeModifier, 0);
01365 }
01366 
01367 static int explode_refresh_exec(bContext *C, wmOperator *op)
01368 {
01369         Object *ob = ED_object_active_context(C);
01370         ExplodeModifierData *emd = (ExplodeModifierData *)edit_modifier_property_get(op, ob, eModifierType_Explode);
01371         
01372         if (!emd)
01373                 return OPERATOR_CANCELLED;
01374 
01375         emd->flag |= eExplodeFlag_CalcFaces;
01376 
01377         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
01378         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
01379         
01380         return OPERATOR_FINISHED;
01381 }
01382 
01383 static int explode_refresh_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
01384 {
01385         if (edit_modifier_invoke_properties(C, op))
01386                 return explode_refresh_exec(C, op);
01387         else
01388                 return OPERATOR_CANCELLED;
01389 }
01390 
01391 
01392 void OBJECT_OT_explode_refresh(wmOperatorType *ot)
01393 {
01394         ot->name= "Explode Refresh";
01395         ot->description= "Refresh data in the Explode modifier";
01396         ot->idname= "OBJECT_OT_explode_refresh";
01397 
01398         ot->poll= explode_poll;
01399         ot->invoke= explode_refresh_invoke;
01400         ot->exec= explode_refresh_exec;
01401         
01402         /* flags */
01403         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
01404         edit_modifier_properties(ot);
01405 }
01406