2 * ***** BEGIN GPL LICENSE BLOCK *****
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * The Original Code is Copyright (C) 2009 Blender Foundation.
19 * All rights reserved.
21 * Contributor(s): Blender Foundation
23 * ***** END GPL LICENSE BLOCK *****
26 /** \file blender/editors/physics/particle_object.c
34 #include "MEM_guardedalloc.h"
36 #include "DNA_meshdata_types.h"
37 #include "DNA_modifier_types.h"
38 #include "DNA_scene_types.h"
41 #include "BLI_listbase.h"
42 #include "BLI_utildefines.h"
43 #include "BLI_string.h"
45 #include "BKE_context.h"
46 #include "BKE_DerivedMesh.h"
47 #include "BKE_cdderivedmesh.h"
48 #include "BKE_global.h"
49 #include "BKE_library.h"
51 #include "BKE_modifier.h"
52 #include "BKE_object.h"
53 #include "BKE_particle.h"
54 #include "BKE_pointcache.h"
55 #include "BKE_report.h"
57 #include "DEG_depsgraph.h"
58 #include "DEG_depsgraph_build.h"
60 #include "RNA_access.h"
61 #include "RNA_define.h"
66 #include "ED_particle.h"
67 #include "ED_screen.h"
68 #include "ED_object.h"
70 #include "UI_resources.h"
72 #include "physics_intern.h"
74 extern void PE_create_particle_edit(Scene *scene, SceneLayer *sl, Object *ob, PointCache *cache, ParticleSystem *psys);
75 extern void PTCacheUndo_clear(PTCacheEdit *edit);
76 extern void recalc_lengths(PTCacheEdit *edit);
77 extern void recalc_emitter_field(Object *ob, ParticleSystem *psys);
78 extern void update_world_cos(Object *ob, PTCacheEdit *edit);
80 #define KEY_K PTCacheEditKey *key; int k
81 #define POINT_P PTCacheEditPoint *point; int p
82 #define LOOP_POINTS for (p=0, point=edit->points; p<edit->totpoint; p++, point++)
84 #define LOOP_VISIBLE_POINTS for (p=0, point=edit->points; p<edit->totpoint; p++, point++) if (!(point->flag & PEP_HIDE))
85 #define LOOP_SELECTED_POINTS for (p=0, point=edit->points; p<edit->totpoint; p++, point++) if (point_is_selected(point))
86 #define LOOP_UNSELECTED_POINTS for (p=0, point=edit->points; p<edit->totpoint; p++, point++) if (!point_is_selected(point))
87 #define LOOP_EDITED_POINTS for (p=0, point=edit->points; p<edit->totpoint; p++, point++) if (point->flag & PEP_EDIT_RECALC)
88 #define LOOP_TAGGED_POINTS for (p=0, point=edit->points; p<edit->totpoint; p++, point++) if (point->flag & PEP_TAG)
90 #define LOOP_KEYS for (k=0, key=point->keys; k<point->totkey; k++, key++)
92 #define LOOP_VISIBLE_KEYS for (k=0, key=point->keys; k<point->totkey; k++, key++) if (!(key->flag & PEK_HIDE))
93 #define LOOP_SELECTED_KEYS for (k=0, key=point->keys; k<point->totkey; k++, key++) if ((key->flag & PEK_SELECT) && !(key->flag & PEK_HIDE))
94 #define LOOP_TAGGED_KEYS for (k=0, key=point->keys; k<point->totkey; k++, key++) if (key->flag & PEK_TAG)
96 #define KEY_WCO (key->flag & PEK_USE_WCO ? key->world_co : key->co)
99 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}};
101 /********************** particle system slot operators *********************/
103 static int particle_system_add_exec(bContext *C, wmOperator *UNUSED(op))
105 Object *ob= ED_object_context(C);
106 Scene *scene = CTX_data_scene(C);
109 return OPERATOR_CANCELLED;
111 object_add_particle_system(scene, ob, NULL);
113 WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, ob);
114 WM_event_add_notifier(C, NC_OBJECT|ND_POINTCACHE, ob);
116 return OPERATOR_FINISHED;
119 void OBJECT_OT_particle_system_add(wmOperatorType *ot)
122 ot->name = "Add Particle System Slot";
123 ot->idname = "OBJECT_OT_particle_system_add";
124 ot->description = "Add a particle system";
127 ot->poll = ED_operator_object_active_editable;
128 ot->exec = particle_system_add_exec;
131 ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
134 static int particle_system_remove_exec(bContext *C, wmOperator *UNUSED(op))
136 Object *ob = ED_object_context(C);
137 Scene *scene = CTX_data_scene(C);
138 SceneLayer *sl = CTX_data_scene_layer(C);
142 return OPERATOR_CANCELLED;
144 mode_orig = ob->mode;
145 object_remove_particle_system(scene, ob);
147 /* possible this isn't the active object
148 * object_remove_particle_system() clears the mode on the last psys
150 if (mode_orig & OB_MODE_PARTICLE_EDIT) {
151 if ((ob->mode & OB_MODE_PARTICLE_EDIT) == 0) {
152 if (sl->basact && sl->basact->object == ob) {
153 WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_OBJECT, NULL);
158 WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, ob);
159 WM_event_add_notifier(C, NC_OBJECT|ND_POINTCACHE, ob);
161 return OPERATOR_FINISHED;
164 void OBJECT_OT_particle_system_remove(wmOperatorType *ot)
167 ot->name = "Remove Particle System Slot";
168 ot->idname = "OBJECT_OT_particle_system_remove";
169 ot->description = "Remove the selected particle system";
172 ot->poll = ED_operator_object_active_editable;
173 ot->exec = particle_system_remove_exec;
176 ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
179 /********************** new particle settings operator *********************/
181 static int psys_poll(bContext *C)
183 PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
184 return (ptr.data != NULL);
187 static int new_particle_settings_exec(bContext *C, wmOperator *UNUSED(op))
189 Main *bmain= CTX_data_main(C);
190 ParticleSystem *psys;
191 ParticleSettings *part = NULL;
195 ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
199 /* add or copy particle setting */
201 part= BKE_particlesettings_copy(bmain, psys->part);
203 part= psys_new_settings("ParticleSettings", bmain);
208 id_us_min(&psys->part->id);
212 psys_check_boid_data(psys);
214 DEG_relations_tag_update(bmain);
215 DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
217 WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, ob);
219 return OPERATOR_FINISHED;
222 void PARTICLE_OT_new(wmOperatorType *ot)
225 ot->name = "New Particle Settings";
226 ot->idname = "PARTICLE_OT_new";
227 ot->description = "Add new particle settings";
230 ot->exec = new_particle_settings_exec;
231 ot->poll = psys_poll;
234 ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
237 /********************** keyed particle target operators *********************/
239 static int new_particle_target_exec(bContext *C, wmOperator *UNUSED(op))
241 Main *bmain = CTX_data_main(C);
242 PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
243 ParticleSystem *psys= ptr.data;
244 Object *ob = ptr.id.data;
249 return OPERATOR_CANCELLED;
251 pt = psys->targets.first;
252 for (; pt; pt=pt->next)
253 pt->flag &= ~PTARGET_CURRENT;
255 pt = MEM_callocN(sizeof(ParticleTarget), "keyed particle target");
257 pt->flag |= PTARGET_CURRENT;
260 BLI_addtail(&psys->targets, pt);
262 DEG_relations_tag_update(bmain);
263 DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
265 WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, ob);
267 return OPERATOR_FINISHED;
270 void PARTICLE_OT_new_target(wmOperatorType *ot)
273 ot->name = "New Particle Target";
274 ot->idname = "PARTICLE_OT_new_target";
275 ot->description = "Add a new particle target";
278 ot->exec = new_particle_target_exec;
281 ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
284 static int remove_particle_target_exec(bContext *C, wmOperator *UNUSED(op))
286 Main *bmain = CTX_data_main(C);
287 PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
288 ParticleSystem *psys= ptr.data;
289 Object *ob = ptr.id.data;
294 return OPERATOR_CANCELLED;
296 pt = psys->targets.first;
297 for (; pt; pt=pt->next) {
298 if (pt->flag & PTARGET_CURRENT) {
299 BLI_remlink(&psys->targets, pt);
305 pt = psys->targets.last;
308 pt->flag |= PTARGET_CURRENT;
310 DEG_relations_tag_update(bmain);
311 DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
313 WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, ob);
315 return OPERATOR_FINISHED;
318 void PARTICLE_OT_target_remove(wmOperatorType *ot)
321 ot->name = "Remove Particle Target";
322 ot->idname = "PARTICLE_OT_target_remove";
323 ot->description = "Remove the selected particle target";
326 ot->exec = remove_particle_target_exec;
329 ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
332 /************************ move up particle target operator *********************/
334 static int target_move_up_exec(bContext *C, wmOperator *UNUSED(op))
336 PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
337 ParticleSystem *psys= ptr.data;
338 Object *ob = ptr.id.data;
342 return OPERATOR_CANCELLED;
344 pt = psys->targets.first;
345 for (; pt; pt=pt->next) {
346 if (pt->flag & PTARGET_CURRENT && pt->prev) {
347 BLI_remlink(&psys->targets, pt);
348 BLI_insertlinkbefore(&psys->targets, pt->prev, pt);
350 DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
351 WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, ob);
356 return OPERATOR_FINISHED;
359 void PARTICLE_OT_target_move_up(wmOperatorType *ot)
361 ot->name = "Move Up Target";
362 ot->idname = "PARTICLE_OT_target_move_up";
363 ot->description = "Move particle target up in the list";
365 ot->exec = target_move_up_exec;
368 ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
371 /************************ move down particle target operator *********************/
373 static int target_move_down_exec(bContext *C, wmOperator *UNUSED(op))
375 PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
376 ParticleSystem *psys= ptr.data;
377 Object *ob = ptr.id.data;
381 return OPERATOR_CANCELLED;
382 pt = psys->targets.first;
383 for (; pt; pt=pt->next) {
384 if (pt->flag & PTARGET_CURRENT && pt->next) {
385 BLI_remlink(&psys->targets, pt);
386 BLI_insertlinkafter(&psys->targets, pt->next, pt);
388 DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
389 WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, ob);
394 return OPERATOR_FINISHED;
397 void PARTICLE_OT_target_move_down(wmOperatorType *ot)
399 ot->name = "Move Down Target";
400 ot->idname = "PARTICLE_OT_target_move_down";
401 ot->description = "Move particle target down in the list";
403 ot->exec = target_move_down_exec;
406 ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
409 /************************ move up particle dupliweight operator *********************/
411 static int dupliob_move_up_exec(bContext *C, wmOperator *UNUSED(op))
413 PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
414 ParticleSystem *psys= ptr.data;
415 ParticleSettings *part;
416 ParticleDupliWeight *dw;
419 return OPERATOR_CANCELLED;
422 for (dw=part->dupliweights.first; dw; dw=dw->next) {
423 if (dw->flag & PART_DUPLIW_CURRENT && dw->prev) {
424 BLI_remlink(&part->dupliweights, dw);
425 BLI_insertlinkbefore(&part->dupliweights, dw->prev, dw);
427 WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, NULL);
432 return OPERATOR_FINISHED;
435 void PARTICLE_OT_dupliob_move_up(wmOperatorType *ot)
437 ot->name = "Move Up Dupli Object";
438 ot->idname = "PARTICLE_OT_dupliob_move_up";
439 ot->description = "Move dupli object up in the list";
441 ot->exec = dupliob_move_up_exec;
444 ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
447 /********************** particle dupliweight operators *********************/
449 static int copy_particle_dupliob_exec(bContext *C, wmOperator *UNUSED(op))
451 PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
452 ParticleSystem *psys= ptr.data;
453 ParticleSettings *part;
454 ParticleDupliWeight *dw;
457 return OPERATOR_CANCELLED;
459 for (dw=part->dupliweights.first; dw; dw=dw->next) {
460 if (dw->flag & PART_DUPLIW_CURRENT) {
461 dw->flag &= ~PART_DUPLIW_CURRENT;
462 dw = MEM_dupallocN(dw);
463 dw->flag |= PART_DUPLIW_CURRENT;
464 BLI_addhead(&part->dupliweights, dw);
466 WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, NULL);
471 return OPERATOR_FINISHED;
474 void PARTICLE_OT_dupliob_copy(wmOperatorType *ot)
477 ot->name = "Copy Particle Dupliob";
478 ot->idname = "PARTICLE_OT_dupliob_copy";
479 ot->description = "Duplicate the current dupliobject";
482 ot->exec = copy_particle_dupliob_exec;
485 ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
488 static int remove_particle_dupliob_exec(bContext *C, wmOperator *UNUSED(op))
490 PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
491 ParticleSystem *psys= ptr.data;
492 ParticleSettings *part;
493 ParticleDupliWeight *dw;
496 return OPERATOR_CANCELLED;
499 for (dw=part->dupliweights.first; dw; dw=dw->next) {
500 if (dw->flag & PART_DUPLIW_CURRENT) {
501 BLI_remlink(&part->dupliweights, dw);
507 dw = part->dupliweights.last;
510 dw->flag |= PART_DUPLIW_CURRENT;
512 WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, NULL);
514 return OPERATOR_FINISHED;
517 void PARTICLE_OT_dupliob_remove(wmOperatorType *ot)
520 ot->name = "Remove Particle Dupliobject";
521 ot->idname = "PARTICLE_OT_dupliob_remove";
522 ot->description = "Remove the selected dupliobject";
525 ot->exec = remove_particle_dupliob_exec;
528 ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
531 /************************ move down particle dupliweight operator *********************/
533 static int dupliob_move_down_exec(bContext *C, wmOperator *UNUSED(op))
535 PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
536 ParticleSystem *psys= ptr.data;
537 ParticleSettings *part;
538 ParticleDupliWeight *dw;
541 return OPERATOR_CANCELLED;
544 for (dw=part->dupliweights.first; dw; dw=dw->next) {
545 if (dw->flag & PART_DUPLIW_CURRENT && dw->next) {
546 BLI_remlink(&part->dupliweights, dw);
547 BLI_insertlinkafter(&part->dupliweights, dw->next, dw);
549 WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, NULL);
554 return OPERATOR_FINISHED;
557 void PARTICLE_OT_dupliob_move_down(wmOperatorType *ot)
559 ot->name = "Move Down Dupli Object";
560 ot->idname = "PARTICLE_OT_dupliob_move_down";
561 ot->description = "Move dupli object down in the list";
563 ot->exec = dupliob_move_down_exec;
566 ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
569 /************************ connect/disconnect hair operators *********************/
571 static void disconnect_hair(Scene *scene, SceneLayer *sl, Object *ob, ParticleSystem *psys)
573 ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys);
574 ParticleEditSettings *pset= PE_settings(scene);
577 PTCacheEditPoint *point;
578 PTCacheEditKey *ekey = NULL;
583 if (!ob || !psys || psys->flag & PSYS_GLOBAL_HAIR)
586 if (!psys->part || psys->part->type != PART_HAIR)
590 point= edit ? edit->points : NULL;
592 for (i=0, pa=psys->particles; i<psys->totpart; i++, pa++) {
598 psys_mat_hair_to_global(ob, psmd->dm_final, psys->part->from, pa, hairmat);
600 for (k=0, key=pa->hair; k<pa->totkey; k++, key++) {
601 mul_m4_v3(hairmat, key->co);
604 ekey->flag &= ~PEK_USE_WCO;
610 psys_free_path_cache(psys, psys->edit);
612 psys->flag |= PSYS_GLOBAL_HAIR;
614 if (ELEM(pset->brushtype, PE_BRUSH_ADD, PE_BRUSH_PUFF))
615 pset->brushtype = PE_BRUSH_NONE;
617 PE_update_object(scene, sl, ob, 0);
620 static int disconnect_hair_exec(bContext *C, wmOperator *op)
622 Scene *scene= CTX_data_scene(C);
623 SceneLayer *sl = CTX_data_scene_layer(C);
624 Object *ob= ED_object_context(C);
625 ParticleSystem *psys= NULL;
626 const bool all = RNA_boolean_get(op->ptr, "all");
629 return OPERATOR_CANCELLED;
632 for (psys=ob->particlesystem.first; psys; psys=psys->next) {
633 disconnect_hair(scene, sl, ob, psys);
637 psys = psys_get_current(ob);
638 disconnect_hair(scene, sl, ob, psys);
641 DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
642 WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, ob);
644 return OPERATOR_FINISHED;
647 void PARTICLE_OT_disconnect_hair(wmOperatorType *ot)
649 ot->name = "Disconnect Hair";
650 ot->description = "Disconnect hair from the emitter mesh";
651 ot->idname = "PARTICLE_OT_disconnect_hair";
653 ot->exec = disconnect_hair_exec;
656 ot->flag = OPTYPE_UNDO; /* No REGISTER, redo does not work due to missing update, see T47750. */
658 RNA_def_boolean(ot->srna, "all", 0, "All hair", "Disconnect all hair systems from the emitter mesh");
661 /* from/to_world_space : whether from/to particles are in world or hair space
662 * from/to_mat : additional transform for from/to particles (e.g. for using object space copying)
664 static bool remap_hair_emitter(Scene *scene, SceneLayer *sl, Object *ob, ParticleSystem *psys,
665 Object *target_ob, ParticleSystem *target_psys, PTCacheEdit *target_edit,
666 float from_mat[4][4], float to_mat[4][4], bool from_global, bool to_global)
668 ParticleSystemModifierData *target_psmd = psys_get_modifier(target_ob, target_psys);
669 ParticleData *pa, *tpa;
670 PTCacheEditPoint *edit_point;
671 PTCacheEditKey *ekey;
672 BVHTreeFromMesh bvhtree= {NULL};
673 MFace *mface = NULL, *mf;
674 MEdge *medge = NULL, *me;
676 DerivedMesh *dm, *target_dm;
679 float from_ob_imat[4][4], to_ob_imat[4][4];
680 float from_imat[4][4], to_imat[4][4];
682 if (!target_psmd->dm_final)
684 if (!psys->part || psys->part->type != PART_HAIR)
686 if (!target_psys->part || target_psys->part->type != PART_HAIR)
689 edit_point = target_edit ? target_edit->points : NULL;
691 invert_m4_m4(from_ob_imat, ob->obmat);
692 invert_m4_m4(to_ob_imat, target_ob->obmat);
693 invert_m4_m4(from_imat, from_mat);
694 invert_m4_m4(to_imat, to_mat);
696 if (target_psmd->dm_final->deformedOnly) {
697 /* we don't want to mess up target_psmd->dm when converting to global coordinates below */
698 dm = target_psmd->dm_final;
701 dm = target_psmd->dm_deformed;
703 target_dm = target_psmd->dm_final;
707 /* don't modify the original vertices */
710 /* BMESH_ONLY, deform dm may not have tessface */
711 DM_ensure_tessface(dm);
713 numverts = dm->getNumVerts(dm);
714 mvert = dm->getVertArray(dm);
716 /* convert to global coordinates */
717 for (i=0; i<numverts; i++)
718 mul_m4_v3(to_mat, mvert[i].co);
720 if (dm->getNumTessFaces(dm) != 0) {
721 mface = dm->getTessFaceArray(dm);
722 bvhtree_from_mesh_faces(&bvhtree, dm, 0.0, 2, 6);
724 else if (dm->getNumEdges(dm) != 0) {
725 medge = dm->getEdgeArray(dm);
726 bvhtree_from_mesh_edges(&bvhtree, dm, 0.0, 2, 6);
733 for (i = 0, tpa = target_psys->particles, pa = psys->particles;
734 i < target_psys->totpart;
738 BVHTreeNearest nearest;
741 mul_v3_m4v3(from_co, from_ob_imat, pa->hair[0].co);
743 mul_v3_m4v3(from_co, from_ob_imat, pa->hair[0].world_co);
744 mul_m4_v3(from_mat, from_co);
747 nearest.dist_sq = FLT_MAX;
749 BLI_bvhtree_find_nearest(bvhtree.tree, from_co, &nearest, bvhtree.nearest_callback, &bvhtree);
751 if (nearest.index == -1) {
752 if (G.debug & G_DEBUG)
753 printf("No nearest point found for hair root!");
760 mf = &mface[nearest.index];
762 copy_v3_v3(v[0], mvert[mf->v1].co);
763 copy_v3_v3(v[1], mvert[mf->v2].co);
764 copy_v3_v3(v[2], mvert[mf->v3].co);
766 copy_v3_v3(v[3], mvert[mf->v4].co);
767 interp_weights_poly_v3(tpa->fuv, v, 4, nearest.co);
770 interp_weights_poly_v3(tpa->fuv, v, 3, nearest.co);
773 tpa->num = nearest.index;
774 tpa->num_dmcache = psys_particle_dm_face_lookup(target_dm, dm, tpa->num, tpa->fuv, NULL);
777 me = &medge[nearest.index];
779 tpa->fuv[1] = line_point_factor_v3(nearest.co,
782 tpa->fuv[0] = 1.0f - tpa->fuv[1];
783 tpa->fuv[2] = tpa->fuv[3] = 0.0f;
786 tpa->num = nearest.index;
787 tpa->num_dmcache = -1;
790 /* translate hair keys */
793 float hairmat[4][4], imat[4][4];
797 copy_m4_m4(imat, target_ob->obmat);
799 /* note: using target_dm here, which is in target_ob object space and has full modifiers */
800 psys_mat_hair_to_object(target_ob, target_dm, target_psys->part->from, tpa, hairmat);
801 invert_m4_m4(imat, hairmat);
803 mul_m4_m4m4(imat, imat, to_imat);
805 /* offset in world space */
806 sub_v3_v3v3(offset, nearest.co, from_co);
809 for (k=0, key=pa->hair, tkey=tpa->hair, ekey = edit_point->keys; k<tpa->totkey; k++, key++, tkey++, ekey++) {
813 mul_v3_m4v3(co_orig, from_ob_imat, key->co);
815 mul_v3_m4v3(co_orig, from_ob_imat, key->world_co);
816 mul_m4_v3(from_mat, co_orig);
818 add_v3_v3v3(tkey->co, co_orig, offset);
820 mul_m4_v3(imat, tkey->co);
822 ekey->flag |= PEK_USE_WCO;
828 for (k=0, key=pa->hair, tkey=tpa->hair; k<tpa->totkey; k++, key++, tkey++) {
832 mul_v3_m4v3(co_orig, from_ob_imat, key->co);
834 mul_v3_m4v3(co_orig, from_ob_imat, key->world_co);
835 mul_m4_v3(from_mat, co_orig);
837 add_v3_v3v3(tkey->co, co_orig, offset);
839 mul_m4_v3(imat, tkey->co);
845 free_bvhtree_from_mesh(&bvhtree);
848 psys_free_path_cache(target_psys, target_edit);
850 PE_update_object(scene, sl, target_ob, 0);
855 static bool connect_hair(Scene *scene, SceneLayer *sl, Object *ob, ParticleSystem *psys)
862 ok = remap_hair_emitter(scene, sl, ob, psys, ob, psys, psys->edit, ob->obmat, ob->obmat, psys->flag & PSYS_GLOBAL_HAIR, false);
863 psys->flag &= ~PSYS_GLOBAL_HAIR;
868 static int connect_hair_exec(bContext *C, wmOperator *op)
870 Scene *scene= CTX_data_scene(C);
871 SceneLayer *sl = CTX_data_scene_layer(C);
872 Object *ob= ED_object_context(C);
873 ParticleSystem *psys= NULL;
874 const bool all = RNA_boolean_get(op->ptr, "all");
875 bool any_connected = false;
878 return OPERATOR_CANCELLED;
881 for (psys=ob->particlesystem.first; psys; psys=psys->next) {
882 any_connected |= connect_hair(scene, sl, ob, psys);
886 psys = psys_get_current(ob);
887 any_connected |= connect_hair(scene, sl, ob, psys);
890 if (!any_connected) {
891 BKE_report(op->reports, RPT_WARNING,
892 "No hair connected (can't connect hair if particle system modifier is disabled)");
893 return OPERATOR_CANCELLED;
896 DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
897 WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, ob);
899 return OPERATOR_FINISHED;
902 void PARTICLE_OT_connect_hair(wmOperatorType *ot)
904 ot->name = "Connect Hair";
905 ot->description = "Connect hair to the emitter mesh";
906 ot->idname = "PARTICLE_OT_connect_hair";
908 ot->exec = connect_hair_exec;
911 ot->flag = OPTYPE_UNDO; /* No REGISTER, redo does not work due to missing update, see T47750. */
913 RNA_def_boolean(ot->srna, "all", 0, "All hair", "Connect all hair systems to the emitter mesh");
916 /************************ particle system copy operator *********************/
918 typedef enum eCopyParticlesSpace {
919 PAR_COPY_SPACE_OBJECT = 0,
920 PAR_COPY_SPACE_WORLD = 1,
921 } eCopyParticlesSpace;
923 static void copy_particle_edit(Scene *scene, SceneLayer *sl, Object *ob, ParticleSystem *psys, ParticleSystem *psys_from)
925 PTCacheEdit *edit_from = psys_from->edit, *edit;
933 edit = MEM_dupallocN(edit_from);
937 edit->pathcache = NULL;
938 BLI_listbase_clear(&edit->pathcachebufs);
940 edit->emitter_field = NULL;
941 edit->emitter_cosnos = NULL;
943 BLI_listbase_clear(&edit->undo);
944 edit->curundo = NULL;
946 edit->points = MEM_dupallocN(edit_from->points);
947 pa = psys->particles;
949 HairKey *hkey = pa->hair;
951 point->keys= MEM_dupallocN(point->keys);
954 key->time = &hkey->time;
955 key->flag = hkey->editflag;
956 if (!(psys->flag & PSYS_GLOBAL_HAIR)) {
957 key->flag |= PEK_USE_WCO;
958 hkey->editflag |= PEK_USE_WCO;
966 update_world_cos(ob, edit);
968 UI_GetThemeColor3ubv(TH_EDGE_SELECT, edit->sel_col);
969 UI_GetThemeColor3ubv(TH_WIRE, edit->nosel_col);
971 recalc_lengths(edit);
972 recalc_emitter_field(ob, psys);
973 PE_update_object(scene, sl, ob, true);
975 PTCacheUndo_clear(edit);
976 PE_undo_push(scene, sl, "Original");
979 static void remove_particle_systems_from_object(Object *ob_to)
981 ModifierData *md, *md_next;
983 if (ob_to->type != OB_MESH)
985 if (!ob_to->data || ID_IS_LINKED_DATABLOCK(ob_to->data))
988 for (md = ob_to->modifiers.first; md; md = md_next) {
991 /* remove all particle system modifiers as well,
992 * these need to sync to the particle system list
994 if (ELEM(md->type, eModifierType_ParticleSystem, eModifierType_DynamicPaint, eModifierType_Smoke)) {
995 BLI_remlink(&ob_to->modifiers, md);
1000 BKE_object_free_particlesystems(ob_to);
1003 /* single_psys_from is optional, if NULL all psys of ob_from are copied */
1004 static bool copy_particle_systems_to_object(Main *bmain,
1008 ParticleSystem *single_psys_from,
1011 bool duplicate_settings)
1014 ParticleSystem *psys_start = NULL, *psys, *psys_from;
1015 ParticleSystem **tmp_psys;
1016 DerivedMesh *final_dm;
1017 CustomDataMask cdmask;
1020 if (ob_to->type != OB_MESH)
1022 if (!ob_to->data || ID_IS_LINKED_DATABLOCK(ob_to->data))
1025 /* For remapping we need a valid DM.
1026 * Because the modifiers are appended at the end it's safe to use
1027 * the final DM of the object without particles.
1028 * However, when evaluating the DM all the particle modifiers must be valid,
1029 * i.e. have the psys assigned already.
1030 * To break this hen/egg problem we create all psys separately first (to collect required customdata masks),
1031 * then create the DM, then add them to the object and make the psys modifiers ...
1033 #define PSYS_FROM_FIRST (single_psys_from ? single_psys_from : ob_from->particlesystem.first)
1034 #define PSYS_FROM_NEXT(cur) (single_psys_from ? NULL : (cur)->next)
1035 totpsys = single_psys_from ? 1 : BLI_listbase_count(&ob_from->particlesystem);
1037 tmp_psys = MEM_mallocN(sizeof(ParticleSystem*) * totpsys, "temporary particle system array");
1040 for (psys_from = PSYS_FROM_FIRST, i = 0;
1042 psys_from = PSYS_FROM_NEXT(psys_from), ++i) {
1044 psys = BKE_object_copy_particlesystem(psys_from);
1047 if (psys_start == NULL)
1050 cdmask |= psys_emitter_customdata_mask(psys);
1052 /* to iterate source and target psys in sync,
1053 * we need to know where the newly added psys start
1055 psys_start = totpsys > 0 ? tmp_psys[0] : NULL;
1057 /* get the DM (psys and their modifiers have not been appended yet) */
1058 final_dm = mesh_get_derived_final(scene, ob_to, cdmask);
1060 /* now append psys to the object and make modifiers */
1061 for (i = 0, psys_from = PSYS_FROM_FIRST;
1063 ++i, psys_from = PSYS_FROM_NEXT(psys_from)) {
1065 ParticleSystemModifierData *psmd;
1069 /* append to the object */
1070 BLI_addtail(&ob_to->particlesystem, psys);
1072 /* add a particle system modifier for each system */
1073 md = modifier_new(eModifierType_ParticleSystem);
1074 psmd = (ParticleSystemModifierData *)md;
1075 /* push on top of the stack, no use trying to reproduce old stack order */
1076 BLI_addtail(&ob_to->modifiers, md);
1078 BLI_snprintf(md->name, sizeof(md->name), "ParticleSystem %i", i);
1079 modifier_unique_name(&ob_to->modifiers, (ModifierData *)psmd);
1082 psmd->dm_final = CDDM_copy(final_dm);
1083 CDDM_calc_normals(psmd->dm_final);
1084 DM_ensure_tessface(psmd->dm_final);
1086 if (psys_from->edit)
1087 copy_particle_edit(scene, sl, ob_to, psys, psys_from);
1089 if (duplicate_settings) {
1090 id_us_min(&psys->part->id);
1091 psys->part = BKE_particlesettings_copy(bmain, psys->part);
1094 MEM_freeN(tmp_psys);
1096 /* note: do this after creating DM copies for all the particle system modifiers,
1097 * the remapping otherwise makes final_dm invalid!
1099 for (psys = psys_start, psys_from = PSYS_FROM_FIRST, i = 0;
1101 psys = psys->next, psys_from = PSYS_FROM_NEXT(psys_from), ++i) {
1103 float (*from_mat)[4], (*to_mat)[4];
1106 case PAR_COPY_SPACE_OBJECT:
1110 case PAR_COPY_SPACE_WORLD:
1111 from_mat = ob_from->obmat;
1112 to_mat = ob_to->obmat;
1115 /* should not happen */
1116 from_mat = to_mat = NULL;
1120 if (ob_from != ob_to) {
1121 remap_hair_emitter(scene, sl, ob_from, psys_from, ob_to, psys, psys->edit, from_mat, to_mat, psys_from->flag & PSYS_GLOBAL_HAIR, psys->flag & PSYS_GLOBAL_HAIR);
1124 /* tag for recalc */
1125 // psys->recalc |= PSYS_RECALC_RESET;
1128 #undef PSYS_FROM_FIRST
1129 #undef PSYS_FROM_NEXT
1131 DEG_id_tag_update(&ob_to->id, OB_RECALC_DATA);
1132 WM_main_add_notifier(NC_OBJECT | ND_PARTICLE | NA_EDITED, ob_to);
1136 static int copy_particle_systems_poll(bContext *C)
1139 if (!ED_operator_object_active_editable(C))
1142 ob = ED_object_active_context(C);
1143 if (BLI_listbase_is_empty(&ob->particlesystem))
1149 static int copy_particle_systems_exec(bContext *C, wmOperator *op)
1151 const int space = RNA_enum_get(op->ptr, "space");
1152 const bool remove_target_particles = RNA_boolean_get(op->ptr, "remove_target_particles");
1153 const bool use_active = RNA_boolean_get(op->ptr, "use_active");
1154 Main *bmain = CTX_data_main(C);
1155 Scene *scene = CTX_data_scene(C);
1156 SceneLayer *sl = CTX_data_scene_layer(C);
1157 Object *ob_from = ED_object_active_context(C);
1158 ParticleSystem *psys_from = use_active ? CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem).data : NULL;
1160 int changed_tot = 0;
1163 CTX_DATA_BEGIN (C, Object *, ob_to, selected_editable_objects)
1165 if (ob_from != ob_to) {
1166 bool changed = false;
1167 if (remove_target_particles) {
1168 remove_particle_systems_from_object(ob_to);
1171 if (copy_particle_systems_to_object(bmain, scene, sl, ob_from, psys_from, ob_to, space, false))
1182 if ((changed_tot == 0 && fail == 0) || fail) {
1183 BKE_reportf(op->reports, RPT_ERROR,
1184 "Copy particle systems to selected: %d done, %d failed",
1188 return OPERATOR_FINISHED;
1191 void PARTICLE_OT_copy_particle_systems(wmOperatorType *ot)
1193 static EnumPropertyItem space_items[] = {
1194 {PAR_COPY_SPACE_OBJECT, "OBJECT", 0, "Object", "Copy inside each object's local space"},
1195 {PAR_COPY_SPACE_WORLD, "WORLD", 0, "World", "Copy in world space"},
1196 {0, NULL, 0, NULL, NULL}
1199 ot->name = "Copy Particle Systems";
1200 ot->description = "Copy particle systems from the active object to selected objects";
1201 ot->idname = "PARTICLE_OT_copy_particle_systems";
1203 ot->poll = copy_particle_systems_poll;
1204 ot->exec = copy_particle_systems_exec;
1207 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1209 RNA_def_enum(ot->srna, "space", space_items, PAR_COPY_SPACE_OBJECT, "Space", "Space transform for copying from one object to another");
1210 RNA_def_boolean(ot->srna, "remove_target_particles", true, "Remove Target Particles", "Remove particle systems on the target objects");
1211 RNA_def_boolean(ot->srna, "use_active", false, "Use Active", "Use the active particle system from the context");
1214 static int duplicate_particle_systems_poll(bContext *C)
1216 if (!ED_operator_object_active_editable(C)) {
1219 Object *ob = ED_object_active_context(C);
1220 if (BLI_listbase_is_empty(&ob->particlesystem)) {
1226 static int duplicate_particle_systems_exec(bContext *C, wmOperator *op)
1228 const bool duplicate_settings = RNA_boolean_get(op->ptr, "use_duplicate_settings");
1229 Scene *scene = CTX_data_scene(C);
1230 Object *ob = ED_object_active_context(C);
1231 ParticleSystem *psys = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem).data;
1232 copy_particle_systems_to_object(CTX_data_main(C), scene, CTX_data_scene_layer(C), ob, psys, ob,
1233 PAR_COPY_SPACE_OBJECT, duplicate_settings);
1234 return OPERATOR_FINISHED;
1237 void PARTICLE_OT_duplicate_particle_system(wmOperatorType *ot)
1239 ot->name = "Duplicate Particle Systems";
1240 ot->description = "Duplicate particle system within the active object";
1241 ot->idname = "PARTICLE_OT_duplicate_particle_system";
1243 ot->poll = duplicate_particle_systems_poll;
1244 ot->exec = duplicate_particle_systems_exec;
1247 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1249 RNA_def_boolean(ot->srna, "use_duplicate_settings", false, "Duplicate Settings",
1250 "Duplicate settings as well, so new particle system uses own settings");