Merge branch 'master' into blender2.8
authorCampbell Barton <ideasman42@gmail.com>
Mon, 19 Mar 2018 17:06:27 +0000 (18:06 +0100)
committerCampbell Barton <ideasman42@gmail.com>
Mon, 19 Mar 2018 17:14:05 +0000 (18:14 +0100)
28 files changed:
1  2 
build_files/cmake/macros.cmake
doc/doxygen/doxygen.source.h
source/blender/blenkernel/CMakeLists.txt
source/blender/editors/CMakeLists.txt
source/blender/editors/armature/CMakeLists.txt
source/blender/editors/armature/armature_utils.c
source/blender/editors/curve/CMakeLists.txt
source/blender/editors/curve/editcurve.c
source/blender/editors/include/ED_armature.h
source/blender/editors/include/ED_object.h
source/blender/editors/lattice/CMakeLists.txt
source/blender/editors/lattice/editlattice_tools.c
source/blender/editors/metaball/CMakeLists.txt
source/blender/editors/metaball/mball_edit.c
source/blender/editors/object/CMakeLists.txt
source/blender/editors/object/object_edit.c
source/blender/editors/object/object_intern.h
source/blender/editors/object/object_ops.c
source/blender/editors/physics/CMakeLists.txt
source/blender/editors/physics/particle_edit.c
source/blender/editors/physics/particle_edit_undo.c
source/blender/editors/physics/particle_object.c
source/blender/editors/physics/physics_intern.h
source/blender/editors/space_api/spacetypes.c
source/blender/editors/space_view3d/view3d_select.c
source/blender/editors/util/undo.c
source/blender/makesrna/intern/rna_object.c
source/blenderplayer/bad_level_call_stubs/stubs.c

Simple merge
Simple merge
index 3f6bb5b9954738b2f3d1e2efcb0c58a2bd20e784,231810aee313f991517a2fc1a4db23cb38872b25..f36a9e99a64f7853d86408a89fa699a9b51d13fc
@@@ -103,9 -101,10 +103,10 @@@ set(SR
        intern/displist.c
        intern/dynamicpaint.c
        intern/editderivedmesh.c
+       intern/editlattice.c
        intern/editmesh.c
        intern/editmesh_bvh.c
 +      intern/editmesh_tangent.c
        intern/effect.c
        intern/fcurve.c
        intern/fluidsim.c
        BKE_customdata_file.h
        BKE_data_transfer.h
        BKE_deform.h
 -      BKE_depsgraph.h
        BKE_displist.h
        BKE_dynamicpaint.h
+       BKE_editlattice.h
        BKE_editmesh.h
        BKE_editmesh_bvh.h
 +      BKE_editmesh_tangent.h
        BKE_effect.h
        BKE_fcurve.h
        BKE_fluidsim.h
index 757fca0a1b236fad2773c2c681a2e3413a9e2620,be8829b04185a95d06c51f58f324d9e2f4da0df8..c7ce4b44803254786292b13ac4b627cfa364c1b9
@@@ -29,7 -29,7 +29,8 @@@ if(WITH_BLENDER
        add_subdirectory(gpencil)
        add_subdirectory(interface)
        add_subdirectory(io)
+       add_subdirectory(lattice)
 +      add_subdirectory(manipulator_library)
        add_subdirectory(mask)
        add_subdirectory(mesh)
        add_subdirectory(metaball)
index bf29aba34f8a0c0f2ef62e3a571613f4b059b121,5b2fdf29dd5312ed824193efd0bdddb311b2d5c1..a116cf5e5d0aa93c99d35478abcd32699b6a509f
@@@ -203,40 -192,11 +203,32 @@@ void ED_object_constraint_dependency_up
  void ED_object_constraint_tag_update(struct Object *ob, struct bConstraint *con);
  void ED_object_constraint_dependency_tag_update(struct Main *bmain, struct Object *ob, struct bConstraint *con);
  
- /* object_lattice.c */
- bool ED_lattice_select_pick(struct bContext *C, const int mval[2], bool extend, bool deselect, bool toggle);
- void undo_push_lattice(struct bContext *C, const char *name);
- /* object_lattice.c */
- void ED_lattice_flags_set(struct Object *obedit, int flag);
  /* object_modes.c */
  bool ED_object_mode_compat_test(const struct Object *ob, eObjectMode mode);
 -bool ED_object_mode_compat_set(struct bContext *C, struct Object *ob, eObjectMode mode, struct ReportList *reports);
 +bool ED_object_mode_compat_set(struct bContext *C, struct WorkSpace *workspace, eObjectMode mode, struct ReportList *reports);
  void ED_object_mode_toggle(struct bContext *C, eObjectMode mode);
  
 +bool ED_object_mode_generic_enter(
 +        struct bContext *C,
 +        eObjectMode object_mode);
 +void ED_object_mode_generic_exit(
 +        const struct EvaluationContext *eval_ctx,
 +        struct WorkSpace *workspace, struct Scene *scene, struct Object *ob);
 +bool ED_object_mode_generic_has_data(
 +        const struct EvaluationContext *eval_ctx,
 +        struct Object *ob);
 +
 +bool ED_object_mode_generic_enter_or_other_window(
 +        struct bContext *C, const struct wmWindow *win_compare,
 +        eObjectMode object_mode);
 +void ED_object_mode_generic_exit_or_other_window(
 +        const struct EvaluationContext *eval_ctx, struct wmWindowManager *wm,
 +        struct WorkSpace *workspace, struct Scene *scene, struct Object *ob);
 +
 +bool ED_object_mode_generic_exists(
 +        struct wmWindowManager *wm, struct Object *ob,
 +        eObjectMode object_mode);
 +
  /* object_modifier.c */
  enum {
        MODIFIER_APPLY_DATA = 1,
index 0000000000000000000000000000000000000000,3bb954ddf461e784f77a6f5ef5ddea7b9c1bdebf..eaf837cf97817f51546dcceeaa66420a8f74da0a
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,45 +1,46 @@@
+ # ***** BEGIN GPL LICENSE BLOCK *****
+ #
+ # This program is free software; you can redistribute it and/or
+ # modify it under the terms of the GNU General Public License
+ # as published by the Free Software Foundation; either version 2
+ # of the License, or (at your option) any later version.
+ #
+ # This program is distributed in the hope that it will be useful,
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ # GNU General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+ # along with this program; if not, write to the Free Software Foundation,
+ # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ #
+ # Contributor(s): Jacques Beaurain.
+ #
+ # ***** END GPL LICENSE BLOCK *****
+ set(INC
+       ../include
+       ../../blenkernel
+       ../../blenlib
++      ../../depsgraph
+       ../../makesdna
+       ../../makesrna
+       ../../render/extern/include
+       ../../windowmanager
+       ../../../../intern/guardedalloc
+ )
+ set(INC_SYS
+ )
+ set(SRC
+       editlattice_select.c
+       editlattice_tools.c
+       editlattice_undo.c
+       lattice_ops.c
+       lattice_intern.h
+ )
+ blender_add_lib(bf_editor_lattice "${SRC}" "${INC}" "${INC_SYS}")
index 0000000000000000000000000000000000000000,c39ba44c1dcb7201e4480b95e55be6f1df3afd31..bf60c1e7da605da7f089b378f28836eecb470618
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,340 +1,341 @@@
 -#include "BKE_depsgraph.h"
+ /*
+  * ***** BEGIN GPL LICENSE BLOCK *****
+  *
+  * This program is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU General Public License
+  * as published by the Free Software Foundation; either version 2
+  * of the License, or (at your option) any later version.
+  *
+  * This program is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  * GNU General Public License for more details.
+  *
+  * You should have received a copy of the GNU General Public License
+  * along with this program; if not, write to the Free Software Foundation,
+  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+  *
+  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+  * All rights reserved.
+  *
+  * Contributor(s): Blender Foundation
+  *
+  * ***** END GPL LICENSE BLOCK *****
+  */
+ /** \file blender/editors/lattice/editlattice_tools.c
+  *  \ingroup edlattice
+  */
+ #include "BLI_math.h"
+ #include "BLI_utildefines.h"
+ #include "DNA_curve_types.h"
+ #include "DNA_lattice_types.h"
+ #include "DNA_object_types.h"
+ #include "DNA_scene_types.h"
+ #include "RNA_access.h"
+ #include "RNA_define.h"
+ #include "BKE_context.h"
 -      DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ #include "BKE_lattice.h"
++#include "DEG_depsgraph.h"
++
+ #include "ED_screen.h"
+ #include "WM_api.h"
+ #include "WM_types.h"
+ #include "lattice_intern.h"
+ /** \} */
+ /* -------------------------------------------------------------------- */
+ /** \name Make Regular Operator
+  * \{ */
+ static int make_regular_poll(bContext *C)
+ {
+       Object *ob;
+       if (ED_operator_editlattice(C)) return 1;
+       ob = CTX_data_active_object(C);
+       return (ob && ob->type == OB_LATTICE);
+ }
+ static int make_regular_exec(bContext *C, wmOperator *UNUSED(op))
+ {
+       Object *ob = CTX_data_edit_object(C);
+       Lattice *lt;
+       if (ob) {
+               lt = ob->data;
+               BKE_lattice_resize(lt->editlatt->latt, lt->pntsu, lt->pntsv, lt->pntsw, NULL);
+       }
+       else {
+               ob = CTX_data_active_object(C);
+               lt = ob->data;
+               BKE_lattice_resize(lt, lt->pntsu, lt->pntsv, lt->pntsw, NULL);
+       }
 -      DAG_id_tag_update(&obedit->id, OB_RECALC_DATA);
++      DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
+       WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
+       return OPERATOR_FINISHED;
+ }
+ void LATTICE_OT_make_regular(wmOperatorType *ot)
+ {
+       /* identifiers */
+       ot->name = "Make Regular";
+       ot->description = "Set UVW control points a uniform distance apart";
+       ot->idname = "LATTICE_OT_make_regular";
+       /* api callbacks */
+       ot->exec = make_regular_exec;
+       ot->poll = make_regular_poll;
+       /* flags */
+       ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ }
+ /** \} */
+ /* -------------------------------------------------------------------- */
+ /** \name Flip Verts Operator
+  * \{ */
+ /* flipping options */
+ typedef enum eLattice_FlipAxes {
+       LATTICE_FLIP_U = 0,
+       LATTICE_FLIP_V = 1,
+       LATTICE_FLIP_W = 2
+ } eLattice_FlipAxes;
+ /**
+  * Flip midpoint value so that relative distances between midpoint and neighbor-pair is maintained
+  * ! Assumes that uvw <=> xyz (i.e. axis-aligned index-axes with coordinate-axes)
+  * - Helper for lattice_flip_exec()
+  */
+ static void lattice_flip_point_value(Lattice *lt, int u, int v, int w, float mid, eLattice_FlipAxes axis)
+ {
+       BPoint *bp;
+       float diff;
+       /* just the point in the middle (unpaired) */
+       bp = &lt->def[BKE_lattice_index_from_uvw(lt, u, v, w)];
+       /* flip over axis */
+       diff = mid - bp->vec[axis];
+       bp->vec[axis] = mid + diff;
+ }
+ /**
+  * Swap pairs of lattice points along a specified axis
+  * - Helper for lattice_flip_exec()
+  */
+ static void lattice_swap_point_pairs(Lattice *lt, int u, int v, int w, float mid, eLattice_FlipAxes axis)
+ {
+       BPoint *bpA, *bpB;
+       int numU = lt->pntsu;
+       int numV = lt->pntsv;
+       int numW = lt->pntsw;
+       int u0 = u, u1 = u;
+       int v0 = v, v1 = v;
+       int w0 = w, w1 = w;
+       /* get pair index by just overriding the relevant pair-value
+        * - "-1" else buffer overflow
+        */
+       switch (axis) {
+               case LATTICE_FLIP_U:
+                       u1 = numU - u - 1;
+                       break;
+               case LATTICE_FLIP_V:
+                       v1 = numV - v - 1;
+                       break;
+               case LATTICE_FLIP_W:
+                       w1 = numW - w - 1;
+                       break;
+       }
+       /* get points to operate on */
+       bpA = &lt->def[BKE_lattice_index_from_uvw(lt, u0, v0, w0)];
+       bpB = &lt->def[BKE_lattice_index_from_uvw(lt, u1, v1, w1)];
+       /* Swap all coordinates, so that flipped coordinates belong to
+        * the indices on the correct side of the lattice.
+        *
+        *   Coords:  (-2 4) |0| (3 4)   --> (3 4) |0| (-2 4)
+        *   Indices:  (0,L)     (1,R)   --> (0,L)     (1,R)
+        */
+       swap_v3_v3(bpA->vec, bpB->vec);
+       /* However, we need to mirror the coordinate values on the axis we're dealing with,
+        * otherwise we'd have effectively only rotated the points around. If we don't do this,
+        * we'd just be reimplementing the naive mirroring algorithm, which causes unwanted deforms
+        * such as flipped normals, etc.
+        *
+        *   Coords:  (3 4) |0| (-2 4)  --\
+        *                                 \-> (-3 4) |0| (2 4)
+        *   Indices: (0,L)     (1,R)   -->     (0,L)     (1,R)
+        */
+       lattice_flip_point_value(lt, u0, v0, w0, mid, axis);
+       lattice_flip_point_value(lt, u1, v1, w1, mid, axis);
+ }
+ static int lattice_flip_exec(bContext *C, wmOperator *op)
+ {
+       Object *obedit = CTX_data_edit_object(C);
+       Lattice *lt;
+       eLattice_FlipAxes axis = RNA_enum_get(op->ptr, "axis");
+       int numU, numV, numW;
+       int totP;
+       float mid = 0.0f;
+       short isOdd = 0;
+       /* get lattice - we need the "edit lattice" from the lattice... confusing... */
+       lt = (Lattice *)obedit->data;
+       lt = lt->editlatt->latt;
+       numU = lt->pntsu;
+       numV = lt->pntsv;
+       numW = lt->pntsw;
+       totP = numU * numV * numW;
+       /* First Pass: determine midpoint - used for flipping center verts if there are odd number of points on axis */
+       switch (axis) {
+               case LATTICE_FLIP_U:
+                       isOdd = numU & 1;
+                       break;
+               case LATTICE_FLIP_V:
+                       isOdd = numV & 1;
+                       break;
+               case LATTICE_FLIP_W:
+                       isOdd = numW & 1;
+                       break;
+               default:
+                       printf("lattice_flip(): Unknown flipping axis (%u)\n", axis);
+                       return OPERATOR_CANCELLED;
+       }
+       if (isOdd) {
+               BPoint *bp;
+               float avgInv = 1.0f / (float)totP;
+               int i;
+               /* midpoint calculation - assuming that u/v/w are axis-aligned */
+               for (i = 0, bp = lt->def; i < totP; i++, bp++) {
+                       mid += bp->vec[axis] * avgInv;
+               }
+       }
+       /* Second Pass: swap pairs of vertices per axis, assuming they are all sorted */
+       switch (axis) {
+               case LATTICE_FLIP_U:
+               {
+                       int u, v, w;
+                       /* v/w strips - front to back, top to bottom */
+                       for (w = 0; w < numW; w++) {
+                               for (v = 0; v < numV; v++) {
+                                       /* swap coordinates of pairs of vertices on u */
+                                       for (u = 0; u < (numU / 2); u++) {
+                                               lattice_swap_point_pairs(lt, u, v, w, mid, axis);
+                                       }
+                                       /* flip u-coordinate of midpoint (i.e. unpaired point on u) */
+                                       if (isOdd) {
+                                               u = (numU / 2);
+                                               lattice_flip_point_value(lt, u, v, w, mid, axis);
+                                       }
+                               }
+                       }
+                       break;
+               }
+               case LATTICE_FLIP_V:
+               {
+                       int u, v, w;
+                       /* u/w strips - front to back, left to right */
+                       for (w = 0; w < numW; w++) {
+                               for (u = 0; u < numU; u++) {
+                                       /* swap coordinates of pairs of vertices on v */
+                                       for (v = 0; v < (numV / 2); v++) {
+                                               lattice_swap_point_pairs(lt, u, v, w, mid, axis);
+                                       }
+                                       /* flip v-coordinate of midpoint (i.e. unpaired point on v) */
+                                       if (isOdd) {
+                                               v = (numV / 2);
+                                               lattice_flip_point_value(lt, u, v, w, mid, axis);
+                                       }
+                               }
+                       }
+                       break;
+               }
+               case LATTICE_FLIP_W:
+               {
+                       int u, v, w;
+                       for (v = 0; v < numV; v++) {
+                               for (u = 0; u < numU; u++) {
+                                       /* swap coordinates of pairs of vertices on w */
+                                       for (w = 0; w < (numW / 2); w++) {
+                                               lattice_swap_point_pairs(lt, u, v, w, mid, axis);
+                                       }
+                                       /* flip w-coordinate of midpoint (i.e. unpaired point on w) */
+                                       if (isOdd) {
+                                               w = (numW / 2);
+                                               lattice_flip_point_value(lt, u, v, w, mid, axis);
+                                       }
+                               }
+                       }
+                       break;
+               }
+               default: /* shouldn't happen, but just in case */
+                       break;
+       }
+       /* updates */
++      DEG_id_tag_update(&obedit->id, OB_RECALC_DATA);
+       WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
+       return OPERATOR_FINISHED;
+ }
+ void LATTICE_OT_flip(wmOperatorType *ot)
+ {
+       static const EnumPropertyItem flip_items[] = {
+               {LATTICE_FLIP_U, "U", 0, "U (X) Axis", ""},
+               {LATTICE_FLIP_V, "V", 0, "V (Y) Axis", ""},
+               {LATTICE_FLIP_W, "W", 0, "W (Z) Axis", ""},
+               {0, NULL, 0, NULL, NULL}};
+       /* identifiers */
+       ot->name = "Flip (Distortion Free)";
+       ot->description = "Mirror all control points without inverting the lattice deform";
+       ot->idname = "LATTICE_OT_flip";
+       /* api callbacks */
+       ot->poll = ED_operator_editlattice;
+       ot->invoke = WM_menu_invoke;
+       ot->exec = lattice_flip_exec;
+       /* flags */
+       ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+       /* properties */
+       ot->prop = RNA_def_enum(ot->srna, "axis", flip_items, LATTICE_FLIP_U, "Flip Axis", "Coordinates along this axis get flipped");
+ }
+ /** \} */
index 3c75f08bd00a279e571f757f3ea5d70c39210cf3,24740a3372b5ed107e550f3a4710d7f86f06bf79..646b8137b2d1be0230f0b21bf81e1b4b8558ce83
@@@ -47,10 -46,8 +47,9 @@@ set(SR
        object_bake_api.c
        object_constraint.c
        object_edit.c
 +      object_facemap_ops.c
        object_group.c
        object_hook.c
-       object_lattice.c
        object_lod.c
        object_modes.c
        object_modifier.c
index 18288613f6d7dcc36dfb604256995a7e5a4dea44,f67ecbce1d01b7c22a2128190b4b2edb357ce22b..3e629c8d7f6dd0fa0402f561232ee9a842de13fe
  #include "BKE_sca.h"
  #include "BKE_softbody.h"
  #include "BKE_modifier.h"
+ #include "BKE_editlattice.h"
  #include "BKE_editmesh.h"
  #include "BKE_report.h"
 +#include "BKE_object.h"
 +#include "BKE_workspace.h"
 +
 +#include "DEG_depsgraph.h"
 +#include "DEG_depsgraph_build.h"
  
  #include "ED_armature.h"
  #include "ED_curve.h"
@@@ -421,8 -614,9 +422,8 @@@ void ED_object_editmode_enter(bContext 
                WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_EDITMODE_MBALL, scene);
        }
        else if (ob->type == OB_LATTICE) {
 -              scene->obedit = ob; /* XXX for context */
                ok = 1;
-               ED_lattice_editlatt_make(ob);
+               BKE_editlattice_make(ob);
  
                WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_EDITMODE_LATTICE, scene);
        }
index 597cdf08c76e5693ffaeb8f6fbf99175c414d3e8,93bfd1567079fdd5e7cf27cd1b027ee2502d6d23..e1dcec1d9ab827c061ef8e95d4401c43191162be
@@@ -4331,299 -4235,12 +4309,12 @@@ void PARTICLE_OT_shape_cut(wmOperatorTy
        ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
  }
  
- /*********************** undo ***************************/
- static void free_PTCacheUndo(PTCacheUndo *undo)
- {
-       PTCacheEditPoint *point;
-       int i;
-       for (i=0, point=undo->points; i<undo->totpoint; i++, point++) {
-               if (undo->particles && (undo->particles + i)->hair)
-                       MEM_freeN((undo->particles + i)->hair);
-               if (point->keys)
-                       MEM_freeN(point->keys);
-       }
-       if (undo->points)
-               MEM_freeN(undo->points);
-       if (undo->particles)
-               MEM_freeN(undo->particles);
-       BKE_ptcache_free_mem(&undo->mem_cache);
- }
- static void make_PTCacheUndo(PTCacheEdit *edit, PTCacheUndo *undo)
- {
-       PTCacheEditPoint *point;
-       int i;
-       undo->totpoint= edit->totpoint;
-       if (edit->psys) {
-               ParticleData *pa;
-               pa= undo->particles= MEM_dupallocN(edit->psys->particles);
-               for (i=0; i<edit->totpoint; i++, pa++)
-                       pa->hair= MEM_dupallocN(pa->hair);
-               undo->psys_flag = edit->psys->flag;
-       }
-       else {
-               PTCacheMem *pm;
-               BLI_duplicatelist(&undo->mem_cache, &edit->pid.cache->mem_cache);
-               pm = undo->mem_cache.first;
-               for (; pm; pm=pm->next) {
-                       for (i=0; i<BPHYS_TOT_DATA; i++)
-                               pm->data[i] = MEM_dupallocN(pm->data[i]);
-               }
-       }
-       point= undo->points = MEM_dupallocN(edit->points);
-       undo->totpoint = edit->totpoint;
-       for (i=0; i<edit->totpoint; i++, point++) {
-               point->keys= MEM_dupallocN(point->keys);
-               /* no need to update edit key->co & key->time pointers here */
-       }
- }
- static void get_PTCacheUndo(PTCacheEdit *edit, PTCacheUndo *undo)
- {
-       ParticleSystem *psys = edit->psys;
-       ParticleData *pa;
-       HairKey *hkey;
-       POINT_P; KEY_K;
-       LOOP_POINTS {
-               if (psys && psys->particles[p].hair)
-                       MEM_freeN(psys->particles[p].hair);
-               if (point->keys)
-                       MEM_freeN(point->keys);
-       }
-       if (psys && psys->particles)
-               MEM_freeN(psys->particles);
-       if (edit->points)
-               MEM_freeN(edit->points);
-       if (edit->mirror_cache) {
-               MEM_freeN(edit->mirror_cache);
-               edit->mirror_cache= NULL;
-       }
-       edit->points= MEM_dupallocN(undo->points);
-       edit->totpoint = undo->totpoint;
-       LOOP_POINTS {
-               point->keys= MEM_dupallocN(point->keys);
-       }
-       if (psys) {
-               psys->particles= MEM_dupallocN(undo->particles);
-               psys->totpart= undo->totpoint;
-               LOOP_POINTS {
-                       pa = psys->particles + p;
-                       hkey= pa->hair = MEM_dupallocN(pa->hair);
-                       LOOP_KEYS {
-                               key->co= hkey->co;
-                               key->time= &hkey->time;
-                               hkey++;
-                       }
-               }
-               psys->flag = undo->psys_flag;
-       }
-       else {
-               PTCacheMem *pm;
-               int i;
-               BKE_ptcache_free_mem(&edit->pid.cache->mem_cache);
-               BLI_duplicatelist(&edit->pid.cache->mem_cache, &undo->mem_cache);
-               pm = edit->pid.cache->mem_cache.first;
-               for (; pm; pm=pm->next) {
-                       for (i=0; i<BPHYS_TOT_DATA; i++)
-                               pm->data[i] = MEM_dupallocN(pm->data[i]);
-                       BKE_ptcache_mem_pointers_init(pm);
-                       LOOP_POINTS {
-                               LOOP_KEYS {
-                                       if ((int)key->ftime == (int)pm->frame) {
-                                               key->co = pm->cur[BPHYS_DATA_LOCATION];
-                                               key->vel = pm->cur[BPHYS_DATA_VELOCITY];
-                                               key->rot = pm->cur[BPHYS_DATA_ROTATION];
-                                               key->time = &key->ftime;
-                                       }
-                               }
-                               BKE_ptcache_mem_pointers_incr(pm);
-                       }
-               }
-       }
- }
- void PE_undo_push(Scene *scene, ViewLayer *view_layer, const char *str)
- {
-       PTCacheEdit *edit= PE_get_current(scene, view_layer, OBACT(view_layer));
-       PTCacheUndo *undo;
-       int nr;
-       if (!edit) return;
-       /* remove all undos after (also when curundo==NULL) */
-       while (edit->undo.last != edit->curundo) {
-               undo= edit->undo.last;
-               BLI_remlink(&edit->undo, undo);
-               free_PTCacheUndo(undo);
-               MEM_freeN(undo);
-       }
-       /* make new */
-       edit->curundo= undo= MEM_callocN(sizeof(PTCacheUndo), "particle undo file");
-       BLI_strncpy(undo->name, str, sizeof(undo->name));
-       BLI_addtail(&edit->undo, undo);
-       
-       /* and limit amount to the maximum */
-       nr= 0;
-       undo= edit->undo.last;
-       while (undo) {
-               nr++;
-               if (nr==U.undosteps) break;
-               undo= undo->prev;
-       }
-       if (undo) {
-               while (edit->undo.first != undo) {
-                       PTCacheUndo *first= edit->undo.first;
-                       BLI_remlink(&edit->undo, first);
-                       free_PTCacheUndo(first);
-                       MEM_freeN(first);
-               }
-       }
-       /* copy  */
-       make_PTCacheUndo(edit, edit->curundo);
- }
- void PE_undo_step(Scene *scene, ViewLayer *view_layer, int step)
- {     
-       PTCacheEdit *edit= PE_get_current(scene, view_layer, OBACT(view_layer));
-       if (!edit) return;
-       if (step==0) {
-               get_PTCacheUndo(edit, edit->curundo);
-       }
-       else if (step==1) {
-               
-               if (edit->curundo==NULL || edit->curundo->prev==NULL) {
-                       /* pass */
-               }
-               else {
-                       if (G.debug & G_DEBUG) printf("undo %s\n", edit->curundo->name);
-                       edit->curundo= edit->curundo->prev;
-                       get_PTCacheUndo(edit, edit->curundo);
-               }
-       }
-       else {
-               /* curundo has to remain current situation! */
-               
-               if (edit->curundo==NULL || edit->curundo->next==NULL) {
-                       /* pass */
-               }
-               else {
-                       get_PTCacheUndo(edit, edit->curundo->next);
-                       edit->curundo= edit->curundo->next;
-                       if (G.debug & G_DEBUG) printf("redo %s\n", edit->curundo->name);
-               }
-       }
-       DEG_id_tag_update(&OBACT(view_layer)->id, OB_RECALC_DATA);
- }
- bool PE_undo_is_valid(Scene *scene, ViewLayer *view_layer)
- {
-       PTCacheEdit *edit= PE_get_current(scene, view_layer, OBACT(view_layer));
-       
-       if (edit) {
-               return (edit->undo.last != edit->undo.first);
-       }
-       return 0;
- }
- void PTCacheUndo_clear(PTCacheEdit *edit)
- {
-       PTCacheUndo *undo;
-       if (edit==NULL) return;
-       
-       undo= edit->undo.first;
-       while (undo) {
-               free_PTCacheUndo(undo);
-               undo= undo->next;
-       }
-       BLI_freelistN(&edit->undo);
-       edit->curundo= NULL;
- }
- void PE_undo(Scene *scene, ViewLayer *view_layer)
- {
-       PE_undo_step(scene, view_layer, 1);
- }
- void PE_redo(Scene *scene, ViewLayer *view_layer)
- {
-       PE_undo_step(scene, view_layer, -1);
- }
- void PE_undo_number(Scene *scene, ViewLayer *view_layer, int nr)
- {
-       PTCacheEdit *edit= PE_get_current(scene, view_layer, OBACT(view_layer));
-       PTCacheUndo *undo;
-       int a=0;
-       
-       for (undo= edit->undo.first; undo; undo= undo->next, a++) {
-               if (a==nr) break;
-       }
-       edit->curundo= undo;
-       PE_undo_step(scene, view_layer, 0);
- }
- /* get name of undo item, return null if no item with this index */
- /* if active pointer, set it to 1 if true */
- const char *PE_undo_get_name(Scene *scene, ViewLayer *view_layer, int nr, bool *r_active)
- {
-       PTCacheEdit *edit= PE_get_current(scene, view_layer, OBACT(view_layer));
-       PTCacheUndo *undo;
-       
-       if (r_active) *r_active = false;
-       
-       if (edit) {
-               undo= BLI_findlink(&edit->undo, nr);
-               if (undo) {
-                       if (r_active && (undo == edit->curundo)) {
-                               *r_active = true;
-                       }
-                       return undo->name;
-               }
-       }
-       return NULL;
- }
  /************************ utilities ******************************/
  
 -int PE_minmax(Scene *scene, float min[3], float max[3])
 +int PE_minmax(Scene *scene, ViewLayer *view_layer, float min[3], float max[3])
  {
 -      Object *ob= OBACT;
 -      PTCacheEdit *edit= PE_get_current(scene, ob);
 +      Object *ob= OBACT(view_layer);
 +      PTCacheEdit *edit= PE_get_current(scene, view_layer, ob);
        ParticleSystem *psys;
        ParticleSystemModifierData *psmd = NULL;
        POINT_P; KEY_K;
index 0000000000000000000000000000000000000000,3899d445b78449de4429cb7b66965fbec8275726..7089e840a05588a0640688095a53df675522f275
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,344 +1,342 @@@
 -#include "BKE_depsgraph.h"
+ /*
+  * ***** BEGIN GPL LICENSE BLOCK *****
+  *
+  * This program is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU General Public License
+  * as published by the Free Software Foundation; either version 2
+  * of the License, or (at your option) any later version.
+  *
+  * This program is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  * GNU General Public License for more details.
+  *
+  * You should have received a copy of the GNU General Public License
+  * along with this program; if not, write to the Free Software Foundation,
+  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+  *
+  * The Original Code is Copyright (C) 2007 by Janne Karhu.
+  * All rights reserved.
+  *
+  * The Original Code is: all of this file.
+  *
+  * Contributor(s): none yet.
+  *
+  * ***** END GPL LICENSE BLOCK *****
+  */
+ /** \file blender/editors/physics/particle_edit_undo.c
+  *  \ingroup edphys
+  */
+ #include <stdlib.h>
+ #include <math.h>
+ #include <string.h>
+ #include <assert.h>
+ #include "MEM_guardedalloc.h"
+ #include "DNA_scene_types.h"
+ #include "DNA_meshdata_types.h"
+ #include "BLI_listbase.h"
+ #include "BLI_string.h"
+ #include "BLI_utildefines.h"
 -
 -
 -
+ #include "BKE_global.h"
+ #include "BKE_particle.h"
+ #include "BKE_pointcache.h"
++#include "DEG_depsgraph.h"
+ #include "ED_particle.h"
 -void PE_undo_push(Scene *scene, const char *str)
+ #include "particle_edit_utildefines.h"
+ #include "physics_intern.h"
++
+ static void free_PTCacheUndo(PTCacheUndo *undo)
+ {
+       PTCacheEditPoint *point;
+       int i;
+       for (i=0, point=undo->points; i<undo->totpoint; i++, point++) {
+               if (undo->particles && (undo->particles + i)->hair)
+                       MEM_freeN((undo->particles + i)->hair);
+               if (point->keys)
+                       MEM_freeN(point->keys);
+       }
+       if (undo->points)
+               MEM_freeN(undo->points);
+       if (undo->particles)
+               MEM_freeN(undo->particles);
+       BKE_ptcache_free_mem(&undo->mem_cache);
+ }
+ static void make_PTCacheUndo(PTCacheEdit *edit, PTCacheUndo *undo)
+ {
+       PTCacheEditPoint *point;
+       int i;
+       undo->totpoint= edit->totpoint;
+       if (edit->psys) {
+               ParticleData *pa;
+               pa= undo->particles= MEM_dupallocN(edit->psys->particles);
+               for (i=0; i<edit->totpoint; i++, pa++)
+                       pa->hair= MEM_dupallocN(pa->hair);
+               undo->psys_flag = edit->psys->flag;
+       }
+       else {
+               PTCacheMem *pm;
+               BLI_duplicatelist(&undo->mem_cache, &edit->pid.cache->mem_cache);
+               pm = undo->mem_cache.first;
+               for (; pm; pm=pm->next) {
+                       for (i=0; i<BPHYS_TOT_DATA; i++)
+                               pm->data[i] = MEM_dupallocN(pm->data[i]);
+               }
+       }
+       point= undo->points = MEM_dupallocN(edit->points);
+       undo->totpoint = edit->totpoint;
+       for (i=0; i<edit->totpoint; i++, point++) {
+               point->keys= MEM_dupallocN(point->keys);
+               /* no need to update edit key->co & key->time pointers here */
+       }
+ }
+ static void get_PTCacheUndo(PTCacheEdit *edit, PTCacheUndo *undo)
+ {
+       ParticleSystem *psys = edit->psys;
+       ParticleData *pa;
+       HairKey *hkey;
+       POINT_P; KEY_K;
+       LOOP_POINTS {
+               if (psys && psys->particles[p].hair)
+                       MEM_freeN(psys->particles[p].hair);
+               if (point->keys)
+                       MEM_freeN(point->keys);
+       }
+       if (psys && psys->particles)
+               MEM_freeN(psys->particles);
+       if (edit->points)
+               MEM_freeN(edit->points);
+       if (edit->mirror_cache) {
+               MEM_freeN(edit->mirror_cache);
+               edit->mirror_cache= NULL;
+       }
+       edit->points= MEM_dupallocN(undo->points);
+       edit->totpoint = undo->totpoint;
+       LOOP_POINTS {
+               point->keys= MEM_dupallocN(point->keys);
+       }
+       if (psys) {
+               psys->particles= MEM_dupallocN(undo->particles);
+               psys->totpart= undo->totpoint;
+               LOOP_POINTS {
+                       pa = psys->particles + p;
+                       hkey= pa->hair = MEM_dupallocN(pa->hair);
+                       LOOP_KEYS {
+                               key->co= hkey->co;
+                               key->time= &hkey->time;
+                               hkey++;
+                       }
+               }
+               psys->flag = undo->psys_flag;
+       }
+       else {
+               PTCacheMem *pm;
+               int i;
+               BKE_ptcache_free_mem(&edit->pid.cache->mem_cache);
+               BLI_duplicatelist(&edit->pid.cache->mem_cache, &undo->mem_cache);
+               pm = edit->pid.cache->mem_cache.first;
+               for (; pm; pm=pm->next) {
+                       for (i=0; i<BPHYS_TOT_DATA; i++)
+                               pm->data[i] = MEM_dupallocN(pm->data[i]);
+                       BKE_ptcache_mem_pointers_init(pm);
+                       LOOP_POINTS {
+                               LOOP_KEYS {
+                                       if ((int)key->ftime == (int)pm->frame) {
+                                               key->co = pm->cur[BPHYS_DATA_LOCATION];
+                                               key->vel = pm->cur[BPHYS_DATA_VELOCITY];
+                                               key->rot = pm->cur[BPHYS_DATA_ROTATION];
+                                               key->time = &key->ftime;
+                                       }
+                               }
+                               BKE_ptcache_mem_pointers_incr(pm);
+                       }
+               }
+       }
+ }
 -      PTCacheEdit *edit= PE_get_current(scene, OBACT);
++void PE_undo_push(Scene *scene, ViewLayer *view_layer, const char *str)
+ {
 -      
++      PTCacheEdit *edit= PE_get_current(scene, view_layer, OBACT(view_layer));
+       PTCacheUndo *undo;
+       int nr;
+       if (!edit) return;
+       /* remove all undos after (also when curundo==NULL) */
+       while (edit->undo.last != edit->curundo) {
+               undo= edit->undo.last;
+               BLI_remlink(&edit->undo, undo);
+               free_PTCacheUndo(undo);
+               MEM_freeN(undo);
+       }
+       /* make new */
+       edit->curundo= undo= MEM_callocN(sizeof(PTCacheUndo), "particle undo file");
+       BLI_strncpy(undo->name, str, sizeof(undo->name));
+       BLI_addtail(&edit->undo, undo);
 -void PE_undo_step(Scene *scene, int step)
 -{     
 -      PTCacheEdit *edit= PE_get_current(scene, OBACT);
++
+       /* and limit amount to the maximum */
+       nr= 0;
+       undo= edit->undo.last;
+       while (undo) {
+               nr++;
+               if (nr==U.undosteps) break;
+               undo= undo->prev;
+       }
+       if (undo) {
+               while (edit->undo.first != undo) {
+                       PTCacheUndo *first= edit->undo.first;
+                       BLI_remlink(&edit->undo, first);
+                       free_PTCacheUndo(first);
+                       MEM_freeN(first);
+               }
+       }
+       /* copy  */
+       make_PTCacheUndo(edit, edit->curundo);
+ }
 -              
++void PE_undo_step(Scene *scene, ViewLayer *view_layer, int step)
++{
++      PTCacheEdit *edit= PE_get_current(scene, view_layer, OBACT(view_layer));
+       if (!edit) return;
+       if (step==0) {
+               get_PTCacheUndo(edit, edit->curundo);
+       }
+       else if (step==1) {
 -              
++
+               if (edit->curundo==NULL || edit->curundo->prev==NULL) {
+                       /* pass */
+               }
+               else {
+                       if (G.debug & G_DEBUG) printf("undo %s\n", edit->curundo->name);
+                       edit->curundo= edit->curundo->prev;
+                       get_PTCacheUndo(edit, edit->curundo);
+               }
+       }
+       else {
+               /* curundo has to remain current situation! */
 -      DAG_id_tag_update(&OBACT->id, OB_RECALC_DATA);
++
+               if (edit->curundo==NULL || edit->curundo->next==NULL) {
+                       /* pass */
+               }
+               else {
+                       get_PTCacheUndo(edit, edit->curundo->next);
+                       edit->curundo= edit->curundo->next;
+                       if (G.debug & G_DEBUG) printf("redo %s\n", edit->curundo->name);
+               }
+       }
 -bool PE_undo_is_valid(Scene *scene)
++      DEG_id_tag_update(&OBACT(view_layer)->id, OB_RECALC_DATA);
+ }
 -      PTCacheEdit *edit= PE_get_current(scene, OBACT);
 -      
++bool PE_undo_is_valid(Scene *scene, ViewLayer *view_layer)
+ {
 -      
++      PTCacheEdit *edit= PE_get_current(scene, view_layer, OBACT(view_layer));
++
+       if (edit) {
+               return (edit->undo.last != edit->undo.first);
+       }
+       return 0;
+ }
+ void PTCacheUndo_clear(PTCacheEdit *edit)
+ {
+       PTCacheUndo *undo;
+       if (edit==NULL) return;
 -void PE_undo(Scene *scene)
++
+       undo= edit->undo.first;
+       while (undo) {
+               free_PTCacheUndo(undo);
+               undo= undo->next;
+       }
+       BLI_freelistN(&edit->undo);
+       edit->curundo= NULL;
+ }
 -      PE_undo_step(scene, 1);
++void PE_undo(Scene *scene, ViewLayer *view_layer)
+ {
 -void PE_redo(Scene *scene)
++      PE_undo_step(scene, view_layer, 1);
+ }
 -      PE_undo_step(scene, -1);
++void PE_redo(Scene *scene, ViewLayer *view_layer)
+ {
 -void PE_undo_number(Scene *scene, int nr)
++      PE_undo_step(scene, view_layer, -1);
+ }
 -      PTCacheEdit *edit= PE_get_current(scene, OBACT);
++void PE_undo_number(Scene *scene, ViewLayer *view_layer, int nr)
+ {
 -      
++      PTCacheEdit *edit= PE_get_current(scene, view_layer, OBACT(view_layer));
+       PTCacheUndo *undo;
+       int a=0;
 -      PE_undo_step(scene, 0);
++
+       for (undo= edit->undo.first; undo; undo= undo->next, a++) {
+               if (a==nr) break;
+       }
+       edit->curundo= undo;
 -const char *PE_undo_get_name(Scene *scene, int nr, bool *r_active)
++      PE_undo_step(scene, view_layer, 0);
+ }
+ /* get name of undo item, return null if no item with this index */
+ /* if active pointer, set it to 1 if true */
 -      PTCacheEdit *edit= PE_get_current(scene, OBACT);
++const char *PE_undo_get_name(Scene *scene, ViewLayer *view_layer, int nr, bool *r_active)
+ {
 -      
++      PTCacheEdit *edit= PE_get_current(scene, view_layer, OBACT(view_layer));
+       PTCacheUndo *undo;
 -      
++
+       if (r_active) *r_active = false;
++
+       if (edit) {
+               undo= BLI_findlink(&edit->undo, nr);
+               if (undo) {
+                       if (r_active && (undo == edit->curundo)) {
+                               *r_active = true;
+                       }
+                       return undo->name;
+               }
+       }
+       return NULL;
+ }
index 6b6df15e987598fcc742151fbf210bda81139e51,cb28193663466d637469a7aa9780169ee6a501e4..8888589b5d797f00897b9cea801e655e7f0a77ed
  #ifndef __PHYSICS_INTERN_H__
  #define __PHYSICS_INTERN_H__
  
++struct EvaluationContext;
+ struct Object;
+ struct PTCacheEdit;
+ struct ParticleSystem;
+ struct PointCache;
+ struct Scene;
++struct ViewLayer;
  struct wmOperatorType;
  
  /* particle_edit.c */
@@@ -63,6 -68,12 +70,14 @@@ void PARTICLE_OT_edited_clear(struct wm
  
  void PARTICLE_OT_unify_length(struct wmOperatorType *ot);
  
 -void PE_create_particle_edit(struct Scene *scene, struct Object *ob, struct PointCache *cache, struct ParticleSystem *psys);
+ void PTCacheUndo_clear(struct PTCacheEdit *edit);
++void PE_create_particle_edit(
++        const struct EvaluationContext *eval_ctx, struct Scene *scene, struct ViewLayer *view_layer,
++        struct Object *ob, struct PointCache *cache, struct ParticleSystem *psys);
+ void recalc_lengths(struct PTCacheEdit *edit);
+ void recalc_emitter_field(struct Object *ob, struct ParticleSystem *psys);
+ void update_world_cos(struct Object *ob, struct PTCacheEdit *edit);
  /* particle_object.c */
  void OBJECT_OT_particle_system_add(struct wmOperatorType *ot);
  void OBJECT_OT_particle_system_remove(struct wmOperatorType *ot);
Simple merge
index 751d96d5c51eebcef47eeb1e88f0d5736f442fd2,98092124dd55f3f44a19d4f99c6a2ac75d13ec40..03fd58bfbcd55e17ff228b68e8802a66ace88f88
@@@ -629,11 -559,7 +629,8 @@@ bool ED_transform_snap_object_project_r
          /* return args */
          float r_loc[3], float r_no[3], int *r_index,
          struct Object **r_ob, float r_obmat[4][4]) RET_ZERO
 +void BIF_selectTransformOrientationValue(struct View3D *v3d, int orientation) RET_NONE
  
- void ED_lattice_editlatt_make(struct Object *obedit) RET_NONE
- void ED_lattice_editlatt_load(struct Object *obedit) RET_NONE
  void ED_curve_editnurb_load(struct Object *obedit) RET_NONE
  void ED_curve_editnurb_make(struct Object *obedit) RET_NONE