|
Blender
V2.59
|
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