47#include "RNA_prototypes.hh"
60static float I[4][4] = {
61 {1.0f, 0.0f, 0.0f, 0.0f},
62 {0.0f, 1.0f, 0.0f, 0.0f},
63 {0.0f, 0.0f, 1.0f, 0.0f},
64 {0.0f, 0.0f, 0.0f, 1.0f},
90 ot->name =
"Add Particle System Slot";
91 ot->idname =
"OBJECT_OT_particle_system_add";
92 ot->description =
"Add a particle system";
114 mode_orig = ob->
mode;
139 ot->name =
"Remove Particle System Slot";
140 ot->idname =
"OBJECT_OT_particle_system_remove";
141 ot->description =
"Remove the selected particle system";
156 return (
ptr.data !=
nullptr);
201 ot->name =
"New Particle Settings";
202 ot->idname =
"PARTICLE_OT_new";
203 ot->description =
"Add new particle settings";
229 for (; pt; pt = pt->
next) {
251 ot->name =
"New Particle Target";
252 ot->idname =
"PARTICLE_OT_new_target";
253 ot->description =
"Add a new particle target";
276 for (; pt; pt = pt->
next) {
300 ot->name =
"Remove Particle Target";
301 ot->idname =
"PARTICLE_OT_target_remove";
302 ot->description =
"Remove the selected particle target";
325 for (; pt; pt = pt->
next) {
341 ot->name =
"Move Up Target";
342 ot->idname =
"PARTICLE_OT_target_move_up";
343 ot->description =
"Move particle target up in the list";
364 for (; pt; pt = pt->
next) {
380 ot->name =
"Move Down Target";
381 ot->idname =
"PARTICLE_OT_target_move_down";
382 ot->description =
"Move particle target down in the list";
410 ot->name =
"Refresh Instance Objects";
411 ot->idname =
"PARTICLE_OT_dupliob_refresh";
412 ot->description =
"Refresh list of instance objects and their weights";
449 ot->name =
"Move Up Instance Object";
450 ot->idname =
"PARTICLE_OT_dupliob_move_up";
451 ot->description =
"Move instance object up in the list";
490 ot->name =
"Copy Particle Instance Object";
491 ot->idname =
"PARTICLE_OT_dupliob_copy";
492 ot->description =
"Duplicate the current instance object";
534 ot->name =
"Remove Particle Instance Object";
535 ot->idname =
"PARTICLE_OT_dupliob_remove";
536 ot->description =
"Remove the selected instance object";
574 ot->name =
"Move Down Instance Object";
575 ot->idname =
"PARTICLE_OT_dupliob_move_down";
576 ot->description =
"Move instance object down in the list";
609 point = edit ? edit->
points :
nullptr;
619 for (k = 0, key = pa->
hair; k < pa->totkey; k++, key++) {
670 ot->name =
"Disconnect Hair";
671 ot->description =
"Disconnect hair from the emitter mesh";
672 ot->idname =
"PARTICLE_OT_disconnect_hair";
681 ot->srna,
"all",
false,
"All Hair",
"Disconnect all hair systems from the emitter mesh");
694 const float from_mat[4][4],
695 const float to_mat[4][4],
706 const MFace *mface =
nullptr, *mf;
708 Mesh *mesh, *target_mesh;
711 float from_ob_imat[4][4], to_ob_imat[4][4];
712 float from_imat[4][4], to_imat[4][4];
724 edit_point = target_edit ? target_edit->
points :
nullptr;
726 invert_m4_m4(from_ob_imat, ob->object_to_world().ptr());
727 invert_m4_m4(to_ob_imat, target_ob->object_to_world().ptr());
741 if (mesh ==
nullptr) {
755 for (
int i = 0;
i < numverts;
i++) {
761 bvhtree = mesh->bvh_legacy_faces();
764 edges = mesh->edges().data();
765 bvhtree = mesh->bvh_edges();
792 if (nearest.
index == -1) {
794 printf(
"No nearest point found for hair root!");
802 mf = &mface[nearest.
index];
817 if (use_dm_final_indices) {
826 edge = &edges[nearest.
index];
829 tpa->
fuv[0] = 1.0f - tpa->
fuv[1];
830 tpa->
fuv[2] = tpa->
fuv[3] = 0.0f;
840 float hairmat[4][4], imat[4][4];
844 copy_m4_m4(imat, target_ob->object_to_world().ptr());
858 for (k = 0, key = pa->
hair, tkey = tpa->
hair, ekey = edit_point->
keys; k < tpa->totkey;
859 k++, key++, tkey++, ekey++)
881 for (k = 0, key = pa->
hair, tkey = tpa->
hair; k < tpa->totkey; k++, key++, tkey++) {
924 ob->object_to_world().ptr(),
925 ob->object_to_world().ptr(),
942 bool any_connected =
false;
958 if (!any_connected) {
961 "No hair connected (cannot connect hair if particle system modifier is disabled)");
973 ot->name =
"Connect Hair";
974 ot->description =
"Connect hair to the emitter mesh";
975 ot->idname =
"PARTICLE_OT_connect_hair";
984 ot->srna,
"all",
false,
"All Hair",
"Connect all hair systems to the emitter mesh");
1014 edit->mirror_cache =
nullptr;
1017 edit->emitter_field =
nullptr;
1018 edit->emitter_cosnos =
nullptr;
1028 key->time = &hkey->
time;
1084 bool duplicate_settings)
1111#define PSYS_FROM_FIRST \
1112 static_cast<ParticleSystem *>( \
1113 (single_psys_from ? single_psys_from : ob_from->particlesystem.first))
1114#define PSYS_FROM_NEXT(cur) (single_psys_from ? nullptr : (cur)->next)
1123 if (psys_start ==
nullptr) {
1132 psys_start = totpsys > 0 ? tmp_psys[0] :
nullptr;
1157 if (psys_from->edit) {
1161 if (duplicate_settings) {
1174 const float (*from_mat)[4], (*to_mat)[4];
1182 from_mat = ob_from->object_to_world().ptr();
1183 to_mat = ob_to->object_to_world().ptr();
1187 from_mat = to_mat =
nullptr;
1191 if (ob_from != ob_to) {
1209#undef PSYS_FROM_FIRST
1210#undef PSYS_FROM_NEXT
1236 const bool remove_target_particles =
RNA_boolean_get(op->
ptr,
"remove_target_particles");
1245 if (psys_from ==
nullptr) {
1251 int changed_tot = 0;
1255 if (ob_from != ob_to) {
1256 bool changed =
false;
1257 if (remove_target_particles) {
1275 if (changed_tot > 0) {
1279 if ((changed_tot == 0 && fail == 0) || fail) {
1282 "Copy particle systems to selected: %d done, %d failed",
1295 {0,
nullptr, 0,
nullptr,
nullptr},
1298 ot->name =
"Copy Particle Systems";
1299 ot->description =
"Copy particle systems from the active object to selected objects";
1300 ot->idname =
"PARTICLE_OT_copy_particle_systems";
1313 "Space transform for copying from one object to another");
1315 "remove_target_particles",
1317 "Remove Target Particles",
1318 "Remove particle systems on the target objects");
1323 "Use the active particle system from the context");
1350 if (psys ==
nullptr) {
1361 ot->name =
"Duplicate Particle System";
1362 ot->description =
"Duplicate particle system within the active object";
1363 ot->idname =
"PARTICLE_OT_duplicate_particle_system";
1372 "use_duplicate_settings",
1374 "Duplicate Settings",
1375 "Duplicate settings as well, so the new particle system uses its own settings");
1400 if (!scene || !ob) {
1429 ot->name =
"Remove All Particle Systems";
1430 ot->description =
"Remove all particle system within the active object";
1431 ot->idname =
"PARTICLE_OT_particle_system_remove_all";
#define CTX_DATA_BEGIN(C, Type, instance, member)
PointerRNA CTX_data_pointer_get_type(const bContext *C, const char *member, StructRNA *type)
void CTX_wm_operator_poll_msg_set(bContext *C, const char *msg)
Depsgraph * CTX_data_ensure_evaluated_depsgraph(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
Main * CTX_data_main(const bContext *C)
ViewLayer * CTX_data_view_layer(const bContext *C)
CustomData interface, see also DNA_customdata_types.h.
const void * CustomData_get_layer(const CustomData *data, eCustomDataType type)
void BKE_view_layer_synced_ensure(const Scene *scene, ViewLayer *view_layer)
Object * BKE_view_layer_active_object_get(const ViewLayer *view_layer)
bool BKE_id_is_editable(const Main *bmain, const ID *id)
void BKE_id_free(Main *bmain, void *idv)
ID * BKE_id_copy_ex(Main *bmain, const ID *id, ID **new_id_p, int flag)
ID * BKE_id_copy(Main *bmain, const ID *id)
void BKE_mesh_tessface_ensure(Mesh *mesh)
void BKE_modifiers_persistent_uid_init(const Object &object, ModifierData &md)
void BKE_modifier_unique_name(ListBase *modifiers, ModifierData *md)
void BKE_modifier_free(ModifierData *md)
ModifierData * BKE_modifier_new(int type)
General operations, lookup, etc. for blender objects.
void BKE_object_free_particlesystems(Object *ob)
ParticleSystem * BKE_object_copy_particlesystem(ParticleSystem *psys, int flag)
struct ModifierData * object_add_particle_system(struct Main *bmain, const struct Scene *scene, struct Object *ob, const char *name)
struct ParticleSystemModifierData * psys_get_modifier(struct Object *ob, struct ParticleSystem *psys)
void psys_unique_name(struct Object *object, struct ParticleSystem *psys, const char *defname) ATTR_NONNULL(1
void psys_mat_hair_to_global(struct Object *ob, struct Mesh *mesh, short from, struct ParticleData *pa, float hairmat[4][4])
void psys_check_group_weights(struct ParticleSettings *part)
void psys_mat_hair_to_object(struct Object *ob, struct Mesh *mesh, short from, struct ParticleData *pa, float hairmat[4][4])
void psys_emitter_customdata_mask(struct ParticleSystem *psys, struct CustomData_MeshMasks *r_cddata_masks)
void psys_check_boid_data(struct ParticleSystem *psys)
void object_remove_particle_system(struct Main *bmain, struct Scene *scene, struct Object *ob, struct ParticleSystem *psys)
struct ParticleSystem * psys_get_current(struct Object *ob)
struct ParticleSystem * psys_eval_get(struct Depsgraph *depsgraph, struct Object *object, struct ParticleSystem *psys)
void psys_free_path_cache(struct ParticleSystem *psys, struct PTCacheEdit *edit)
int psys_particle_dm_face_lookup(struct Mesh *mesh_final, struct Mesh *mesh_original, int findex_orig, const float fw[4], struct LinkNode **poly_nodes)
struct ParticleSettings * BKE_particlesettings_add(struct Main *bmain, const char *name)
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
void BKE_report(ReportList *reports, eReportType type, const char *message)
int BLI_bvhtree_find_nearest(const BVHTree *tree, const float co[3], BVHTreeNearest *nearest, BVHTree_NearestPointCallback callback, void *userdata)
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE void BLI_listbase_clear(ListBase *lb)
BLI_INLINE bool BLI_listbase_is_empty(const ListBase *lb)
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
void BLI_addtail(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
void BLI_insertlinkafter(ListBase *listbase, void *vprevlink, void *vnewlink) ATTR_NONNULL(1)
void BLI_remlink(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
void BLI_addhead(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
int BLI_listbase_count(const ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void BLI_insertlinkbefore(ListBase *listbase, void *vnextlink, void *vnewlink) ATTR_NONNULL(1)
float line_point_factor_v3(const float p[3], const float l1[3], const float l2[3])
void interp_weights_poly_v3(float w[], float v[][3], int n, const float co[3])
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
void mul_m4_v3(const float M[4][4], float r[3])
void copy_m4_m4(float m1[4][4], const float m2[4][4])
void mul_v3_m4v3(float r[3], const float mat[4][4], const float vec[3])
bool invert_m4_m4(float inverse[4][4], const float mat[4][4])
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void add_v3_v3v3(float r[3], const float a[3], const float b[3])
#define SNPRINTF_UTF8(dst, format,...)
void DEG_id_tag_update(ID *id, unsigned int flags)
void DEG_relations_tag_update(Main *bmain)
T * DEG_get_evaluated(const Depsgraph *depsgraph, T *id)
#define ID_IS_EDITABLE(_id)
#define ID_IS_OVERRIDE_LIBRARY(_id)
@ eModifierType_ParticleSystem
@ eModifierType_DynamicPaint
void PE_update_object(Depsgraph *depsgraph, Scene *scene, Object *ob, int useflag)
ParticleEditSettings * PE_settings(Scene *scene)
bool ED_operator_object_active_local_editable(bContext *C)
Read Guarded memory(de)allocation.
ATTR_WARN_UNUSED_RESULT const BMVert * v
BPy_StructRNA * depsgraph
ccl_device_inline T to_global(const float2 p, const T X, const T Y)
bool all(VecOp< bool, D >) RET
void * MEM_callocN(size_t len, const char *str)
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
void * MEM_dupallocN(const void *vmemh)
void MEM_freeN(void *vmemh)
Object * context_object(const bContext *C)
Object * context_active_object(const bContext *C)
VecBase< int32_t, 2 > int2
void recalc_emitter_field(Depsgraph *, Object *, ParticleSystem *psys)
void update_world_cos(Object *ob, PTCacheEdit *edit)
void recalc_lengths(PTCacheEdit *edit)
static void disconnect_hair(Depsgraph *depsgraph, Scene *scene, Object *ob, ParticleSystem *psys)
static bool duplicate_particle_systems_poll(bContext *C)
static wmOperatorStatus new_particle_target_exec(bContext *C, wmOperator *)
void PARTICLE_OT_target_move_up(wmOperatorType *ot)
static wmOperatorStatus dupliob_move_down_exec(bContext *C, wmOperator *)
void PARTICLE_OT_dupliob_copy(wmOperatorType *ot)
void PARTICLE_OT_dupliob_refresh(wmOperatorType *ot)
static wmOperatorStatus particle_system_remove_all_exec(bContext *C, wmOperator *)
static wmOperatorStatus dupliob_move_up_exec(bContext *C, wmOperator *)
static bool remap_hair_emitter(Depsgraph *depsgraph, Scene *scene, Object *ob, ParticleSystem *psys, Object *target_ob, ParticleSystem *target_psys, PTCacheEdit *target_edit, const float from_mat[4][4], const float to_mat[4][4], bool from_global, bool to_global)
void PARTICLE_OT_particle_system_remove_all(wmOperatorType *ot)
static wmOperatorStatus target_move_down_exec(bContext *C, wmOperator *)
void PARTICLE_OT_new(wmOperatorType *ot)
static wmOperatorStatus duplicate_particle_systems_exec(bContext *C, wmOperator *op)
void PARTICLE_OT_new_target(wmOperatorType *ot)
static wmOperatorStatus copy_particle_dupliob_exec(bContext *C, wmOperator *)
void PARTICLE_OT_disconnect_hair(wmOperatorType *ot)
void PARTICLE_OT_dupliob_move_down(wmOperatorType *ot)
static bool psys_poll(bContext *C)
void PARTICLE_OT_target_remove(wmOperatorType *ot)
static void copy_particle_edit(Depsgraph *depsgraph, Scene *scene, Object *ob, ParticleSystem *psys, ParticleSystem *psys_from)
static wmOperatorStatus dupliob_refresh_exec(bContext *C, wmOperator *)
static bool copy_particle_systems_poll(bContext *C)
static wmOperatorStatus copy_particle_systems_exec(bContext *C, wmOperator *op)
void PARTICLE_OT_connect_hair(wmOperatorType *ot)
static wmOperatorStatus remove_particle_target_exec(bContext *C, wmOperator *)
void OBJECT_OT_particle_system_remove(wmOperatorType *ot)
void PARTICLE_OT_copy_particle_systems(wmOperatorType *ot)
void PARTICLE_OT_dupliob_remove(wmOperatorType *ot)
static wmOperatorStatus target_move_up_exec(bContext *C, wmOperator *)
static bool copy_particle_systems_to_object(const bContext *C, Scene *scene, Object *ob_from, ParticleSystem *single_psys_from, Object *ob_to, int space, bool duplicate_settings)
static wmOperatorStatus particle_system_add_exec(bContext *C, wmOperator *)
static wmOperatorStatus remove_particle_dupliob_exec(bContext *C, wmOperator *)
static void remove_particle_systems_from_object(Object *ob_to)
static wmOperatorStatus connect_hair_exec(bContext *C, wmOperator *op)
static wmOperatorStatus disconnect_hair_exec(bContext *C, wmOperator *op)
static bool remove_all_particle_systems_poll(bContext *C)
static wmOperatorStatus new_particle_settings_exec(bContext *C, wmOperator *)
void PARTICLE_OT_dupliob_move_up(wmOperatorType *ot)
#define PSYS_FROM_NEXT(cur)
static wmOperatorStatus particle_system_remove_exec(bContext *C, wmOperator *)
void OBJECT_OT_particle_system_add(wmOperatorType *ot)
void PARTICLE_OT_target_move_down(wmOperatorType *ot)
void PARTICLE_OT_duplicate_particle_system(wmOperatorType *ot)
static bool connect_hair(Depsgraph *depsgraph, Scene *scene, Object *ob, ParticleSystem *psys)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
int RNA_enum_get(PointerRNA *ptr, const char *name)
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, const int default_value, const char *ui_name, const char *ui_description)
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, const bool default_value, const char *ui_name, const char *ui_description)
static const EnumPropertyItem space_items[]
MeshRuntimeHandle * runtime
struct ModifierData * next
struct PTCacheEditKey * keys
struct ParticleCacheKey ** pathcache
PTCacheEditPoint * points
struct ParticleSystem * psys
struct ListBase instance_weights
struct ParticleSystem * psys
struct Mesh * mesh_original
struct PTCacheEdit * edit
struct ParticleTarget * prev
struct ParticleTarget * next
BVHTree_NearestPointCallback nearest_callback
struct ReportList * reports
void WM_main_add_notifier(uint type, void *reference)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)