2 * ***** BEGIN GPL LICENSE BLOCK *****
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19 * All rights reserved.
21 * Contributor(s): Blender Foundation, 2009
23 * ***** END GPL LICENSE BLOCK *****
26 /** \file blender/editors/object/object_modifier.c
35 #include "MEM_guardedalloc.h"
37 #include "DNA_anim_types.h"
38 #include "DNA_curve_types.h"
39 #include "DNA_key_types.h"
40 #include "DNA_mesh_types.h"
41 #include "DNA_meshdata_types.h"
42 #include "DNA_object_force.h"
43 #include "DNA_scene_types.h"
46 #include "BLI_listbase.h"
47 #include "BLI_string.h"
48 #include "BLI_path_util.h"
49 #include "BLI_editVert.h"
50 #include "BLI_utildefines.h"
52 #include "BKE_animsys.h"
53 #include "BKE_curve.h"
54 #include "BKE_context.h"
55 #include "BKE_depsgraph.h"
56 #include "BKE_displist.h"
57 #include "BKE_DerivedMesh.h"
58 #include "BKE_effect.h"
59 #include "BKE_global.h"
61 #include "BKE_lattice.h"
64 #include "BKE_modifier.h"
65 #include "BKE_multires.h"
66 #include "BKE_report.h"
67 #include "BKE_object.h"
68 #include "BKE_ocean.h"
69 #include "BKE_particle.h"
70 #include "BKE_softbody.h"
71 #include "BKE_tessmesh.h"
73 #include "RNA_access.h"
74 #include "RNA_define.h"
75 #include "RNA_enum_types.h"
77 #include "ED_armature.h"
78 #include "ED_object.h"
79 #include "ED_screen.h"
85 #include "object_intern.h"
87 /******************************** API ****************************/
89 ModifierData *ED_object_modifier_add(ReportList *reports, Main *bmain, Scene *scene, Object *ob, const char *name, int type)
91 ModifierData *md=NULL, *new_md=NULL;
92 ModifierTypeInfo *mti = modifierType_getInfo(type);
94 /* only geometry objects should be able to get modifiers [#25291] */
95 if(!ELEM5(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_LATTICE)) {
96 BKE_reportf(reports, RPT_WARNING, "Modifiers cannot be added to Object '%s'", ob->id.name+2);
100 if(mti->flags&eModifierTypeFlag_Single) {
101 if(modifiers_findByType(ob, type)) {
102 BKE_report(reports, RPT_WARNING, "Only one modifier of this type allowed");
107 if(type == eModifierType_ParticleSystem) {
108 /* don't need to worry about the new modifier's name, since that is set to the number
109 * of particle systems which shouldn't have too many duplicates
111 new_md = object_add_particle_system(scene, ob, name);
114 /* get new modifier data to add */
115 new_md= modifier_new(type);
117 if(mti->flags&eModifierTypeFlag_RequiresOriginalData) {
118 md = ob->modifiers.first;
120 while(md && modifierType_getInfo(md->type)->type==eModifierTypeType_OnlyDeform)
123 BLI_insertlinkbefore(&ob->modifiers, md, new_md);
126 BLI_addtail(&ob->modifiers, new_md);
129 BLI_strncpy(new_md->name, name, sizeof(new_md->name));
131 /* make sure modifier data has unique name */
133 modifier_unique_name(&ob->modifiers, new_md);
136 if(type == eModifierType_Softbody) {
138 ob->soft= sbNew(scene);
139 ob->softflag |= OB_SB_GOAL|OB_SB_EDGES;
142 else if(type == eModifierType_Collision) {
144 ob->pd= object_add_collision_fields(0);
147 DAG_scene_sort(bmain, scene);
149 else if(type == eModifierType_Surface)
150 DAG_scene_sort(bmain, scene);
151 else if(type == eModifierType_Multires)
152 /* set totlvl from existing MDISPS layer if object already had it */
153 multiresModifier_set_levels_from_disps((MultiresModifierData *)new_md, ob);
156 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
161 static int object_modifier_remove(Object *ob, ModifierData *md, int *sort_depsgraph)
165 /* It seems on rapid delete it is possible to
166 * get called twice on same modifier, so make
167 * sure it is in list. */
168 for(obmd=ob->modifiers.first; obmd; obmd=obmd->next)
176 if(md->type == eModifierType_ParticleSystem) {
177 ParticleSystemModifierData *psmd=(ParticleSystemModifierData*)md;
179 BLI_remlink(&ob->particlesystem, psmd->psys);
180 psys_free(ob, psmd->psys);
183 else if(md->type == eModifierType_Softbody) {
190 else if(md->type == eModifierType_Collision) {
196 else if(md->type == eModifierType_Surface) {
197 if(ob->pd && ob->pd->shape == PFIELD_SHAPE_SURFACE)
198 ob->pd->shape = PFIELD_SHAPE_PLANE;
202 else if(md->type == eModifierType_Smoke) {
205 else if(md->type == eModifierType_Multires) {
210 /* ensure MDISPS CustomData layer is't used by another multires modifiers */
211 for(tmpmd= ob->modifiers.first; tmpmd; tmpmd= tmpmd->next)
212 if(tmpmd!=md && tmpmd->type == eModifierType_Multires) {
218 if(me->edit_btmesh) {
219 BMEditMesh *em= me->edit_btmesh;
220 /* CustomData_external_remove is used here only to mark layer as non-external
221 for further free-ing, so zero element count looks safer than em->totface */
222 CustomData_external_remove(&em->bm->ldata, &me->id, CD_MDISPS, 0);
223 BM_free_data_layer(em->bm, &em->bm->ldata, CD_MDISPS);
225 CustomData_external_remove(&me->ldata, &me->id, CD_MDISPS, me->totloop);
226 CustomData_free_layer_active(&me->ldata, CD_MDISPS, me->totloop);
231 if(ELEM(md->type, eModifierType_Softbody, eModifierType_Cloth) &&
232 ob->particlesystem.first == NULL) {
233 ob->mode &= ~OB_MODE_PARTICLE_EDIT;
236 BLI_remlink(&ob->modifiers, md);
242 int ED_object_modifier_remove(ReportList *reports, Main *bmain, Scene *scene, Object *ob, ModifierData *md)
244 int sort_depsgraph = 0;
247 ok= object_modifier_remove(ob, md, &sort_depsgraph);
250 BKE_reportf(reports, RPT_ERROR, "Modifier '%s' not in object '%s'", ob->id.name, md->name);
254 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
256 /* sorting has to be done after the update so that dynamic systems can react properly */
258 DAG_scene_sort(bmain, scene);
263 void ED_object_modifier_clear(Main *bmain, Scene *scene, Object *ob)
265 ModifierData *md =ob->modifiers.first;
266 int sort_depsgraph = 0;
272 ModifierData *next_md;
276 object_modifier_remove(ob, md, &sort_depsgraph);
281 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
283 /* sorting has to be done after the update so that dynamic systems can react properly */
285 DAG_scene_sort(bmain, scene);
288 int ED_object_modifier_move_up(ReportList *reports, Object *ob, ModifierData *md)
291 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
293 if(mti->type!=eModifierTypeType_OnlyDeform) {
294 ModifierTypeInfo *nmti = modifierType_getInfo(md->prev->type);
296 if(nmti->flags&eModifierTypeFlag_RequiresOriginalData) {
297 BKE_report(reports, RPT_WARNING, "Cannot move above a modifier requiring original data");
302 BLI_remlink(&ob->modifiers, md);
303 BLI_insertlink(&ob->modifiers, md->prev->prev, md);
309 int ED_object_modifier_move_down(ReportList *reports, Object *ob, ModifierData *md)
312 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
314 if(mti->flags&eModifierTypeFlag_RequiresOriginalData) {
315 ModifierTypeInfo *nmti = modifierType_getInfo(md->next->type);
317 if(nmti->type!=eModifierTypeType_OnlyDeform) {
318 BKE_report(reports, RPT_WARNING, "Cannot move beyond a non-deforming modifier");
323 BLI_remlink(&ob->modifiers, md);
324 BLI_insertlink(&ob->modifiers, md->next, md);
330 int ED_object_modifier_convert(ReportList *UNUSED(reports), Main *bmain, Scene *scene, Object *ob, ModifierData *md)
333 ParticleSystem *psys;
334 ParticleCacheKey *key, **cache;
335 ParticleSettings *part;
340 int totvert=0, totedge=0, cvert=0;
341 int totpart=0, totchild=0;
343 if(md->type != eModifierType_ParticleSystem) return 0;
344 if(ob && ob->mode & OB_MODE_PARTICLE_EDIT) return 0;
346 psys=((ParticleSystemModifierData *)md)->psys;
349 if(part->ren_as != PART_DRAW_PATH || psys->pathcache == NULL)
352 totpart= psys->totcached;
353 totchild= psys->totchildcache;
355 if(totchild && (part->draw&PART_DRAW_PARENT)==0)
359 cache= psys->pathcache;
360 for(a=0; a<totpart; a++) {
364 totvert+= key->steps+1;
365 totedge+= key->steps;
369 cache= psys->childcache;
370 for(a=0; a<totchild; a++) {
374 totvert+= key->steps+1;
375 totedge+= key->steps;
379 if(totvert==0) return 0;
382 obn= add_object(scene, OB_MESH);
385 me->totvert= totvert;
386 me->totedge= totedge;
388 me->mvert= CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, totvert);
389 me->medge= CustomData_add_layer(&me->edata, CD_MEDGE, CD_CALLOC, NULL, totedge);
390 me->mface= CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, 0);
395 /* copy coordinates */
396 cache= psys->pathcache;
397 for(a=0; a<totpart; a++) {
400 for(k=0; k<=kmax; k++,key++,cvert++,mvert++) {
401 copy_v3_v3(mvert->co,key->co);
405 medge->flag= ME_EDGEDRAW|ME_EDGERENDER|ME_LOOSEEDGE;
409 /* cheap trick to select the roots */
410 mvert->flag |= SELECT;
415 cache=psys->childcache;
416 for(a=0; a<totchild; a++) {
419 for(k=0; k<=kmax; k++,key++,cvert++,mvert++) {
420 copy_v3_v3(mvert->co,key->co);
424 medge->flag= ME_EDGEDRAW|ME_EDGERENDER|ME_LOOSEEDGE;
428 /* cheap trick to select the roots */
429 mvert->flag |= SELECT;
434 DAG_scene_sort(bmain, scene);
439 static int modifier_apply_shape(ReportList *reports, Scene *scene, Object *ob, ModifierData *md)
441 ModifierTypeInfo *mti= modifierType_getInfo(md->type);
445 if (mti->isDisabled && mti->isDisabled(md, 0)) {
446 BKE_report(reports, RPT_ERROR, "Modifier is disabled, skipping apply");
451 It should be ridiculously easy to extract the original verts that we want
452 and form the shape data. We can probably use the CD KEYINDEX layer (or
453 whatever I ended up calling it, too tired to check now), though this would
454 by necassity have to make some potentially ugly assumptions about the order
455 of the mesh data :-/ you can probably assume in 99% of cases that the first
456 element of a given index is the original, and any subsequent duplicates are
457 copies/interpolates, but that's an assumption that would need to be tested
458 and then predominantly stated in comments in a half dozen headers.
461 if (ob->type==OB_MESH) {
467 if(!modifier_sameTopology(md) || mti->type == eModifierTypeType_NonGeometrical) {
468 BKE_report(reports, RPT_ERROR, "Only deforming modifiers can be applied to Shapes");
472 dm = mesh_create_derived_for_modifier(scene, ob, md, 0);
474 BKE_report(reports, RPT_ERROR, "Modifier is disabled or returned error, skipping apply");
479 key= me->key= add_key((ID *)me);
480 key->type= KEY_RELATIVE;
481 /* if that was the first key block added, then it was the basis.
482 * Initialise it with the mesh, and add another for the modifier */
483 kb= add_keyblock(key, NULL);
487 kb= add_keyblock(key, md->name);
488 DM_to_meshkey(dm, me, kb);
493 BKE_report(reports, RPT_ERROR, "Cannot apply modifier for this object type");
499 static int modifier_apply_obdata(ReportList *reports, Scene *scene, Object *ob, ModifierData *md)
501 ModifierTypeInfo *mti= modifierType_getInfo(md->type);
505 if (mti->isDisabled && mti->isDisabled(md, 0)) {
506 BKE_report(reports, RPT_ERROR, "Modifier is disabled, skipping apply");
510 if (ob->type==OB_MESH) {
513 MultiresModifierData *mmd= find_multires_modifier_before(scene, md);
515 if(me->key && mti->type != eModifierTypeType_NonGeometrical) {
516 BKE_report(reports, RPT_ERROR, "Modifier cannot be applied to Mesh with Shape Keys");
520 /* Multires: ensure that recent sculpting is applied */
521 if(md->type == eModifierType_Multires)
522 multires_force_update(ob);
524 if (mmd && mmd->totlvl && mti->type==eModifierTypeType_OnlyDeform) {
525 if(!multiresModifier_reshapeFromDeformMod (scene, mmd, ob, md)) {
526 BKE_report(reports, RPT_ERROR, "Multires modifier returned error, skipping apply");
530 dm = mesh_create_derived_for_modifier(scene, ob, md, 1);
532 BKE_report(reports, RPT_ERROR, "Modifier returned error, skipping apply");
536 DM_to_mesh(dm, me, ob);
540 if(md->type == eModifierType_Multires) {
541 CustomData_external_remove(&me->ldata, &me->id, CD_MDISPS, me->totloop);
542 CustomData_free_layer_active(&me->ldata, CD_MDISPS, me->totloop);
546 else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
549 float (*vertexCos)[3];
551 if (mti->type==eModifierTypeType_Constructive) {
552 BKE_report(reports, RPT_ERROR, "Cannot apply constructive modifiers on curve");
557 BKE_report(reports, RPT_INFO, "Applied modifier only changed CV points, not tesselated/bevel vertices");
559 vertexCos = curve_getVertexCos(cu, &cu->nurb, &numVerts);
560 mti->deformVerts(md, ob, NULL, vertexCos, numVerts, 0, 0);
561 curve_applyVertexCos(cu, &cu->nurb, vertexCos);
563 MEM_freeN(vertexCos);
565 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
568 BKE_report(reports, RPT_ERROR, "Cannot apply modifier for this object type");
572 /* lattice modifier can be applied to particle system too */
573 if(ob->particlesystem.first) {
575 ParticleSystem *psys = ob->particlesystem.first;
577 for(; psys; psys=psys->next) {
579 if(psys->part->type != PART_HAIR)
582 psys_apply_hair_lattice(scene, ob, psys);
589 int ED_object_modifier_apply(ReportList *reports, Scene *scene, Object *ob, ModifierData *md, int mode)
594 BKE_report(reports, RPT_ERROR, "Modifiers cannot be applied in editmode");
596 } else if (((ID*) ob->data)->us>1) {
597 BKE_report(reports, RPT_ERROR, "Modifiers cannot be applied to multi-user data");
601 if (md!=ob->modifiers.first)
602 BKE_report(reports, RPT_INFO, "Applied modifier was not first, result may not be as expected");
604 /* allow apply of a not-realtime modifier, by first re-enabling realtime. */
606 md->mode |= eModifierMode_Realtime;
608 if (mode == MODIFIER_APPLY_SHAPE) {
609 if (!modifier_apply_shape(reports, scene, ob, md)) {
614 if (!modifier_apply_obdata(reports, scene, ob, md)) {
620 BLI_remlink(&ob->modifiers, md);
626 int ED_object_modifier_copy(ReportList *UNUSED(reports), Object *ob, ModifierData *md)
630 nmd = modifier_new(md->type);
631 modifier_copyData(md, nmd);
632 BLI_insertlink(&ob->modifiers, md, nmd);
633 modifier_unique_name(&ob->modifiers, nmd);
638 /************************ add modifier operator *********************/
640 static int modifier_add_exec(bContext *C, wmOperator *op)
642 Main *bmain= CTX_data_main(C);
643 Scene *scene= CTX_data_scene(C);
644 Object *ob = ED_object_active_context(C);
645 int type= RNA_enum_get(op->ptr, "type");
647 if(!ED_object_modifier_add(op->reports, bmain, scene, ob, NULL, type))
648 return OPERATOR_CANCELLED;
650 WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
652 return OPERATOR_FINISHED;
655 static EnumPropertyItem *modifier_add_itemf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), int *free)
657 Object *ob= ED_object_active_context(C);
658 EnumPropertyItem *item= NULL, *md_item, *group_item= NULL;
659 ModifierTypeInfo *mti;
663 return modifier_type_items;
665 for(a=0; modifier_type_items[a].identifier; a++) {
666 md_item= &modifier_type_items[a];
668 if(md_item->identifier[0]) {
669 mti= modifierType_getInfo(md_item->value);
671 if(mti->flags & eModifierTypeFlag_NoUserAdd)
674 if(!((mti->flags & eModifierTypeFlag_AcceptsCVs) ||
675 (ob->type==OB_MESH && (mti->flags & eModifierTypeFlag_AcceptsMesh))))
686 RNA_enum_item_add(&item, &totitem, group_item);
690 RNA_enum_item_add(&item, &totitem, md_item);
693 RNA_enum_item_end(&item, &totitem);
699 void OBJECT_OT_modifier_add(wmOperatorType *ot)
704 ot->name= "Add Modifier";
705 ot->description = "Add a modifier to the active object";
706 ot->idname= "OBJECT_OT_modifier_add";
709 ot->invoke= WM_menu_invoke;
710 ot->exec= modifier_add_exec;
711 ot->poll= ED_operator_object_active_editable;
714 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
717 prop= RNA_def_enum(ot->srna, "type", modifier_type_items, eModifierType_Subsurf, "Type", "");
718 RNA_def_enum_funcs(prop, modifier_add_itemf);
722 /************************ generic functions for operators using mod names and data context *********************/
724 static int edit_modifier_poll_generic(bContext *C, StructRNA *rna_type, int obtype_flag)
726 PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", rna_type);
727 Object *ob= (ptr.id.data)?ptr.id.data:ED_object_active_context(C);
729 if (!ob || ob->id.lib) return 0;
730 if (obtype_flag && ((1<<ob->type) & obtype_flag)==0) return 0;
731 if (ptr.id.data && ((ID*)ptr.id.data)->lib) return 0;
736 static int edit_modifier_poll(bContext *C)
738 return edit_modifier_poll_generic(C, &RNA_Modifier, 0);
741 static void edit_modifier_properties(wmOperatorType *ot)
743 RNA_def_string(ot->srna, "modifier", "", MAX_NAME, "Modifier", "Name of the modifier to edit");
746 static int edit_modifier_invoke_properties(bContext *C, wmOperator *op)
748 PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier);
751 if (RNA_struct_property_is_set(op->ptr, "modifier"))
756 RNA_string_set(op->ptr, "modifier", md->name);
763 static ModifierData *edit_modifier_property_get(wmOperator *op, Object *ob, int type)
765 char modifier_name[MAX_NAME];
767 RNA_string_get(op->ptr, "modifier", modifier_name);
769 md = modifiers_findByName(ob, modifier_name);
771 if (md && type != 0 && md->type != type)
777 /************************ remove modifier operator *********************/
779 static int modifier_remove_exec(bContext *C, wmOperator *op)
781 Main *bmain= CTX_data_main(C);
782 Scene *scene= CTX_data_scene(C);
783 Object *ob = ED_object_active_context(C);
784 ModifierData *md = edit_modifier_property_get(op, ob, 0);
785 int mode_orig = ob ? ob->mode : 0;
787 if(!ob || !md || !ED_object_modifier_remove(op->reports, bmain, scene, ob, md))
788 return OPERATOR_CANCELLED;
790 WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
792 /* if cloth/softbody was removed, particle mode could be cleared */
793 if(mode_orig & OB_MODE_PARTICLE_EDIT)
794 if((ob->mode & OB_MODE_PARTICLE_EDIT)==0)
795 if(scene->basact && scene->basact->object==ob)
796 WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_OBJECT, NULL);
798 return OPERATOR_FINISHED;
801 static int modifier_remove_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
803 if (edit_modifier_invoke_properties(C, op))
804 return modifier_remove_exec(C, op);
806 return OPERATOR_CANCELLED;
809 void OBJECT_OT_modifier_remove(wmOperatorType *ot)
811 ot->name= "Remove Modifier";
812 ot->description= "Remove a modifier from the active object";
813 ot->idname= "OBJECT_OT_modifier_remove";
815 ot->invoke= modifier_remove_invoke;
816 ot->exec= modifier_remove_exec;
817 ot->poll= edit_modifier_poll;
820 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
821 edit_modifier_properties(ot);
824 /************************ move up modifier operator *********************/
826 static int modifier_move_up_exec(bContext *C, wmOperator *op)
828 Object *ob = ED_object_active_context(C);
829 ModifierData *md = edit_modifier_property_get(op, ob, 0);
831 if(!ob || !md || !ED_object_modifier_move_up(op->reports, ob, md))
832 return OPERATOR_CANCELLED;
834 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
835 WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
837 return OPERATOR_FINISHED;
840 static int modifier_move_up_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
842 if (edit_modifier_invoke_properties(C, op))
843 return modifier_move_up_exec(C, op);
845 return OPERATOR_CANCELLED;
848 void OBJECT_OT_modifier_move_up(wmOperatorType *ot)
850 ot->name= "Move Up Modifier";
851 ot->description= "Move modifier up in the stack";
852 ot->idname= "OBJECT_OT_modifier_move_up";
854 ot->invoke= modifier_move_up_invoke;
855 ot->exec= modifier_move_up_exec;
856 ot->poll= edit_modifier_poll;
859 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
860 edit_modifier_properties(ot);
863 /************************ move down modifier operator *********************/
865 static int modifier_move_down_exec(bContext *C, wmOperator *op)
867 Object *ob = ED_object_active_context(C);
868 ModifierData *md = edit_modifier_property_get(op, ob, 0);
870 if(!ob || !md || !ED_object_modifier_move_down(op->reports, ob, md))
871 return OPERATOR_CANCELLED;
873 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
874 WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
876 return OPERATOR_FINISHED;
879 static int modifier_move_down_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
881 if (edit_modifier_invoke_properties(C, op))
882 return modifier_move_down_exec(C, op);
884 return OPERATOR_CANCELLED;
887 void OBJECT_OT_modifier_move_down(wmOperatorType *ot)
889 ot->name= "Move Down Modifier";
890 ot->description= "Move modifier down in the stack";
891 ot->idname= "OBJECT_OT_modifier_move_down";
893 ot->invoke= modifier_move_down_invoke;
894 ot->exec= modifier_move_down_exec;
895 ot->poll= edit_modifier_poll;
898 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
899 edit_modifier_properties(ot);
902 /************************ apply modifier operator *********************/
904 static int modifier_apply_exec(bContext *C, wmOperator *op)
906 Scene *scene= CTX_data_scene(C);
907 Object *ob = ED_object_active_context(C);
908 ModifierData *md = edit_modifier_property_get(op, ob, 0);
909 int apply_as= RNA_enum_get(op->ptr, "apply_as");
911 if(!ob || !md || !ED_object_modifier_apply(op->reports, scene, ob, md, apply_as)) {
912 return OPERATOR_CANCELLED;
915 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
916 WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
918 return OPERATOR_FINISHED;
921 static int modifier_apply_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
923 if (edit_modifier_invoke_properties(C, op))
924 return modifier_apply_exec(C, op);
926 return OPERATOR_CANCELLED;
929 static EnumPropertyItem modifier_apply_as_items[] = {
930 {MODIFIER_APPLY_DATA, "DATA", 0, "Object Data", "Apply modifier to the object's data"},
931 {MODIFIER_APPLY_SHAPE, "SHAPE", 0, "New Shape", "Apply deform-only modifier to a new shape on this object"},
932 {0, NULL, 0, NULL, NULL}};
934 void OBJECT_OT_modifier_apply(wmOperatorType *ot)
936 ot->name= "Apply Modifier";
937 ot->description= "Apply modifier and remove from the stack";
938 ot->idname= "OBJECT_OT_modifier_apply";
940 ot->invoke= modifier_apply_invoke;
941 ot->exec= modifier_apply_exec;
942 ot->poll= edit_modifier_poll;
945 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
947 RNA_def_enum(ot->srna, "apply_as", modifier_apply_as_items, MODIFIER_APPLY_DATA, "Apply as", "How to apply the modifier to the geometry");
948 edit_modifier_properties(ot);
951 /************************ convert modifier operator *********************/
953 static int modifier_convert_exec(bContext *C, wmOperator *op)
955 Main *bmain= CTX_data_main(C);
956 Scene *scene= CTX_data_scene(C);
957 Object *ob = ED_object_active_context(C);
958 ModifierData *md = edit_modifier_property_get(op, ob, 0);
960 if(!ob || !md || !ED_object_modifier_convert(op->reports, bmain, scene, ob, md))
961 return OPERATOR_CANCELLED;
963 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
964 WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
966 return OPERATOR_FINISHED;
969 static int modifier_convert_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
971 if (edit_modifier_invoke_properties(C, op))
972 return modifier_convert_exec(C, op);
974 return OPERATOR_CANCELLED;
977 void OBJECT_OT_modifier_convert(wmOperatorType *ot)
979 ot->name= "Convert Modifier";
980 ot->description= "Convert particles to a mesh object";
981 ot->idname= "OBJECT_OT_modifier_convert";
983 ot->invoke= modifier_convert_invoke;
984 ot->exec= modifier_convert_exec;
985 ot->poll= edit_modifier_poll;
988 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
989 edit_modifier_properties(ot);
992 /************************ copy modifier operator *********************/
994 static int modifier_copy_exec(bContext *C, wmOperator *op)
996 Object *ob = ED_object_active_context(C);
997 ModifierData *md = edit_modifier_property_get(op, ob, 0);
999 if(!ob || !md || !ED_object_modifier_copy(op->reports, ob, md))
1000 return OPERATOR_CANCELLED;
1002 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
1003 WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
1005 return OPERATOR_FINISHED;
1008 static int modifier_copy_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
1010 if (edit_modifier_invoke_properties(C, op))
1011 return modifier_copy_exec(C, op);
1013 return OPERATOR_CANCELLED;
1016 void OBJECT_OT_modifier_copy(wmOperatorType *ot)
1018 ot->name= "Copy Modifier";
1019 ot->description= "Duplicate modifier at the same position in the stack";
1020 ot->idname= "OBJECT_OT_modifier_copy";
1022 ot->invoke= modifier_copy_invoke;
1023 ot->exec= modifier_copy_exec;
1024 ot->poll= edit_modifier_poll;
1027 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1028 edit_modifier_properties(ot);
1031 /************* multires delete higher levels operator ****************/
1033 static int multires_poll(bContext *C)
1035 return edit_modifier_poll_generic(C, &RNA_MultiresModifier, (1<<OB_MESH));
1038 static int multires_higher_levels_delete_exec(bContext *C, wmOperator *op)
1040 Object *ob = ED_object_active_context(C);
1041 MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get(op, ob, eModifierType_Multires);
1044 return OPERATOR_CANCELLED;
1046 multiresModifier_del_levels(mmd, ob, 1);
1048 WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
1050 return OPERATOR_FINISHED;
1053 static int multires_higher_levels_delete_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
1055 if (edit_modifier_invoke_properties(C, op))
1056 return multires_higher_levels_delete_exec(C, op);
1058 return OPERATOR_CANCELLED;
1061 void OBJECT_OT_multires_higher_levels_delete(wmOperatorType *ot)
1063 ot->name= "Delete Higher Levels";
1064 ot->description= "Deletes the higher resolution mesh, potential loss of detail";
1065 ot->idname= "OBJECT_OT_multires_higher_levels_delete";
1067 ot->poll= multires_poll;
1068 ot->invoke= multires_higher_levels_delete_invoke;
1069 ot->exec= multires_higher_levels_delete_exec;
1072 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1073 edit_modifier_properties(ot);
1076 /****************** multires subdivide operator *********************/
1078 static int multires_subdivide_exec(bContext *C, wmOperator *op)
1080 Object *ob = ED_object_active_context(C);
1081 MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get(op, ob, eModifierType_Multires);
1084 return OPERATOR_CANCELLED;
1086 multiresModifier_subdivide(mmd, ob, 0, mmd->simple);
1088 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
1089 WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
1091 return OPERATOR_FINISHED;
1094 static int multires_subdivide_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
1096 if (edit_modifier_invoke_properties(C, op))
1097 return multires_subdivide_exec(C, op);
1099 return OPERATOR_CANCELLED;
1102 void OBJECT_OT_multires_subdivide(wmOperatorType *ot)
1104 ot->name= "Multires Subdivide";
1105 ot->description= "Add a new level of subdivision";
1106 ot->idname= "OBJECT_OT_multires_subdivide";
1108 ot->poll= multires_poll;
1109 ot->invoke= multires_subdivide_invoke;
1110 ot->exec= multires_subdivide_exec;
1113 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1114 edit_modifier_properties(ot);
1117 /****************** multires reshape operator *********************/
1119 static int multires_reshape_exec(bContext *C, wmOperator *op)
1121 Object *ob= ED_object_active_context(C), *secondob= NULL;
1122 Scene *scene= CTX_data_scene(C);
1123 MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get(op, ob, eModifierType_Multires);
1126 return OPERATOR_CANCELLED;
1129 BKE_report(op->reports, RPT_ERROR, "Reshape can work only with higher levels of subdivisions");
1130 return OPERATOR_CANCELLED;
1133 CTX_DATA_BEGIN(C, Object*, selob, selected_editable_objects) {
1134 if(selob->type == OB_MESH && selob != ob) {
1142 BKE_report(op->reports, RPT_ERROR, "Second selected mesh object require to copy shape from");
1143 return OPERATOR_CANCELLED;
1146 if(!multiresModifier_reshape(scene, mmd, ob, secondob)) {
1147 BKE_report(op->reports, RPT_ERROR, "Objects do not have the same number of vertices");
1148 return OPERATOR_CANCELLED;
1151 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
1152 WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
1154 return OPERATOR_FINISHED;
1157 static int multires_reshape_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
1159 if (edit_modifier_invoke_properties(C, op))
1160 return multires_reshape_exec(C, op);
1162 return OPERATOR_CANCELLED;
1165 void OBJECT_OT_multires_reshape(wmOperatorType *ot)
1167 ot->name= "Multires Reshape";
1168 ot->description= "Copy vertex coordinates from other object";
1169 ot->idname= "OBJECT_OT_multires_reshape";
1171 ot->poll= multires_poll;
1172 ot->invoke= multires_reshape_invoke;
1173 ot->exec= multires_reshape_exec;
1176 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1177 edit_modifier_properties(ot);
1180 static int multires_test_exec(bContext *C, wmOperator *op)
1182 Object *ob= ED_object_active_context(C);
1183 Mesh *me = ob->data;
1186 int i, x = RNA_int_get(op->ptr, "x"), y = RNA_int_get(op->ptr, "y");
1188 if (ob->type != OB_MESH || !me)
1189 return OPERATOR_CANCELLED;
1191 mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS);
1193 return OPERATOR_CANCELLED;
1196 for (i=0; i<me->totpoly; i++, mp++) {
1200 ml = me->mloop + mp->loopstart;
1201 for (j=0; j<mp->totloop; j++, ml++) {
1202 MLoop *ml_prev = ME_POLY_LOOP_PREV(me->mloop, mp, j);
1203 MLoop *ml_next = ME_POLY_LOOP_NEXT(me->mloop, mp, j);
1205 if ((me->mvert[ml->v].flag&SELECT) && (me->mvert[ml_prev->v].flag&SELECT) && (me->mvert[ml_next->v].flag&SELECT)) {
1206 MDisps *md = mdisps + mp->loopstart + j;
1207 int res = sqrt(md->totdisp);
1209 if (x >= res) x = res-1;
1210 if (y >= res) y = res-1;
1212 md->disps[y*res + x][2] += 1.0;
1217 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
1218 WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
1220 return OPERATOR_FINISHED;
1223 void OBJECT_OT_test_multires(wmOperatorType *ot)
1225 ot->name= "Multires Object Mode Test";
1226 ot->description= "";
1227 ot->idname= "OBJECT_OT_test_multires";
1229 ot->poll= multires_poll;
1230 ot->exec= multires_test_exec;
1233 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1234 RNA_def_int(ot->srna, "x", 0, 0, 100, "x", "x", 0, 100);
1235 RNA_def_int(ot->srna, "y", 0, 0, 100, "y", "y", 0, 100);
1240 /****************** multires save external operator *********************/
1242 static int multires_external_save_exec(bContext *C, wmOperator *op)
1244 Object *ob = ED_object_active_context(C);
1245 Mesh *me= (ob)? ob->data: op->customdata;
1246 char path[FILE_MAX];
1247 int relative= RNA_boolean_get(op->ptr, "relative_path");
1250 return OPERATOR_CANCELLED;
1252 if(CustomData_external_test(&me->ldata, CD_MDISPS))
1253 return OPERATOR_CANCELLED;
1255 RNA_string_get(op->ptr, "filepath", path);
1258 BLI_path_rel(path, G.main->name);
1260 CustomData_external_add(&me->ldata, &me->id, CD_MDISPS, me->totloop, path);
1261 CustomData_external_write(&me->ldata, &me->id, CD_MASK_MESH, me->totloop, 0);
1263 return OPERATOR_FINISHED;
1266 static int multires_external_save_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
1268 Object *ob = ED_object_active_context(C);
1269 MultiresModifierData *mmd;
1271 char path[FILE_MAX];
1273 if (!edit_modifier_invoke_properties(C, op))
1274 return OPERATOR_CANCELLED;
1276 mmd = (MultiresModifierData *)edit_modifier_property_get(op, ob, eModifierType_Multires);
1279 return OPERATOR_CANCELLED;
1281 if(CustomData_external_test(&me->ldata, CD_MDISPS))
1282 return OPERATOR_CANCELLED;
1284 if(RNA_struct_property_is_set(op->ptr, "filepath"))
1285 return multires_external_save_exec(C, op);
1289 BLI_snprintf(path, sizeof(path), "//%s.btx", me->id.name+2);
1290 RNA_string_set(op->ptr, "filepath", path);
1292 WM_event_add_fileselect(C, op);
1294 return OPERATOR_RUNNING_MODAL;
1297 void OBJECT_OT_multires_external_save(wmOperatorType *ot)
1299 ot->name= "Multires Save External";
1300 ot->description= "Save displacements to an external file";
1301 ot->idname= "OBJECT_OT_multires_external_save";
1303 // XXX modifier no longer in context after file browser .. ot->poll= multires_poll;
1304 ot->exec= multires_external_save_exec;
1305 ot->invoke= multires_external_save_invoke;
1306 ot->poll= multires_poll;
1309 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1311 WM_operator_properties_filesel(ot, FOLDERFILE|BTXFILE, FILE_SPECIAL, FILE_SAVE, WM_FILESEL_FILEPATH|WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY);
1312 edit_modifier_properties(ot);
1315 /****************** multires pack operator *********************/
1317 static int multires_external_pack_exec(bContext *C, wmOperator *UNUSED(op))
1319 Object *ob = ED_object_active_context(C);
1322 if(!CustomData_external_test(&me->ldata, CD_MDISPS))
1323 return OPERATOR_CANCELLED;
1325 // XXX don't remove..
1326 CustomData_external_remove(&me->ldata, &me->id, CD_MDISPS, me->totloop);
1328 return OPERATOR_FINISHED;
1331 void OBJECT_OT_multires_external_pack(wmOperatorType *ot)
1333 ot->name= "Multires Pack External";
1334 ot->description= "Pack displacements from an external file";
1335 ot->idname= "OBJECT_OT_multires_external_pack";
1337 ot->poll= multires_poll;
1338 ot->exec= multires_external_pack_exec;
1341 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1344 /********************* multires apply base ***********************/
1345 static int multires_base_apply_exec(bContext *C, wmOperator *op)
1347 Object *ob = ED_object_active_context(C);
1348 MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get(op, ob, eModifierType_Multires);
1351 return OPERATOR_CANCELLED;
1353 multiresModifier_base_apply(mmd, ob);
1355 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
1356 WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
1358 return OPERATOR_FINISHED;
1361 static int multires_base_apply_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
1363 if (edit_modifier_invoke_properties(C, op))
1364 return multires_base_apply_exec(C, op);
1366 return OPERATOR_CANCELLED;
1370 void OBJECT_OT_multires_base_apply(wmOperatorType *ot)
1372 ot->name= "Multires Apply Base";
1373 ot->description= "Modify the base mesh to conform to the displaced mesh";
1374 ot->idname= "OBJECT_OT_multires_base_apply";
1376 ot->poll= multires_poll;
1377 ot->invoke= multires_base_apply_invoke;
1378 ot->exec= multires_base_apply_exec;
1381 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1382 edit_modifier_properties(ot);
1386 /************************ mdef bind operator *********************/
1388 static int meshdeform_poll(bContext *C)
1390 return edit_modifier_poll_generic(C, &RNA_MeshDeformModifier, (1<<OB_MESH));
1393 static int meshdeform_bind_exec(bContext *C, wmOperator *op)
1395 Scene *scene= CTX_data_scene(C);
1396 Object *ob = ED_object_active_context(C);
1397 MeshDeformModifierData *mmd = (MeshDeformModifierData *)edit_modifier_property_get(op, ob, eModifierType_MeshDeform);
1400 return OPERATOR_CANCELLED;
1402 if(mmd->bindcagecos) {
1403 MEM_freeN(mmd->bindcagecos);
1404 if(mmd->dyngrid) MEM_freeN(mmd->dyngrid);
1405 if(mmd->dyninfluences) MEM_freeN(mmd->dyninfluences);
1406 if(mmd->bindinfluences) MEM_freeN(mmd->bindinfluences);
1407 if(mmd->bindoffsets) MEM_freeN(mmd->bindoffsets);
1408 if(mmd->dynverts) MEM_freeN(mmd->dynverts);
1409 if(mmd->bindweights) MEM_freeN(mmd->bindweights); /* deprecated */
1410 if(mmd->bindcos) MEM_freeN(mmd->bindcos); /* deprecated */
1412 mmd->bindcagecos= NULL;
1414 mmd->dyninfluences= NULL;
1415 mmd->bindoffsets= NULL;
1416 mmd->dynverts= NULL;
1417 mmd->bindweights= NULL; /* deprecated */
1418 mmd->bindcos= NULL; /* deprecated */
1420 mmd->totcagevert= 0;
1421 mmd->totinfluence= 0;
1423 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
1424 WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
1428 int mode= mmd->modifier.mode;
1430 /* force modifier to run, it will call binding routine */
1431 mmd->bindfunc= mesh_deform_bind;
1432 mmd->modifier.mode |= eModifierMode_Realtime;
1434 if(ob->type == OB_MESH) {
1435 dm= mesh_create_derived_view(scene, ob, 0);
1438 else if(ob->type == OB_LATTICE) {
1439 lattice_calc_modifiers(scene, ob);
1441 else if(ob->type==OB_MBALL) {
1442 makeDispListMBall(scene, ob);
1444 else if(ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT)) {
1445 makeDispListCurveTypes(scene, ob, 0);
1448 mmd->bindfunc= NULL;
1449 mmd->modifier.mode= mode;
1452 return OPERATOR_FINISHED;
1455 static int meshdeform_bind_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
1457 if (edit_modifier_invoke_properties(C, op))
1458 return meshdeform_bind_exec(C, op);
1460 return OPERATOR_CANCELLED;
1463 void OBJECT_OT_meshdeform_bind(wmOperatorType *ot)
1466 ot->name= "Mesh Deform Bind";
1467 ot->description = "Bind mesh to cage in mesh deform modifier";
1468 ot->idname= "OBJECT_OT_meshdeform_bind";
1471 ot->poll= meshdeform_poll;
1472 ot->invoke= meshdeform_bind_invoke;
1473 ot->exec= meshdeform_bind_exec;
1476 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1477 edit_modifier_properties(ot);
1480 /****************** explode refresh operator *********************/
1482 static int explode_poll(bContext *C)
1484 return edit_modifier_poll_generic(C, &RNA_ExplodeModifier, 0);
1487 static int explode_refresh_exec(bContext *C, wmOperator *op)
1489 Object *ob = ED_object_active_context(C);
1490 ExplodeModifierData *emd = (ExplodeModifierData *)edit_modifier_property_get(op, ob, eModifierType_Explode);
1493 return OPERATOR_CANCELLED;
1495 emd->flag |= eExplodeFlag_CalcFaces;
1497 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
1498 WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
1500 return OPERATOR_FINISHED;
1503 static int explode_refresh_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
1505 if (edit_modifier_invoke_properties(C, op))
1506 return explode_refresh_exec(C, op);
1508 return OPERATOR_CANCELLED;
1512 void OBJECT_OT_explode_refresh(wmOperatorType *ot)
1514 ot->name= "Explode Refresh";
1515 ot->description= "Refresh data in the Explode modifier";
1516 ot->idname= "OBJECT_OT_explode_refresh";
1518 ot->poll= explode_poll;
1519 ot->invoke= explode_refresh_invoke;
1520 ot->exec= explode_refresh_exec;
1523 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1524 edit_modifier_properties(ot);
1528 /****************** ocean bake operator *********************/
1530 static int ocean_bake_poll(bContext *C)
1532 return edit_modifier_poll_generic(C, &RNA_OceanModifier, 0);
1535 /* copied from init_ocean_modifier, MOD_ocean.c */
1536 static void init_ocean_modifier_bake(struct Ocean *oc, struct OceanModifierData *omd)
1538 int do_heightfield, do_chop, do_normals, do_jacobian;
1540 if (!omd || !oc) return;
1542 do_heightfield = TRUE;
1543 do_chop = (omd->chop_amount > 0);
1544 do_normals = (omd->flag & MOD_OCEAN_GENERATE_NORMALS);
1545 do_jacobian = (omd->flag & MOD_OCEAN_GENERATE_FOAM);
1547 BKE_init_ocean(oc, omd->resolution*omd->resolution, omd->resolution*omd->resolution, omd->spatial_size, omd->spatial_size,
1548 omd->wind_velocity, omd->smallest_wave, 1.0, omd->wave_direction, omd->damp, omd->wave_alignment,
1549 omd->depth, omd->time,
1550 do_heightfield, do_chop, do_normals, do_jacobian,
1554 typedef struct OceanBakeJob {
1557 short *stop, *do_update;
1560 struct OceanCache *och;
1561 struct Ocean *ocean;
1562 struct OceanModifierData *omd;
1565 static void oceanbake_free(void *customdata)
1567 OceanBakeJob *oj= customdata;
1571 /* called by oceanbake, only to check job 'stop' value */
1572 static int oceanbake_breakjob(void *UNUSED(customdata))
1574 //OceanBakeJob *ob= (OceanBakeJob *)customdata;
1575 //return *(ob->stop);
1577 /* this is not nice yet, need to make the jobs list template better
1578 * for identifying/acting upon various different jobs */
1579 /* but for now we'll reuse the render break... */
1583 /* called by oceanbake, wmJob sends notifier */
1584 static void oceanbake_update(void *customdata, float progress, int *cancel)
1586 OceanBakeJob *oj= customdata;
1588 if (oceanbake_breakjob(oj))
1591 *(oj->do_update)= 1;
1592 *(oj->progress)= progress;
1595 static void oceanbake_startjob(void *customdata, short *stop, short *do_update, float *progress)
1597 OceanBakeJob *oj= customdata;
1600 oj->do_update = do_update;
1601 oj->progress = progress;
1603 G.afbreek= 0; /* XXX shared with render - replace with job 'stop' switch */
1605 BKE_bake_ocean(oj->ocean, oj->och, oceanbake_update, (void *)oj);
1611 static void oceanbake_endjob(void *customdata)
1613 OceanBakeJob *oj= customdata;
1616 BKE_free_ocean(oj->ocean);
1620 oj->omd->oceancache = oj->och;
1621 oj->omd->cached = TRUE;
1624 static int ocean_bake_exec(bContext *C, wmOperator *op)
1626 Object *ob = ED_object_active_context(C);
1627 OceanModifierData *omd = (OceanModifierData *)edit_modifier_property_get(op, ob, eModifierType_Ocean);
1628 Scene *scene = CTX_data_scene(C);
1630 struct Ocean *ocean;
1632 int free= RNA_boolean_get(op->ptr, "free");
1638 return OPERATOR_CANCELLED;
1641 omd->refresh |= MOD_OCEAN_REFRESH_CLEAR_CACHE;
1642 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
1643 WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
1644 return OPERATOR_FINISHED;
1647 och = BKE_init_ocean_cache(omd->cachepath, modifier_path_relbase(ob),
1648 omd->bakestart, omd->bakeend, omd->wave_scale,
1649 omd->chop_amount, omd->foam_coverage, omd->foam_fade, omd->resolution);
1651 och->time = MEM_mallocN(och->duration*sizeof(float), "foam bake time");
1653 cfra = scene->r.cfra;
1655 /* precalculate time variable before baking */
1656 for (f=omd->bakestart; f<=omd->bakeend; f++) {
1657 /* from physics_fluid.c:
1659 * XXX: This can't be used due to an anim sys optimisation that ignores recalc object animation,
1660 * leaving it for the depgraph (this ignores object animation such as modifier properties though... :/ )
1661 * --> BKE_animsys_evaluate_all_animation(G.main, eval_time);
1662 * This doesn't work with drivers:
1663 * --> BKE_animsys_evaluate_animdata(&fsDomain->id, fsDomain->adt, eval_time, ADT_RECALC_ALL);
1666 /* Modifying the global scene isn't nice, but we can do it in
1667 * this part of the process before a threaded job is created */
1669 //scene->r.cfra = f;
1670 //ED_update_for_newframe(CTX_data_main(C), scene, CTX_wm_screen(C), 1);
1672 /* ok, this doesn't work with drivers, but is way faster.
1673 * let's use this for now and hope nobody wants to drive the time value... */
1674 BKE_animsys_evaluate_animdata(scene, (ID *)ob, ob->adt, f, ADT_RECALC_ANIM);
1676 och->time[i] = omd->time;
1680 /* make a copy of ocean to use for baking - threadsafety */
1681 ocean = BKE_add_ocean();
1682 init_ocean_modifier_bake(ocean, omd);
1685 BKE_bake_ocean(ocean, och);
1687 omd->oceancache = och;
1690 scene->r.cfra = cfra;
1692 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
1693 WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
1698 scene->r.cfra = cfra;
1701 steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, "Ocean Simulation", WM_JOB_PROGRESS);
1702 oj= MEM_callocN(sizeof(OceanBakeJob), "ocean bake job");
1707 WM_jobs_customdata(steve, oj, oceanbake_free);
1708 WM_jobs_timer(steve, 0.1, NC_OBJECT|ND_MODIFIER, NC_OBJECT|ND_MODIFIER);
1709 WM_jobs_callbacks(steve, oceanbake_startjob, NULL, NULL, oceanbake_endjob);
1711 WM_jobs_start(CTX_wm_manager(C), steve);
1715 return OPERATOR_FINISHED;
1718 static int ocean_bake_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
1720 if (edit_modifier_invoke_properties(C, op))
1721 return ocean_bake_exec(C, op);
1723 return OPERATOR_CANCELLED;
1727 void OBJECT_OT_ocean_bake(wmOperatorType *ot)
1729 ot->name= "Bake Ocean";
1730 ot->description= "Bake an image sequence of ocean data";
1731 ot->idname= "OBJECT_OT_ocean_bake";
1733 ot->poll= ocean_bake_poll;
1734 ot->invoke= ocean_bake_invoke;
1735 ot->exec= ocean_bake_exec;
1738 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1739 edit_modifier_properties(ot);
1741 RNA_def_boolean(ot->srna, "free", FALSE, "Free", "Free the bake, rather than generating it");