1 /*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License
4 * as published by the Free Software Foundation; either version 2
5 * of the License, or (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software Foundation,
14 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15 *
16 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17 * All rights reserved.
18 */
19
20 /** \file
21 * \ingroup edobj
22 */
23
24 #include <math.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27
28 #include "MEM_guardedalloc.h"
29
30 #include "DNA_anim_types.h"
31 #include "DNA_armature_types.h"
32 #include "DNA_curve_types.h"
33 #include "DNA_key_types.h"
34 #include "DNA_mesh_types.h"
35 #include "DNA_meshdata_types.h"
36 #include "DNA_object_force_types.h"
37 #include "DNA_scene_types.h"
38
39 #include "BLI_bitmap.h"
40 #include "BLI_listbase.h"
41 #include "BLI_math.h"
42 #include "BLI_path_util.h"
43 #include "BLI_string.h"
44 #include "BLI_string_utf8.h"
45 #include "BLI_utildefines.h"
46
47 #include "BKE_DerivedMesh.h"
48 #include "BKE_animsys.h"
49 #include "BKE_armature.h"
50 #include "BKE_context.h"
51 #include "BKE_curve.h"
52 #include "BKE_displist.h"
53 #include "BKE_editmesh.h"
54 #include "BKE_effect.h"
55 #include "BKE_global.h"
56 #include "BKE_gpencil_modifier.h"
57 #include "BKE_hair.h"
58 #include "BKE_key.h"
59 #include "BKE_lattice.h"
60 #include "BKE_lib_id.h"
61 #include "BKE_main.h"
62 #include "BKE_mesh.h"
63 #include "BKE_mesh_mapping.h"
64 #include "BKE_mesh_runtime.h"
65 #include "BKE_modifier.h"
66 #include "BKE_multires.h"
67 #include "BKE_object.h"
68 #include "BKE_object_deform.h"
69 #include "BKE_ocean.h"
70 #include "BKE_paint.h"
71 #include "BKE_particle.h"
72 #include "BKE_pointcloud.h"
73 #include "BKE_report.h"
74 #include "BKE_scene.h"
75 #include "BKE_softbody.h"
76 #include "BKE_volume.h"
77
78 #include "DEG_depsgraph.h"
79 #include "DEG_depsgraph_build.h"
80 #include "DEG_depsgraph_query.h"
81
82 #include "RNA_access.h"
83 #include "RNA_define.h"
84 #include "RNA_enum_types.h"
85
86 #include "ED_armature.h"
87 #include "ED_mesh.h"
88 #include "ED_object.h"
89 #include "ED_screen.h"
90 #include "ED_sculpt.h"
91
92 #include "UI_interface.h"
93
94 #include "WM_api.h"
95 #include "WM_types.h"
96
97 #include "object_intern.h"
98
99 static void modifier_skin_customdata_delete(struct Object *ob);
100
101 /* ------------------------------------------------------------------- */
102 /** \name Public Api
103 * \{ */
104
object_force_modifier_update_for_bind(Depsgraph * depsgraph,Object * ob)105 static void object_force_modifier_update_for_bind(Depsgraph *depsgraph, Object *ob)
106 {
107 Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
108 Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
109 BKE_object_eval_reset(ob_eval);
110 if (ob->type == OB_MESH) {
111 Mesh *me_eval = mesh_create_eval_final(depsgraph, scene_eval, ob_eval, &CD_MASK_BAREMESH);
112 BKE_mesh_eval_delete(me_eval);
113 }
114 else if (ob->type == OB_LATTICE) {
115 BKE_lattice_modifiers_calc(depsgraph, scene_eval, ob_eval);
116 }
117 else if (ob->type == OB_MBALL) {
118 BKE_displist_make_mball(depsgraph, scene_eval, ob_eval);
119 }
120 else if (ELEM(ob->type, OB_CURVE, OB_SURF, OB_FONT)) {
121 BKE_displist_make_curveTypes(depsgraph, scene_eval, ob_eval, false, false);
122 }
123 else if (ob->type == OB_GPENCIL) {
124 BKE_gpencil_modifiers_calc(depsgraph, scene_eval, ob_eval);
125 }
126 else if (ob->type == OB_HAIR) {
127 BKE_hair_data_update(depsgraph, scene_eval, ob);
128 }
129 else if (ob->type == OB_POINTCLOUD) {
130 BKE_pointcloud_data_update(depsgraph, scene_eval, ob);
131 }
132 else if (ob->type == OB_VOLUME) {
133 BKE_volume_data_update(depsgraph, scene_eval, ob);
134 }
135 }
136
object_force_modifier_bind_simple_options(Depsgraph * depsgraph,Object * object,ModifierData * md)137 static void object_force_modifier_bind_simple_options(Depsgraph *depsgraph,
138 Object *object,
139 ModifierData *md)
140 {
141 ModifierData *md_eval = (ModifierData *)BKE_modifier_get_evaluated(depsgraph, object, md);
142 const int mode = md_eval->mode;
143 md_eval->mode |= eModifierMode_Realtime;
144 object_force_modifier_update_for_bind(depsgraph, object);
145 md_eval->mode = mode;
146 }
147
148 /**
149 * Add a modifier to given object, including relevant extra processing needed by some physics types
150 * (particles, simulations...).
151 *
152 * \param scene: is only used to set current frame in some cases, and may be NULL.
153 */
ED_object_modifier_add(ReportList * reports,Main * bmain,Scene * scene,Object * ob,const char * name,int type)154 ModifierData *ED_object_modifier_add(
155 ReportList *reports, Main *bmain, Scene *scene, Object *ob, const char *name, int type)
156 {
157 ModifierData *md = NULL, *new_md = NULL;
158 const ModifierTypeInfo *mti = BKE_modifier_get_info(type);
159
160 /* Check compatibility of modifier [T25291, T50373]. */
161 if (!BKE_object_support_modifier_type_check(ob, type)) {
162 BKE_reportf(reports, RPT_WARNING, "Modifiers cannot be added to object '%s'", ob->id.name + 2);
163 return NULL;
164 }
165
166 if (mti->flags & eModifierTypeFlag_Single) {
167 if (BKE_modifiers_findby_type(ob, type)) {
168 BKE_report(reports, RPT_WARNING, "Only one modifier of this type is allowed");
169 return NULL;
170 }
171 }
172
173 if (type == eModifierType_ParticleSystem) {
174 /* don't need to worry about the new modifier's name, since that is set to the number
175 * of particle systems which shouldn't have too many duplicates
176 */
177 new_md = object_add_particle_system(bmain, scene, ob, name);
178 }
179 else {
180 /* get new modifier data to add */
181 new_md = BKE_modifier_new(type);
182
183 if (mti->flags & eModifierTypeFlag_RequiresOriginalData) {
184 md = ob->modifiers.first;
185
186 while (md && BKE_modifier_get_info(md->type)->type == eModifierTypeType_OnlyDeform) {
187 md = md->next;
188 }
189
190 BLI_insertlinkbefore(&ob->modifiers, md, new_md);
191 }
192 else {
193 BLI_addtail(&ob->modifiers, new_md);
194 }
195
196 if (name) {
197 BLI_strncpy_utf8(new_md->name, name, sizeof(new_md->name));
198 }
199
200 /* make sure modifier data has unique name */
201
202 BKE_modifier_unique_name(&ob->modifiers, new_md);
203
204 /* special cases */
205 if (type == eModifierType_Softbody) {
206 if (!ob->soft) {
207 ob->soft = sbNew(scene);
208 ob->softflag |= OB_SB_GOAL | OB_SB_EDGES;
209 }
210 }
211 else if (type == eModifierType_Collision) {
212 if (!ob->pd) {
213 ob->pd = BKE_partdeflect_new(0);
214 }
215
216 ob->pd->deflect = 1;
217 }
218 else if (type == eModifierType_Surface) {
219 /* pass */
220 }
221 else if (type == eModifierType_Multires) {
222 /* set totlvl from existing MDISPS layer if object already had it */
223 multiresModifier_set_levels_from_disps((MultiresModifierData *)new_md, ob);
224
225 if (ob->mode & OB_MODE_SCULPT) {
226 /* ensure that grid paint mask layer is created */
227 BKE_sculpt_mask_layers_ensure(ob, (MultiresModifierData *)new_md);
228 }
229 }
230 else if (type == eModifierType_Skin) {
231 /* ensure skin-node customdata exists */
232 BKE_mesh_ensure_skin_customdata(ob->data);
233 }
234 }
235
236 DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
237 DEG_relations_tag_update(bmain);
238
239 return new_md;
240 }
241
242 /* Return true if the object has a modifier of type 'type' other than
243 * the modifier pointed to be 'exclude', otherwise returns false. */
object_has_modifier(const Object * ob,const ModifierData * exclude,ModifierType type)244 static bool object_has_modifier(const Object *ob, const ModifierData *exclude, ModifierType type)
245 {
246 LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) {
247 if ((md != exclude) && (md->type == type)) {
248 return true;
249 }
250 }
251
252 return false;
253 }
254
255 /* If the object data of 'orig_ob' has other users, run 'callback' on
256 * each of them.
257 *
258 * If include_orig is true, the callback will run on 'orig_ob' too.
259 *
260 * If the callback ever returns true, iteration will stop and the
261 * function value will be true. Otherwise the function returns false.
262 */
ED_object_iter_other(Main * bmain,Object * orig_ob,const bool include_orig,bool (* callback)(Object * ob,void * callback_data),void * callback_data)263 bool ED_object_iter_other(Main *bmain,
264 Object *orig_ob,
265 const bool include_orig,
266 bool (*callback)(Object *ob, void *callback_data),
267 void *callback_data)
268 {
269 ID *ob_data_id = orig_ob->data;
270 int users = ob_data_id->us;
271
272 if (ob_data_id->flag & LIB_FAKEUSER) {
273 users--;
274 }
275
276 /* First check that the object's data has multiple users */
277 if (users > 1) {
278 Object *ob;
279 int totfound = include_orig ? 0 : 1;
280
281 for (ob = bmain->objects.first; ob && totfound < users; ob = ob->id.next) {
282 if (((ob != orig_ob) || include_orig) && (ob->data == orig_ob->data)) {
283 if (callback(ob, callback_data)) {
284 return true;
285 }
286
287 totfound++;
288 }
289 }
290 }
291 else if (include_orig) {
292 return callback(orig_ob, callback_data);
293 }
294
295 return false;
296 }
297
object_has_modifier_cb(Object * ob,void * data)298 static bool object_has_modifier_cb(Object *ob, void *data)
299 {
300 ModifierType type = *((ModifierType *)data);
301
302 return object_has_modifier(ob, NULL, type);
303 }
304
305 /* Use with ED_object_iter_other(). Sets the total number of levels
306 * for any multires modifiers on the object to the int pointed to by
307 * callback_data. */
ED_object_multires_update_totlevels_cb(Object * ob,void * totlevel_v)308 bool ED_object_multires_update_totlevels_cb(Object *ob, void *totlevel_v)
309 {
310 int totlevel = *((char *)totlevel_v);
311
312 LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) {
313 if (md->type == eModifierType_Multires) {
314 multires_set_tot_level(ob, (MultiresModifierData *)md, totlevel);
315 DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
316 }
317 }
318 return false;
319 }
320
321 /* Return true if no modifier of type 'type' other than 'exclude' */
object_modifier_safe_to_delete(Main * bmain,Object * ob,ModifierData * exclude,ModifierType type)322 static bool object_modifier_safe_to_delete(Main *bmain,
323 Object *ob,
324 ModifierData *exclude,
325 ModifierType type)
326 {
327 return (!object_has_modifier(ob, exclude, type) &&
328 !ED_object_iter_other(bmain, ob, false, object_has_modifier_cb, &type));
329 }
330
object_modifier_remove(Main * bmain,Scene * scene,Object * ob,ModifierData * md,bool * r_sort_depsgraph)331 static bool object_modifier_remove(
332 Main *bmain, Scene *scene, Object *ob, ModifierData *md, bool *r_sort_depsgraph)
333 {
334 /* It seems on rapid delete it is possible to
335 * get called twice on same modifier, so make
336 * sure it is in list. */
337 if (BLI_findindex(&ob->modifiers, md) == -1) {
338 return 0;
339 }
340
341 /* special cases */
342 if (md->type == eModifierType_ParticleSystem) {
343 object_remove_particle_system(bmain, scene, ob);
344 return true;
345 }
346
347 if (md->type == eModifierType_Softbody) {
348 if (ob->soft) {
349 sbFree(ob);
350 ob->softflag = 0; /* TODO(Sybren): this should probably be moved into sbFree() */
351 }
352 }
353 else if (md->type == eModifierType_Collision) {
354 if (ob->pd) {
355 ob->pd->deflect = 0;
356 }
357
358 *r_sort_depsgraph = true;
359 }
360 else if (md->type == eModifierType_Surface) {
361 *r_sort_depsgraph = true;
362 }
363 else if (md->type == eModifierType_Multires) {
364 /* Delete MDisps layer if not used by another multires modifier */
365 if (object_modifier_safe_to_delete(bmain, ob, md, eModifierType_Multires)) {
366 multires_customdata_delete(ob->data);
367 }
368 }
369 else if (md->type == eModifierType_Skin) {
370 /* Delete MVertSkin layer if not used by another skin modifier */
371 if (object_modifier_safe_to_delete(bmain, ob, md, eModifierType_Skin)) {
372 modifier_skin_customdata_delete(ob);
373 }
374 }
375
376 if (ELEM(md->type, eModifierType_Softbody, eModifierType_Cloth) &&
377 BLI_listbase_is_empty(&ob->particlesystem)) {
378 ob->mode &= ~OB_MODE_PARTICLE_EDIT;
379 }
380
381 BLI_remlink(&ob->modifiers, md);
382 BKE_modifier_free(md);
383 BKE_object_free_derived_caches(ob);
384
385 return 1;
386 }
387
ED_object_modifier_remove(ReportList * reports,Main * bmain,Scene * scene,Object * ob,ModifierData * md)388 bool ED_object_modifier_remove(
389 ReportList *reports, Main *bmain, Scene *scene, Object *ob, ModifierData *md)
390 {
391 bool sort_depsgraph = false;
392
393 bool ok = object_modifier_remove(bmain, scene, ob, md, &sort_depsgraph);
394
395 if (!ok) {
396 BKE_reportf(reports, RPT_ERROR, "Modifier '%s' not in object '%s'", md->name, ob->id.name);
397 return false;
398 }
399
400 DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
401 DEG_relations_tag_update(bmain);
402
403 return true;
404 }
405
ED_object_modifier_clear(Main * bmain,Scene * scene,Object * ob)406 void ED_object_modifier_clear(Main *bmain, Scene *scene, Object *ob)
407 {
408 ModifierData *md = ob->modifiers.first;
409 bool sort_depsgraph = false;
410
411 if (!md) {
412 return;
413 }
414
415 while (md) {
416 ModifierData *next_md = md->next;
417
418 object_modifier_remove(bmain, scene, ob, md, &sort_depsgraph);
419
420 md = next_md;
421 }
422
423 DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
424 DEG_relations_tag_update(bmain);
425 }
426
ED_object_modifier_move_up(ReportList * reports,Object * ob,ModifierData * md)427 bool ED_object_modifier_move_up(ReportList *reports, Object *ob, ModifierData *md)
428 {
429 if (md->prev) {
430 const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
431
432 if (mti->type != eModifierTypeType_OnlyDeform) {
433 const ModifierTypeInfo *nmti = BKE_modifier_get_info(md->prev->type);
434
435 if (nmti->flags & eModifierTypeFlag_RequiresOriginalData) {
436 BKE_report(reports, RPT_WARNING, "Cannot move above a modifier requiring original data");
437 return false;
438 }
439 }
440
441 BLI_remlink(&ob->modifiers, md);
442 BLI_insertlinkbefore(&ob->modifiers, md->prev, md);
443 }
444 else {
445 BKE_report(reports, RPT_WARNING, "Cannot move modifier beyond the start of the list");
446 return false;
447 }
448
449 return true;
450 }
451
ED_object_modifier_move_down(ReportList * reports,Object * ob,ModifierData * md)452 bool ED_object_modifier_move_down(ReportList *reports, Object *ob, ModifierData *md)
453 {
454 if (md->next) {
455 const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
456
457 if (mti->flags & eModifierTypeFlag_RequiresOriginalData) {
458 const ModifierTypeInfo *nmti = BKE_modifier_get_info(md->next->type);
459
460 if (nmti->type != eModifierTypeType_OnlyDeform) {
461 BKE_report(reports, RPT_WARNING, "Cannot move beyond a non-deforming modifier");
462 return false;
463 }
464 }
465
466 BLI_remlink(&ob->modifiers, md);
467 BLI_insertlinkafter(&ob->modifiers, md->next, md);
468 }
469 else {
470 BKE_report(reports, RPT_WARNING, "Cannot move modifier beyond the end of the list");
471 return false;
472 }
473
474 return true;
475 }
476
ED_object_modifier_move_to_index(ReportList * reports,Object * ob,ModifierData * md,const int index)477 bool ED_object_modifier_move_to_index(ReportList *reports,
478 Object *ob,
479 ModifierData *md,
480 const int index)
481 {
482 BLI_assert(md != NULL);
483 BLI_assert(index >= 0);
484 if (index >= BLI_listbase_count(&ob->modifiers)) {
485 BKE_report(reports, RPT_WARNING, "Cannot move modifier beyond the end of the stack");
486 return false;
487 }
488
489 int md_index = BLI_findindex(&ob->modifiers, md);
490 BLI_assert(md_index != -1);
491 if (md_index < index) {
492 /* Move modifier down in list. */
493 for (; md_index < index; md_index++) {
494 if (!ED_object_modifier_move_down(reports, ob, md)) {
495 break;
496 }
497 }
498 }
499 else {
500 /* Move modifier up in list. */
501 for (; md_index > index; md_index--) {
502 if (!ED_object_modifier_move_up(reports, ob, md)) {
503 break;
504 }
505 }
506 }
507
508 DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
509 WM_main_add_notifier(NC_OBJECT | ND_MODIFIER, ob);
510
511 return true;
512 }
513
ED_object_modifier_link(bContext * C,Object * ob_dst,Object * ob_src)514 void ED_object_modifier_link(bContext *C, Object *ob_dst, Object *ob_src)
515 {
516 BKE_object_link_modifiers(ob_dst, ob_src);
517 WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob_dst);
518 DEG_id_tag_update(&ob_dst->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_ANIMATION);
519
520 Main *bmain = CTX_data_main(C);
521 DEG_relations_tag_update(bmain);
522 }
523
ED_object_modifier_copy_to_object(bContext * C,Object * ob_dst,Object * ob_src,ModifierData * md)524 void ED_object_modifier_copy_to_object(bContext *C,
525 Object *ob_dst,
526 Object *ob_src,
527 ModifierData *md)
528 {
529 BKE_object_copy_modifier(ob_dst, ob_src, md);
530 WM_main_add_notifier(NC_OBJECT | ND_MODIFIER, ob_dst);
531 DEG_id_tag_update(&ob_dst->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_ANIMATION);
532
533 Main *bmain = CTX_data_main(C);
534 DEG_relations_tag_update(bmain);
535 }
536
ED_object_modifier_convert(ReportList * UNUSED (reports),Main * bmain,Depsgraph * depsgraph,ViewLayer * view_layer,Object * ob,ModifierData * md)537 bool ED_object_modifier_convert(ReportList *UNUSED(reports),
538 Main *bmain,
539 Depsgraph *depsgraph,
540 ViewLayer *view_layer,
541 Object *ob,
542 ModifierData *md)
543 {
544 int cvert = 0;
545
546 if (md->type != eModifierType_ParticleSystem) {
547 return false;
548 }
549 if (ob && ob->mode & OB_MODE_PARTICLE_EDIT) {
550 return false;
551 }
552
553 ParticleSystem *psys_orig = ((ParticleSystemModifierData *)md)->psys;
554 ParticleSettings *part = psys_orig->part;
555
556 if (part->ren_as != PART_DRAW_PATH) {
557 return false;
558 }
559 ParticleSystem *psys_eval = psys_eval_get(depsgraph, ob, psys_orig);
560 if (psys_eval->pathcache == NULL) {
561 return false;
562 }
563
564 int totpart = psys_eval->totcached;
565 int totchild = psys_eval->totchildcache;
566
567 if (totchild && (part->draw & PART_DRAW_PARENT) == 0) {
568 totpart = 0;
569 }
570
571 /* count */
572 int totvert = 0, totedge = 0;
573 ParticleCacheKey **cache = psys_eval->pathcache;
574 for (int a = 0; a < totpart; a++) {
575 ParticleCacheKey *key = cache[a];
576
577 if (key->segments > 0) {
578 totvert += key->segments + 1;
579 totedge += key->segments;
580 }
581 }
582
583 cache = psys_eval->childcache;
584 for (int a = 0; a < totchild; a++) {
585 ParticleCacheKey *key = cache[a];
586
587 if (key->segments > 0) {
588 totvert += key->segments + 1;
589 totedge += key->segments;
590 }
591 }
592
593 if (totvert == 0) {
594 return false;
595 }
596
597 /* add new mesh */
598 Object *obn = BKE_object_add(bmain, view_layer, OB_MESH, NULL);
599 Mesh *me = obn->data;
600
601 me->totvert = totvert;
602 me->totedge = totedge;
603
604 me->mvert = CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, totvert);
605 me->medge = CustomData_add_layer(&me->edata, CD_MEDGE, CD_CALLOC, NULL, totedge);
606 me->mface = CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, 0);
607
608 MVert *mvert = me->mvert;
609 MEdge *medge = me->medge;
610
611 /* copy coordinates */
612 cache = psys_eval->pathcache;
613 for (int a = 0; a < totpart; a++) {
614 ParticleCacheKey *key = cache[a];
615 int kmax = key->segments;
616 for (int k = 0; k <= kmax; k++, key++, cvert++, mvert++) {
617 copy_v3_v3(mvert->co, key->co);
618 if (k) {
619 medge->v1 = cvert - 1;
620 medge->v2 = cvert;
621 medge->flag = ME_EDGEDRAW | ME_EDGERENDER | ME_LOOSEEDGE;
622 medge++;
623 }
624 else {
625 /* cheap trick to select the roots */
626 mvert->flag |= SELECT;
627 }
628 }
629 }
630
631 cache = psys_eval->childcache;
632 for (int a = 0; a < totchild; a++) {
633 ParticleCacheKey *key = cache[a];
634 int kmax = key->segments;
635 for (int k = 0; k <= kmax; k++, key++, cvert++, mvert++) {
636 copy_v3_v3(mvert->co, key->co);
637 if (k) {
638 medge->v1 = cvert - 1;
639 medge->v2 = cvert;
640 medge->flag = ME_EDGEDRAW | ME_EDGERENDER | ME_LOOSEEDGE;
641 medge++;
642 }
643 else {
644 /* cheap trick to select the roots */
645 mvert->flag |= SELECT;
646 }
647 }
648 }
649
650 DEG_relations_tag_update(bmain);
651
652 return true;
653 }
654
655 /* Gets mesh for the modifier which corresponds to an evaluated state. */
modifier_apply_create_mesh_for_modifier(Depsgraph * depsgraph,Object * object,ModifierData * md_eval,bool build_shapekey_layers)656 static Mesh *modifier_apply_create_mesh_for_modifier(Depsgraph *depsgraph,
657 Object *object,
658 ModifierData *md_eval,
659 bool build_shapekey_layers)
660 {
661 Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
662 Object *object_eval = DEG_get_evaluated_object(depsgraph, object);
663 Mesh *mesh_applied = BKE_mesh_create_derived_for_modifier(
664 depsgraph, scene_eval, object_eval, md_eval, build_shapekey_layers);
665 return mesh_applied;
666 }
667
modifier_apply_shape(Main * bmain,ReportList * reports,Depsgraph * depsgraph,Scene * scene,Object * ob,ModifierData * md_eval)668 static int modifier_apply_shape(Main *bmain,
669 ReportList *reports,
670 Depsgraph *depsgraph,
671 Scene *scene,
672 Object *ob,
673 ModifierData *md_eval)
674 {
675 const ModifierTypeInfo *mti = BKE_modifier_get_info(md_eval->type);
676
677 if (mti->isDisabled && mti->isDisabled(scene, md_eval, 0)) {
678 BKE_report(reports, RPT_ERROR, "Modifier is disabled, skipping apply");
679 return 0;
680 }
681
682 /*
683 * It should be ridiculously easy to extract the original verts that we want
684 * and form the shape data. We can probably use the CD KEYINDEX layer (or
685 * whatever I ended up calling it, too tired to check now), though this would
686 * by necessity have to make some potentially ugly assumptions about the order
687 * of the mesh data :-/ you can probably assume in 99% of cases that the first
688 * element of a given index is the original, and any subsequent duplicates are
689 * copies/interpolates, but that's an assumption that would need to be tested
690 * and then predominantly stated in comments in a half dozen headers.
691 */
692
693 if (ob->type == OB_MESH) {
694 Mesh *mesh_applied;
695 Mesh *me = ob->data;
696 Key *key = me->key;
697
698 if (!BKE_modifier_is_same_topology(md_eval) || mti->type == eModifierTypeType_NonGeometrical) {
699 BKE_report(reports, RPT_ERROR, "Only deforming modifiers can be applied to shapes");
700 return 0;
701 }
702
703 mesh_applied = modifier_apply_create_mesh_for_modifier(depsgraph, ob, md_eval, false);
704 if (!mesh_applied) {
705 BKE_report(reports, RPT_ERROR, "Modifier is disabled or returned error, skipping apply");
706 return 0;
707 }
708
709 if (key == NULL) {
710 key = me->key = BKE_key_add(bmain, (ID *)me);
711 key->type = KEY_RELATIVE;
712 /* if that was the first key block added, then it was the basis.
713 * Initialize it with the mesh, and add another for the modifier */
714 KeyBlock *kb = BKE_keyblock_add(key, NULL);
715 BKE_keyblock_convert_from_mesh(me, key, kb);
716 }
717
718 KeyBlock *kb = BKE_keyblock_add(key, md_eval->name);
719 BKE_mesh_nomain_to_meshkey(mesh_applied, me, kb);
720
721 BKE_id_free(NULL, mesh_applied);
722 }
723 else {
724 /* TODO: implement for hair, pointclouds and volumes. */
725 BKE_report(reports, RPT_ERROR, "Cannot apply modifier for this object type");
726 return 0;
727 }
728 return 1;
729 }
730
modifier_apply_obdata(ReportList * reports,Depsgraph * depsgraph,Scene * scene,Object * ob,ModifierData * md_eval)731 static int modifier_apply_obdata(
732 ReportList *reports, Depsgraph *depsgraph, Scene *scene, Object *ob, ModifierData *md_eval)
733 {
734 const ModifierTypeInfo *mti = BKE_modifier_get_info(md_eval->type);
735
736 if (mti->isDisabled && mti->isDisabled(scene, md_eval, 0)) {
737 BKE_report(reports, RPT_ERROR, "Modifier is disabled, skipping apply");
738 return 0;
739 }
740
741 if (ob->type == OB_MESH) {
742 Mesh *mesh_applied;
743 Mesh *me = ob->data;
744 MultiresModifierData *mmd = find_multires_modifier_before(scene, md_eval);
745
746 if (me->key && mti->type != eModifierTypeType_NonGeometrical) {
747 BKE_report(reports, RPT_ERROR, "Modifier cannot be applied to a mesh with shape keys");
748 return 0;
749 }
750
751 /* Multires: ensure that recent sculpting is applied */
752 if (md_eval->type == eModifierType_Multires) {
753 multires_force_sculpt_rebuild(ob);
754 }
755
756 if (mmd && mmd->totlvl && mti->type == eModifierTypeType_OnlyDeform) {
757 if (!multiresModifier_reshapeFromDeformModifier(depsgraph, ob, mmd, md_eval)) {
758 BKE_report(reports, RPT_ERROR, "Multires modifier returned error, skipping apply");
759 return 0;
760 }
761 }
762 else {
763 mesh_applied = modifier_apply_create_mesh_for_modifier(depsgraph, ob, md_eval, true);
764 if (!mesh_applied) {
765 BKE_report(reports, RPT_ERROR, "Modifier returned error, skipping apply");
766 return 0;
767 }
768
769 BKE_mesh_nomain_to_mesh(mesh_applied, me, ob, &CD_MASK_MESH, true);
770
771 if (md_eval->type == eModifierType_Multires) {
772 multires_customdata_delete(me);
773 }
774 }
775 }
776 else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
777 Object *object_eval = DEG_get_evaluated_object(depsgraph, ob);
778 Curve *curve = ob->data;
779 Curve *curve_eval = (Curve *)object_eval->data;
780 ModifierEvalContext mectx = {depsgraph, object_eval, 0};
781
782 if (ELEM(mti->type, eModifierTypeType_Constructive, eModifierTypeType_Nonconstructive)) {
783 BKE_report(
784 reports, RPT_ERROR, "Transform curve to mesh in order to apply constructive modifiers");
785 return 0;
786 }
787
788 BKE_report(reports,
789 RPT_INFO,
790 "Applied modifier only changed CV points, not tessellated/bevel vertices");
791
792 int numVerts;
793 float(*vertexCos)[3] = BKE_curve_nurbs_vert_coords_alloc(&curve_eval->nurb, &numVerts);
794 mti->deformVerts(md_eval, &mectx, NULL, vertexCos, numVerts);
795 BKE_curve_nurbs_vert_coords_apply(&curve->nurb, vertexCos, false);
796
797 MEM_freeN(vertexCos);
798
799 DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
800 }
801 else {
802 /* TODO: implement for hair, pointclouds and volumes. */
803 BKE_report(reports, RPT_ERROR, "Cannot apply modifier for this object type");
804 return 0;
805 }
806
807 /* lattice modifier can be applied to particle system too */
808 if (ob->particlesystem.first) {
809 LISTBASE_FOREACH (ParticleSystem *, psys, &ob->particlesystem) {
810 if (psys->part->type != PART_HAIR) {
811 continue;
812 }
813
814 psys_apply_hair_lattice(depsgraph, scene, ob, psys);
815 }
816 }
817
818 return 1;
819 }
820
ED_object_modifier_apply(Main * bmain,ReportList * reports,Depsgraph * depsgraph,Scene * scene,Object * ob,ModifierData * md,int mode,bool keep_modifier)821 bool ED_object_modifier_apply(Main *bmain,
822 ReportList *reports,
823 Depsgraph *depsgraph,
824 Scene *scene,
825 Object *ob,
826 ModifierData *md,
827 int mode,
828 bool keep_modifier)
829 {
830 if (BKE_object_is_in_editmode(ob)) {
831 BKE_report(reports, RPT_ERROR, "Modifiers cannot be applied in edit mode");
832 return false;
833 }
834 if (mode != MODIFIER_APPLY_SHAPE && ID_REAL_USERS(ob->data) > 1) {
835 BKE_report(reports, RPT_ERROR, "Modifiers cannot be applied to multi-user data");
836 return false;
837 }
838 if ((ob->mode & OB_MODE_SCULPT) && (find_multires_modifier_before(scene, md)) &&
839 (BKE_modifier_is_same_topology(md) == false)) {
840 BKE_report(reports,
841 RPT_ERROR,
842 "Constructive modifier cannot be applied to multi-res data in sculpt mode");
843 return false;
844 }
845
846 if (md != ob->modifiers.first) {
847 BKE_report(reports, RPT_INFO, "Applied modifier was not first, result may not be as expected");
848 }
849
850 /* Get evaluated modifier, so object links pointer to evaluated data,
851 * but still use original object it is applied to the original mesh. */
852 Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
853 ModifierData *md_eval = (ob_eval) ? BKE_modifiers_findby_name(ob_eval, md->name) : md;
854
855 /* allow apply of a not-realtime modifier, by first re-enabling realtime. */
856 int prev_mode = md_eval->mode;
857 md_eval->mode |= eModifierMode_Realtime;
858
859 if (mode == MODIFIER_APPLY_SHAPE) {
860 if (!modifier_apply_shape(bmain, reports, depsgraph, scene, ob, md_eval)) {
861 md_eval->mode = prev_mode;
862 return false;
863 }
864 }
865 else {
866 if (!modifier_apply_obdata(reports, depsgraph, scene, ob, md_eval)) {
867 md_eval->mode = prev_mode;
868 return false;
869 }
870 }
871
872 md_eval->mode = prev_mode;
873
874 if (!keep_modifier) {
875 BLI_remlink(&ob->modifiers, md);
876 BKE_modifier_free(md);
877 }
878
879 BKE_object_free_derived_caches(ob);
880
881 return true;
882 }
883
ED_object_modifier_copy(ReportList * UNUSED (reports),Main * bmain,Scene * scene,Object * ob,ModifierData * md)884 int ED_object_modifier_copy(
885 ReportList *UNUSED(reports), Main *bmain, Scene *scene, Object *ob, ModifierData *md)
886 {
887 ModifierData *nmd;
888
889 if (md->type == eModifierType_ParticleSystem) {
890 nmd = object_copy_particle_system(bmain, scene, ob, ((ParticleSystemModifierData *)md)->psys);
891 BLI_remlink(&ob->modifiers, nmd);
892 BLI_insertlinkafter(&ob->modifiers, md, nmd);
893 return true;
894 }
895
896 nmd = BKE_modifier_new(md->type);
897 BKE_modifier_copydata(md, nmd);
898 BLI_insertlinkafter(&ob->modifiers, md, nmd);
899 BKE_modifier_unique_name(&ob->modifiers, nmd);
900
901 nmd->flag |= eModifierFlag_OverrideLibrary_Local;
902
903 return 1;
904 }
905
906 /** \} */
907
908 /* ------------------------------------------------------------------- */
909 /** \name Add Modifier Operator
910 * \{ */
911
modifier_add_exec(bContext * C,wmOperator * op)912 static int modifier_add_exec(bContext *C, wmOperator *op)
913 {
914 Main *bmain = CTX_data_main(C);
915 Scene *scene = CTX_data_scene(C);
916 Object *ob = ED_object_active_context(C);
917 int type = RNA_enum_get(op->ptr, "type");
918
919 if (!ED_object_modifier_add(op->reports, bmain, scene, ob, NULL, type)) {
920 return OPERATOR_CANCELLED;
921 }
922
923 WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
924
925 return OPERATOR_FINISHED;
926 }
927
modifier_add_itemf(bContext * C,PointerRNA * UNUSED (ptr),PropertyRNA * UNUSED (prop),bool * r_free)928 static const EnumPropertyItem *modifier_add_itemf(bContext *C,
929 PointerRNA *UNUSED(ptr),
930 PropertyRNA *UNUSED(prop),
931 bool *r_free)
932 {
933 Object *ob = ED_object_active_context(C);
934
935 if (!ob) {
936 return rna_enum_object_modifier_type_items;
937 }
938
939 EnumPropertyItem *items = NULL;
940 int totitem = 0;
941
942 const EnumPropertyItem *group_item = NULL;
943 for (int a = 0; rna_enum_object_modifier_type_items[a].identifier; a++) {
944 const EnumPropertyItem *md_item = &rna_enum_object_modifier_type_items[a];
945
946 if (md_item->identifier[0]) {
947 const ModifierTypeInfo *mti = BKE_modifier_get_info(md_item->value);
948
949 if (mti->flags & eModifierTypeFlag_NoUserAdd) {
950 continue;
951 }
952
953 if (!BKE_object_support_modifier_type_check(ob, md_item->value)) {
954 continue;
955 }
956 }
957 else {
958 group_item = md_item;
959 continue;
960 }
961
962 if (group_item) {
963 RNA_enum_item_add(&items, &totitem, group_item);
964 group_item = NULL;
965 }
966
967 RNA_enum_item_add(&items, &totitem, md_item);
968 }
969
970 RNA_enum_item_end(&items, &totitem);
971 *r_free = true;
972
973 return items;
974 }
975
OBJECT_OT_modifier_add(wmOperatorType * ot)976 void OBJECT_OT_modifier_add(wmOperatorType *ot)
977 {
978 PropertyRNA *prop;
979
980 /* identifiers */
981 ot->name = "Add Modifier";
982 ot->description = "Add a procedural operation/effect to the active object";
983 ot->idname = "OBJECT_OT_modifier_add";
984
985 /* api callbacks */
986 ot->invoke = WM_menu_invoke;
987 ot->exec = modifier_add_exec;
988 ot->poll = ED_operator_object_active_editable;
989
990 /* flags */
991 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
992
993 /* properties */
994 prop = RNA_def_enum(
995 ot->srna, "type", rna_enum_object_modifier_type_items, eModifierType_Subsurf, "Type", "");
996 RNA_def_enum_funcs(prop, modifier_add_itemf);
997 ot->prop = prop;
998 }
999
1000 /** \} */
1001
1002 /* ------------------------------------------------------------------- */
1003 /** \name Generic Functions For Operators
1004 *
1005 * Using modifier names and data context.
1006 * \{ */
1007
edit_modifier_poll_generic(bContext * C,StructRNA * rna_type,int obtype_flag,const bool is_editmode_allowed,const bool is_liboverride_allowed)1008 bool edit_modifier_poll_generic(bContext *C,
1009 StructRNA *rna_type,
1010 int obtype_flag,
1011 const bool is_editmode_allowed,
1012 const bool is_liboverride_allowed)
1013 {
1014 PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", rna_type);
1015 Object *ob = (ptr.owner_id) ? (Object *)ptr.owner_id : ED_object_active_context(C);
1016 ModifierData *mod = ptr.data; /* May be NULL. */
1017
1018 if (!ob || ID_IS_LINKED(ob)) {
1019 return false;
1020 }
1021 if (obtype_flag && ((1 << ob->type) & obtype_flag) == 0) {
1022 return false;
1023 }
1024 if (ptr.owner_id && ID_IS_LINKED(ptr.owner_id)) {
1025 return false;
1026 }
1027
1028 if (ID_IS_OVERRIDE_LIBRARY(ob) && !is_liboverride_allowed) {
1029 if ((mod == NULL) || (mod->flag & eModifierFlag_OverrideLibrary_Local) == 0) {
1030 CTX_wm_operator_poll_msg_set(C, "Cannot edit modifiers coming from library override");
1031 return false;
1032 }
1033 }
1034
1035 if (!is_editmode_allowed && CTX_data_edit_object(C) != NULL) {
1036 CTX_wm_operator_poll_msg_set(C, "This modifier operation is not allowed from Edit mode");
1037 return false;
1038 }
1039
1040 return true;
1041 }
1042
edit_modifier_poll(bContext * C)1043 static bool edit_modifier_poll(bContext *C)
1044 {
1045 return edit_modifier_poll_generic(C, &RNA_Modifier, 0, true, false);
1046 }
1047
1048 /* Used by operators performing actions allowed also on modifiers from the overridden linked object
1049 * (not only from added 'local' ones). */
edit_modifier_liboverride_allowed_poll(bContext * C)1050 static bool edit_modifier_liboverride_allowed_poll(bContext *C)
1051 {
1052 return edit_modifier_poll_generic(C, &RNA_Modifier, 0, true, true);
1053 }
1054
edit_modifier_properties(wmOperatorType * ot)1055 void edit_modifier_properties(wmOperatorType *ot)
1056 {
1057 PropertyRNA *prop = RNA_def_string(
1058 ot->srna, "modifier", NULL, MAX_NAME, "Modifier", "Name of the modifier to edit");
1059 RNA_def_property_flag(prop, PROP_HIDDEN);
1060 }
1061
edit_modifier_report_property(wmOperatorType * ot)1062 static void edit_modifier_report_property(wmOperatorType *ot)
1063 {
1064 PropertyRNA *prop = RNA_def_boolean(
1065 ot->srna, "report", false, "Report", "Create a notification after the operation");
1066 RNA_def_property_flag(prop, PROP_HIDDEN);
1067 }
1068
1069 /**
1070 * \param event: If this isn't NULL, the operator will also look for panels underneath
1071 * the cursor with customdata set to a modifier.
1072 * \param r_retval: This should be used if #event is used in order to to return
1073 * #OPERATOR_PASS_THROUGH to check other operators with the same key set.
1074 */
edit_modifier_invoke_properties(bContext * C,wmOperator * op,const wmEvent * event,int * r_retval)1075 bool edit_modifier_invoke_properties(bContext *C,
1076 wmOperator *op,
1077 const wmEvent *event,
1078 int *r_retval)
1079 {
1080 if (RNA_struct_property_is_set(op->ptr, "modifier")) {
1081 return true;
1082 }
1083
1084 PointerRNA ctx_ptr = CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier);
1085 if (ctx_ptr.data != NULL) {
1086 ModifierData *md = ctx_ptr.data;
1087 RNA_string_set(op->ptr, "modifier", md->name);
1088 return true;
1089 }
1090
1091 /* Check the custom data of panels under the mouse for a modifier. */
1092 if (event != NULL) {
1093 PointerRNA *panel_ptr = UI_region_panel_custom_data_under_cursor(C, event);
1094
1095 if (!(panel_ptr == NULL || RNA_pointer_is_null(panel_ptr))) {
1096 if (RNA_struct_is_a(panel_ptr->type, &RNA_Modifier)) {
1097 ModifierData *md = panel_ptr->data;
1098 RNA_string_set(op->ptr, "modifier", md->name);
1099 return true;
1100 }
1101 BLI_assert(r_retval != NULL); /* We need the return value in this case. */
1102 if (r_retval != NULL) {
1103 *r_retval = (OPERATOR_PASS_THROUGH | OPERATOR_CANCELLED);
1104 }
1105 return false;
1106 }
1107 }
1108
1109 if (r_retval != NULL) {
1110 *r_retval = OPERATOR_CANCELLED;
1111 }
1112 return false;
1113 }
1114
edit_modifier_property_get(wmOperator * op,Object * ob,int type)1115 ModifierData *edit_modifier_property_get(wmOperator *op, Object *ob, int type)
1116 {
1117 char modifier_name[MAX_NAME];
1118 RNA_string_get(op->ptr, "modifier", modifier_name);
1119
1120 ModifierData *md = BKE_modifiers_findby_name(ob, modifier_name);
1121
1122 if (md && type != 0 && md->type != type) {
1123 md = NULL;
1124 }
1125
1126 return md;
1127 }
1128
1129 /** \} */
1130
1131 /* ------------------------------------------------------------------- */
1132 /** \name Remove Modifier Operator
1133 * \{ */
1134
modifier_remove_exec(bContext * C,wmOperator * op)1135 static int modifier_remove_exec(bContext *C, wmOperator *op)
1136 {
1137 Main *bmain = CTX_data_main(C);
1138 Scene *scene = CTX_data_scene(C);
1139 ViewLayer *view_layer = CTX_data_view_layer(C);
1140 Object *ob = ED_object_active_context(C);
1141 ModifierData *md = edit_modifier_property_get(op, ob, 0);
1142 int mode_orig = ob->mode;
1143
1144 if (md == NULL) {
1145 return OPERATOR_CANCELLED;
1146 }
1147
1148 /* Store name temporarily for report. */
1149 char name[MAX_NAME];
1150 strcpy(name, md->name);
1151
1152 if (!ED_object_modifier_remove(op->reports, bmain, scene, ob, md)) {
1153 return OPERATOR_CANCELLED;
1154 }
1155
1156 WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
1157
1158 /* if cloth/softbody was removed, particle mode could be cleared */
1159 if (mode_orig & OB_MODE_PARTICLE_EDIT) {
1160 if ((ob->mode & OB_MODE_PARTICLE_EDIT) == 0) {
1161 if (ob == OBACT(view_layer)) {
1162 WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_MODE_OBJECT, NULL);
1163 }
1164 }
1165 }
1166
1167 if (RNA_boolean_get(op->ptr, "report")) {
1168 BKE_reportf(op->reports, RPT_INFO, "Removed modifier: %s", name);
1169 }
1170
1171 return OPERATOR_FINISHED;
1172 }
1173
modifier_remove_invoke(bContext * C,wmOperator * op,const wmEvent * event)1174 static int modifier_remove_invoke(bContext *C, wmOperator *op, const wmEvent *event)
1175 {
1176 int retval;
1177 if (edit_modifier_invoke_properties(C, op, event, &retval)) {
1178 return modifier_remove_exec(C, op);
1179 }
1180 return retval;
1181 }
1182
OBJECT_OT_modifier_remove(wmOperatorType * ot)1183 void OBJECT_OT_modifier_remove(wmOperatorType *ot)
1184 {
1185 ot->name = "Remove Modifier";
1186 ot->description = "Remove a modifier from the active object";
1187 ot->idname = "OBJECT_OT_modifier_remove";
1188
1189 ot->invoke = modifier_remove_invoke;
1190 ot->exec = modifier_remove_exec;
1191 ot->poll = edit_modifier_poll;
1192
1193 /* flags */
1194 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1195 edit_modifier_properties(ot);
1196 edit_modifier_report_property(ot);
1197 }
1198
1199 /** \} */
1200
1201 /* ------------------------------------------------------------------- */
1202 /** \name Move Up Modifier Operator
1203 * \{ */
1204
modifier_move_up_exec(bContext * C,wmOperator * op)1205 static int modifier_move_up_exec(bContext *C, wmOperator *op)
1206 {
1207 Object *ob = ED_object_active_context(C);
1208 ModifierData *md = edit_modifier_property_get(op, ob, 0);
1209
1210 if (!md || !ED_object_modifier_move_up(op->reports, ob, md)) {
1211 return OPERATOR_CANCELLED;
1212 }
1213
1214 DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
1215 WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
1216
1217 return OPERATOR_FINISHED;
1218 }
1219
modifier_move_up_invoke(bContext * C,wmOperator * op,const wmEvent * event)1220 static int modifier_move_up_invoke(bContext *C, wmOperator *op, const wmEvent *event)
1221 {
1222 int retval;
1223 if (edit_modifier_invoke_properties(C, op, event, &retval)) {
1224 return modifier_move_up_exec(C, op);
1225 }
1226 return retval;
1227 }
1228
OBJECT_OT_modifier_move_up(wmOperatorType * ot)1229 void OBJECT_OT_modifier_move_up(wmOperatorType *ot)
1230 {
1231 ot->name = "Move Up Modifier";
1232 ot->description = "Move modifier up in the stack";
1233 ot->idname = "OBJECT_OT_modifier_move_up";
1234
1235 ot->invoke = modifier_move_up_invoke;
1236 ot->exec = modifier_move_up_exec;
1237 ot->poll = edit_modifier_poll;
1238
1239 /* flags */
1240 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1241 edit_modifier_properties(ot);
1242 }
1243
1244 /** \} */
1245
1246 /* ------------------------------------------------------------------- */
1247 /** \name Move Down Modifier Operator
1248 * \{ */
1249
modifier_move_down_exec(bContext * C,wmOperator * op)1250 static int modifier_move_down_exec(bContext *C, wmOperator *op)
1251 {
1252 Object *ob = ED_object_active_context(C);
1253 ModifierData *md = edit_modifier_property_get(op, ob, 0);
1254
1255 if (!md || !ED_object_modifier_move_down(op->reports, ob, md)) {
1256 return OPERATOR_CANCELLED;
1257 }
1258
1259 DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
1260 WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
1261
1262 return OPERATOR_FINISHED;
1263 }
1264
modifier_move_down_invoke(bContext * C,wmOperator * op,const wmEvent * event)1265 static int modifier_move_down_invoke(bContext *C, wmOperator *op, const wmEvent *event)
1266 {
1267 int retval;
1268 if (edit_modifier_invoke_properties(C, op, event, &retval)) {
1269 return modifier_move_down_exec(C, op);
1270 }
1271 return retval;
1272 }
1273
OBJECT_OT_modifier_move_down(wmOperatorType * ot)1274 void OBJECT_OT_modifier_move_down(wmOperatorType *ot)
1275 {
1276 ot->name = "Move Down Modifier";
1277 ot->description = "Move modifier down in the stack";
1278 ot->idname = "OBJECT_OT_modifier_move_down";
1279
1280 ot->invoke = modifier_move_down_invoke;
1281 ot->exec = modifier_move_down_exec;
1282 ot->poll = edit_modifier_poll;
1283
1284 /* flags */
1285 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1286 edit_modifier_properties(ot);
1287 }
1288
1289 /** \} */
1290
1291 /* ------------------------------------------------------------------- */
1292 /** \name Move to Index Modifier Operator
1293 * \{ */
1294
modifier_move_to_index_exec(bContext * C,wmOperator * op)1295 static int modifier_move_to_index_exec(bContext *C, wmOperator *op)
1296 {
1297 Object *ob = ED_object_active_context(C);
1298 ModifierData *md = edit_modifier_property_get(op, ob, 0);
1299 int index = RNA_int_get(op->ptr, "index");
1300
1301 if (!ED_object_modifier_move_to_index(op->reports, ob, md, index)) {
1302 return OPERATOR_CANCELLED;
1303 }
1304
1305 return OPERATOR_FINISHED;
1306 }
1307
modifier_move_to_index_invoke(bContext * C,wmOperator * op,const wmEvent * event)1308 static int modifier_move_to_index_invoke(bContext *C, wmOperator *op, const wmEvent *event)
1309 {
1310 int retval;
1311 if (edit_modifier_invoke_properties(C, op, event, &retval)) {
1312 return modifier_move_to_index_exec(C, op);
1313 }
1314 return retval;
1315 }
1316
OBJECT_OT_modifier_move_to_index(wmOperatorType * ot)1317 void OBJECT_OT_modifier_move_to_index(wmOperatorType *ot)
1318 {
1319 ot->name = "Move Active Modifier to Index";
1320 ot->description =
1321 "Change the modifier's index in the stack so it evaluates after the set number of others";
1322 ot->idname = "OBJECT_OT_modifier_move_to_index";
1323
1324 ot->invoke = modifier_move_to_index_invoke;
1325 ot->exec = modifier_move_to_index_exec;
1326 ot->poll = edit_modifier_poll;
1327
1328 /* flags */
1329 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1330 edit_modifier_properties(ot);
1331 RNA_def_int(
1332 ot->srna, "index", 0, 0, INT_MAX, "Index", "The index to move the modifier to", 0, INT_MAX);
1333 }
1334
1335 /** \} */
1336
1337 /* ------------------------------------------------------------------- */
1338 /** \name Apply Modifier Operator
1339 * \{ */
1340
modifier_apply_poll_ex(bContext * C,bool allow_shared)1341 static bool modifier_apply_poll_ex(bContext *C, bool allow_shared)
1342 {
1343 if (!edit_modifier_poll_generic(C, &RNA_Modifier, 0, false, false)) {
1344 return false;
1345 }
1346
1347 Scene *scene = CTX_data_scene(C);
1348 PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier);
1349 Object *ob = (ptr.owner_id != NULL) ? (Object *)ptr.owner_id : ED_object_active_context(C);
1350 ModifierData *md = ptr.data; /* May be NULL. */
1351
1352 if (ID_IS_OVERRIDE_LIBRARY(ob) || ((ob->data != NULL) && ID_IS_OVERRIDE_LIBRARY(ob->data))) {
1353 CTX_wm_operator_poll_msg_set(C, "Modifiers cannot be applied on override data");
1354 return false;
1355 }
1356 if (!allow_shared && (ob->data != NULL) && ID_REAL_USERS(ob->data) > 1) {
1357 CTX_wm_operator_poll_msg_set(C, "Modifiers cannot be applied to multi-user data");
1358 return false;
1359 }
1360 if (md != NULL) {
1361 if ((ob->mode & OB_MODE_SCULPT) && (find_multires_modifier_before(scene, md)) &&
1362 (BKE_modifier_is_same_topology(md) == false)) {
1363 CTX_wm_operator_poll_msg_set(
1364 C, "Constructive modifier cannot be applied to multi-res data in sculpt mode");
1365 return false;
1366 }
1367 }
1368 return true;
1369 }
1370
modifier_apply_poll(bContext * C)1371 static bool modifier_apply_poll(bContext *C)
1372 {
1373 return modifier_apply_poll_ex(C, false);
1374 }
1375
modifier_apply_exec_ex(bContext * C,wmOperator * op,int apply_as,bool keep_modifier)1376 static int modifier_apply_exec_ex(bContext *C, wmOperator *op, int apply_as, bool keep_modifier)
1377 {
1378 Main *bmain = CTX_data_main(C);
1379 Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
1380 Scene *scene = CTX_data_scene(C);
1381 Object *ob = ED_object_active_context(C);
1382 ModifierData *md = edit_modifier_property_get(op, ob, 0);
1383
1384 if (md == NULL) {
1385 return OPERATOR_CANCELLED;
1386 }
1387
1388 /* Store name temporarily for report. */
1389 char name[MAX_NAME];
1390 strcpy(name, md->name);
1391
1392 if (!ED_object_modifier_apply(
1393 bmain, op->reports, depsgraph, scene, ob, md, apply_as, keep_modifier)) {
1394 return OPERATOR_CANCELLED;
1395 }
1396
1397 DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
1398 DEG_relations_tag_update(bmain);
1399 WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
1400
1401 if (RNA_boolean_get(op->ptr, "report")) {
1402 BKE_reportf(op->reports, RPT_INFO, "Applied modifier: %s", name);
1403 }
1404
1405 return OPERATOR_FINISHED;
1406 }
1407
modifier_apply_exec(bContext * C,wmOperator * op)1408 static int modifier_apply_exec(bContext *C, wmOperator *op)
1409 {
1410 return modifier_apply_exec_ex(C, op, MODIFIER_APPLY_DATA, false);
1411 }
1412
modifier_apply_invoke(bContext * C,wmOperator * op,const wmEvent * event)1413 static int modifier_apply_invoke(bContext *C, wmOperator *op, const wmEvent *event)
1414 {
1415 int retval;
1416 if (edit_modifier_invoke_properties(C, op, event, &retval)) {
1417 return modifier_apply_exec(C, op);
1418 }
1419 return retval;
1420 }
1421
OBJECT_OT_modifier_apply(wmOperatorType * ot)1422 void OBJECT_OT_modifier_apply(wmOperatorType *ot)
1423 {
1424 ot->name = "Apply Modifier";
1425 ot->description = "Apply modifier and remove from the stack";
1426 ot->idname = "OBJECT_OT_modifier_apply";
1427
1428 ot->invoke = modifier_apply_invoke;
1429 ot->exec = modifier_apply_exec;
1430 ot->poll = modifier_apply_poll;
1431
1432 /* flags */
1433 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1434
1435 edit_modifier_properties(ot);
1436 edit_modifier_report_property(ot);
1437 }
1438
1439 /** \} */
1440
1441 /* ------------------------------------------------------------------- */
1442 /** \name Apply Modifier As Shapekey Operator
1443 * \{ */
1444
modifier_apply_as_shapekey_poll(bContext * C)1445 static bool modifier_apply_as_shapekey_poll(bContext *C)
1446 {
1447 return modifier_apply_poll_ex(C, true);
1448 }
1449
modifier_apply_as_shapekey_exec(bContext * C,wmOperator * op)1450 static int modifier_apply_as_shapekey_exec(bContext *C, wmOperator *op)
1451 {
1452 bool keep = RNA_boolean_get(op->ptr, "keep_modifier");
1453
1454 return modifier_apply_exec_ex(C, op, MODIFIER_APPLY_SHAPE, keep);
1455 }
1456
modifier_apply_as_shapekey_invoke(bContext * C,wmOperator * op,const wmEvent * event)1457 static int modifier_apply_as_shapekey_invoke(bContext *C, wmOperator *op, const wmEvent *event)
1458 {
1459 int retval;
1460 if (edit_modifier_invoke_properties(C, op, event, &retval)) {
1461 return modifier_apply_as_shapekey_exec(C, op);
1462 }
1463 return retval;
1464 }
1465
modifier_apply_as_shapekey_get_description(struct bContext * UNUSED (C),struct wmOperatorType * UNUSED (op),struct PointerRNA * values)1466 static char *modifier_apply_as_shapekey_get_description(struct bContext *UNUSED(C),
1467 struct wmOperatorType *UNUSED(op),
1468 struct PointerRNA *values)
1469 {
1470 bool keep = RNA_boolean_get(values, "keep_modifier");
1471
1472 if (keep) {
1473 return BLI_strdup("Apply modifier as a new shapekey and keep it in the stack");
1474 }
1475
1476 return NULL;
1477 }
1478
OBJECT_OT_modifier_apply_as_shapekey(wmOperatorType * ot)1479 void OBJECT_OT_modifier_apply_as_shapekey(wmOperatorType *ot)
1480 {
1481 ot->name = "Apply Modifier As Shapekey";
1482 ot->description = "Apply modifier as a new shapekey and remove from the stack";
1483 ot->idname = "OBJECT_OT_modifier_apply_as_shapekey";
1484
1485 ot->invoke = modifier_apply_as_shapekey_invoke;
1486 ot->exec = modifier_apply_as_shapekey_exec;
1487 ot->poll = modifier_apply_as_shapekey_poll;
1488 ot->get_description = modifier_apply_as_shapekey_get_description;
1489
1490 /* flags */
1491 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1492
1493 RNA_def_boolean(
1494 ot->srna, "keep_modifier", false, "Keep Modifier", "Do not remove the modifier from stack");
1495 edit_modifier_properties(ot);
1496 edit_modifier_report_property(ot);
1497 }
1498
1499 /** \} */
1500
1501 /* ------------------------------------------------------------------- */
1502 /** \name Convert Modifier Operator
1503 * \{ */
1504
modifier_convert_exec(bContext * C,wmOperator * op)1505 static int modifier_convert_exec(bContext *C, wmOperator *op)
1506 {
1507 Main *bmain = CTX_data_main(C);
1508 Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
1509 ViewLayer *view_layer = CTX_data_view_layer(C);
1510 Object *ob = ED_object_active_context(C);
1511 ModifierData *md = edit_modifier_property_get(op, ob, 0);
1512
1513 if (!md || !ED_object_modifier_convert(op->reports, bmain, depsgraph, view_layer, ob, md)) {
1514 return OPERATOR_CANCELLED;
1515 }
1516
1517 DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
1518 WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
1519
1520 return OPERATOR_FINISHED;
1521 }
1522
modifier_convert_invoke(bContext * C,wmOperator * op,const wmEvent * UNUSED (event))1523 static int modifier_convert_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
1524 {
1525 if (edit_modifier_invoke_properties(C, op, NULL, NULL)) {
1526 return modifier_convert_exec(C, op);
1527 }
1528 return OPERATOR_CANCELLED;
1529 }
1530
OBJECT_OT_modifier_convert(wmOperatorType * ot)1531 void OBJECT_OT_modifier_convert(wmOperatorType *ot)
1532 {
1533 ot->name = "Convert Modifier";
1534 ot->description = "Convert particles to a mesh object";
1535 ot->idname = "OBJECT_OT_modifier_convert";
1536
1537 ot->invoke = modifier_convert_invoke;
1538 ot->exec = modifier_convert_exec;
1539 ot->poll = edit_modifier_poll;
1540
1541 /* flags */
1542 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1543 edit_modifier_properties(ot);
1544 }
1545
1546 /** \} */
1547
1548 /* ------------------------------------------------------------------- */
1549 /** \name Copy Modifier Operator
1550 * \{ */
1551
modifier_copy_exec(bContext * C,wmOperator * op)1552 static int modifier_copy_exec(bContext *C, wmOperator *op)
1553 {
1554 Main *bmain = CTX_data_main(C);
1555 Scene *scene = CTX_data_scene(C);
1556 Object *ob = ED_object_active_context(C);
1557 ModifierData *md = edit_modifier_property_get(op, ob, 0);
1558
1559 if (!md || !ED_object_modifier_copy(op->reports, bmain, scene, ob, md)) {
1560 return OPERATOR_CANCELLED;
1561 }
1562
1563 DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
1564 WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
1565
1566 return OPERATOR_FINISHED;
1567 }
1568
modifier_copy_invoke(bContext * C,wmOperator * op,const wmEvent * event)1569 static int modifier_copy_invoke(bContext *C, wmOperator *op, const wmEvent *event)
1570 {
1571 int retval;
1572 if (edit_modifier_invoke_properties(C, op, event, &retval)) {
1573 return modifier_copy_exec(C, op);
1574 }
1575 return retval;
1576 }
1577
OBJECT_OT_modifier_copy(wmOperatorType * ot)1578 void OBJECT_OT_modifier_copy(wmOperatorType *ot)
1579 {
1580 ot->name = "Copy Modifier";
1581 ot->description = "Duplicate modifier at the same position in the stack";
1582 ot->idname = "OBJECT_OT_modifier_copy";
1583
1584 ot->invoke = modifier_copy_invoke;
1585 ot->exec = modifier_copy_exec;
1586 ot->poll = edit_modifier_liboverride_allowed_poll;
1587
1588 /* flags */
1589 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1590 edit_modifier_properties(ot);
1591 }
1592
1593 /** \} */
1594
1595 /* ------------------------------------------------------------------- */
1596 /** \name Multires Delete Higher Levels Operator
1597 * \{ */
1598
multires_poll(bContext * C)1599 static bool multires_poll(bContext *C)
1600 {
1601 return edit_modifier_poll_generic(C, &RNA_MultiresModifier, (1 << OB_MESH), true, false);
1602 }
1603
multires_higher_levels_delete_exec(bContext * C,wmOperator * op)1604 static int multires_higher_levels_delete_exec(bContext *C, wmOperator *op)
1605 {
1606 Scene *scene = CTX_data_scene(C);
1607 Object *ob = ED_object_active_context(C);
1608 MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get(
1609 op, ob, eModifierType_Multires);
1610
1611 if (!mmd) {
1612 return OPERATOR_CANCELLED;
1613 }
1614
1615 multiresModifier_del_levels(mmd, scene, ob, 1);
1616
1617 ED_object_iter_other(
1618 CTX_data_main(C), ob, true, ED_object_multires_update_totlevels_cb, &mmd->totlvl);
1619
1620 WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
1621
1622 return OPERATOR_FINISHED;
1623 }
1624
multires_higher_levels_delete_invoke(bContext * C,wmOperator * op,const wmEvent * UNUSED (event))1625 static int multires_higher_levels_delete_invoke(bContext *C,
1626 wmOperator *op,
1627 const wmEvent *UNUSED(event))
1628 {
1629 if (edit_modifier_invoke_properties(C, op, NULL, NULL)) {
1630 return multires_higher_levels_delete_exec(C, op);
1631 }
1632 return OPERATOR_CANCELLED;
1633 }
1634
OBJECT_OT_multires_higher_levels_delete(wmOperatorType * ot)1635 void OBJECT_OT_multires_higher_levels_delete(wmOperatorType *ot)
1636 {
1637 ot->name = "Delete Higher Levels";
1638 ot->description = "Deletes the higher resolution mesh, potential loss of detail";
1639 ot->idname = "OBJECT_OT_multires_higher_levels_delete";
1640
1641 ot->poll = multires_poll;
1642 ot->invoke = multires_higher_levels_delete_invoke;
1643 ot->exec = multires_higher_levels_delete_exec;
1644
1645 /* flags */
1646 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1647 edit_modifier_properties(ot);
1648 }
1649
1650 /** \} */
1651
1652 /* ------------------------------------------------------------------- */
1653 /** \name Multires Subdivide Operator
1654 * \{ */
1655
1656 static EnumPropertyItem prop_multires_subdivide_mode_type[] = {
1657 {MULTIRES_SUBDIVIDE_CATMULL_CLARK,
1658 "CATMULL_CLARK",
1659 0,
1660 "Catmull-Clark",
1661 "Create a new level using Catmull-Clark subdivisions"},
1662 {MULTIRES_SUBDIVIDE_SIMPLE,
1663 "SIMPLE",
1664 0,
1665 "Simple",
1666 "Create a new level using simple subdivisions"},
1667 {MULTIRES_SUBDIVIDE_LINEAR,
1668 "LINEAR",
1669 0,
1670 "Linear",
1671 "Create a new level using linear interpolation of the sculpted displacement"},
1672 {0, NULL, 0, NULL, NULL},
1673 };
1674
multires_subdivide_exec(bContext * C,wmOperator * op)1675 static int multires_subdivide_exec(bContext *C, wmOperator *op)
1676 {
1677 Object *object = ED_object_active_context(C);
1678 MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get(
1679 op, object, eModifierType_Multires);
1680
1681 if (!mmd) {
1682 return OPERATOR_CANCELLED;
1683 }
1684
1685 const eMultiresSubdivideModeType subdivide_mode = (eMultiresSubdivideModeType)(
1686 RNA_enum_get(op->ptr, "mode"));
1687 multiresModifier_subdivide(object, mmd, subdivide_mode);
1688
1689 ED_object_iter_other(
1690 CTX_data_main(C), object, true, ED_object_multires_update_totlevels_cb, &mmd->totlvl);
1691
1692 DEG_id_tag_update(&object->id, ID_RECALC_GEOMETRY);
1693 WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, object);
1694
1695 if (object->mode & OB_MODE_SCULPT) {
1696 /* ensure that grid paint mask layer is created */
1697 BKE_sculpt_mask_layers_ensure(object, mmd);
1698 }
1699
1700 return OPERATOR_FINISHED;
1701 }
1702
multires_subdivide_invoke(bContext * C,wmOperator * op,const wmEvent * UNUSED (event))1703 static int multires_subdivide_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
1704 {
1705 if (edit_modifier_invoke_properties(C, op, NULL, NULL)) {
1706 return multires_subdivide_exec(C, op);
1707 }
1708 return OPERATOR_CANCELLED;
1709 }
1710
OBJECT_OT_multires_subdivide(wmOperatorType * ot)1711 void OBJECT_OT_multires_subdivide(wmOperatorType *ot)
1712 {
1713 ot->name = "Multires Subdivide";
1714 ot->description = "Add a new level of subdivision";
1715 ot->idname = "OBJECT_OT_multires_subdivide";
1716
1717 ot->poll = multires_poll;
1718 ot->invoke = multires_subdivide_invoke;
1719 ot->exec = multires_subdivide_exec;
1720
1721 /* flags */
1722 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1723 edit_modifier_properties(ot);
1724 RNA_def_enum(ot->srna,
1725 "mode",
1726 prop_multires_subdivide_mode_type,
1727 MULTIRES_SUBDIVIDE_CATMULL_CLARK,
1728 "Subdivision Mode",
1729 "How the mesh is going to be subdivided to create a new level");
1730 }
1731
1732 /** \} */
1733
1734 /* ------------------------------------------------------------------- */
1735 /** \name Multires Reshape Operator
1736 * \{ */
1737
multires_reshape_exec(bContext * C,wmOperator * op)1738 static int multires_reshape_exec(bContext *C, wmOperator *op)
1739 {
1740 Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
1741 Object *ob = ED_object_active_context(C), *secondob = NULL;
1742 MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get(
1743 op, ob, eModifierType_Multires);
1744
1745 if (!mmd) {
1746 return OPERATOR_CANCELLED;
1747 }
1748
1749 if (mmd->lvl == 0) {
1750 BKE_report(op->reports, RPT_ERROR, "Reshape can work only with higher levels of subdivisions");
1751 return OPERATOR_CANCELLED;
1752 }
1753
1754 CTX_DATA_BEGIN (C, Object *, selob, selected_editable_objects) {
1755 if (selob->type == OB_MESH && selob != ob) {
1756 secondob = selob;
1757 break;
1758 }
1759 }
1760 CTX_DATA_END;
1761
1762 if (!secondob) {
1763 BKE_report(op->reports, RPT_ERROR, "Second selected mesh object required to copy shape from");
1764 return OPERATOR_CANCELLED;
1765 }
1766
1767 if (!multiresModifier_reshapeFromObject(depsgraph, mmd, ob, secondob)) {
1768 BKE_report(op->reports, RPT_ERROR, "Objects do not have the same number of vertices");
1769 return OPERATOR_CANCELLED;
1770 }
1771
1772 DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
1773 WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
1774
1775 return OPERATOR_FINISHED;
1776 }
1777
multires_reshape_invoke(bContext * C,wmOperator * op,const wmEvent * UNUSED (event))1778 static int multires_reshape_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
1779 {
1780 if (edit_modifier_invoke_properties(C, op, NULL, NULL)) {
1781 return multires_reshape_exec(C, op);
1782 }
1783 return OPERATOR_CANCELLED;
1784 }
1785
OBJECT_OT_multires_reshape(wmOperatorType * ot)1786 void OBJECT_OT_multires_reshape(wmOperatorType *ot)
1787 {
1788 ot->name = "Multires Reshape";
1789 ot->description = "Copy vertex coordinates from other object";
1790 ot->idname = "OBJECT_OT_multires_reshape";
1791
1792 ot->poll = multires_poll;
1793 ot->invoke = multires_reshape_invoke;
1794 ot->exec = multires_reshape_exec;
1795
1796 /* flags */
1797 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1798 edit_modifier_properties(ot);
1799 }
1800
1801 /** \} */
1802
1803 /* ------------------------------------------------------------------- */
1804 /** \name Multires Save External Operator
1805 * \{ */
1806
multires_external_save_exec(bContext * C,wmOperator * op)1807 static int multires_external_save_exec(bContext *C, wmOperator *op)
1808 {
1809 Main *bmain = CTX_data_main(C);
1810 Object *ob = ED_object_active_context(C);
1811 Mesh *me = (ob) ? ob->data : op->customdata;
1812 char path[FILE_MAX];
1813 const bool relative = RNA_boolean_get(op->ptr, "relative_path");
1814
1815 if (!me) {
1816 return OPERATOR_CANCELLED;
1817 }
1818
1819 if (CustomData_external_test(&me->ldata, CD_MDISPS)) {
1820 return OPERATOR_CANCELLED;
1821 }
1822
1823 RNA_string_get(op->ptr, "filepath", path);
1824
1825 if (relative) {
1826 BLI_path_rel(path, BKE_main_blendfile_path(bmain));
1827 }
1828
1829 CustomData_external_add(&me->ldata, &me->id, CD_MDISPS, me->totloop, path);
1830 CustomData_external_write(&me->ldata, &me->id, CD_MASK_MESH.lmask, me->totloop, 0);
1831
1832 return OPERATOR_FINISHED;
1833 }
1834
multires_external_save_invoke(bContext * C,wmOperator * op,const wmEvent * UNUSED (event))1835 static int multires_external_save_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
1836 {
1837 Object *ob = ED_object_active_context(C);
1838 Mesh *me = ob->data;
1839 char path[FILE_MAX];
1840
1841 if (!edit_modifier_invoke_properties(C, op, NULL, NULL)) {
1842 return OPERATOR_CANCELLED;
1843 }
1844
1845 MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get(
1846 op, ob, eModifierType_Multires);
1847
1848 if (!mmd) {
1849 return OPERATOR_CANCELLED;
1850 }
1851
1852 if (CustomData_external_test(&me->ldata, CD_MDISPS)) {
1853 return OPERATOR_CANCELLED;
1854 }
1855
1856 if (RNA_struct_property_is_set(op->ptr, "filepath")) {
1857 return multires_external_save_exec(C, op);
1858 }
1859
1860 op->customdata = me;
1861
1862 BLI_snprintf(path, sizeof(path), "//%s.btx", me->id.name + 2);
1863 RNA_string_set(op->ptr, "filepath", path);
1864
1865 WM_event_add_fileselect(C, op);
1866
1867 return OPERATOR_RUNNING_MODAL;
1868 }
1869
OBJECT_OT_multires_external_save(wmOperatorType * ot)1870 void OBJECT_OT_multires_external_save(wmOperatorType *ot)
1871 {
1872 ot->name = "Multires Save External";
1873 ot->description = "Save displacements to an external file";
1874 ot->idname = "OBJECT_OT_multires_external_save";
1875
1876 /* XXX modifier no longer in context after file browser .. ot->poll = multires_poll; */
1877 ot->exec = multires_external_save_exec;
1878 ot->invoke = multires_external_save_invoke;
1879 ot->poll = multires_poll;
1880
1881 /* flags */
1882 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1883
1884 WM_operator_properties_filesel(ot,
1885 FILE_TYPE_FOLDER | FILE_TYPE_BTX,
1886 FILE_SPECIAL,
1887 FILE_SAVE,
1888 WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH,
1889 FILE_DEFAULTDISPLAY,
1890 FILE_SORT_ALPHA);
1891 edit_modifier_properties(ot);
1892 }
1893
1894 /** \} */
1895
1896 /* ------------------------------------------------------------------- */
1897 /** \name Multires Pack Operator
1898 * \{ */
1899
multires_external_pack_exec(bContext * C,wmOperator * UNUSED (op))1900 static int multires_external_pack_exec(bContext *C, wmOperator *UNUSED(op))
1901 {
1902 Object *ob = ED_object_active_context(C);
1903 Mesh *me = ob->data;
1904
1905 if (!CustomData_external_test(&me->ldata, CD_MDISPS)) {
1906 return OPERATOR_CANCELLED;
1907 }
1908
1909 /* XXX don't remove.. */
1910 CustomData_external_remove(&me->ldata, &me->id, CD_MDISPS, me->totloop);
1911
1912 return OPERATOR_FINISHED;
1913 }
1914
OBJECT_OT_multires_external_pack(wmOperatorType * ot)1915 void OBJECT_OT_multires_external_pack(wmOperatorType *ot)
1916 {
1917 ot->name = "Multires Pack External";
1918 ot->description = "Pack displacements from an external file";
1919 ot->idname = "OBJECT_OT_multires_external_pack";
1920
1921 ot->poll = multires_poll;
1922 ot->exec = multires_external_pack_exec;
1923
1924 /* flags */
1925 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1926 }
1927
1928 /** \} */
1929
1930 /* ------------------------------------------------------------------- */
1931 /** \name Multires Apply Base
1932 * \{ */
1933
multires_base_apply_exec(bContext * C,wmOperator * op)1934 static int multires_base_apply_exec(bContext *C, wmOperator *op)
1935 {
1936 Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
1937 Object *object = ED_object_active_context(C);
1938 MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get(
1939 op, object, eModifierType_Multires);
1940
1941 if (!mmd) {
1942 return OPERATOR_CANCELLED;
1943 }
1944
1945 ED_sculpt_undo_push_multires_mesh_begin(C, op->type->name);
1946
1947 multiresModifier_base_apply(depsgraph, object, mmd);
1948
1949 ED_sculpt_undo_push_multires_mesh_end(C, op->type->name);
1950
1951 DEG_id_tag_update(&object->id, ID_RECALC_GEOMETRY);
1952 WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, object);
1953
1954 return OPERATOR_FINISHED;
1955 }
1956
multires_base_apply_invoke(bContext * C,wmOperator * op,const wmEvent * UNUSED (event))1957 static int multires_base_apply_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
1958 {
1959 if (edit_modifier_invoke_properties(C, op, NULL, NULL)) {
1960 return multires_base_apply_exec(C, op);
1961 }
1962 return OPERATOR_CANCELLED;
1963 }
1964
OBJECT_OT_multires_base_apply(wmOperatorType * ot)1965 void OBJECT_OT_multires_base_apply(wmOperatorType *ot)
1966 {
1967 ot->name = "Multires Apply Base";
1968 ot->description = "Modify the base mesh to conform to the displaced mesh";
1969 ot->idname = "OBJECT_OT_multires_base_apply";
1970
1971 ot->poll = multires_poll;
1972 ot->invoke = multires_base_apply_invoke;
1973 ot->exec = multires_base_apply_exec;
1974
1975 /* flags */
1976 ot->flag = OPTYPE_REGISTER | OPTYPE_INTERNAL;
1977 edit_modifier_properties(ot);
1978 }
1979
1980 /** \} */
1981
1982 /* ------------------------------------------------------------------- */
1983 /** \name Multires Unsubdivide
1984 * \{ */
1985
multires_unsubdivide_exec(bContext * C,wmOperator * op)1986 static int multires_unsubdivide_exec(bContext *C, wmOperator *op)
1987 {
1988 Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
1989 Object *object = ED_object_active_context(C);
1990 MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get(
1991 op, object, eModifierType_Multires);
1992
1993 if (!mmd) {
1994 return OPERATOR_CANCELLED;
1995 }
1996
1997 int new_levels = multiresModifier_rebuild_subdiv(depsgraph, object, mmd, 1, true);
1998 if (new_levels == 0) {
1999 BKE_report(op->reports, RPT_ERROR, "Not valid subdivisions found to rebuild a lower level");
2000 return OPERATOR_CANCELLED;
2001 }
2002
2003 DEG_id_tag_update(&object->id, ID_RECALC_GEOMETRY);
2004 WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, object);
2005
2006 return OPERATOR_FINISHED;
2007 }
2008
multires_unsubdivide_invoke(bContext * C,wmOperator * op,const wmEvent * UNUSED (event))2009 static int multires_unsubdivide_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
2010 {
2011 if (edit_modifier_invoke_properties(C, op, NULL, NULL)) {
2012 return multires_unsubdivide_exec(C, op);
2013 }
2014 return OPERATOR_CANCELLED;
2015 }
2016
OBJECT_OT_multires_unsubdivide(wmOperatorType * ot)2017 void OBJECT_OT_multires_unsubdivide(wmOperatorType *ot)
2018 {
2019 ot->name = "Unsubdivide";
2020 ot->description = "Rebuild a lower subdivision level of the current base mesh";
2021 ot->idname = "OBJECT_OT_multires_unsubdivide";
2022
2023 ot->poll = multires_poll;
2024 ot->invoke = multires_unsubdivide_invoke;
2025 ot->exec = multires_unsubdivide_exec;
2026
2027 /* flags */
2028 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
2029 edit_modifier_properties(ot);
2030 }
2031
2032 /** \} */
2033
2034 /* ------------------------------------------------------------------- */
2035 /** \name Multires Rebuild Subdivisions
2036 * \{ */
2037
multires_rebuild_subdiv_exec(bContext * C,wmOperator * op)2038 static int multires_rebuild_subdiv_exec(bContext *C, wmOperator *op)
2039 {
2040 Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
2041 Object *object = ED_object_active_context(C);
2042 MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get(
2043 op, object, eModifierType_Multires);
2044
2045 if (!mmd) {
2046 return OPERATOR_CANCELLED;
2047 }
2048
2049 int new_levels = multiresModifier_rebuild_subdiv(depsgraph, object, mmd, INT_MAX, false);
2050 if (new_levels == 0) {
2051 BKE_report(op->reports, RPT_ERROR, "Not valid subdivisions found to rebuild lower levels");
2052 return OPERATOR_CANCELLED;
2053 }
2054
2055 BKE_reportf(op->reports, RPT_INFO, "%d new levels rebuilt", new_levels);
2056
2057 DEG_id_tag_update(&object->id, ID_RECALC_GEOMETRY);
2058 WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, object);
2059
2060 return OPERATOR_FINISHED;
2061 }
2062
multires_rebuild_subdiv_invoke(bContext * C,wmOperator * op,const wmEvent * UNUSED (event))2063 static int multires_rebuild_subdiv_invoke(bContext *C,
2064 wmOperator *op,
2065 const wmEvent *UNUSED(event))
2066 {
2067 if (edit_modifier_invoke_properties(C, op, NULL, NULL)) {
2068 return multires_rebuild_subdiv_exec(C, op);
2069 }
2070 return OPERATOR_CANCELLED;
2071 }
2072
OBJECT_OT_multires_rebuild_subdiv(wmOperatorType * ot)2073 void OBJECT_OT_multires_rebuild_subdiv(wmOperatorType *ot)
2074 {
2075 ot->name = "Rebuild Lower Subdivisions";
2076 ot->description =
2077 "Rebuilds all possible subdivisions levels to generate a lower resolution base mesh";
2078 ot->idname = "OBJECT_OT_multires_rebuild_subdiv";
2079
2080 ot->poll = multires_poll;
2081 ot->invoke = multires_rebuild_subdiv_invoke;
2082 ot->exec = multires_rebuild_subdiv_exec;
2083
2084 /* flags */
2085 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
2086 edit_modifier_properties(ot);
2087 }
2088
2089 /** \} */
2090
2091 /* ------------------------------------------------------------------- */
2092 /** \name Skin Modifier
2093 * \{ */
2094
modifier_skin_customdata_delete(Object * ob)2095 static void modifier_skin_customdata_delete(Object *ob)
2096 {
2097 Mesh *me = ob->data;
2098 BMEditMesh *em = me->edit_mesh;
2099
2100 if (em) {
2101 BM_data_layer_free(em->bm, &em->bm->vdata, CD_MVERT_SKIN);
2102 }
2103 else {
2104 CustomData_free_layer_active(&me->vdata, CD_MVERT_SKIN, me->totvert);
2105 }
2106 }
2107
skin_poll(bContext * C)2108 static bool skin_poll(bContext *C)
2109 {
2110 return (edit_modifier_poll_generic(C, &RNA_SkinModifier, (1 << OB_MESH), false, false));
2111 }
2112
skin_edit_poll(bContext * C)2113 static bool skin_edit_poll(bContext *C)
2114 {
2115 Object *ob = CTX_data_edit_object(C);
2116 return (ob != NULL &&
2117 edit_modifier_poll_generic(C, &RNA_SkinModifier, (1 << OB_MESH), true, false) &&
2118 !ID_IS_OVERRIDE_LIBRARY(ob) && !ID_IS_OVERRIDE_LIBRARY(ob->data));
2119 }
2120
skin_root_clear(BMVert * bm_vert,GSet * visited,const int cd_vert_skin_offset)2121 static void skin_root_clear(BMVert *bm_vert, GSet *visited, const int cd_vert_skin_offset)
2122 {
2123 BMEdge *bm_edge;
2124 BMIter bm_iter;
2125
2126 BM_ITER_ELEM (bm_edge, &bm_iter, bm_vert, BM_EDGES_OF_VERT) {
2127 BMVert *v2 = BM_edge_other_vert(bm_edge, bm_vert);
2128
2129 if (BLI_gset_add(visited, v2)) {
2130 MVertSkin *vs = BM_ELEM_CD_GET_VOID_P(v2, cd_vert_skin_offset);
2131
2132 /* clear vertex root flag and add to visited set */
2133 vs->flag &= ~MVERT_SKIN_ROOT;
2134
2135 skin_root_clear(v2, visited, cd_vert_skin_offset);
2136 }
2137 }
2138 }
2139
skin_root_mark_exec(bContext * C,wmOperator * UNUSED (op))2140 static int skin_root_mark_exec(bContext *C, wmOperator *UNUSED(op))
2141 {
2142 Object *ob = CTX_data_edit_object(C);
2143 BMEditMesh *em = BKE_editmesh_from_object(ob);
2144 BMesh *bm = em->bm;
2145
2146 GSet *visited = BLI_gset_ptr_new(__func__);
2147
2148 BKE_mesh_ensure_skin_customdata(ob->data);
2149
2150 const int cd_vert_skin_offset = CustomData_get_offset(&bm->vdata, CD_MVERT_SKIN);
2151
2152 BMVert *bm_vert;
2153 BMIter bm_iter;
2154 BM_ITER_MESH (bm_vert, &bm_iter, bm, BM_VERTS_OF_MESH) {
2155 if (BM_elem_flag_test(bm_vert, BM_ELEM_SELECT) && BLI_gset_add(visited, bm_vert)) {
2156 MVertSkin *vs = BM_ELEM_CD_GET_VOID_P(bm_vert, cd_vert_skin_offset);
2157
2158 /* mark vertex as root and add to visited set */
2159 vs->flag |= MVERT_SKIN_ROOT;
2160
2161 /* clear root flag from all connected vertices (recursively) */
2162 skin_root_clear(bm_vert, visited, cd_vert_skin_offset);
2163 }
2164 }
2165
2166 BLI_gset_free(visited, NULL);
2167
2168 DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
2169 WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
2170
2171 return OPERATOR_FINISHED;
2172 }
2173
OBJECT_OT_skin_root_mark(wmOperatorType * ot)2174 void OBJECT_OT_skin_root_mark(wmOperatorType *ot)
2175 {
2176 ot->name = "Skin Root Mark";
2177 ot->description = "Mark selected vertices as roots";
2178 ot->idname = "OBJECT_OT_skin_root_mark";
2179
2180 ot->poll = skin_edit_poll;
2181 ot->exec = skin_root_mark_exec;
2182
2183 /* flags */
2184 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2185 }
2186
2187 typedef enum {
2188 SKIN_LOOSE_MARK,
2189 SKIN_LOOSE_CLEAR,
2190 } SkinLooseAction;
2191
skin_loose_mark_clear_exec(bContext * C,wmOperator * op)2192 static int skin_loose_mark_clear_exec(bContext *C, wmOperator *op)
2193 {
2194 Object *ob = CTX_data_edit_object(C);
2195 BMEditMesh *em = BKE_editmesh_from_object(ob);
2196 BMesh *bm = em->bm;
2197 SkinLooseAction action = RNA_enum_get(op->ptr, "action");
2198
2199 if (!CustomData_has_layer(&bm->vdata, CD_MVERT_SKIN)) {
2200 return OPERATOR_CANCELLED;
2201 }
2202
2203 BMVert *bm_vert;
2204 BMIter bm_iter;
2205 BM_ITER_MESH (bm_vert, &bm_iter, bm, BM_VERTS_OF_MESH) {
2206 if (BM_elem_flag_test(bm_vert, BM_ELEM_SELECT)) {
2207 MVertSkin *vs = CustomData_bmesh_get(&bm->vdata, bm_vert->head.data, CD_MVERT_SKIN);
2208
2209 switch (action) {
2210 case SKIN_LOOSE_MARK:
2211 vs->flag |= MVERT_SKIN_LOOSE;
2212 break;
2213 case SKIN_LOOSE_CLEAR:
2214 vs->flag &= ~MVERT_SKIN_LOOSE;
2215 break;
2216 }
2217 }
2218 }
2219
2220 DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
2221 WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
2222
2223 return OPERATOR_FINISHED;
2224 }
2225
OBJECT_OT_skin_loose_mark_clear(wmOperatorType * ot)2226 void OBJECT_OT_skin_loose_mark_clear(wmOperatorType *ot)
2227 {
2228 static const EnumPropertyItem action_items[] = {
2229 {SKIN_LOOSE_MARK, "MARK", 0, "Mark", "Mark selected vertices as loose"},
2230 {SKIN_LOOSE_CLEAR, "CLEAR", 0, "Clear", "Set selected vertices as not loose"},
2231 {0, NULL, 0, NULL, NULL},
2232 };
2233
2234 ot->name = "Skin Mark/Clear Loose";
2235 ot->description = "Mark/clear selected vertices as loose";
2236 ot->idname = "OBJECT_OT_skin_loose_mark_clear";
2237
2238 ot->poll = skin_edit_poll;
2239 ot->exec = skin_loose_mark_clear_exec;
2240
2241 /* flags */
2242 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2243
2244 RNA_def_enum(ot->srna, "action", action_items, SKIN_LOOSE_MARK, "Action", NULL);
2245 }
2246
skin_radii_equalize_exec(bContext * C,wmOperator * UNUSED (op))2247 static int skin_radii_equalize_exec(bContext *C, wmOperator *UNUSED(op))
2248 {
2249 Object *ob = CTX_data_edit_object(C);
2250 BMEditMesh *em = BKE_editmesh_from_object(ob);
2251 BMesh *bm = em->bm;
2252
2253 if (!CustomData_has_layer(&bm->vdata, CD_MVERT_SKIN)) {
2254 return OPERATOR_CANCELLED;
2255 }
2256
2257 BMVert *bm_vert;
2258 BMIter bm_iter;
2259 BM_ITER_MESH (bm_vert, &bm_iter, bm, BM_VERTS_OF_MESH) {
2260 if (BM_elem_flag_test(bm_vert, BM_ELEM_SELECT)) {
2261 MVertSkin *vs = CustomData_bmesh_get(&bm->vdata, bm_vert->head.data, CD_MVERT_SKIN);
2262 float avg = (vs->radius[0] + vs->radius[1]) * 0.5f;
2263
2264 vs->radius[0] = vs->radius[1] = avg;
2265 }
2266 }
2267
2268 DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
2269 WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
2270
2271 return OPERATOR_FINISHED;
2272 }
2273
OBJECT_OT_skin_radii_equalize(wmOperatorType * ot)2274 void OBJECT_OT_skin_radii_equalize(wmOperatorType *ot)
2275 {
2276 ot->name = "Skin Radii Equalize";
2277 ot->description = "Make skin radii of selected vertices equal on each axis";
2278 ot->idname = "OBJECT_OT_skin_radii_equalize";
2279
2280 ot->poll = skin_edit_poll;
2281 ot->exec = skin_radii_equalize_exec;
2282
2283 /* flags */
2284 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2285 }
2286
skin_armature_bone_create(Object * skin_ob,MVert * mvert,MEdge * medge,bArmature * arm,BLI_bitmap * edges_visited,const MeshElemMap * emap,EditBone * parent_bone,int parent_v)2287 static void skin_armature_bone_create(Object *skin_ob,
2288 MVert *mvert,
2289 MEdge *medge,
2290 bArmature *arm,
2291 BLI_bitmap *edges_visited,
2292 const MeshElemMap *emap,
2293 EditBone *parent_bone,
2294 int parent_v)
2295 {
2296 for (int i = 0; i < emap[parent_v].count; i++) {
2297 int endx = emap[parent_v].indices[i];
2298 const MEdge *e = &medge[endx];
2299
2300 /* ignore edge if already visited */
2301 if (BLI_BITMAP_TEST(edges_visited, endx)) {
2302 continue;
2303 }
2304 BLI_BITMAP_ENABLE(edges_visited, endx);
2305
2306 int v = (e->v1 == parent_v ? e->v2 : e->v1);
2307
2308 EditBone *bone = ED_armature_ebone_add(arm, "Bone");
2309
2310 bone->parent = parent_bone;
2311 if (parent_bone != NULL) {
2312 bone->flag |= BONE_CONNECTED;
2313 }
2314
2315 copy_v3_v3(bone->head, mvert[parent_v].co);
2316 copy_v3_v3(bone->tail, mvert[v].co);
2317 bone->rad_head = bone->rad_tail = 0.25;
2318 BLI_snprintf(bone->name, sizeof(bone->name), "Bone.%.2d", endx);
2319
2320 /* add bDeformGroup */
2321 bDeformGroup *dg = BKE_object_defgroup_add_name(skin_ob, bone->name);
2322 if (dg != NULL) {
2323 ED_vgroup_vert_add(skin_ob, dg, parent_v, 1, WEIGHT_REPLACE);
2324 ED_vgroup_vert_add(skin_ob, dg, v, 1, WEIGHT_REPLACE);
2325 }
2326
2327 skin_armature_bone_create(skin_ob, mvert, medge, arm, edges_visited, emap, bone, v);
2328 }
2329 }
2330
modifier_skin_armature_create(Depsgraph * depsgraph,Main * bmain,Object * skin_ob)2331 static Object *modifier_skin_armature_create(Depsgraph *depsgraph, Main *bmain, Object *skin_ob)
2332 {
2333 Mesh *me = skin_ob->data;
2334
2335 Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
2336 Object *ob_eval = DEG_get_evaluated_object(depsgraph, skin_ob);
2337
2338 Mesh *me_eval_deform = mesh_get_eval_deform(depsgraph, scene_eval, ob_eval, &CD_MASK_BAREMESH);
2339 MVert *mvert = me_eval_deform->mvert;
2340
2341 /* add vertex weights to original mesh */
2342 CustomData_add_layer(&me->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, me->totvert);
2343
2344 ViewLayer *view_layer = DEG_get_input_view_layer(depsgraph);
2345 Object *arm_ob = BKE_object_add(bmain, view_layer, OB_ARMATURE, NULL);
2346 BKE_object_transform_copy(arm_ob, skin_ob);
2347 bArmature *arm = arm_ob->data;
2348 arm->layer = 1;
2349 arm_ob->dtx |= OB_DRAW_IN_FRONT;
2350 arm->drawtype = ARM_LINE;
2351 arm->edbo = MEM_callocN(sizeof(ListBase), "edbo armature");
2352
2353 MVertSkin *mvert_skin = CustomData_get_layer(&me->vdata, CD_MVERT_SKIN);
2354 int *emap_mem;
2355 MeshElemMap *emap;
2356 BKE_mesh_vert_edge_map_create(&emap, &emap_mem, me->medge, me->totvert, me->totedge);
2357
2358 BLI_bitmap *edges_visited = BLI_BITMAP_NEW(me->totedge, "edge_visited");
2359
2360 /* note: we use EditBones here, easier to set them up and use
2361 * edit-armature functions to convert back to regular bones */
2362 for (int v = 0; v < me->totvert; v++) {
2363 if (mvert_skin[v].flag & MVERT_SKIN_ROOT) {
2364 EditBone *bone = NULL;
2365
2366 /* Unless the skin root has just one adjacent edge, create
2367 * a fake root bone (have it going off in the Y direction
2368 * (arbitrary) */
2369 if (emap[v].count > 1) {
2370 bone = ED_armature_ebone_add(arm, "Bone");
2371
2372 copy_v3_v3(bone->head, me->mvert[v].co);
2373 copy_v3_v3(bone->tail, me->mvert[v].co);
2374
2375 bone->head[1] = 1.0f;
2376 bone->rad_head = bone->rad_tail = 0.25;
2377 }
2378
2379 if (emap[v].count >= 1) {
2380 skin_armature_bone_create(skin_ob, mvert, me->medge, arm, edges_visited, emap, bone, v);
2381 }
2382 }
2383 }
2384
2385 MEM_freeN(edges_visited);
2386 MEM_freeN(emap);
2387 MEM_freeN(emap_mem);
2388
2389 ED_armature_from_edit(bmain, arm);
2390 ED_armature_edit_free(arm);
2391
2392 return arm_ob;
2393 }
2394
skin_armature_create_exec(bContext * C,wmOperator * op)2395 static int skin_armature_create_exec(bContext *C, wmOperator *op)
2396 {
2397 Main *bmain = CTX_data_main(C);
2398 Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
2399 Object *ob = CTX_data_active_object(C);
2400 Mesh *me = ob->data;
2401 ModifierData *skin_md;
2402
2403 if (!CustomData_has_layer(&me->vdata, CD_MVERT_SKIN)) {
2404 BKE_reportf(op->reports, RPT_WARNING, "Mesh '%s' has no skin vertex data", me->id.name + 2);
2405 return OPERATOR_CANCELLED;
2406 }
2407
2408 /* create new armature */
2409 Object *arm_ob = modifier_skin_armature_create(depsgraph, bmain, ob);
2410
2411 /* add a modifier to connect the new armature to the mesh */
2412 ArmatureModifierData *arm_md = (ArmatureModifierData *)BKE_modifier_new(eModifierType_Armature);
2413 if (arm_md) {
2414 skin_md = edit_modifier_property_get(op, ob, eModifierType_Skin);
2415 BLI_insertlinkafter(&ob->modifiers, skin_md, arm_md);
2416
2417 arm_md->object = arm_ob;
2418 arm_md->deformflag = ARM_DEF_VGROUP | ARM_DEF_QUATERNION;
2419 DEG_relations_tag_update(bmain);
2420 DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
2421 }
2422
2423 WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
2424
2425 return OPERATOR_FINISHED;
2426 }
2427
skin_armature_create_invoke(bContext * C,wmOperator * op,const wmEvent * UNUSED (event))2428 static int skin_armature_create_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
2429 {
2430 if (edit_modifier_invoke_properties(C, op, NULL, NULL)) {
2431 return skin_armature_create_exec(C, op);
2432 }
2433 return OPERATOR_CANCELLED;
2434 }
2435
OBJECT_OT_skin_armature_create(wmOperatorType * ot)2436 void OBJECT_OT_skin_armature_create(wmOperatorType *ot)
2437 {
2438 ot->name = "Skin Armature Create";
2439 ot->description = "Create an armature that parallels the skin layout";
2440 ot->idname = "OBJECT_OT_skin_armature_create";
2441
2442 ot->poll = skin_poll;
2443 ot->invoke = skin_armature_create_invoke;
2444 ot->exec = skin_armature_create_exec;
2445
2446 /* flags */
2447 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
2448 edit_modifier_properties(ot);
2449 }
2450 /** \} */
2451
2452 /* ------------------------------------------------------------------- */
2453 /** \name Delta Mesh Bind Operator
2454 * \{ */
2455
correctivesmooth_poll(bContext * C)2456 static bool correctivesmooth_poll(bContext *C)
2457 {
2458 return edit_modifier_poll_generic(C, &RNA_CorrectiveSmoothModifier, 0, true, false);
2459 }
2460
correctivesmooth_bind_exec(bContext * C,wmOperator * op)2461 static int correctivesmooth_bind_exec(bContext *C, wmOperator *op)
2462 {
2463 Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
2464 Scene *scene = CTX_data_scene(C);
2465 Object *ob = ED_object_active_context(C);
2466 CorrectiveSmoothModifierData *csmd = (CorrectiveSmoothModifierData *)edit_modifier_property_get(
2467 op, ob, eModifierType_CorrectiveSmooth);
2468
2469 if (!csmd) {
2470 return OPERATOR_CANCELLED;
2471 }
2472
2473 if (!BKE_modifier_is_enabled(scene, &csmd->modifier, eModifierMode_Realtime)) {
2474 BKE_report(op->reports, RPT_ERROR, "Modifier is disabled");
2475 return OPERATOR_CANCELLED;
2476 }
2477
2478 const bool is_bind = (csmd->bind_coords != NULL);
2479
2480 MEM_SAFE_FREE(csmd->bind_coords);
2481 MEM_SAFE_FREE(csmd->delta_cache.deltas);
2482
2483 if (is_bind) {
2484 /* toggle off */
2485 csmd->bind_coords_num = 0;
2486 }
2487 else {
2488 /* Signal to modifier to recalculate. */
2489 CorrectiveSmoothModifierData *csmd_eval = (CorrectiveSmoothModifierData *)
2490 BKE_modifier_get_evaluated(depsgraph, ob, &csmd->modifier);
2491 csmd_eval->bind_coords_num = (uint)-1;
2492
2493 /* Force modifier to run, it will call binding routine
2494 * (this has to happen outside of depsgraph evaluation). */
2495 object_force_modifier_bind_simple_options(depsgraph, ob, &csmd->modifier);
2496 }
2497
2498 DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
2499 WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
2500
2501 return OPERATOR_FINISHED;
2502 }
2503
correctivesmooth_bind_invoke(bContext * C,wmOperator * op,const wmEvent * UNUSED (event))2504 static int correctivesmooth_bind_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
2505 {
2506 if (edit_modifier_invoke_properties(C, op, NULL, NULL)) {
2507 return correctivesmooth_bind_exec(C, op);
2508 }
2509 return OPERATOR_CANCELLED;
2510 }
2511
OBJECT_OT_correctivesmooth_bind(wmOperatorType * ot)2512 void OBJECT_OT_correctivesmooth_bind(wmOperatorType *ot)
2513 {
2514 /* identifiers */
2515 ot->name = "Corrective Smooth Bind";
2516 ot->description = "Bind base pose in Corrective Smooth modifier";
2517 ot->idname = "OBJECT_OT_correctivesmooth_bind";
2518
2519 /* api callbacks */
2520 ot->poll = correctivesmooth_poll;
2521 ot->invoke = correctivesmooth_bind_invoke;
2522 ot->exec = correctivesmooth_bind_exec;
2523
2524 /* flags */
2525 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
2526 edit_modifier_properties(ot);
2527 }
2528
2529 /** \} */
2530
2531 /* ------------------------------------------------------------------- */
2532 /** \name Mesh Deform Bind Operator
2533 * \{ */
2534
meshdeform_poll(bContext * C)2535 static bool meshdeform_poll(bContext *C)
2536 {
2537 return edit_modifier_poll_generic(C, &RNA_MeshDeformModifier, 0, true, false);
2538 }
2539
meshdeform_bind_exec(bContext * C,wmOperator * op)2540 static int meshdeform_bind_exec(bContext *C, wmOperator *op)
2541 {
2542 Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
2543 Object *ob = ED_object_active_context(C);
2544 MeshDeformModifierData *mmd = (MeshDeformModifierData *)edit_modifier_property_get(
2545 op, ob, eModifierType_MeshDeform);
2546
2547 if (mmd == NULL) {
2548 return OPERATOR_CANCELLED;
2549 }
2550
2551 if (mmd->bindcagecos != NULL) {
2552 MEM_SAFE_FREE(mmd->bindcagecos);
2553 MEM_SAFE_FREE(mmd->dyngrid);
2554 MEM_SAFE_FREE(mmd->dyninfluences);
2555 MEM_SAFE_FREE(mmd->bindinfluences);
2556 MEM_SAFE_FREE(mmd->bindoffsets);
2557 MEM_SAFE_FREE(mmd->dynverts);
2558 MEM_SAFE_FREE(mmd->bindweights); /* Deprecated */
2559 MEM_SAFE_FREE(mmd->bindcos); /* Deprecated */
2560 mmd->totvert = 0;
2561 mmd->totcagevert = 0;
2562 mmd->totinfluence = 0;
2563 }
2564 else {
2565 /* Force modifier to run, it will call binding routine
2566 * (this has to happen outside of depsgraph evaluation). */
2567 MeshDeformModifierData *mmd_eval = (MeshDeformModifierData *)BKE_modifier_get_evaluated(
2568 depsgraph, ob, &mmd->modifier);
2569 mmd_eval->bindfunc = ED_mesh_deform_bind_callback;
2570 object_force_modifier_bind_simple_options(depsgraph, ob, &mmd->modifier);
2571 mmd_eval->bindfunc = NULL;
2572 }
2573
2574 DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
2575 WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
2576 return OPERATOR_FINISHED;
2577 }
2578
meshdeform_bind_invoke(bContext * C,wmOperator * op,const wmEvent * UNUSED (event))2579 static int meshdeform_bind_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
2580 {
2581 if (edit_modifier_invoke_properties(C, op, NULL, NULL)) {
2582 return meshdeform_bind_exec(C, op);
2583 }
2584 return OPERATOR_CANCELLED;
2585 }
2586
OBJECT_OT_meshdeform_bind(wmOperatorType * ot)2587 void OBJECT_OT_meshdeform_bind(wmOperatorType *ot)
2588 {
2589 /* identifiers */
2590 ot->name = "Mesh Deform Bind";
2591 ot->description = "Bind mesh to cage in mesh deform modifier";
2592 ot->idname = "OBJECT_OT_meshdeform_bind";
2593
2594 /* api callbacks */
2595 ot->poll = meshdeform_poll;
2596 ot->invoke = meshdeform_bind_invoke;
2597 ot->exec = meshdeform_bind_exec;
2598
2599 /* flags */
2600 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
2601 edit_modifier_properties(ot);
2602 }
2603
2604 /** \} */
2605
2606 /* ------------------------------------------------------------------- */
2607 /** \name Explode Refresh Operator
2608 * \{ */
2609
explode_poll(bContext * C)2610 static bool explode_poll(bContext *C)
2611 {
2612 return edit_modifier_poll_generic(C, &RNA_ExplodeModifier, 0, true, false);
2613 }
2614
explode_refresh_exec(bContext * C,wmOperator * op)2615 static int explode_refresh_exec(bContext *C, wmOperator *op)
2616 {
2617 Object *ob = ED_object_active_context(C);
2618 ExplodeModifierData *emd = (ExplodeModifierData *)edit_modifier_property_get(
2619 op, ob, eModifierType_Explode);
2620
2621 if (!emd) {
2622 return OPERATOR_CANCELLED;
2623 }
2624
2625 emd->flag |= eExplodeFlag_CalcFaces;
2626
2627 DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
2628 WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
2629
2630 return OPERATOR_FINISHED;
2631 }
2632
explode_refresh_invoke(bContext * C,wmOperator * op,const wmEvent * UNUSED (event))2633 static int explode_refresh_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
2634 {
2635 if (edit_modifier_invoke_properties(C, op, NULL, NULL)) {
2636 return explode_refresh_exec(C, op);
2637 }
2638 return OPERATOR_CANCELLED;
2639 }
2640
OBJECT_OT_explode_refresh(wmOperatorType * ot)2641 void OBJECT_OT_explode_refresh(wmOperatorType *ot)
2642 {
2643 ot->name = "Explode Refresh";
2644 ot->description = "Refresh data in the Explode modifier";
2645 ot->idname = "OBJECT_OT_explode_refresh";
2646
2647 ot->poll = explode_poll;
2648 ot->invoke = explode_refresh_invoke;
2649 ot->exec = explode_refresh_exec;
2650
2651 /* flags */
2652 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
2653 edit_modifier_properties(ot);
2654 }
2655
2656 /** \} */
2657
2658 /* ------------------------------------------------------------------- */
2659 /** \name Ocean Bake Operator
2660 * \{ */
2661
ocean_bake_poll(bContext * C)2662 static bool ocean_bake_poll(bContext *C)
2663 {
2664 return edit_modifier_poll_generic(C, &RNA_OceanModifier, 0, true, false);
2665 }
2666
2667 typedef struct OceanBakeJob {
2668 /* from wmJob */
2669 struct Object *owner;
2670 short *stop, *do_update;
2671 float *progress;
2672 int current_frame;
2673 struct OceanCache *och;
2674 struct Ocean *ocean;
2675 struct OceanModifierData *omd;
2676 } OceanBakeJob;
2677
oceanbake_free(void * customdata)2678 static void oceanbake_free(void *customdata)
2679 {
2680 OceanBakeJob *oj = customdata;
2681 MEM_freeN(oj);
2682 }
2683
2684 /* called by oceanbake, only to check job 'stop' value */
oceanbake_breakjob(void * UNUSED (customdata))2685 static int oceanbake_breakjob(void *UNUSED(customdata))
2686 {
2687 // OceanBakeJob *ob = (OceanBakeJob *)customdata;
2688 // return *(ob->stop);
2689
2690 /* this is not nice yet, need to make the jobs list template better
2691 * for identifying/acting upon various different jobs */
2692 /* but for now we'll reuse the render break... */
2693 return (G.is_break);
2694 }
2695
2696 /* called by oceanbake, wmJob sends notifier */
oceanbake_update(void * customdata,float progress,int * cancel)2697 static void oceanbake_update(void *customdata, float progress, int *cancel)
2698 {
2699 OceanBakeJob *oj = customdata;
2700
2701 if (oceanbake_breakjob(oj)) {
2702 *cancel = 1;
2703 }
2704
2705 *(oj->do_update) = true;
2706 *(oj->progress) = progress;
2707 }
2708
oceanbake_startjob(void * customdata,short * stop,short * do_update,float * progress)2709 static void oceanbake_startjob(void *customdata, short *stop, short *do_update, float *progress)
2710 {
2711 OceanBakeJob *oj = customdata;
2712
2713 oj->stop = stop;
2714 oj->do_update = do_update;
2715 oj->progress = progress;
2716
2717 G.is_break = false; /* XXX shared with render - replace with job 'stop' switch */
2718
2719 BKE_ocean_bake(oj->ocean, oj->och, oceanbake_update, (void *)oj);
2720
2721 *do_update = true;
2722 *stop = 0;
2723 }
2724
oceanbake_endjob(void * customdata)2725 static void oceanbake_endjob(void *customdata)
2726 {
2727 OceanBakeJob *oj = customdata;
2728
2729 if (oj->ocean) {
2730 BKE_ocean_free(oj->ocean);
2731 oj->ocean = NULL;
2732 }
2733
2734 oj->omd->oceancache = oj->och;
2735 oj->omd->cached = true;
2736
2737 Object *ob = oj->owner;
2738 DEG_id_tag_update(&ob->id, ID_RECALC_COPY_ON_WRITE);
2739 }
2740
ocean_bake_exec(bContext * C,wmOperator * op)2741 static int ocean_bake_exec(bContext *C, wmOperator *op)
2742 {
2743 Main *bmain = CTX_data_main(C);
2744 Object *ob = ED_object_active_context(C);
2745 OceanModifierData *omd = (OceanModifierData *)edit_modifier_property_get(
2746 op, ob, eModifierType_Ocean);
2747 Scene *scene = CTX_data_scene(C);
2748 const bool free = RNA_boolean_get(op->ptr, "free");
2749
2750 if (!omd) {
2751 return OPERATOR_CANCELLED;
2752 }
2753
2754 if (free) {
2755 BKE_ocean_free_modifier_cache(omd);
2756 DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
2757 WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
2758 return OPERATOR_FINISHED;
2759 }
2760
2761 OceanCache *och = BKE_ocean_init_cache(omd->cachepath,
2762 BKE_modifier_path_relbase(bmain, ob),
2763 omd->bakestart,
2764 omd->bakeend,
2765 omd->wave_scale,
2766 omd->chop_amount,
2767 omd->foam_coverage,
2768 omd->foam_fade,
2769 omd->resolution);
2770
2771 och->time = MEM_mallocN(och->duration * sizeof(float), "foam bake time");
2772
2773 int cfra = scene->r.cfra;
2774
2775 /* precalculate time variable before baking */
2776 int i = 0;
2777 Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
2778 for (int f = omd->bakestart; f <= omd->bakeend; f++) {
2779 /* For now only simple animation of time value is supported, nothing else.
2780 * No drivers or other modifier parameters. */
2781 /* TODO(sergey): This operates on an original data, so no flush is needed. However, baking
2782 * usually should happen on an evaluated objects, so this seems to be deeper issue here. */
2783
2784 const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph,
2785 f);
2786 BKE_animsys_evaluate_animdata((ID *)ob, ob->adt, &anim_eval_context, ADT_RECALC_ANIM, false);
2787
2788 och->time[i] = omd->time;
2789 i++;
2790 }
2791
2792 /* make a copy of ocean to use for baking - threadsafety */
2793 struct Ocean *ocean = BKE_ocean_add();
2794 BKE_ocean_init_from_modifier(ocean, omd, omd->resolution);
2795
2796 #if 0
2797 BKE_ocean_bake(ocean, och);
2798
2799 omd->oceancache = och;
2800 omd->cached = true;
2801
2802 scene->r.cfra = cfra;
2803
2804 DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
2805 WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
2806 #endif
2807
2808 /* job stuff */
2809
2810 scene->r.cfra = cfra;
2811
2812 /* setup job */
2813 wmJob *wm_job = WM_jobs_get(CTX_wm_manager(C),
2814 CTX_wm_window(C),
2815 scene,
2816 "Ocean Simulation",
2817 WM_JOB_PROGRESS,
2818 WM_JOB_TYPE_OBJECT_SIM_OCEAN);
2819 OceanBakeJob *oj = MEM_callocN(sizeof(OceanBakeJob), "ocean bake job");
2820 oj->owner = ob;
2821 oj->ocean = ocean;
2822 oj->och = och;
2823 oj->omd = omd;
2824
2825 WM_jobs_customdata_set(wm_job, oj, oceanbake_free);
2826 WM_jobs_timer(wm_job, 0.1, NC_OBJECT | ND_MODIFIER, NC_OBJECT | ND_MODIFIER);
2827 WM_jobs_callbacks(wm_job, oceanbake_startjob, NULL, NULL, oceanbake_endjob);
2828
2829 WM_jobs_start(CTX_wm_manager(C), wm_job);
2830
2831 return OPERATOR_FINISHED;
2832 }
2833
ocean_bake_invoke(bContext * C,wmOperator * op,const wmEvent * UNUSED (event))2834 static int ocean_bake_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
2835 {
2836 if (edit_modifier_invoke_properties(C, op, NULL, NULL)) {
2837 return ocean_bake_exec(C, op);
2838 }
2839 return OPERATOR_CANCELLED;
2840 }
2841
OBJECT_OT_ocean_bake(wmOperatorType * ot)2842 void OBJECT_OT_ocean_bake(wmOperatorType *ot)
2843 {
2844 ot->name = "Bake Ocean";
2845 ot->description = "Bake an image sequence of ocean data";
2846 ot->idname = "OBJECT_OT_ocean_bake";
2847
2848 ot->poll = ocean_bake_poll;
2849 ot->invoke = ocean_bake_invoke;
2850 ot->exec = ocean_bake_exec;
2851
2852 /* flags */
2853 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
2854 edit_modifier_properties(ot);
2855
2856 RNA_def_boolean(ot->srna, "free", false, "Free", "Free the bake, rather than generating it");
2857 }
2858
2859 /** \} */
2860
2861 /* ------------------------------------------------------------------- */
2862 /** \name Laplaciandeform Bind Operator
2863 * \{ */
2864
laplaciandeform_poll(bContext * C)2865 static bool laplaciandeform_poll(bContext *C)
2866 {
2867 return edit_modifier_poll_generic(C, &RNA_LaplacianDeformModifier, 0, false, false);
2868 }
2869
laplaciandeform_bind_exec(bContext * C,wmOperator * op)2870 static int laplaciandeform_bind_exec(bContext *C, wmOperator *op)
2871 {
2872 Object *ob = ED_object_active_context(C);
2873 Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
2874 LaplacianDeformModifierData *lmd = (LaplacianDeformModifierData *)edit_modifier_property_get(
2875 op, ob, eModifierType_LaplacianDeform);
2876
2877 if (lmd == NULL) {
2878 return OPERATOR_CANCELLED;
2879 }
2880
2881 if (lmd->flag & MOD_LAPLACIANDEFORM_BIND) {
2882 lmd->flag &= ~MOD_LAPLACIANDEFORM_BIND;
2883 }
2884 else {
2885 lmd->flag |= MOD_LAPLACIANDEFORM_BIND;
2886 }
2887
2888 LaplacianDeformModifierData *lmd_eval = (LaplacianDeformModifierData *)
2889 BKE_modifier_get_evaluated(depsgraph, ob, &lmd->modifier);
2890 lmd_eval->flag = lmd->flag;
2891
2892 /* Force modifier to run, it will call binding routine
2893 * (this has to happen outside of depsgraph evaluation). */
2894 object_force_modifier_bind_simple_options(depsgraph, ob, &lmd->modifier);
2895
2896 /* This is hard to know from the modifier itself whether the evaluation is
2897 * happening for binding or not. So we copy all the required data here. */
2898 lmd->total_verts = lmd_eval->total_verts;
2899 if (lmd_eval->vertexco == NULL) {
2900 MEM_SAFE_FREE(lmd->vertexco);
2901 }
2902 else {
2903 lmd->vertexco = MEM_dupallocN(lmd_eval->vertexco);
2904 }
2905
2906 DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
2907 WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
2908 return OPERATOR_FINISHED;
2909 }
2910
laplaciandeform_bind_invoke(bContext * C,wmOperator * op,const wmEvent * UNUSED (event))2911 static int laplaciandeform_bind_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
2912 {
2913 if (edit_modifier_invoke_properties(C, op, NULL, NULL)) {
2914 return laplaciandeform_bind_exec(C, op);
2915 }
2916 return OPERATOR_CANCELLED;
2917 }
2918
OBJECT_OT_laplaciandeform_bind(wmOperatorType * ot)2919 void OBJECT_OT_laplaciandeform_bind(wmOperatorType *ot)
2920 {
2921 /* identifiers */
2922 ot->name = "Laplacian Deform Bind";
2923 ot->description = "Bind mesh to system in laplacian deform modifier";
2924 ot->idname = "OBJECT_OT_laplaciandeform_bind";
2925
2926 /* api callbacks */
2927 ot->poll = laplaciandeform_poll;
2928 ot->invoke = laplaciandeform_bind_invoke;
2929 ot->exec = laplaciandeform_bind_exec;
2930
2931 /* flags */
2932 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
2933 edit_modifier_properties(ot);
2934 }
2935
2936 /** \} */
2937
2938 /* ------------------------------------------------------------------- */
2939 /** \name Surface Deform Bind Operator
2940 * \{ */
2941
surfacedeform_bind_poll(bContext * C)2942 static bool surfacedeform_bind_poll(bContext *C)
2943 {
2944 return edit_modifier_poll_generic(C, &RNA_SurfaceDeformModifier, 0, true, false);
2945 }
2946
surfacedeform_bind_exec(bContext * C,wmOperator * op)2947 static int surfacedeform_bind_exec(bContext *C, wmOperator *op)
2948 {
2949 Object *ob = ED_object_active_context(C);
2950 Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
2951 SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)edit_modifier_property_get(
2952 op, ob, eModifierType_SurfaceDeform);
2953
2954 if (smd == NULL) {
2955 return OPERATOR_CANCELLED;
2956 }
2957
2958 if (smd->flags & MOD_SDEF_BIND) {
2959 smd->flags &= ~MOD_SDEF_BIND;
2960 }
2961 else if (smd->target) {
2962 smd->flags |= MOD_SDEF_BIND;
2963 }
2964
2965 SurfaceDeformModifierData *smd_eval = (SurfaceDeformModifierData *)BKE_modifier_get_evaluated(
2966 depsgraph, ob, &smd->modifier);
2967 smd_eval->flags = smd->flags;
2968
2969 /* Force modifier to run, it will call binding routine
2970 * (this has to happen outside of depsgraph evaluation). */
2971 object_force_modifier_bind_simple_options(depsgraph, ob, &smd->modifier);
2972
2973 DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
2974 WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
2975 return OPERATOR_FINISHED;
2976 }
2977
surfacedeform_bind_invoke(bContext * C,wmOperator * op,const wmEvent * UNUSED (event))2978 static int surfacedeform_bind_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
2979 {
2980 if (edit_modifier_invoke_properties(C, op, NULL, NULL)) {
2981 return surfacedeform_bind_exec(C, op);
2982 }
2983 return OPERATOR_CANCELLED;
2984 }
2985
OBJECT_OT_surfacedeform_bind(wmOperatorType * ot)2986 void OBJECT_OT_surfacedeform_bind(wmOperatorType *ot)
2987 {
2988 /* identifiers */
2989 ot->name = "Surface Deform Bind";
2990 ot->description = "Bind mesh to target in surface deform modifier";
2991 ot->idname = "OBJECT_OT_surfacedeform_bind";
2992
2993 /* api callbacks */
2994 ot->poll = surfacedeform_bind_poll;
2995 ot->invoke = surfacedeform_bind_invoke;
2996 ot->exec = surfacedeform_bind_exec;
2997
2998 /* flags */
2999 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
3000 edit_modifier_properties(ot);
3001 }
3002
3003 /** \} */
3004