Rename ID_IS_LINKED_DATABLOCK to ID_IS_LINKED.
[blender.git] / source / blender / editors / physics / particle_object.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version. 
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2009 Blender Foundation.
19  * All rights reserved.
20  *
21  * Contributor(s): Blender Foundation
22  *
23  * ***** END GPL LICENSE BLOCK *****
24  */
25
26 /** \file blender/editors/physics/particle_object.c
27  *  \ingroup edphys
28  */
29
30
31 #include <stdlib.h>
32 #include <string.h>
33
34 #include "MEM_guardedalloc.h"
35
36 #include "DNA_meshdata_types.h"
37 #include "DNA_modifier_types.h"
38 #include "DNA_scene_types.h"
39
40 #include "BLI_math.h"
41 #include "BLI_listbase.h"
42 #include "BLI_utildefines.h"
43 #include "BLI_string.h"
44
45 #include "BKE_context.h"
46 #include "BKE_depsgraph.h"
47 #include "BKE_DerivedMesh.h"
48 #include "BKE_cdderivedmesh.h"
49 #include "BKE_global.h"
50 #include "BKE_library.h"
51 #include "BKE_main.h"
52 #include "BKE_modifier.h"
53 #include "BKE_object.h"
54 #include "BKE_particle.h"
55 #include "BKE_pointcache.h"
56 #include "BKE_report.h"
57
58 #include "RNA_access.h"
59 #include "RNA_define.h"
60
61 #include "WM_api.h"
62 #include "WM_types.h"
63
64 #include "ED_particle.h"
65 #include "ED_screen.h"
66 #include "ED_object.h"
67
68 #include "UI_resources.h"
69
70 #include "physics_intern.h"
71
72 extern void PE_create_particle_edit(Scene *scene, Object *ob, PointCache *cache, ParticleSystem *psys);
73 extern void PTCacheUndo_clear(PTCacheEdit *edit);
74 extern void recalc_lengths(PTCacheEdit *edit);
75 extern void recalc_emitter_field(Object *ob, ParticleSystem *psys);
76 extern void update_world_cos(Object *ob, PTCacheEdit *edit);
77
78 #define KEY_K                                   PTCacheEditKey *key; int k
79 #define POINT_P                                 PTCacheEditPoint *point; int p
80 #define LOOP_POINTS                             for (p=0, point=edit->points; p<edit->totpoint; p++, point++)
81 #if 0
82 #define LOOP_VISIBLE_POINTS             for (p=0, point=edit->points; p<edit->totpoint; p++, point++) if (!(point->flag & PEP_HIDE))
83 #define LOOP_SELECTED_POINTS    for (p=0, point=edit->points; p<edit->totpoint; p++, point++) if (point_is_selected(point))
84 #define LOOP_UNSELECTED_POINTS  for (p=0, point=edit->points; p<edit->totpoint; p++, point++) if (!point_is_selected(point))
85 #define LOOP_EDITED_POINTS              for (p=0, point=edit->points; p<edit->totpoint; p++, point++) if (point->flag & PEP_EDIT_RECALC)
86 #define LOOP_TAGGED_POINTS              for (p=0, point=edit->points; p<edit->totpoint; p++, point++) if (point->flag & PEP_TAG)
87 #endif
88 #define LOOP_KEYS                               for (k=0, key=point->keys; k<point->totkey; k++, key++)
89 #if 0
90 #define LOOP_VISIBLE_KEYS               for (k=0, key=point->keys; k<point->totkey; k++, key++) if (!(key->flag & PEK_HIDE))
91 #define LOOP_SELECTED_KEYS              for (k=0, key=point->keys; k<point->totkey; k++, key++) if ((key->flag & PEK_SELECT) && !(key->flag & PEK_HIDE))
92 #define LOOP_TAGGED_KEYS                for (k=0, key=point->keys; k<point->totkey; k++, key++) if (key->flag & PEK_TAG)
93
94 #define KEY_WCO                                 (key->flag & PEK_USE_WCO ? key->world_co : key->co)
95 #endif
96
97 static float I[4][4] = {{1.0f, 0.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f, 1.0f}};
98
99 /********************** particle system slot operators *********************/
100
101 static int particle_system_add_exec(bContext *C, wmOperator *UNUSED(op))
102 {
103         Object *ob= ED_object_context(C);
104         Scene *scene = CTX_data_scene(C);
105
106         if (!scene || !ob)
107                 return OPERATOR_CANCELLED;
108
109         object_add_particle_system(scene, ob, NULL);
110         
111         WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, ob);
112         WM_event_add_notifier(C, NC_OBJECT|ND_POINTCACHE, ob);
113         
114         return OPERATOR_FINISHED;
115 }
116
117 void OBJECT_OT_particle_system_add(wmOperatorType *ot)
118 {
119         /* identifiers */
120         ot->name = "Add Particle System Slot";
121         ot->idname = "OBJECT_OT_particle_system_add";
122         ot->description = "Add a particle system";
123         
124         /* api callbacks */
125         ot->poll = ED_operator_object_active_editable;
126         ot->exec = particle_system_add_exec;
127         
128         /* flags */
129         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
130 }
131
132 static int particle_system_remove_exec(bContext *C, wmOperator *UNUSED(op))
133 {
134         Object *ob = ED_object_context(C);
135         Scene *scene = CTX_data_scene(C);
136         int mode_orig;
137
138         if (!scene || !ob)
139                 return OPERATOR_CANCELLED;
140
141         mode_orig = ob->mode;
142         object_remove_particle_system(scene, ob);
143
144         /* possible this isn't the active object
145          * object_remove_particle_system() clears the mode on the last psys
146          */
147         if (mode_orig & OB_MODE_PARTICLE_EDIT) {
148                 if ((ob->mode & OB_MODE_PARTICLE_EDIT) == 0) {
149                         if (scene->basact && scene->basact->object == ob) {
150                                 WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_OBJECT, NULL);
151                         }
152                 }
153         }
154
155         WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, ob);
156         WM_event_add_notifier(C, NC_OBJECT|ND_POINTCACHE, ob);
157         
158         return OPERATOR_FINISHED;
159 }
160
161 void OBJECT_OT_particle_system_remove(wmOperatorType *ot)
162 {
163         /* identifiers */
164         ot->name = "Remove Particle System Slot";
165         ot->idname = "OBJECT_OT_particle_system_remove";
166         ot->description = "Remove the selected particle system";
167         
168         /* api callbacks */
169         ot->poll = ED_operator_object_active_editable;
170         ot->exec = particle_system_remove_exec;
171
172         /* flags */
173         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
174 }
175
176 /********************** new particle settings operator *********************/
177
178 static int psys_poll(bContext *C)
179 {
180         PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
181         return (ptr.data != NULL);
182 }
183
184 static int new_particle_settings_exec(bContext *C, wmOperator *UNUSED(op))
185 {
186         Main *bmain= CTX_data_main(C);
187         ParticleSystem *psys;
188         ParticleSettings *part = NULL;
189         Object *ob;
190         PointerRNA ptr;
191
192         ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
193
194         psys = ptr.data;
195
196         /* add or copy particle setting */
197         if (psys->part)
198                 part= BKE_particlesettings_copy(bmain, psys->part);
199         else
200                 part= psys_new_settings("ParticleSettings", bmain);
201
202         ob= ptr.id.data;
203
204         if (psys->part)
205                 id_us_min(&psys->part->id);
206
207         psys->part = part;
208
209         psys_check_boid_data(psys);
210
211         DAG_relations_tag_update(bmain);
212         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
213
214         WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, ob);
215         
216         return OPERATOR_FINISHED;
217 }
218
219 void PARTICLE_OT_new(wmOperatorType *ot)
220 {
221         /* identifiers */
222         ot->name = "New Particle Settings";
223         ot->idname = "PARTICLE_OT_new";
224         ot->description = "Add new particle settings";
225         
226         /* api callbacks */
227         ot->exec = new_particle_settings_exec;
228         ot->poll = psys_poll;
229
230         /* flags */
231         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
232 }
233
234 /********************** keyed particle target operators *********************/
235
236 static int new_particle_target_exec(bContext *C, wmOperator *UNUSED(op))
237 {
238         Main *bmain = CTX_data_main(C);
239         PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
240         ParticleSystem *psys= ptr.data;
241         Object *ob = ptr.id.data;
242
243         ParticleTarget *pt;
244
245         if (!psys)
246                 return OPERATOR_CANCELLED;
247
248         pt = psys->targets.first;
249         for (; pt; pt=pt->next)
250                 pt->flag &= ~PTARGET_CURRENT;
251
252         pt = MEM_callocN(sizeof(ParticleTarget), "keyed particle target");
253
254         pt->flag |= PTARGET_CURRENT;
255         pt->psys = 1;
256
257         BLI_addtail(&psys->targets, pt);
258
259         DAG_relations_tag_update(bmain);
260         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
261
262         WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, ob);
263         
264         return OPERATOR_FINISHED;
265 }
266
267 void PARTICLE_OT_new_target(wmOperatorType *ot)
268 {
269         /* identifiers */
270         ot->name = "New Particle Target";
271         ot->idname = "PARTICLE_OT_new_target";
272         ot->description = "Add a new particle target";
273         
274         /* api callbacks */
275         ot->exec = new_particle_target_exec;
276
277         /* flags */
278         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
279 }
280
281 static int remove_particle_target_exec(bContext *C, wmOperator *UNUSED(op))
282 {
283         Main *bmain = CTX_data_main(C);
284         PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
285         ParticleSystem *psys= ptr.data;
286         Object *ob = ptr.id.data;
287
288         ParticleTarget *pt;
289
290         if (!psys)
291                 return OPERATOR_CANCELLED;
292
293         pt = psys->targets.first;
294         for (; pt; pt=pt->next) {
295                 if (pt->flag & PTARGET_CURRENT) {
296                         BLI_remlink(&psys->targets, pt);
297                         MEM_freeN(pt);
298                         break;
299                 }
300
301         }
302         pt = psys->targets.last;
303
304         if (pt)
305                 pt->flag |= PTARGET_CURRENT;
306
307         DAG_relations_tag_update(bmain);
308         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
309
310         WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, ob);
311         
312         return OPERATOR_FINISHED;
313 }
314
315 void PARTICLE_OT_target_remove(wmOperatorType *ot)
316 {
317         /* identifiers */
318         ot->name = "Remove Particle Target";
319         ot->idname = "PARTICLE_OT_target_remove";
320         ot->description = "Remove the selected particle target";
321         
322         /* api callbacks */
323         ot->exec = remove_particle_target_exec;
324
325         /* flags */
326         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
327 }
328
329 /************************ move up particle target operator *********************/
330
331 static int target_move_up_exec(bContext *C, wmOperator *UNUSED(op))
332 {
333         PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
334         ParticleSystem *psys= ptr.data;
335         Object *ob = ptr.id.data;
336         ParticleTarget *pt;
337
338         if (!psys)
339                 return OPERATOR_CANCELLED;
340         
341         pt = psys->targets.first;
342         for (; pt; pt=pt->next) {
343                 if (pt->flag & PTARGET_CURRENT && pt->prev) {
344                         BLI_remlink(&psys->targets, pt);
345                         BLI_insertlinkbefore(&psys->targets, pt->prev, pt);
346
347                         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
348                         WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, ob);
349                         break;
350                 }
351         }
352         
353         return OPERATOR_FINISHED;
354 }
355
356 void PARTICLE_OT_target_move_up(wmOperatorType *ot)
357 {
358         ot->name = "Move Up Target";
359         ot->idname = "PARTICLE_OT_target_move_up";
360         ot->description = "Move particle target up in the list";
361         
362         ot->exec = target_move_up_exec;
363         
364         /* flags */
365         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
366 }
367
368 /************************ move down particle target operator *********************/
369
370 static int target_move_down_exec(bContext *C, wmOperator *UNUSED(op))
371 {
372         PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
373         ParticleSystem *psys= ptr.data;
374         Object *ob = ptr.id.data;
375         ParticleTarget *pt;
376
377         if (!psys)
378                 return OPERATOR_CANCELLED;
379         pt = psys->targets.first;
380         for (; pt; pt=pt->next) {
381                 if (pt->flag & PTARGET_CURRENT && pt->next) {
382                         BLI_remlink(&psys->targets, pt);
383                         BLI_insertlinkafter(&psys->targets, pt->next, pt);
384
385                         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
386                         WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, ob);
387                         break;
388                 }
389         }
390         
391         return OPERATOR_FINISHED;
392 }
393
394 void PARTICLE_OT_target_move_down(wmOperatorType *ot)
395 {
396         ot->name = "Move Down Target";
397         ot->idname = "PARTICLE_OT_target_move_down";
398         ot->description = "Move particle target down in the list";
399         
400         ot->exec = target_move_down_exec;
401         
402         /* flags */
403         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
404 }
405
406 /************************ move up particle dupliweight operator *********************/
407
408 static int dupliob_move_up_exec(bContext *C, wmOperator *UNUSED(op))
409 {
410         PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
411         ParticleSystem *psys= ptr.data;
412         ParticleSettings *part;
413         ParticleDupliWeight *dw;
414
415         if (!psys)
416                 return OPERATOR_CANCELLED;
417
418         part = psys->part;
419         for (dw=part->dupliweights.first; dw; dw=dw->next) {
420                 if (dw->flag & PART_DUPLIW_CURRENT && dw->prev) {
421                         BLI_remlink(&part->dupliweights, dw);
422                         BLI_insertlinkbefore(&part->dupliweights, dw->prev, dw);
423
424                         WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, NULL);
425                         break;
426                 }
427         }
428         
429         return OPERATOR_FINISHED;
430 }
431
432 void PARTICLE_OT_dupliob_move_up(wmOperatorType *ot)
433 {
434         ot->name = "Move Up Dupli Object";
435         ot->idname = "PARTICLE_OT_dupliob_move_up";
436         ot->description = "Move dupli object up in the list";
437         
438         ot->exec = dupliob_move_up_exec;
439         
440         /* flags */
441         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
442 }
443
444 /********************** particle dupliweight operators *********************/
445
446 static int copy_particle_dupliob_exec(bContext *C, wmOperator *UNUSED(op))
447 {
448         PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
449         ParticleSystem *psys= ptr.data;
450         ParticleSettings *part;
451         ParticleDupliWeight *dw;
452
453         if (!psys)
454                 return OPERATOR_CANCELLED;
455         part = psys->part;
456         for (dw=part->dupliweights.first; dw; dw=dw->next) {
457                 if (dw->flag & PART_DUPLIW_CURRENT) {
458                         dw->flag &= ~PART_DUPLIW_CURRENT;
459                         dw = MEM_dupallocN(dw);
460                         dw->flag |= PART_DUPLIW_CURRENT;
461                         BLI_addhead(&part->dupliweights, dw);
462
463                         WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, NULL);
464                         break;
465                 }
466         }
467         
468         return OPERATOR_FINISHED;
469 }
470
471 void PARTICLE_OT_dupliob_copy(wmOperatorType *ot)
472 {
473         /* identifiers */
474         ot->name = "Copy Particle Dupliob";
475         ot->idname = "PARTICLE_OT_dupliob_copy";
476         ot->description = "Duplicate the current dupliobject";
477         
478         /* api callbacks */
479         ot->exec = copy_particle_dupliob_exec;
480
481         /* flags */
482         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
483 }
484
485 static int remove_particle_dupliob_exec(bContext *C, wmOperator *UNUSED(op))
486 {
487         PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
488         ParticleSystem *psys= ptr.data;
489         ParticleSettings *part;
490         ParticleDupliWeight *dw;
491
492         if (!psys)
493                 return OPERATOR_CANCELLED;
494
495         part = psys->part;
496         for (dw=part->dupliweights.first; dw; dw=dw->next) {
497                 if (dw->flag & PART_DUPLIW_CURRENT) {
498                         BLI_remlink(&part->dupliweights, dw);
499                         MEM_freeN(dw);
500                         break;
501                 }
502
503         }
504         dw = part->dupliweights.last;
505
506         if (dw)
507                 dw->flag |= PART_DUPLIW_CURRENT;
508
509         WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, NULL);
510         
511         return OPERATOR_FINISHED;
512 }
513
514 void PARTICLE_OT_dupliob_remove(wmOperatorType *ot)
515 {
516         /* identifiers */
517         ot->name = "Remove Particle Dupliobject";
518         ot->idname = "PARTICLE_OT_dupliob_remove";
519         ot->description = "Remove the selected dupliobject";
520         
521         /* api callbacks */
522         ot->exec = remove_particle_dupliob_exec;
523
524         /* flags */
525         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
526 }
527
528 /************************ move down particle dupliweight operator *********************/
529
530 static int dupliob_move_down_exec(bContext *C, wmOperator *UNUSED(op))
531 {
532         PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
533         ParticleSystem *psys= ptr.data;
534         ParticleSettings *part;
535         ParticleDupliWeight *dw;
536
537         if (!psys)
538                 return OPERATOR_CANCELLED;
539
540         part = psys->part;
541         for (dw=part->dupliweights.first; dw; dw=dw->next) {
542                 if (dw->flag & PART_DUPLIW_CURRENT && dw->next) {
543                         BLI_remlink(&part->dupliweights, dw);
544                         BLI_insertlinkafter(&part->dupliweights, dw->next, dw);
545
546                         WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, NULL);
547                         break;
548                 }
549         }
550         
551         return OPERATOR_FINISHED;
552 }
553
554 void PARTICLE_OT_dupliob_move_down(wmOperatorType *ot)
555 {
556         ot->name = "Move Down Dupli Object";
557         ot->idname = "PARTICLE_OT_dupliob_move_down";
558         ot->description = "Move dupli object down in the list";
559         
560         ot->exec = dupliob_move_down_exec;
561         
562         /* flags */
563         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
564 }
565
566 /************************ connect/disconnect hair operators *********************/
567
568 static void disconnect_hair(Scene *scene, Object *ob, ParticleSystem *psys)
569 {
570         ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys);
571         ParticleEditSettings *pset= PE_settings(scene);
572         ParticleData *pa;
573         PTCacheEdit *edit;
574         PTCacheEditPoint *point;
575         PTCacheEditKey *ekey = NULL;
576         HairKey *key;
577         int i, k;
578         float hairmat[4][4];
579
580         if (!ob || !psys || psys->flag & PSYS_GLOBAL_HAIR)
581                 return;
582
583         if (!psys->part || psys->part->type != PART_HAIR)
584                 return;
585         
586         edit = psys->edit;
587         point= edit ? edit->points : NULL;
588
589         for (i=0, pa=psys->particles; i<psys->totpart; i++, pa++) {
590                 if (point) {
591                         ekey = point->keys;
592                         point++;
593                 }
594
595                 psys_mat_hair_to_global(ob, psmd->dm_final, psys->part->from, pa, hairmat);
596
597                 for (k=0, key=pa->hair; k<pa->totkey; k++, key++) {
598                         mul_m4_v3(hairmat, key->co);
599                         
600                         if (ekey) {
601                                 ekey->flag &= ~PEK_USE_WCO;
602                                 ekey++;
603                         }
604                 }
605         }
606
607         psys_free_path_cache(psys, psys->edit);
608
609         psys->flag |= PSYS_GLOBAL_HAIR;
610
611         if (ELEM(pset->brushtype, PE_BRUSH_ADD, PE_BRUSH_PUFF))
612                 pset->brushtype = PE_BRUSH_NONE;
613
614         PE_update_object(scene, ob, 0);
615 }
616
617 static int disconnect_hair_exec(bContext *C, wmOperator *op)
618 {
619         Scene *scene= CTX_data_scene(C);
620         Object *ob= ED_object_context(C);
621         ParticleSystem *psys= NULL;
622         const bool all = RNA_boolean_get(op->ptr, "all");
623
624         if (!ob)
625                 return OPERATOR_CANCELLED;
626
627         if (all) {
628                 for (psys=ob->particlesystem.first; psys; psys=psys->next) {
629                         disconnect_hair(scene, ob, psys);
630                 }
631         }
632         else {
633                 psys = psys_get_current(ob);
634                 disconnect_hair(scene, ob, psys);
635         }
636
637         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
638         WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, ob);
639
640         return OPERATOR_FINISHED;
641 }
642
643 void PARTICLE_OT_disconnect_hair(wmOperatorType *ot)
644 {
645         ot->name = "Disconnect Hair";
646         ot->description = "Disconnect hair from the emitter mesh";
647         ot->idname = "PARTICLE_OT_disconnect_hair";
648         
649         ot->exec = disconnect_hair_exec;
650         
651         /* flags */
652         ot->flag = OPTYPE_UNDO;  /* No REGISTER, redo does not work due to missing update, see T47750. */
653
654         RNA_def_boolean(ot->srna, "all", 0, "All hair", "Disconnect all hair systems from the emitter mesh");
655 }
656
657 /* from/to_world_space : whether from/to particles are in world or hair space
658  * from/to_mat : additional transform for from/to particles (e.g. for using object space copying)
659  */
660 static bool remap_hair_emitter(Scene *scene, Object *ob, ParticleSystem *psys,
661                                Object *target_ob, ParticleSystem *target_psys, PTCacheEdit *target_edit,
662                                float from_mat[4][4], float to_mat[4][4], bool from_global, bool to_global)
663 {
664         ParticleSystemModifierData *target_psmd = psys_get_modifier(target_ob, target_psys);
665         ParticleData *pa, *tpa;
666         PTCacheEditPoint *edit_point;
667         PTCacheEditKey *ekey;
668         BVHTreeFromMesh bvhtree= {NULL};
669         MFace *mface = NULL, *mf;
670         MEdge *medge = NULL, *me;
671         MVert *mvert;
672         DerivedMesh *dm, *target_dm;
673         int numverts;
674         int i, k;
675         float from_ob_imat[4][4], to_ob_imat[4][4];
676         float from_imat[4][4], to_imat[4][4];
677
678         if (!target_psmd->dm_final)
679                 return false;
680         if (!psys->part || psys->part->type != PART_HAIR)
681                 return false;
682         if (!target_psys->part || target_psys->part->type != PART_HAIR)
683                 return false;
684         
685         edit_point = target_edit ? target_edit->points : NULL;
686         
687         invert_m4_m4(from_ob_imat, ob->obmat);
688         invert_m4_m4(to_ob_imat, target_ob->obmat);
689         invert_m4_m4(from_imat, from_mat);
690         invert_m4_m4(to_imat, to_mat);
691         
692         if (target_psmd->dm_final->deformedOnly) {
693                 /* we don't want to mess up target_psmd->dm when converting to global coordinates below */
694                 dm = target_psmd->dm_final;
695         }
696         else {
697                 dm = target_psmd->dm_deformed;
698         }
699         target_dm = target_psmd->dm_final;
700         if (dm == NULL) {
701                 return false;
702         }
703         /* don't modify the original vertices */
704         dm = CDDM_copy(dm);
705
706         /* BMESH_ONLY, deform dm may not have tessface */
707         DM_ensure_tessface(dm);
708
709         numverts = dm->getNumVerts(dm);
710         mvert = dm->getVertArray(dm);
711
712         /* convert to global coordinates */
713         for (i=0; i<numverts; i++)
714                 mul_m4_v3(to_mat, mvert[i].co);
715
716         if (dm->getNumTessFaces(dm) != 0) {
717                 mface = dm->getTessFaceArray(dm);
718                 bvhtree_from_mesh_faces(&bvhtree, dm, 0.0, 2, 6);
719         }
720         else if (dm->getNumEdges(dm) != 0) {
721                 medge = dm->getEdgeArray(dm);
722                 bvhtree_from_mesh_edges(&bvhtree, dm, 0.0, 2, 6);
723         }
724         else {
725                 dm->release(dm);
726                 return false;
727         }
728
729         for (i = 0, tpa = target_psys->particles, pa = psys->particles;
730              i < target_psys->totpart;
731              i++, tpa++, pa++) {
732
733                 float from_co[3];
734                 BVHTreeNearest nearest;
735
736                 if (from_global)
737                         mul_v3_m4v3(from_co, from_ob_imat, pa->hair[0].co);
738                 else
739                         mul_v3_m4v3(from_co, from_ob_imat, pa->hair[0].world_co);
740                 mul_m4_v3(from_mat, from_co);
741
742                 nearest.index = -1;
743                 nearest.dist_sq = FLT_MAX;
744
745                 BLI_bvhtree_find_nearest(bvhtree.tree, from_co, &nearest, bvhtree.nearest_callback, &bvhtree);
746
747                 if (nearest.index == -1) {
748                         if (G.debug & G_DEBUG)
749                                 printf("No nearest point found for hair root!");
750                         continue;
751                 }
752
753                 if (mface) {
754                         float v[4][3];
755                         
756                         mf = &mface[nearest.index];
757
758                         copy_v3_v3(v[0], mvert[mf->v1].co);
759                         copy_v3_v3(v[1], mvert[mf->v2].co);
760                         copy_v3_v3(v[2], mvert[mf->v3].co);
761                         if (mf->v4) {
762                                 copy_v3_v3(v[3], mvert[mf->v4].co);
763                                 interp_weights_poly_v3(tpa->fuv, v, 4, nearest.co);
764                         }
765                         else
766                                 interp_weights_poly_v3(tpa->fuv, v, 3, nearest.co);
767                         tpa->foffset = 0.0f;
768
769                         tpa->num = nearest.index;
770                         tpa->num_dmcache = psys_particle_dm_face_lookup(target_dm, dm, tpa->num, tpa->fuv, NULL);
771                 }
772                 else {
773                         me = &medge[nearest.index];
774
775                         tpa->fuv[1] = line_point_factor_v3(nearest.co,
776                                                            mvert[me->v1].co,
777                                                            mvert[me->v2].co);
778                         tpa->fuv[0] = 1.0f - tpa->fuv[1];
779                         tpa->fuv[2] = tpa->fuv[3] = 0.0f;
780                         tpa->foffset = 0.0f;
781
782                         tpa->num = nearest.index;
783                         tpa->num_dmcache = -1;
784                 }
785
786                 /* translate hair keys */
787                 {
788                         HairKey *key, *tkey;
789                         float hairmat[4][4], imat[4][4];
790                         float offset[3];
791                         
792                         if (to_global)
793                                 copy_m4_m4(imat, target_ob->obmat);
794                         else {
795                                 /* note: using target_dm here, which is in target_ob object space and has full modifiers */
796                                 psys_mat_hair_to_object(target_ob, target_dm, target_psys->part->from, tpa, hairmat);
797                                 invert_m4_m4(imat, hairmat);
798                         }
799                         mul_m4_m4m4(imat, imat, to_imat);
800                         
801                         /* offset in world space */
802                         sub_v3_v3v3(offset, nearest.co, from_co);
803                         
804                         if (edit_point) {
805                                 for (k=0, key=pa->hair, tkey=tpa->hair, ekey = edit_point->keys; k<tpa->totkey; k++, key++, tkey++, ekey++) {
806                                         float co_orig[3];
807                                         
808                                         if (from_global)
809                                                 mul_v3_m4v3(co_orig, from_ob_imat, key->co);
810                                         else
811                                                 mul_v3_m4v3(co_orig, from_ob_imat, key->world_co);
812                                         mul_m4_v3(from_mat, co_orig);
813                                         
814                                         add_v3_v3v3(tkey->co, co_orig, offset);
815                                         
816                                         mul_m4_v3(imat, tkey->co);
817                                         
818                                         ekey->flag |= PEK_USE_WCO;
819                                 }
820                                 
821                                 edit_point++;
822                         }
823                         else {
824                                 for (k=0, key=pa->hair, tkey=tpa->hair; k<tpa->totkey; k++, key++, tkey++) {
825                                         float co_orig[3];
826                                         
827                                         if (from_global)
828                                                 mul_v3_m4v3(co_orig, from_ob_imat, key->co);
829                                         else
830                                                 mul_v3_m4v3(co_orig, from_ob_imat, key->world_co);
831                                         mul_m4_v3(from_mat, co_orig);
832                                         
833                                         add_v3_v3v3(tkey->co, co_orig, offset);
834                                         
835                                         mul_m4_v3(imat, tkey->co);
836                                 }
837                         }
838                 }
839         }
840
841         free_bvhtree_from_mesh(&bvhtree);
842         dm->release(dm);
843
844         psys_free_path_cache(target_psys, target_edit);
845
846         PE_update_object(scene, target_ob, 0);
847
848         return true;
849 }
850
851 static bool connect_hair(Scene *scene, Object *ob, ParticleSystem *psys)
852 {
853         bool ok;
854         
855         if (!psys)
856                 return false;
857         
858         ok = remap_hair_emitter(scene, ob, psys, ob, psys, psys->edit, ob->obmat, ob->obmat, psys->flag & PSYS_GLOBAL_HAIR, false);
859         psys->flag &= ~PSYS_GLOBAL_HAIR;
860         
861         return ok;
862 }
863
864 static int connect_hair_exec(bContext *C, wmOperator *op)
865 {
866         Scene *scene= CTX_data_scene(C);
867         Object *ob= ED_object_context(C);
868         ParticleSystem *psys= NULL;
869         const bool all = RNA_boolean_get(op->ptr, "all");
870         bool any_connected = false;
871
872         if (!ob)
873                 return OPERATOR_CANCELLED;
874
875         if (all) {
876                 for (psys=ob->particlesystem.first; psys; psys=psys->next) {
877                         any_connected |= connect_hair(scene, ob, psys);
878                 }
879         }
880         else {
881                 psys = psys_get_current(ob);
882                 any_connected |= connect_hair(scene, ob, psys);
883         }
884
885         if (!any_connected) {
886                 BKE_report(op->reports, RPT_WARNING,
887                            "No hair connected (can't connect hair if particle system modifier is disabled)");
888                 return OPERATOR_CANCELLED;
889         }
890
891         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
892         WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, ob);
893
894         return OPERATOR_FINISHED;
895 }
896
897 void PARTICLE_OT_connect_hair(wmOperatorType *ot)
898 {
899         ot->name = "Connect Hair";
900         ot->description = "Connect hair to the emitter mesh";
901         ot->idname = "PARTICLE_OT_connect_hair";
902         
903         ot->exec = connect_hair_exec;
904         
905         /* flags */
906         ot->flag = OPTYPE_UNDO;  /* No REGISTER, redo does not work due to missing update, see T47750. */
907
908         RNA_def_boolean(ot->srna, "all", 0, "All hair", "Connect all hair systems to the emitter mesh");
909 }
910
911 /************************ particle system copy operator *********************/
912
913 typedef enum eCopyParticlesSpace {
914         PAR_COPY_SPACE_OBJECT   = 0,
915         PAR_COPY_SPACE_WORLD    = 1,
916 } eCopyParticlesSpace;
917
918 static void copy_particle_edit(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSystem *psys_from)
919 {
920         PTCacheEdit *edit_from = psys_from->edit, *edit;
921         ParticleData *pa;
922         KEY_K;
923         POINT_P;
924         
925         if (!edit_from)
926                 return;
927         
928         edit = MEM_dupallocN(edit_from);
929         edit->psys = psys;
930         psys->edit = edit;
931         
932         edit->pathcache = NULL;
933         BLI_listbase_clear(&edit->pathcachebufs);
934         
935         edit->emitter_field = NULL;
936         edit->emitter_cosnos = NULL;
937         
938         BLI_listbase_clear(&edit->undo);
939         edit->curundo = NULL;
940         
941         edit->points = MEM_dupallocN(edit_from->points);
942         pa = psys->particles;
943         LOOP_POINTS {
944                 HairKey *hkey = pa->hair;
945                 
946                 point->keys= MEM_dupallocN(point->keys);
947                 LOOP_KEYS {
948                         key->co = hkey->co;
949                         key->time = &hkey->time;
950                         key->flag = hkey->editflag;
951                         if (!(psys->flag & PSYS_GLOBAL_HAIR)) {
952                                 key->flag |= PEK_USE_WCO;
953                                 hkey->editflag |= PEK_USE_WCO;
954                         }
955                         
956                         hkey++;
957                 }
958                 
959                 pa++;
960         }
961         update_world_cos(ob, edit);
962         
963         UI_GetThemeColor3ubv(TH_EDGE_SELECT, edit->sel_col);
964         UI_GetThemeColor3ubv(TH_WIRE, edit->nosel_col);
965         
966         recalc_lengths(edit);
967         recalc_emitter_field(ob, psys);
968         PE_update_object(scene, ob, true);
969         
970         PTCacheUndo_clear(edit);
971         PE_undo_push(scene, "Original");
972 }
973
974 static void remove_particle_systems_from_object(Object *ob_to)
975 {
976         ModifierData *md, *md_next;
977         
978         if (ob_to->type != OB_MESH)
979                 return;
980         if (!ob_to->data || ID_IS_LINKED(ob_to->data))
981                 return;
982         
983         for (md = ob_to->modifiers.first; md; md = md_next) {
984                 md_next = md->next;
985                 
986                 /* remove all particle system modifiers as well,
987                  * these need to sync to the particle system list
988                  */
989                 if (ELEM(md->type, eModifierType_ParticleSystem, eModifierType_DynamicPaint, eModifierType_Smoke)) {
990                         BLI_remlink(&ob_to->modifiers, md);
991                         modifier_free(md);
992                 }
993         }
994         
995         BKE_object_free_particlesystems(ob_to);
996 }
997
998 /* single_psys_from is optional, if NULL all psys of ob_from are copied */
999 static bool copy_particle_systems_to_object(Main *bmain,
1000                                             Scene *scene,
1001                                             Object *ob_from,
1002                                             ParticleSystem *single_psys_from,
1003                                             Object *ob_to,
1004                                             int space,
1005                                             bool duplicate_settings)
1006 {
1007         ModifierData *md;
1008         ParticleSystem *psys_start = NULL, *psys, *psys_from;
1009         ParticleSystem **tmp_psys;
1010         DerivedMesh *final_dm;
1011         CustomDataMask cdmask;
1012         int i, totpsys;
1013         
1014         if (ob_to->type != OB_MESH)
1015                 return false;
1016         if (!ob_to->data || ID_IS_LINKED(ob_to->data))
1017                 return false;
1018         
1019         /* For remapping we need a valid DM.
1020          * Because the modifiers are appended at the end it's safe to use
1021          * the final DM of the object without particles.
1022          * However, when evaluating the DM all the particle modifiers must be valid,
1023          * i.e. have the psys assigned already.
1024          * To break this hen/egg problem we create all psys separately first (to collect required customdata masks),
1025          * then create the DM, then add them to the object and make the psys modifiers ...
1026          */
1027         #define PSYS_FROM_FIRST (single_psys_from ? single_psys_from : ob_from->particlesystem.first)
1028         #define PSYS_FROM_NEXT(cur) (single_psys_from ? NULL : (cur)->next)
1029         totpsys = single_psys_from ? 1 : BLI_listbase_count(&ob_from->particlesystem);
1030         
1031         tmp_psys = MEM_mallocN(sizeof(ParticleSystem*) * totpsys, "temporary particle system array");
1032         
1033         cdmask = 0;
1034         for (psys_from = PSYS_FROM_FIRST, i = 0;
1035              psys_from;
1036              psys_from = PSYS_FROM_NEXT(psys_from), ++i) {
1037                 
1038                 psys = BKE_object_copy_particlesystem(psys_from, 0);
1039                 tmp_psys[i] = psys;
1040                 
1041                 if (psys_start == NULL)
1042                         psys_start = psys;
1043                 
1044                 cdmask |= psys_emitter_customdata_mask(psys);
1045         }
1046         /* to iterate source and target psys in sync,
1047          * we need to know where the newly added psys start
1048          */
1049         psys_start = totpsys > 0 ? tmp_psys[0] : NULL;
1050         
1051         /* get the DM (psys and their modifiers have not been appended yet) */
1052         final_dm = mesh_get_derived_final(scene, ob_to, cdmask);
1053         
1054         /* now append psys to the object and make modifiers */
1055         for (i = 0, psys_from = PSYS_FROM_FIRST;
1056              i < totpsys;
1057              ++i, psys_from = PSYS_FROM_NEXT(psys_from)) {
1058                 
1059                 ParticleSystemModifierData *psmd;
1060                 
1061                 psys = tmp_psys[i];
1062                 
1063                 /* append to the object */
1064                 BLI_addtail(&ob_to->particlesystem, psys);
1065                 
1066                 /* add a particle system modifier for each system */
1067                 md = modifier_new(eModifierType_ParticleSystem);
1068                 psmd = (ParticleSystemModifierData *)md;
1069                 /* push on top of the stack, no use trying to reproduce old stack order */
1070                 BLI_addtail(&ob_to->modifiers, md);
1071                 
1072                 BLI_snprintf(md->name, sizeof(md->name), "ParticleSystem %i", i);
1073                 modifier_unique_name(&ob_to->modifiers, (ModifierData *)psmd);
1074                 
1075                 psmd->psys = psys;
1076                 psmd->dm_final = CDDM_copy(final_dm);
1077                 CDDM_calc_normals(psmd->dm_final);
1078                 DM_ensure_tessface(psmd->dm_final);
1079                 
1080                 if (psys_from->edit)
1081                         copy_particle_edit(scene, ob_to, psys, psys_from);
1082
1083                 if (duplicate_settings) {
1084                         id_us_min(&psys->part->id);
1085                         psys->part = BKE_particlesettings_copy(bmain, psys->part);
1086                 }
1087         }
1088         MEM_freeN(tmp_psys);
1089         
1090         /* note: do this after creating DM copies for all the particle system modifiers,
1091          * the remapping otherwise makes final_dm invalid!
1092          */
1093         for (psys = psys_start, psys_from = PSYS_FROM_FIRST, i = 0;
1094              psys;
1095              psys = psys->next, psys_from = PSYS_FROM_NEXT(psys_from), ++i) {
1096                 
1097                 float (*from_mat)[4], (*to_mat)[4];
1098                 
1099                 switch (space) {
1100                         case PAR_COPY_SPACE_OBJECT:
1101                                 from_mat = I;
1102                                 to_mat = I;
1103                                 break;
1104                         case PAR_COPY_SPACE_WORLD:
1105                                 from_mat = ob_from->obmat;
1106                                 to_mat = ob_to->obmat;
1107                                 break;
1108                         default:
1109                                 /* should not happen */
1110                                 from_mat = to_mat = NULL;
1111                                 BLI_assert(false);
1112                                 break;
1113                 }
1114                 if (ob_from != ob_to) {
1115                         remap_hair_emitter(scene, ob_from, psys_from, ob_to, psys, psys->edit, from_mat, to_mat, psys_from->flag & PSYS_GLOBAL_HAIR, psys->flag & PSYS_GLOBAL_HAIR);
1116                 }
1117                 
1118                 /* tag for recalc */
1119 //              psys->recalc |= PSYS_RECALC_RESET;
1120         }
1121         
1122         #undef PSYS_FROM_FIRST
1123         #undef PSYS_FROM_NEXT
1124         
1125         DAG_id_tag_update(&ob_to->id, OB_RECALC_DATA);
1126         WM_main_add_notifier(NC_OBJECT | ND_PARTICLE | NA_EDITED, ob_to);
1127         return true;
1128 }
1129
1130 static int copy_particle_systems_poll(bContext *C)
1131 {
1132         Object *ob;
1133         if (!ED_operator_object_active_editable(C))
1134                 return false;
1135         
1136         ob = ED_object_active_context(C);
1137         if (BLI_listbase_is_empty(&ob->particlesystem))
1138                 return false;
1139         
1140         return true;
1141 }
1142
1143 static int copy_particle_systems_exec(bContext *C, wmOperator *op)
1144 {
1145         const int space = RNA_enum_get(op->ptr, "space");
1146         const bool remove_target_particles = RNA_boolean_get(op->ptr, "remove_target_particles");
1147         const bool use_active = RNA_boolean_get(op->ptr, "use_active");
1148         Main *bmain = CTX_data_main(C);
1149         Scene *scene = CTX_data_scene(C);
1150         Object *ob_from = ED_object_active_context(C);
1151         ParticleSystem *psys_from = use_active ? CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem).data : NULL;
1152         
1153         int changed_tot = 0;
1154         int fail = 0;
1155         
1156         CTX_DATA_BEGIN (C, Object *, ob_to, selected_editable_objects)
1157         {
1158                 if (ob_from != ob_to) {
1159                         bool changed = false;
1160                         if (remove_target_particles) {
1161                                 remove_particle_systems_from_object(ob_to);
1162                                 changed = true;
1163                         }
1164                         if (copy_particle_systems_to_object(bmain, scene, ob_from, psys_from, ob_to, space, false))
1165                                 changed = true;
1166                         else
1167                                 fail++;
1168                         
1169                         if (changed)
1170                                 changed_tot++;
1171                 }
1172         }
1173         CTX_DATA_END;
1174         
1175         if ((changed_tot == 0 && fail == 0) || fail) {
1176                 BKE_reportf(op->reports, RPT_ERROR,
1177                             "Copy particle systems to selected: %d done, %d failed",
1178                             changed_tot, fail);
1179         }
1180         
1181         return OPERATOR_FINISHED;
1182 }
1183
1184 void PARTICLE_OT_copy_particle_systems(wmOperatorType *ot)
1185 {
1186         static const EnumPropertyItem space_items[] = {
1187                 {PAR_COPY_SPACE_OBJECT, "OBJECT", 0, "Object", "Copy inside each object's local space"},
1188                 {PAR_COPY_SPACE_WORLD, "WORLD", 0, "World", "Copy in world space"},
1189                 {0, NULL, 0, NULL, NULL}
1190         };
1191         
1192         ot->name = "Copy Particle Systems";
1193         ot->description = "Copy particle systems from the active object to selected objects";
1194         ot->idname = "PARTICLE_OT_copy_particle_systems";
1195         
1196         ot->poll = copy_particle_systems_poll;
1197         ot->exec = copy_particle_systems_exec;
1198         
1199         /* flags */
1200         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1201         
1202         RNA_def_enum(ot->srna, "space", space_items, PAR_COPY_SPACE_OBJECT, "Space", "Space transform for copying from one object to another");
1203         RNA_def_boolean(ot->srna, "remove_target_particles", true, "Remove Target Particles", "Remove particle systems on the target objects");
1204         RNA_def_boolean(ot->srna, "use_active", false, "Use Active", "Use the active particle system from the context");
1205 }
1206
1207 static int duplicate_particle_systems_poll(bContext *C)
1208 {
1209         if (!ED_operator_object_active_editable(C)) {
1210                 return false;
1211         }
1212         Object *ob = ED_object_active_context(C);
1213         if (BLI_listbase_is_empty(&ob->particlesystem)) {
1214                 return false;
1215         }
1216         return true;
1217 }
1218
1219 static int duplicate_particle_systems_exec(bContext *C, wmOperator *op)
1220 {
1221         const bool duplicate_settings = RNA_boolean_get(op->ptr, "use_duplicate_settings");
1222         Scene *scene = CTX_data_scene(C);
1223         Object *ob = ED_object_active_context(C);
1224         ParticleSystem *psys = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem).data;
1225         copy_particle_systems_to_object(CTX_data_main(C), scene, ob, psys, ob,
1226                                         PAR_COPY_SPACE_OBJECT, duplicate_settings);
1227         return OPERATOR_FINISHED;
1228 }
1229
1230 void PARTICLE_OT_duplicate_particle_system(wmOperatorType *ot)
1231 {
1232         ot->name = "Duplicate Particle Systems";
1233         ot->description = "Duplicate particle system within the active object";
1234         ot->idname = "PARTICLE_OT_duplicate_particle_system";
1235
1236         ot->poll = duplicate_particle_systems_poll;
1237         ot->exec = duplicate_particle_systems_exec;
1238
1239         /* flags */
1240         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1241
1242         RNA_def_boolean(ot->srna, "use_duplicate_settings", false, "Duplicate Settings",
1243                         "Duplicate settings as well, so new particle system uses own settings");
1244 }