Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/transform/transform_conversions.c')
-rw-r--r--source/blender/editors/transform/transform_conversions.c203
1 files changed, 202 insertions, 1 deletions
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index f5b5faa4ad2..ce3d903b8f6 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -50,7 +50,6 @@
#include "DNA_gpencil_types.h"
#include "DNA_movieclip_types.h"
#include "DNA_mask_types.h"
-#include "DNA_object_types.h"
#include "MEM_guardedalloc.h"
@@ -82,7 +81,9 @@
#include "BKE_nla.h"
#include "BKE_node.h"
#include "BKE_object.h"
+#include "BKE_particle.h"
#include "BKE_paint.h"
+#include "BKE_pointcache.h"
#include "BKE_report.h"
#include "BKE_rigidbody.h"
#include "BKE_scene.h"
@@ -95,6 +96,7 @@
#include "ED_anim_api.h"
#include "ED_armature.h"
+#include "ED_particle.h"
#include "ED_image.h"
#include "ED_keyframing.h"
#include "ED_keyframes_edit.h"
@@ -1801,6 +1803,174 @@ static void createTransLatticeVerts(TransInfo *t)
}
}
+/* ******************* particle edit **************** */
+static void createTransParticleVerts(bContext *C, TransInfo *t)
+{
+ TransData *td = NULL;
+ TransDataExtension *tx;
+ Base *base = CTX_data_active_base(C);
+ Object *ob = CTX_data_active_object(C);
+ ParticleEditSettings *pset = PE_settings(t->scene);
+ PTCacheEdit *edit = PE_get_current(t->scene, ob);
+ ParticleSystem *psys = NULL;
+ ParticleSystemModifierData *psmd = NULL;
+ PTCacheEditPoint *point;
+ PTCacheEditKey *key;
+ float mat[4][4];
+ int i, k, transformparticle;
+ int count = 0, hasselected = 0;
+ const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0;
+
+ if (edit == NULL || t->settings->particle.selectmode == SCE_SELECT_PATH) return;
+
+ psys = edit->psys;
+
+ if (psys)
+ psmd = psys_get_modifier(ob, psys);
+
+ base->flag |= BA_HAS_RECALC_DATA;
+
+ for (i = 0, point = edit->points; i < edit->totpoint; i++, point++) {
+ point->flag &= ~PEP_TRANSFORM;
+ transformparticle = 0;
+
+ if ((point->flag & PEP_HIDE) == 0) {
+ for (k = 0, key = point->keys; k < point->totkey; k++, key++) {
+ if ((key->flag & PEK_HIDE) == 0) {
+ if (key->flag & PEK_SELECT) {
+ hasselected = 1;
+ transformparticle = 1;
+ }
+ else if (is_prop_edit)
+ transformparticle = 1;
+ }
+ }
+ }
+
+ if (transformparticle) {
+ count += point->totkey;
+ point->flag |= PEP_TRANSFORM;
+ }
+ }
+
+ /* note: in prop mode we need at least 1 selected */
+ if (hasselected == 0) return;
+
+ t->total = count;
+ td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransObData(Particle Mode)");
+
+ if (t->mode == TFM_BAKE_TIME)
+ tx = t->ext = MEM_callocN(t->total * sizeof(TransDataExtension), "Particle_TransExtension");
+ else
+ tx = t->ext = NULL;
+
+ unit_m4(mat);
+
+ invert_m4_m4(ob->imat, ob->obmat);
+
+ for (i = 0, point = edit->points; i < edit->totpoint; i++, point++) {
+ TransData *head, *tail;
+ head = tail = td;
+
+ if (!(point->flag & PEP_TRANSFORM)) continue;
+
+ if (psys && !(psys->flag & PSYS_GLOBAL_HAIR))
+ psys_mat_hair_to_global(ob, psmd->dm_final, psys->part->from, psys->particles + i, mat);
+
+ for (k = 0, key = point->keys; k < point->totkey; k++, key++) {
+ if (key->flag & PEK_USE_WCO) {
+ copy_v3_v3(key->world_co, key->co);
+ mul_m4_v3(mat, key->world_co);
+ td->loc = key->world_co;
+ }
+ else
+ td->loc = key->co;
+
+ copy_v3_v3(td->iloc, td->loc);
+ copy_v3_v3(td->center, td->loc);
+
+ if (key->flag & PEK_SELECT)
+ td->flag |= TD_SELECTED;
+ else if (!is_prop_edit)
+ td->flag |= TD_SKIP;
+
+ unit_m3(td->mtx);
+ unit_m3(td->smtx);
+
+ /* don't allow moving roots */
+ if (k == 0 && pset->flag & PE_LOCK_FIRST && (!psys || !(psys->flag & PSYS_GLOBAL_HAIR)))
+ td->protectflag |= OB_LOCK_LOC;
+
+ td->ob = ob;
+ td->ext = tx;
+ if (t->mode == TFM_BAKE_TIME) {
+ td->val = key->time;
+ td->ival = *(key->time);
+ /* abuse size and quat for min/max values */
+ td->flag |= TD_NO_EXT;
+ if (k == 0) tx->size = NULL;
+ else tx->size = (key - 1)->time;
+
+ if (k == point->totkey - 1) tx->quat = NULL;
+ else tx->quat = (key + 1)->time;
+ }
+
+ td++;
+ if (tx)
+ tx++;
+ tail++;
+ }
+ if (is_prop_edit && head != tail)
+ calc_distanceCurveVerts(head, tail - 1);
+ }
+}
+
+void flushTransParticles(TransInfo *t)
+{
+ Scene *scene = t->scene;
+ Object *ob = OBACT;
+ PTCacheEdit *edit = PE_get_current(scene, ob);
+ ParticleSystem *psys = edit->psys;
+ ParticleSystemModifierData *psmd = NULL;
+ PTCacheEditPoint *point;
+ PTCacheEditKey *key;
+ TransData *td;
+ float mat[4][4], imat[4][4], co[3];
+ int i, k;
+ const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0;
+
+ if (psys)
+ psmd = psys_get_modifier(ob, psys);
+
+ /* we do transform in world space, so flush world space position
+ * back to particle local space (only for hair particles) */
+ td = t->data;
+ for (i = 0, point = edit->points; i < edit->totpoint; i++, point++, td++) {
+ if (!(point->flag & PEP_TRANSFORM)) continue;
+
+ if (psys && !(psys->flag & PSYS_GLOBAL_HAIR)) {
+ psys_mat_hair_to_global(ob, psmd->dm_final, psys->part->from, psys->particles + i, mat);
+ invert_m4_m4(imat, mat);
+
+ for (k = 0, key = point->keys; k < point->totkey; k++, key++) {
+ copy_v3_v3(co, key->world_co);
+ mul_m4_v3(imat, co);
+
+
+ /* optimization for proportional edit */
+ if (!is_prop_edit || !compare_v3v3(key->co, co, 0.0001f)) {
+ copy_v3_v3(key->co, co);
+ point->flag |= PEP_EDIT_RECALC;
+ }
+ }
+ }
+ else
+ point->flag |= PEP_EDIT_RECALC;
+ }
+
+ PE_update_object(scene, OBACT, 1);
+}
+
/* ********************* mesh ****************** */
static bool bmesh_test_dist_add(BMVert *v, BMVert *v_other,
@@ -6145,6 +6315,13 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
else if (t->options & CTX_PAINT_CURVE) {
/* pass */
}
+ else if ((t->scene->basact) &&
+ (ob = t->scene->basact->object) &&
+ (ob->mode & OB_MODE_PARTICLE_EDIT) &&
+ PE_get_current(t->scene, ob))
+ {
+ /* do nothing */
+ }
else { /* Objects */
int i;
@@ -6152,6 +6329,8 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
for (i = 0; i < t->total; i++) {
TransData *td = t->data + i;
+ ListBase pidlist;
+ PTCacheID *pid;
ob = td->ob;
if (td->flag & TD_NOACTION)
@@ -6160,6 +6339,18 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
if (td->flag & TD_SKIP)
continue;
+ /* flag object caches as outdated */
+ BKE_ptcache_ids_from_object(&pidlist, ob, t->scene, MAX_DUPLI_RECUR);
+ for (pid = pidlist.first; pid; pid = pid->next) {
+ if (pid->type != PTCACHE_TYPE_PARTICLES) /* particles don't need reset on geometry change */
+ pid->cache->flag |= PTCACHE_OUTDATED;
+ }
+ BLI_freelistN(&pidlist);
+
+ /* pointcache refresh */
+ if (BKE_ptcache_object_reset(t->scene, ob, PTCACHE_RESET_OUTDATED))
+ DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+
/* Needed for proper updating of "quick cached" dynamics. */
/* Creates troubles for moving animated objects without */
/* autokey though, probably needed is an anim sys override? */
@@ -7879,6 +8070,16 @@ void createTransData(bContext *C, TransInfo *t)
}
}
+ else if (ob && (ob->mode & OB_MODE_PARTICLE_EDIT) && PE_start_edit(PE_get_current(scene, ob))) {
+ createTransParticleVerts(C, t);
+ t->flag |= T_POINTS;
+
+ if (t->data && t->flag & T_PROP_EDIT) {
+ sort_trans_data(t); // makes selected become first in array
+ set_prop_dist(t, 1);
+ sort_trans_data_dist(t);
+ }
+ }
else if (ob && (ob->mode & OB_MODE_ALL_PAINT)) {
if ((t->options & CTX_PAINT_CURVE) && !ELEM(t->mode, TFM_SHEAR, TFM_SHRINKFATTEN)) {
t->flag |= T_POINTS | T_2D_EDIT;