Blender V2.61 - r43446
|
00001 /* 00002 * ***** BEGIN GPL LICENSE BLOCK ***** 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 * 00018 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. 00019 * All rights reserved. 00020 * 00021 * Contributor(s): Blender Foundation, 2009 00022 * 00023 * ***** END GPL LICENSE BLOCK ***** 00024 */ 00025 00031 #include <math.h> 00032 #include <stdio.h> 00033 #include <stdlib.h> 00034 00035 #include "MEM_guardedalloc.h" 00036 00037 #include "DNA_anim_types.h" 00038 #include "DNA_curve_types.h" 00039 #include "DNA_key_types.h" 00040 #include "DNA_mesh_types.h" 00041 #include "DNA_meshdata_types.h" 00042 #include "DNA_object_force.h" 00043 #include "DNA_scene_types.h" 00044 00045 #include "BLI_math.h" 00046 #include "BLI_listbase.h" 00047 #include "BLI_string.h" 00048 #include "BLI_path_util.h" 00049 #include "BLI_editVert.h" 00050 #include "BLI_utildefines.h" 00051 00052 #include "BKE_animsys.h" 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_ocean.h" 00069 #include "BKE_particle.h" 00070 #include "BKE_softbody.h" 00071 00072 #include "RNA_access.h" 00073 #include "RNA_define.h" 00074 #include "RNA_enum_types.h" 00075 00076 #include "ED_armature.h" 00077 #include "ED_object.h" 00078 #include "ED_screen.h" 00079 #include "ED_mesh.h" 00080 00081 #include "WM_api.h" 00082 #include "WM_types.h" 00083 00084 #include "object_intern.h" 00085 00086 /******************************** API ****************************/ 00087 00088 ModifierData *ED_object_modifier_add(ReportList *reports, Main *bmain, Scene *scene, Object *ob, const char *name, int type) 00089 { 00090 ModifierData *md=NULL, *new_md=NULL; 00091 ModifierTypeInfo *mti = modifierType_getInfo(type); 00092 00093 /* only geometry objects should be able to get modifiers [#25291] */ 00094 if(!ELEM5(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_LATTICE)) { 00095 BKE_reportf(reports, RPT_WARNING, "Modifiers cannot be added to Object '%s'", ob->id.name+2); 00096 return NULL; 00097 } 00098 00099 if(mti->flags&eModifierTypeFlag_Single) { 00100 if(modifiers_findByType(ob, type)) { 00101 BKE_report(reports, RPT_WARNING, "Only one modifier of this type allowed"); 00102 return NULL; 00103 } 00104 } 00105 00106 if(type == eModifierType_ParticleSystem) { 00107 /* don't need to worry about the new modifier's name, since that is set to the number 00108 * of particle systems which shouldn't have too many duplicates 00109 */ 00110 new_md = object_add_particle_system(scene, ob, name); 00111 } 00112 else { 00113 /* get new modifier data to add */ 00114 new_md= modifier_new(type); 00115 00116 if(mti->flags&eModifierTypeFlag_RequiresOriginalData) { 00117 md = ob->modifiers.first; 00118 00119 while(md && modifierType_getInfo(md->type)->type==eModifierTypeType_OnlyDeform) 00120 md = md->next; 00121 00122 BLI_insertlinkbefore(&ob->modifiers, md, new_md); 00123 } 00124 else 00125 BLI_addtail(&ob->modifiers, new_md); 00126 00127 if(name) 00128 BLI_strncpy(new_md->name, name, sizeof(new_md->name)); 00129 00130 /* make sure modifier data has unique name */ 00131 00132 modifier_unique_name(&ob->modifiers, new_md); 00133 00134 /* special cases */ 00135 if(type == eModifierType_Softbody) { 00136 if(!ob->soft) { 00137 ob->soft= sbNew(scene); 00138 ob->softflag |= OB_SB_GOAL|OB_SB_EDGES; 00139 } 00140 } 00141 else if(type == eModifierType_Collision) { 00142 if(!ob->pd) 00143 ob->pd= object_add_collision_fields(0); 00144 00145 ob->pd->deflect= 1; 00146 DAG_scene_sort(bmain, scene); 00147 } 00148 else if(type == eModifierType_Surface) 00149 DAG_scene_sort(bmain, scene); 00150 else if(type == eModifierType_Multires) 00151 /* set totlvl from existing MDISPS layer if object already had it */ 00152 multiresModifier_set_levels_from_disps((MultiresModifierData *)new_md, ob); 00153 } 00154 00155 DAG_id_tag_update(&ob->id, OB_RECALC_DATA); 00156 00157 return new_md; 00158 } 00159 00160 static int object_modifier_remove(Object *ob, ModifierData *md, int *sort_depsgraph) 00161 { 00162 ModifierData *obmd; 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 return 0; 00173 00174 /* special cases */ 00175 if(md->type == eModifierType_ParticleSystem) { 00176 ParticleSystemModifierData *psmd=(ParticleSystemModifierData*)md; 00177 00178 BLI_remlink(&ob->particlesystem, psmd->psys); 00179 psys_free(ob, psmd->psys); 00180 psmd->psys= NULL; 00181 } 00182 else if(md->type == eModifierType_Softbody) { 00183 if(ob->soft) { 00184 sbFree(ob->soft); 00185 ob->soft= NULL; 00186 ob->softflag= 0; 00187 } 00188 } 00189 else if(md->type == eModifierType_Collision) { 00190 if(ob->pd) 00191 ob->pd->deflect= 0; 00192 00193 *sort_depsgraph = 1; 00194 } 00195 else if(md->type == eModifierType_Surface) { 00196 if(ob->pd && ob->pd->shape == PFIELD_SHAPE_SURFACE) 00197 ob->pd->shape = PFIELD_SHAPE_PLANE; 00198 00199 *sort_depsgraph = 1; 00200 } 00201 else if(md->type == eModifierType_Smoke) { 00202 ob->dt = OB_TEXTURE; 00203 } 00204 else if(md->type == eModifierType_Multires) { 00205 int ok= 1; 00206 Mesh *me= ob->data; 00207 ModifierData *tmpmd; 00208 00209 /* ensure MDISPS CustomData layer is't used by another multires modifiers */ 00210 for(tmpmd= ob->modifiers.first; tmpmd; tmpmd= tmpmd->next) 00211 if(tmpmd!=md && tmpmd->type == eModifierType_Multires) { 00212 ok= 0; 00213 break; 00214 } 00215 00216 if(ok) { 00217 if(me->edit_mesh) { 00218 EditMesh *em= me->edit_mesh; 00219 /* CustomData_external_remove is used here only to mark layer as non-external 00220 for further free-ing, so zero element count looks safer than em->totface */ 00221 CustomData_external_remove(&em->fdata, &me->id, CD_MDISPS, 0); 00222 EM_free_data_layer(em, &em->fdata, CD_MDISPS); 00223 } else { 00224 CustomData_external_remove(&me->fdata, &me->id, CD_MDISPS, me->totface); 00225 CustomData_free_layer_active(&me->fdata, CD_MDISPS, me->totface); 00226 } 00227 } 00228 } 00229 00230 if(ELEM(md->type, eModifierType_Softbody, eModifierType_Cloth) && 00231 ob->particlesystem.first == NULL) { 00232 ob->mode &= ~OB_MODE_PARTICLE_EDIT; 00233 } 00234 00235 BLI_remlink(&ob->modifiers, md); 00236 modifier_free(md); 00237 00238 return 1; 00239 } 00240 00241 int ED_object_modifier_remove(ReportList *reports, Main *bmain, Scene *scene, Object *ob, ModifierData *md) 00242 { 00243 int sort_depsgraph = 0; 00244 int ok; 00245 00246 ok= object_modifier_remove(ob, md, &sort_depsgraph); 00247 00248 if(!ok) { 00249 BKE_reportf(reports, RPT_ERROR, "Modifier '%s' not in object '%s'", ob->id.name, md->name); 00250 return 0; 00251 } 00252 00253 DAG_id_tag_update(&ob->id, OB_RECALC_DATA); 00254 00255 /* sorting has to be done after the update so that dynamic systems can react properly */ 00256 if(sort_depsgraph) 00257 DAG_scene_sort(bmain, scene); 00258 00259 return 1; 00260 } 00261 00262 void ED_object_modifier_clear(Main *bmain, Scene *scene, Object *ob) 00263 { 00264 ModifierData *md =ob->modifiers.first; 00265 int sort_depsgraph = 0; 00266 00267 if(!md) 00268 return; 00269 00270 while(md) { 00271 ModifierData *next_md; 00272 00273 next_md= md->next; 00274 00275 object_modifier_remove(ob, md, &sort_depsgraph); 00276 00277 md= next_md; 00278 } 00279 00280 DAG_id_tag_update(&ob->id, OB_RECALC_DATA); 00281 00282 /* sorting has to be done after the update so that dynamic systems can react properly */ 00283 if(sort_depsgraph) 00284 DAG_scene_sort(bmain, scene); 00285 } 00286 00287 int ED_object_modifier_move_up(ReportList *reports, Object *ob, ModifierData *md) 00288 { 00289 if(md->prev) { 00290 ModifierTypeInfo *mti = modifierType_getInfo(md->type); 00291 00292 if(mti->type!=eModifierTypeType_OnlyDeform) { 00293 ModifierTypeInfo *nmti = modifierType_getInfo(md->prev->type); 00294 00295 if(nmti->flags&eModifierTypeFlag_RequiresOriginalData) { 00296 BKE_report(reports, RPT_WARNING, "Cannot move above a modifier requiring original data"); 00297 return 0; 00298 } 00299 } 00300 00301 BLI_remlink(&ob->modifiers, md); 00302 BLI_insertlink(&ob->modifiers, md->prev->prev, md); 00303 } 00304 00305 return 1; 00306 } 00307 00308 int ED_object_modifier_move_down(ReportList *reports, Object *ob, ModifierData *md) 00309 { 00310 if(md->next) { 00311 ModifierTypeInfo *mti = modifierType_getInfo(md->type); 00312 00313 if(mti->flags&eModifierTypeFlag_RequiresOriginalData) { 00314 ModifierTypeInfo *nmti = modifierType_getInfo(md->next->type); 00315 00316 if(nmti->type!=eModifierTypeType_OnlyDeform) { 00317 BKE_report(reports, RPT_WARNING, "Cannot move beyond a non-deforming modifier"); 00318 return 0; 00319 } 00320 } 00321 00322 BLI_remlink(&ob->modifiers, md); 00323 BLI_insertlink(&ob->modifiers, md->next, md); 00324 } 00325 00326 return 1; 00327 } 00328 00329 int ED_object_modifier_convert(ReportList *UNUSED(reports), Main *bmain, Scene *scene, Object *ob, ModifierData *md) 00330 { 00331 Object *obn; 00332 ParticleSystem *psys; 00333 ParticleCacheKey *key, **cache; 00334 ParticleSettings *part; 00335 Mesh *me; 00336 MVert *mvert; 00337 MEdge *medge; 00338 int a, k, kmax; 00339 int totvert=0, totedge=0, cvert=0; 00340 int totpart=0, totchild=0; 00341 00342 if(md->type != eModifierType_ParticleSystem) return 0; 00343 if(ob && ob->mode & OB_MODE_PARTICLE_EDIT) return 0; 00344 00345 psys=((ParticleSystemModifierData *)md)->psys; 00346 part= psys->part; 00347 00348 if(part->ren_as != PART_DRAW_PATH || psys->pathcache == NULL) 00349 return 0; 00350 00351 totpart= psys->totcached; 00352 totchild= psys->totchildcache; 00353 00354 if(totchild && (part->draw&PART_DRAW_PARENT)==0) 00355 totpart= 0; 00356 00357 /* count */ 00358 cache= psys->pathcache; 00359 for(a=0; a<totpart; a++) { 00360 key= cache[a]; 00361 00362 if(key->steps > 0) { 00363 totvert+= key->steps+1; 00364 totedge+= key->steps; 00365 } 00366 } 00367 00368 cache= psys->childcache; 00369 for(a=0; a<totchild; a++) { 00370 key= cache[a]; 00371 00372 if(key->steps > 0) { 00373 totvert+= key->steps+1; 00374 totedge+= key->steps; 00375 } 00376 } 00377 00378 if(totvert==0) return 0; 00379 00380 /* add new mesh */ 00381 obn= add_object(scene, OB_MESH); 00382 me= obn->data; 00383 00384 me->totvert= totvert; 00385 me->totedge= totedge; 00386 00387 me->mvert= CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, totvert); 00388 me->medge= CustomData_add_layer(&me->edata, CD_MEDGE, CD_CALLOC, NULL, totedge); 00389 me->mface= CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, 0); 00390 00391 mvert= me->mvert; 00392 medge= me->medge; 00393 00394 /* copy coordinates */ 00395 cache= psys->pathcache; 00396 for(a=0; a<totpart; a++) { 00397 key= cache[a]; 00398 kmax= key->steps; 00399 for(k=0; k<=kmax; k++,key++,cvert++,mvert++) { 00400 copy_v3_v3(mvert->co,key->co); 00401 if(k) { 00402 medge->v1= cvert-1; 00403 medge->v2= cvert; 00404 medge->flag= ME_EDGEDRAW|ME_EDGERENDER|ME_LOOSEEDGE; 00405 medge++; 00406 } 00407 else { 00408 /* cheap trick to select the roots */ 00409 mvert->flag |= SELECT; 00410 } 00411 } 00412 } 00413 00414 cache=psys->childcache; 00415 for(a=0; a<totchild; a++) { 00416 key=cache[a]; 00417 kmax=key->steps; 00418 for(k=0; k<=kmax; k++,key++,cvert++,mvert++) { 00419 copy_v3_v3(mvert->co,key->co); 00420 if(k) { 00421 medge->v1=cvert-1; 00422 medge->v2=cvert; 00423 medge->flag= ME_EDGEDRAW|ME_EDGERENDER|ME_LOOSEEDGE; 00424 medge++; 00425 } 00426 else { 00427 /* cheap trick to select the roots */ 00428 mvert->flag |= SELECT; 00429 } 00430 } 00431 } 00432 00433 DAG_scene_sort(bmain, scene); 00434 00435 return 1; 00436 } 00437 00438 static int modifier_apply_shape(ReportList *reports, Scene *scene, Object *ob, ModifierData *md) 00439 { 00440 ModifierTypeInfo *mti= modifierType_getInfo(md->type); 00441 00442 md->scene= scene; 00443 00444 if (mti->isDisabled && mti->isDisabled(md, 0)) { 00445 BKE_report(reports, RPT_ERROR, "Modifier is disabled, skipping apply"); 00446 return 0; 00447 } 00448 00449 if (ob->type==OB_MESH) { 00450 DerivedMesh *dm; 00451 Mesh *me= ob->data; 00452 Key *key=me->key; 00453 KeyBlock *kb; 00454 00455 if(!modifier_sameTopology(md) || mti->type == eModifierTypeType_NonGeometrical) { 00456 BKE_report(reports, RPT_ERROR, "Only deforming modifiers can be applied to Shapes"); 00457 return 0; 00458 } 00459 00460 dm = mesh_create_derived_for_modifier(scene, ob, md); 00461 if (!dm) { 00462 BKE_report(reports, RPT_ERROR, "Modifier is disabled or returned error, skipping apply"); 00463 return 0; 00464 } 00465 00466 if(key == NULL) { 00467 key= me->key= add_key((ID *)me); 00468 key->type= KEY_RELATIVE; 00469 /* if that was the first key block added, then it was the basis. 00470 * Initialise it with the mesh, and add another for the modifier */ 00471 kb= add_keyblock(key, NULL); 00472 mesh_to_key(me, kb); 00473 } 00474 00475 kb= add_keyblock(key, md->name); 00476 DM_to_meshkey(dm, me, kb); 00477 00478 dm->release(dm); 00479 } 00480 else { 00481 BKE_report(reports, RPT_ERROR, "Cannot apply modifier for this object type"); 00482 return 0; 00483 } 00484 return 1; 00485 } 00486 00487 static int modifier_apply_obdata(ReportList *reports, Scene *scene, Object *ob, ModifierData *md) 00488 { 00489 ModifierTypeInfo *mti= modifierType_getInfo(md->type); 00490 00491 md->scene= scene; 00492 00493 if (mti->isDisabled && mti->isDisabled(md, 0)) { 00494 BKE_report(reports, RPT_ERROR, "Modifier is disabled, skipping apply"); 00495 return 0; 00496 } 00497 00498 if (ob->type==OB_MESH) { 00499 DerivedMesh *dm; 00500 Mesh *me = ob->data; 00501 MultiresModifierData *mmd= find_multires_modifier_before(scene, md); 00502 00503 if(me->key && mti->type != eModifierTypeType_NonGeometrical) { 00504 BKE_report(reports, RPT_ERROR, "Modifier cannot be applied to Mesh with Shape Keys"); 00505 return 0; 00506 } 00507 00508 /* Multires: ensure that recent sculpting is applied */ 00509 if(md->type == eModifierType_Multires) 00510 multires_force_update(ob); 00511 00512 if (mmd && mmd->totlvl && mti->type==eModifierTypeType_OnlyDeform) { 00513 if(!multiresModifier_reshapeFromDeformMod (scene, mmd, ob, md)) { 00514 BKE_report(reports, RPT_ERROR, "Multires modifier returned error, skipping apply"); 00515 return 0; 00516 } 00517 } else { 00518 dm = mesh_create_derived_for_modifier(scene, ob, md); 00519 if (!dm) { 00520 BKE_report(reports, RPT_ERROR, "Modifier returned error, skipping apply"); 00521 return 0; 00522 } 00523 00524 DM_to_mesh(dm, me); 00525 00526 dm->release(dm); 00527 00528 if(md->type == eModifierType_Multires) { 00529 CustomData_external_remove(&me->fdata, &me->id, CD_MDISPS, me->totface); 00530 CustomData_free_layer_active(&me->fdata, CD_MDISPS, me->totface); 00531 } 00532 } 00533 } 00534 else if (ELEM(ob->type, OB_CURVE, OB_SURF)) { 00535 Curve *cu; 00536 int numVerts; 00537 float (*vertexCos)[3]; 00538 00539 if (mti->type==eModifierTypeType_Constructive) { 00540 BKE_report(reports, RPT_ERROR, "Cannot apply constructive modifiers on curve"); 00541 return 0; 00542 } 00543 00544 cu = ob->data; 00545 BKE_report(reports, RPT_INFO, "Applied modifier only changed CV points, not tesselated/bevel vertices"); 00546 00547 vertexCos = curve_getVertexCos(cu, &cu->nurb, &numVerts); 00548 mti->deformVerts(md, ob, NULL, vertexCos, numVerts, 0, 0); 00549 curve_applyVertexCos(cu, &cu->nurb, vertexCos); 00550 00551 MEM_freeN(vertexCos); 00552 00553 DAG_id_tag_update(&ob->id, OB_RECALC_DATA); 00554 } 00555 else { 00556 BKE_report(reports, RPT_ERROR, "Cannot apply modifier for this object type"); 00557 return 0; 00558 } 00559 00560 /* lattice modifier can be applied to particle system too */ 00561 if(ob->particlesystem.first) { 00562 00563 ParticleSystem *psys = ob->particlesystem.first; 00564 00565 for(; psys; psys=psys->next) { 00566 00567 if(psys->part->type != PART_HAIR) 00568 continue; 00569 00570 psys_apply_hair_lattice(scene, ob, psys); 00571 } 00572 } 00573 00574 return 1; 00575 } 00576 00577 int ED_object_modifier_apply(ReportList *reports, Scene *scene, Object *ob, ModifierData *md, int mode) 00578 { 00579 int prev_mode; 00580 00581 if (scene->obedit) { 00582 BKE_report(reports, RPT_ERROR, "Modifiers cannot be applied in editmode"); 00583 return 0; 00584 } else if (((ID*) ob->data)->us>1) { 00585 BKE_report(reports, RPT_ERROR, "Modifiers cannot be applied to multi-user data"); 00586 return 0; 00587 } 00588 00589 if (md!=ob->modifiers.first) 00590 BKE_report(reports, RPT_INFO, "Applied modifier was not first, result may not be as expected"); 00591 00592 /* allow apply of a not-realtime modifier, by first re-enabling realtime. */ 00593 prev_mode= md->mode; 00594 md->mode |= eModifierMode_Realtime; 00595 00596 if (mode == MODIFIER_APPLY_SHAPE) { 00597 if (!modifier_apply_shape(reports, scene, ob, md)) { 00598 md->mode= prev_mode; 00599 return 0; 00600 } 00601 } else { 00602 if (!modifier_apply_obdata(reports, scene, ob, md)) { 00603 md->mode= prev_mode; 00604 return 0; 00605 } 00606 } 00607 00608 BLI_remlink(&ob->modifiers, md); 00609 modifier_free(md); 00610 00611 return 1; 00612 } 00613 00614 int ED_object_modifier_copy(ReportList *UNUSED(reports), Object *ob, ModifierData *md) 00615 { 00616 ModifierData *nmd; 00617 00618 nmd = modifier_new(md->type); 00619 modifier_copyData(md, nmd); 00620 BLI_insertlink(&ob->modifiers, md, nmd); 00621 modifier_unique_name(&ob->modifiers, nmd); 00622 00623 return 1; 00624 } 00625 00626 /************************ add modifier operator *********************/ 00627 00628 static int modifier_add_exec(bContext *C, wmOperator *op) 00629 { 00630 Main *bmain= CTX_data_main(C); 00631 Scene *scene= CTX_data_scene(C); 00632 Object *ob = ED_object_active_context(C); 00633 int type= RNA_enum_get(op->ptr, "type"); 00634 00635 if(!ED_object_modifier_add(op->reports, bmain, scene, ob, NULL, type)) 00636 return OPERATOR_CANCELLED; 00637 00638 WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); 00639 00640 return OPERATOR_FINISHED; 00641 } 00642 00643 static EnumPropertyItem *modifier_add_itemf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), int *free) 00644 { 00645 Object *ob= ED_object_active_context(C); 00646 EnumPropertyItem *item= NULL, *md_item, *group_item= NULL; 00647 ModifierTypeInfo *mti; 00648 int totitem= 0, a; 00649 00650 if(!ob) 00651 return modifier_type_items; 00652 00653 for(a=0; modifier_type_items[a].identifier; a++) { 00654 md_item= &modifier_type_items[a]; 00655 00656 if(md_item->identifier[0]) { 00657 mti= modifierType_getInfo(md_item->value); 00658 00659 if(mti->flags & eModifierTypeFlag_NoUserAdd) 00660 continue; 00661 00662 if(!((mti->flags & eModifierTypeFlag_AcceptsCVs) || 00663 (ob->type==OB_MESH && (mti->flags & eModifierTypeFlag_AcceptsMesh)))) 00664 continue; 00665 } 00666 else { 00667 group_item= md_item; 00668 md_item= NULL; 00669 00670 continue; 00671 } 00672 00673 if(group_item) { 00674 RNA_enum_item_add(&item, &totitem, group_item); 00675 group_item= NULL; 00676 } 00677 00678 RNA_enum_item_add(&item, &totitem, md_item); 00679 } 00680 00681 RNA_enum_item_end(&item, &totitem); 00682 *free= 1; 00683 00684 return item; 00685 } 00686 00687 void OBJECT_OT_modifier_add(wmOperatorType *ot) 00688 { 00689 PropertyRNA *prop; 00690 00691 /* identifiers */ 00692 ot->name= "Add Modifier"; 00693 ot->description = "Add a modifier to the active object"; 00694 ot->idname= "OBJECT_OT_modifier_add"; 00695 00696 /* api callbacks */ 00697 ot->invoke= WM_menu_invoke; 00698 ot->exec= modifier_add_exec; 00699 ot->poll= ED_operator_object_active_editable; 00700 00701 /* flags */ 00702 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00703 00704 /* properties */ 00705 prop= RNA_def_enum(ot->srna, "type", modifier_type_items, eModifierType_Subsurf, "Type", ""); 00706 RNA_def_enum_funcs(prop, modifier_add_itemf); 00707 ot->prop= prop; 00708 } 00709 00710 /************************ generic functions for operators using mod names and data context *********************/ 00711 00712 static int edit_modifier_poll_generic(bContext *C, StructRNA *rna_type, int obtype_flag) 00713 { 00714 PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", rna_type); 00715 Object *ob= (ptr.id.data)?ptr.id.data:ED_object_active_context(C); 00716 00717 if (!ob || ob->id.lib) return 0; 00718 if (obtype_flag && ((1<<ob->type) & obtype_flag)==0) return 0; 00719 if (ptr.id.data && ((ID*)ptr.id.data)->lib) return 0; 00720 00721 return 1; 00722 } 00723 00724 static int edit_modifier_poll(bContext *C) 00725 { 00726 return edit_modifier_poll_generic(C, &RNA_Modifier, 0); 00727 } 00728 00729 static void edit_modifier_properties(wmOperatorType *ot) 00730 { 00731 RNA_def_string(ot->srna, "modifier", "", MAX_NAME, "Modifier", "Name of the modifier to edit"); 00732 } 00733 00734 static int edit_modifier_invoke_properties(bContext *C, wmOperator *op) 00735 { 00736 PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier); 00737 ModifierData *md; 00738 00739 if (RNA_struct_property_is_set(op->ptr, "modifier")) 00740 return 1; 00741 00742 if (ptr.data) { 00743 md = ptr.data; 00744 RNA_string_set(op->ptr, "modifier", md->name); 00745 return 1; 00746 } 00747 00748 return 0; 00749 } 00750 00751 static ModifierData *edit_modifier_property_get(wmOperator *op, Object *ob, int type) 00752 { 00753 char modifier_name[MAX_NAME]; 00754 ModifierData *md; 00755 RNA_string_get(op->ptr, "modifier", modifier_name); 00756 00757 md = modifiers_findByName(ob, modifier_name); 00758 00759 if (md && type != 0 && md->type != type) 00760 md = NULL; 00761 00762 return md; 00763 } 00764 00765 /************************ remove modifier operator *********************/ 00766 00767 static int modifier_remove_exec(bContext *C, wmOperator *op) 00768 { 00769 Main *bmain= CTX_data_main(C); 00770 Scene *scene= CTX_data_scene(C); 00771 Object *ob = ED_object_active_context(C); 00772 ModifierData *md = edit_modifier_property_get(op, ob, 0); 00773 int mode_orig = ob ? ob->mode : 0; 00774 00775 if(!ob || !md || !ED_object_modifier_remove(op->reports, bmain, scene, ob, md)) 00776 return OPERATOR_CANCELLED; 00777 00778 WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); 00779 00780 /* if cloth/softbody was removed, particle mode could be cleared */ 00781 if(mode_orig & OB_MODE_PARTICLE_EDIT) 00782 if((ob->mode & OB_MODE_PARTICLE_EDIT)==0) 00783 if(scene->basact && scene->basact->object==ob) 00784 WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_OBJECT, NULL); 00785 00786 return OPERATOR_FINISHED; 00787 } 00788 00789 static int modifier_remove_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) 00790 { 00791 if (edit_modifier_invoke_properties(C, op)) 00792 return modifier_remove_exec(C, op); 00793 else 00794 return OPERATOR_CANCELLED; 00795 } 00796 00797 void OBJECT_OT_modifier_remove(wmOperatorType *ot) 00798 { 00799 ot->name= "Remove Modifier"; 00800 ot->description= "Remove a modifier from the active object"; 00801 ot->idname= "OBJECT_OT_modifier_remove"; 00802 00803 ot->invoke= modifier_remove_invoke; 00804 ot->exec= modifier_remove_exec; 00805 ot->poll= edit_modifier_poll; 00806 00807 /* flags */ 00808 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00809 edit_modifier_properties(ot); 00810 } 00811 00812 /************************ move up modifier operator *********************/ 00813 00814 static int modifier_move_up_exec(bContext *C, wmOperator *op) 00815 { 00816 Object *ob = ED_object_active_context(C); 00817 ModifierData *md = edit_modifier_property_get(op, ob, 0); 00818 00819 if(!ob || !md || !ED_object_modifier_move_up(op->reports, ob, md)) 00820 return OPERATOR_CANCELLED; 00821 00822 DAG_id_tag_update(&ob->id, OB_RECALC_DATA); 00823 WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); 00824 00825 return OPERATOR_FINISHED; 00826 } 00827 00828 static int modifier_move_up_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) 00829 { 00830 if (edit_modifier_invoke_properties(C, op)) 00831 return modifier_move_up_exec(C, op); 00832 else 00833 return OPERATOR_CANCELLED; 00834 } 00835 00836 void OBJECT_OT_modifier_move_up(wmOperatorType *ot) 00837 { 00838 ot->name= "Move Up Modifier"; 00839 ot->description= "Move modifier up in the stack"; 00840 ot->idname= "OBJECT_OT_modifier_move_up"; 00841 00842 ot->invoke= modifier_move_up_invoke; 00843 ot->exec= modifier_move_up_exec; 00844 ot->poll= edit_modifier_poll; 00845 00846 /* flags */ 00847 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00848 edit_modifier_properties(ot); 00849 } 00850 00851 /************************ move down modifier operator *********************/ 00852 00853 static int modifier_move_down_exec(bContext *C, wmOperator *op) 00854 { 00855 Object *ob = ED_object_active_context(C); 00856 ModifierData *md = edit_modifier_property_get(op, ob, 0); 00857 00858 if(!ob || !md || !ED_object_modifier_move_down(op->reports, ob, md)) 00859 return OPERATOR_CANCELLED; 00860 00861 DAG_id_tag_update(&ob->id, OB_RECALC_DATA); 00862 WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); 00863 00864 return OPERATOR_FINISHED; 00865 } 00866 00867 static int modifier_move_down_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) 00868 { 00869 if (edit_modifier_invoke_properties(C, op)) 00870 return modifier_move_down_exec(C, op); 00871 else 00872 return OPERATOR_CANCELLED; 00873 } 00874 00875 void OBJECT_OT_modifier_move_down(wmOperatorType *ot) 00876 { 00877 ot->name= "Move Down Modifier"; 00878 ot->description= "Move modifier down in the stack"; 00879 ot->idname= "OBJECT_OT_modifier_move_down"; 00880 00881 ot->invoke= modifier_move_down_invoke; 00882 ot->exec= modifier_move_down_exec; 00883 ot->poll= edit_modifier_poll; 00884 00885 /* flags */ 00886 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00887 edit_modifier_properties(ot); 00888 } 00889 00890 /************************ apply modifier operator *********************/ 00891 00892 static int modifier_apply_exec(bContext *C, wmOperator *op) 00893 { 00894 Scene *scene= CTX_data_scene(C); 00895 Object *ob = ED_object_active_context(C); 00896 ModifierData *md = edit_modifier_property_get(op, ob, 0); 00897 int apply_as= RNA_enum_get(op->ptr, "apply_as"); 00898 00899 if(!ob || !md || !ED_object_modifier_apply(op->reports, scene, ob, md, apply_as)) { 00900 return OPERATOR_CANCELLED; 00901 } 00902 00903 DAG_id_tag_update(&ob->id, OB_RECALC_DATA); 00904 WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); 00905 00906 return OPERATOR_FINISHED; 00907 } 00908 00909 static int modifier_apply_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) 00910 { 00911 if (edit_modifier_invoke_properties(C, op)) 00912 return modifier_apply_exec(C, op); 00913 else 00914 return OPERATOR_CANCELLED; 00915 } 00916 00917 static EnumPropertyItem modifier_apply_as_items[] = { 00918 {MODIFIER_APPLY_DATA, "DATA", 0, "Object Data", "Apply modifier to the object's data"}, 00919 {MODIFIER_APPLY_SHAPE, "SHAPE", 0, "New Shape", "Apply deform-only modifier to a new shape on this object"}, 00920 {0, NULL, 0, NULL, NULL}}; 00921 00922 void OBJECT_OT_modifier_apply(wmOperatorType *ot) 00923 { 00924 ot->name= "Apply Modifier"; 00925 ot->description= "Apply modifier and remove from the stack"; 00926 ot->idname= "OBJECT_OT_modifier_apply"; 00927 00928 ot->invoke= modifier_apply_invoke; 00929 ot->exec= modifier_apply_exec; 00930 ot->poll= edit_modifier_poll; 00931 00932 /* flags */ 00933 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00934 00935 RNA_def_enum(ot->srna, "apply_as", modifier_apply_as_items, MODIFIER_APPLY_DATA, "Apply as", "How to apply the modifier to the geometry"); 00936 edit_modifier_properties(ot); 00937 } 00938 00939 /************************ convert modifier operator *********************/ 00940 00941 static int modifier_convert_exec(bContext *C, wmOperator *op) 00942 { 00943 Main *bmain= CTX_data_main(C); 00944 Scene *scene= CTX_data_scene(C); 00945 Object *ob = ED_object_active_context(C); 00946 ModifierData *md = edit_modifier_property_get(op, ob, 0); 00947 00948 if(!ob || !md || !ED_object_modifier_convert(op->reports, bmain, scene, ob, md)) 00949 return OPERATOR_CANCELLED; 00950 00951 DAG_id_tag_update(&ob->id, OB_RECALC_DATA); 00952 WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); 00953 00954 return OPERATOR_FINISHED; 00955 } 00956 00957 static int modifier_convert_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) 00958 { 00959 if (edit_modifier_invoke_properties(C, op)) 00960 return modifier_convert_exec(C, op); 00961 else 00962 return OPERATOR_CANCELLED; 00963 } 00964 00965 void OBJECT_OT_modifier_convert(wmOperatorType *ot) 00966 { 00967 ot->name= "Convert Modifier"; 00968 ot->description= "Convert particles to a mesh object"; 00969 ot->idname= "OBJECT_OT_modifier_convert"; 00970 00971 ot->invoke= modifier_convert_invoke; 00972 ot->exec= modifier_convert_exec; 00973 ot->poll= edit_modifier_poll; 00974 00975 /* flags */ 00976 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00977 edit_modifier_properties(ot); 00978 } 00979 00980 /************************ copy modifier operator *********************/ 00981 00982 static int modifier_copy_exec(bContext *C, wmOperator *op) 00983 { 00984 Object *ob = ED_object_active_context(C); 00985 ModifierData *md = edit_modifier_property_get(op, ob, 0); 00986 00987 if(!ob || !md || !ED_object_modifier_copy(op->reports, ob, md)) 00988 return OPERATOR_CANCELLED; 00989 00990 DAG_id_tag_update(&ob->id, OB_RECALC_DATA); 00991 WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); 00992 00993 return OPERATOR_FINISHED; 00994 } 00995 00996 static int modifier_copy_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) 00997 { 00998 if (edit_modifier_invoke_properties(C, op)) 00999 return modifier_copy_exec(C, op); 01000 else 01001 return OPERATOR_CANCELLED; 01002 } 01003 01004 void OBJECT_OT_modifier_copy(wmOperatorType *ot) 01005 { 01006 ot->name= "Copy Modifier"; 01007 ot->description= "Duplicate modifier at the same position in the stack"; 01008 ot->idname= "OBJECT_OT_modifier_copy"; 01009 01010 ot->invoke= modifier_copy_invoke; 01011 ot->exec= modifier_copy_exec; 01012 ot->poll= edit_modifier_poll; 01013 01014 /* flags */ 01015 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 01016 edit_modifier_properties(ot); 01017 } 01018 01019 /************* multires delete higher levels operator ****************/ 01020 01021 static int multires_poll(bContext *C) 01022 { 01023 return edit_modifier_poll_generic(C, &RNA_MultiresModifier, (1<<OB_MESH)); 01024 } 01025 01026 static int multires_higher_levels_delete_exec(bContext *C, wmOperator *op) 01027 { 01028 Object *ob = ED_object_active_context(C); 01029 MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get(op, ob, eModifierType_Multires); 01030 01031 if (!mmd) 01032 return OPERATOR_CANCELLED; 01033 01034 multiresModifier_del_levels(mmd, ob, 1); 01035 01036 WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); 01037 01038 return OPERATOR_FINISHED; 01039 } 01040 01041 static int multires_higher_levels_delete_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) 01042 { 01043 if (edit_modifier_invoke_properties(C, op)) 01044 return multires_higher_levels_delete_exec(C, op); 01045 else 01046 return OPERATOR_CANCELLED; 01047 } 01048 01049 void OBJECT_OT_multires_higher_levels_delete(wmOperatorType *ot) 01050 { 01051 ot->name= "Delete Higher Levels"; 01052 ot->description= "Deletes the higher resolution mesh, potential loss of detail"; 01053 ot->idname= "OBJECT_OT_multires_higher_levels_delete"; 01054 01055 ot->poll= multires_poll; 01056 ot->invoke= multires_higher_levels_delete_invoke; 01057 ot->exec= multires_higher_levels_delete_exec; 01058 01059 /* flags */ 01060 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 01061 edit_modifier_properties(ot); 01062 } 01063 01064 /****************** multires subdivide operator *********************/ 01065 01066 static int multires_subdivide_exec(bContext *C, wmOperator *op) 01067 { 01068 Object *ob = ED_object_active_context(C); 01069 MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get(op, ob, eModifierType_Multires); 01070 01071 if (!mmd) 01072 return OPERATOR_CANCELLED; 01073 01074 multiresModifier_subdivide(mmd, ob, 0, mmd->simple); 01075 01076 DAG_id_tag_update(&ob->id, OB_RECALC_DATA); 01077 WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); 01078 01079 return OPERATOR_FINISHED; 01080 } 01081 01082 static int multires_subdivide_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) 01083 { 01084 if (edit_modifier_invoke_properties(C, op)) 01085 return multires_subdivide_exec(C, op); 01086 else 01087 return OPERATOR_CANCELLED; 01088 } 01089 01090 void OBJECT_OT_multires_subdivide(wmOperatorType *ot) 01091 { 01092 ot->name= "Multires Subdivide"; 01093 ot->description= "Add a new level of subdivision"; 01094 ot->idname= "OBJECT_OT_multires_subdivide"; 01095 01096 ot->poll= multires_poll; 01097 ot->invoke= multires_subdivide_invoke; 01098 ot->exec= multires_subdivide_exec; 01099 01100 /* flags */ 01101 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 01102 edit_modifier_properties(ot); 01103 } 01104 01105 /****************** multires reshape operator *********************/ 01106 01107 static int multires_reshape_exec(bContext *C, wmOperator *op) 01108 { 01109 Object *ob= ED_object_active_context(C), *secondob= NULL; 01110 Scene *scene= CTX_data_scene(C); 01111 MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get(op, ob, eModifierType_Multires); 01112 01113 if (!mmd) 01114 return OPERATOR_CANCELLED; 01115 01116 if(mmd->lvl==0) { 01117 BKE_report(op->reports, RPT_ERROR, "Reshape can work only with higher levels of subdivisions"); 01118 return OPERATOR_CANCELLED; 01119 } 01120 01121 CTX_DATA_BEGIN(C, Object*, selob, selected_editable_objects) { 01122 if(selob->type == OB_MESH && selob != ob) { 01123 secondob= selob; 01124 break; 01125 } 01126 } 01127 CTX_DATA_END; 01128 01129 if(!secondob) { 01130 BKE_report(op->reports, RPT_ERROR, "Second selected mesh object require to copy shape from"); 01131 return OPERATOR_CANCELLED; 01132 } 01133 01134 if(!multiresModifier_reshape(scene, mmd, ob, secondob)) { 01135 BKE_report(op->reports, RPT_ERROR, "Objects do not have the same number of vertices"); 01136 return OPERATOR_CANCELLED; 01137 } 01138 01139 DAG_id_tag_update(&ob->id, OB_RECALC_DATA); 01140 WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); 01141 01142 return OPERATOR_FINISHED; 01143 } 01144 01145 static int multires_reshape_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) 01146 { 01147 if (edit_modifier_invoke_properties(C, op)) 01148 return multires_reshape_exec(C, op); 01149 else 01150 return OPERATOR_CANCELLED; 01151 } 01152 01153 void OBJECT_OT_multires_reshape(wmOperatorType *ot) 01154 { 01155 ot->name= "Multires Reshape"; 01156 ot->description= "Copy vertex coordinates from other object"; 01157 ot->idname= "OBJECT_OT_multires_reshape"; 01158 01159 ot->poll= multires_poll; 01160 ot->invoke= multires_reshape_invoke; 01161 ot->exec= multires_reshape_exec; 01162 01163 /* flags */ 01164 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 01165 edit_modifier_properties(ot); 01166 } 01167 01168 /****************** multires save external operator *********************/ 01169 01170 static int multires_external_save_exec(bContext *C, wmOperator *op) 01171 { 01172 Object *ob = ED_object_active_context(C); 01173 Mesh *me= (ob)? ob->data: op->customdata; 01174 char path[FILE_MAX]; 01175 int relative= RNA_boolean_get(op->ptr, "relative_path"); 01176 01177 if(!me) 01178 return OPERATOR_CANCELLED; 01179 01180 if(CustomData_external_test(&me->fdata, CD_MDISPS)) 01181 return OPERATOR_CANCELLED; 01182 01183 RNA_string_get(op->ptr, "filepath", path); 01184 01185 if(relative) 01186 BLI_path_rel(path, G.main->name); 01187 01188 CustomData_external_add(&me->fdata, &me->id, CD_MDISPS, me->totface, path); 01189 CustomData_external_write(&me->fdata, &me->id, CD_MASK_MESH, me->totface, 0); 01190 01191 return OPERATOR_FINISHED; 01192 } 01193 01194 static int multires_external_save_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) 01195 { 01196 Object *ob = ED_object_active_context(C); 01197 MultiresModifierData *mmd; 01198 Mesh *me= ob->data; 01199 char path[FILE_MAX]; 01200 01201 if (!edit_modifier_invoke_properties(C, op)) 01202 return OPERATOR_CANCELLED; 01203 01204 mmd = (MultiresModifierData *)edit_modifier_property_get(op, ob, eModifierType_Multires); 01205 01206 if (!mmd) 01207 return OPERATOR_CANCELLED; 01208 01209 if(CustomData_external_test(&me->fdata, CD_MDISPS)) 01210 return OPERATOR_CANCELLED; 01211 01212 if(RNA_struct_property_is_set(op->ptr, "filepath")) 01213 return multires_external_save_exec(C, op); 01214 01215 op->customdata= me; 01216 01217 BLI_snprintf(path, sizeof(path), "//%s.btx", me->id.name+2); 01218 RNA_string_set(op->ptr, "filepath", path); 01219 01220 WM_event_add_fileselect(C, op); 01221 01222 return OPERATOR_RUNNING_MODAL; 01223 } 01224 01225 void OBJECT_OT_multires_external_save(wmOperatorType *ot) 01226 { 01227 ot->name= "Multires Save External"; 01228 ot->description= "Save displacements to an external file"; 01229 ot->idname= "OBJECT_OT_multires_external_save"; 01230 01231 // XXX modifier no longer in context after file browser .. ot->poll= multires_poll; 01232 ot->exec= multires_external_save_exec; 01233 ot->invoke= multires_external_save_invoke; 01234 ot->poll= multires_poll; 01235 01236 /* flags */ 01237 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 01238 01239 WM_operator_properties_filesel(ot, FOLDERFILE|BTXFILE, FILE_SPECIAL, FILE_SAVE, WM_FILESEL_FILEPATH|WM_FILESEL_RELPATH); 01240 edit_modifier_properties(ot); 01241 } 01242 01243 /****************** multires pack operator *********************/ 01244 01245 static int multires_external_pack_exec(bContext *C, wmOperator *UNUSED(op)) 01246 { 01247 Object *ob = ED_object_active_context(C); 01248 Mesh *me= ob->data; 01249 01250 if(!CustomData_external_test(&me->fdata, CD_MDISPS)) 01251 return OPERATOR_CANCELLED; 01252 01253 // XXX don't remove.. 01254 CustomData_external_remove(&me->fdata, &me->id, CD_MDISPS, me->totface); 01255 01256 return OPERATOR_FINISHED; 01257 } 01258 01259 void OBJECT_OT_multires_external_pack(wmOperatorType *ot) 01260 { 01261 ot->name= "Multires Pack External"; 01262 ot->description= "Pack displacements from an external file"; 01263 ot->idname= "OBJECT_OT_multires_external_pack"; 01264 01265 ot->poll= multires_poll; 01266 ot->exec= multires_external_pack_exec; 01267 01268 /* flags */ 01269 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 01270 } 01271 01272 /********************* multires apply base ***********************/ 01273 static int multires_base_apply_exec(bContext *C, wmOperator *op) 01274 { 01275 Object *ob = ED_object_active_context(C); 01276 MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get(op, ob, eModifierType_Multires); 01277 01278 if (!mmd) 01279 return OPERATOR_CANCELLED; 01280 01281 multiresModifier_base_apply(mmd, ob); 01282 01283 DAG_id_tag_update(&ob->id, OB_RECALC_DATA); 01284 WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); 01285 01286 return OPERATOR_FINISHED; 01287 } 01288 01289 static int multires_base_apply_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) 01290 { 01291 if (edit_modifier_invoke_properties(C, op)) 01292 return multires_base_apply_exec(C, op); 01293 else 01294 return OPERATOR_CANCELLED; 01295 } 01296 01297 01298 void OBJECT_OT_multires_base_apply(wmOperatorType *ot) 01299 { 01300 ot->name= "Multires Apply Base"; 01301 ot->description= "Modify the base mesh to conform to the displaced mesh"; 01302 ot->idname= "OBJECT_OT_multires_base_apply"; 01303 01304 ot->poll= multires_poll; 01305 ot->invoke= multires_base_apply_invoke; 01306 ot->exec= multires_base_apply_exec; 01307 01308 /* flags */ 01309 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 01310 edit_modifier_properties(ot); 01311 } 01312 01313 01314 /************************ mdef bind operator *********************/ 01315 01316 static int meshdeform_poll(bContext *C) 01317 { 01318 return edit_modifier_poll_generic(C, &RNA_MeshDeformModifier, (1<<OB_MESH)); 01319 } 01320 01321 static int meshdeform_bind_exec(bContext *C, wmOperator *op) 01322 { 01323 Scene *scene= CTX_data_scene(C); 01324 Object *ob = ED_object_active_context(C); 01325 MeshDeformModifierData *mmd = (MeshDeformModifierData *)edit_modifier_property_get(op, ob, eModifierType_MeshDeform); 01326 01327 if (!mmd) 01328 return OPERATOR_CANCELLED; 01329 01330 if(mmd->bindcagecos) { 01331 MEM_freeN(mmd->bindcagecos); 01332 if(mmd->dyngrid) MEM_freeN(mmd->dyngrid); 01333 if(mmd->dyninfluences) MEM_freeN(mmd->dyninfluences); 01334 if(mmd->bindinfluences) MEM_freeN(mmd->bindinfluences); 01335 if(mmd->bindoffsets) MEM_freeN(mmd->bindoffsets); 01336 if(mmd->dynverts) MEM_freeN(mmd->dynverts); 01337 if(mmd->bindweights) MEM_freeN(mmd->bindweights); /* deprecated */ 01338 if(mmd->bindcos) MEM_freeN(mmd->bindcos); /* deprecated */ 01339 01340 mmd->bindcagecos= NULL; 01341 mmd->dyngrid= NULL; 01342 mmd->dyninfluences= NULL; 01343 mmd->bindoffsets= NULL; 01344 mmd->dynverts= NULL; 01345 mmd->bindweights= NULL; /* deprecated */ 01346 mmd->bindcos= NULL; /* deprecated */ 01347 mmd->totvert= 0; 01348 mmd->totcagevert= 0; 01349 mmd->totinfluence= 0; 01350 01351 DAG_id_tag_update(&ob->id, OB_RECALC_DATA); 01352 WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); 01353 } 01354 else { 01355 DerivedMesh *dm; 01356 int mode= mmd->modifier.mode; 01357 01358 /* force modifier to run, it will call binding routine */ 01359 mmd->bindfunc= mesh_deform_bind; 01360 mmd->modifier.mode |= eModifierMode_Realtime; 01361 01362 if(ob->type == OB_MESH) { 01363 dm= mesh_create_derived_view(scene, ob, 0); 01364 dm->release(dm); 01365 } 01366 else if(ob->type == OB_LATTICE) { 01367 lattice_calc_modifiers(scene, ob); 01368 } 01369 else if(ob->type==OB_MBALL) { 01370 makeDispListMBall(scene, ob); 01371 } 01372 else if(ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT)) { 01373 makeDispListCurveTypes(scene, ob, 0); 01374 } 01375 01376 mmd->bindfunc= NULL; 01377 mmd->modifier.mode= mode; 01378 } 01379 01380 return OPERATOR_FINISHED; 01381 } 01382 01383 static int meshdeform_bind_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) 01384 { 01385 if (edit_modifier_invoke_properties(C, op)) 01386 return meshdeform_bind_exec(C, op); 01387 else 01388 return OPERATOR_CANCELLED; 01389 } 01390 01391 void OBJECT_OT_meshdeform_bind(wmOperatorType *ot) 01392 { 01393 /* identifiers */ 01394 ot->name= "Mesh Deform Bind"; 01395 ot->description = "Bind mesh to cage in mesh deform modifier"; 01396 ot->idname= "OBJECT_OT_meshdeform_bind"; 01397 01398 /* api callbacks */ 01399 ot->poll= meshdeform_poll; 01400 ot->invoke= meshdeform_bind_invoke; 01401 ot->exec= meshdeform_bind_exec; 01402 01403 /* flags */ 01404 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 01405 edit_modifier_properties(ot); 01406 } 01407 01408 /****************** explode refresh operator *********************/ 01409 01410 static int explode_poll(bContext *C) 01411 { 01412 return edit_modifier_poll_generic(C, &RNA_ExplodeModifier, 0); 01413 } 01414 01415 static int explode_refresh_exec(bContext *C, wmOperator *op) 01416 { 01417 Object *ob = ED_object_active_context(C); 01418 ExplodeModifierData *emd = (ExplodeModifierData *)edit_modifier_property_get(op, ob, eModifierType_Explode); 01419 01420 if (!emd) 01421 return OPERATOR_CANCELLED; 01422 01423 emd->flag |= eExplodeFlag_CalcFaces; 01424 01425 DAG_id_tag_update(&ob->id, OB_RECALC_DATA); 01426 WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); 01427 01428 return OPERATOR_FINISHED; 01429 } 01430 01431 static int explode_refresh_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) 01432 { 01433 if (edit_modifier_invoke_properties(C, op)) 01434 return explode_refresh_exec(C, op); 01435 else 01436 return OPERATOR_CANCELLED; 01437 } 01438 01439 01440 void OBJECT_OT_explode_refresh(wmOperatorType *ot) 01441 { 01442 ot->name= "Explode Refresh"; 01443 ot->description= "Refresh data in the Explode modifier"; 01444 ot->idname= "OBJECT_OT_explode_refresh"; 01445 01446 ot->poll= explode_poll; 01447 ot->invoke= explode_refresh_invoke; 01448 ot->exec= explode_refresh_exec; 01449 01450 /* flags */ 01451 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 01452 edit_modifier_properties(ot); 01453 } 01454 01455 01456 /****************** ocean bake operator *********************/ 01457 01458 static int ocean_bake_poll(bContext *C) 01459 { 01460 return edit_modifier_poll_generic(C, &RNA_OceanModifier, 0); 01461 } 01462 01463 /* copied from init_ocean_modifier, MOD_ocean.c */ 01464 static void init_ocean_modifier_bake(struct Ocean *oc, struct OceanModifierData *omd) 01465 { 01466 int do_heightfield, do_chop, do_normals, do_jacobian; 01467 01468 if (!omd || !oc) return; 01469 01470 do_heightfield = TRUE; 01471 do_chop = (omd->chop_amount > 0); 01472 do_normals = (omd->flag & MOD_OCEAN_GENERATE_NORMALS); 01473 do_jacobian = (omd->flag & MOD_OCEAN_GENERATE_FOAM); 01474 01475 BKE_init_ocean(oc, omd->resolution*omd->resolution, omd->resolution*omd->resolution, omd->spatial_size, omd->spatial_size, 01476 omd->wind_velocity, omd->smallest_wave, 1.0, omd->wave_direction, omd->damp, omd->wave_alignment, 01477 omd->depth, omd->time, 01478 do_heightfield, do_chop, do_normals, do_jacobian, 01479 omd->seed); 01480 } 01481 01482 typedef struct OceanBakeJob { 01483 /* from wmJob */ 01484 void *owner; 01485 short *stop, *do_update; 01486 float *progress; 01487 int current_frame; 01488 struct OceanCache *och; 01489 struct Ocean *ocean; 01490 struct OceanModifierData *omd; 01491 } OceanBakeJob; 01492 01493 static void oceanbake_free(void *customdata) 01494 { 01495 OceanBakeJob *oj= customdata; 01496 MEM_freeN(oj); 01497 } 01498 01499 /* called by oceanbake, only to check job 'stop' value */ 01500 static int oceanbake_breakjob(void *UNUSED(customdata)) 01501 { 01502 //OceanBakeJob *ob= (OceanBakeJob *)customdata; 01503 //return *(ob->stop); 01504 01505 /* this is not nice yet, need to make the jobs list template better 01506 * for identifying/acting upon various different jobs */ 01507 /* but for now we'll reuse the render break... */ 01508 return (G.afbreek); 01509 } 01510 01511 /* called by oceanbake, wmJob sends notifier */ 01512 static void oceanbake_update(void *customdata, float progress, int *cancel) 01513 { 01514 OceanBakeJob *oj= customdata; 01515 01516 if (oceanbake_breakjob(oj)) 01517 *cancel = 1; 01518 01519 *(oj->do_update)= 1; 01520 *(oj->progress)= progress; 01521 } 01522 01523 static void oceanbake_startjob(void *customdata, short *stop, short *do_update, float *progress) 01524 { 01525 OceanBakeJob *oj= customdata; 01526 01527 oj->stop= stop; 01528 oj->do_update = do_update; 01529 oj->progress = progress; 01530 01531 G.afbreek= 0; /* XXX shared with render - replace with job 'stop' switch */ 01532 01533 BKE_bake_ocean(oj->ocean, oj->och, oceanbake_update, (void *)oj); 01534 01535 *do_update= 1; 01536 *stop = 0; 01537 } 01538 01539 static void oceanbake_endjob(void *customdata) 01540 { 01541 OceanBakeJob *oj= customdata; 01542 01543 if (oj->ocean) { 01544 BKE_free_ocean(oj->ocean); 01545 oj->ocean = NULL; 01546 } 01547 01548 oj->omd->oceancache = oj->och; 01549 oj->omd->cached = TRUE; 01550 } 01551 01552 static int ocean_bake_exec(bContext *C, wmOperator *op) 01553 { 01554 Object *ob = ED_object_active_context(C); 01555 OceanModifierData *omd = (OceanModifierData *)edit_modifier_property_get(op, ob, eModifierType_Ocean); 01556 Scene *scene = CTX_data_scene(C); 01557 OceanCache *och; 01558 struct Ocean *ocean; 01559 int f, cfra, i=0; 01560 int free= RNA_boolean_get(op->ptr, "free"); 01561 01562 wmJob *steve; 01563 OceanBakeJob *oj; 01564 01565 if (!omd) 01566 return OPERATOR_CANCELLED; 01567 01568 if (free) { 01569 omd->refresh |= MOD_OCEAN_REFRESH_CLEAR_CACHE; 01570 DAG_id_tag_update(&ob->id, OB_RECALC_DATA); 01571 WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); 01572 return OPERATOR_FINISHED; 01573 } 01574 01575 och = BKE_init_ocean_cache(omd->cachepath, modifier_path_relbase(ob), 01576 omd->bakestart, omd->bakeend, omd->wave_scale, 01577 omd->chop_amount, omd->foam_coverage, omd->foam_fade, omd->resolution); 01578 01579 och->time = MEM_mallocN(och->duration*sizeof(float), "foam bake time"); 01580 01581 cfra = scene->r.cfra; 01582 01583 /* precalculate time variable before baking */ 01584 for (f=omd->bakestart; f<=omd->bakeend; f++) { 01585 /* from physics_fluid.c: 01586 01587 * XXX: This can't be used due to an anim sys optimisation that ignores recalc object animation, 01588 * leaving it for the depgraph (this ignores object animation such as modifier properties though... :/ ) 01589 * --> BKE_animsys_evaluate_all_animation(G.main, eval_time); 01590 * This doesn't work with drivers: 01591 * --> BKE_animsys_evaluate_animdata(&fsDomain->id, fsDomain->adt, eval_time, ADT_RECALC_ALL); 01592 */ 01593 01594 /* Modifying the global scene isn't nice, but we can do it in 01595 * this part of the process before a threaded job is created */ 01596 01597 //scene->r.cfra = f; 01598 //ED_update_for_newframe(CTX_data_main(C), scene, CTX_wm_screen(C), 1); 01599 01600 /* ok, this doesn't work with drivers, but is way faster. 01601 * let's use this for now and hope nobody wants to drive the time value... */ 01602 BKE_animsys_evaluate_animdata(scene, (ID *)ob, ob->adt, f, ADT_RECALC_ANIM); 01603 01604 och->time[i] = omd->time; 01605 i++; 01606 } 01607 01608 /* make a copy of ocean to use for baking - threadsafety */ 01609 ocean = BKE_add_ocean(); 01610 init_ocean_modifier_bake(ocean, omd); 01611 01612 /* 01613 BKE_bake_ocean(ocean, och); 01614 01615 omd->oceancache = och; 01616 omd->cached = TRUE; 01617 01618 scene->r.cfra = cfra; 01619 01620 DAG_id_tag_update(&ob->id, OB_RECALC_DATA); 01621 WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); 01622 */ 01623 01624 /* job stuff */ 01625 01626 scene->r.cfra = cfra; 01627 01628 /* setup job */ 01629 steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, "Ocean Simulation", WM_JOB_PROGRESS); 01630 oj= MEM_callocN(sizeof(OceanBakeJob), "ocean bake job"); 01631 oj->ocean = ocean; 01632 oj->och = och; 01633 oj->omd = omd; 01634 01635 WM_jobs_customdata(steve, oj, oceanbake_free); 01636 WM_jobs_timer(steve, 0.1, NC_OBJECT|ND_MODIFIER, NC_OBJECT|ND_MODIFIER); 01637 WM_jobs_callbacks(steve, oceanbake_startjob, NULL, NULL, oceanbake_endjob); 01638 01639 WM_jobs_start(CTX_wm_manager(C), steve); 01640 01641 01642 01643 return OPERATOR_FINISHED; 01644 } 01645 01646 static int ocean_bake_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) 01647 { 01648 if (edit_modifier_invoke_properties(C, op)) 01649 return ocean_bake_exec(C, op); 01650 else 01651 return OPERATOR_CANCELLED; 01652 } 01653 01654 01655 void OBJECT_OT_ocean_bake(wmOperatorType *ot) 01656 { 01657 ot->name= "Bake Ocean"; 01658 ot->description= "Bake an image sequence of ocean data"; 01659 ot->idname= "OBJECT_OT_ocean_bake"; 01660 01661 ot->poll= ocean_bake_poll; 01662 ot->invoke= ocean_bake_invoke; 01663 ot->exec= ocean_bake_exec; 01664 01665 /* flags */ 01666 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 01667 edit_modifier_properties(ot); 01668 01669 RNA_def_boolean(ot->srna, "free", FALSE, "Free", "Free the bake, rather than generating it"); 01670 } 01671