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')
-rw-r--r--source/blender/editors/animation/anim_filter.c9
-rw-r--r--source/blender/editors/interface/interface_ops.c6
-rw-r--r--source/blender/editors/mask/mask_shapekey.c9
-rw-r--r--source/blender/editors/mesh/editmesh_knife.c4
-rw-r--r--source/blender/editors/object/object_add.c30
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex.c1
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c9
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_uv.c2
-rw-r--r--source/blender/editors/space_action/action_edit.c9
-rw-r--r--source/blender/editors/space_clip/clip_editor.c8
-rw-r--r--source/blender/editors/space_clip/clip_ops.c5
-rw-r--r--source/blender/editors/space_image/space_image.c7
-rw-r--r--source/blender/editors/space_view3d/drawobject.c8
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c6
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c12
-rw-r--r--source/blender/editors/transform/transform_conversions.c199
16 files changed, 144 insertions, 180 deletions
diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c
index 9d54d938cc7..a4a1e951477 100644
--- a/source/blender/editors/animation/anim_filter.c
+++ b/source/blender/editors/animation/anim_filter.c
@@ -1796,9 +1796,14 @@ static size_t animdata_filter_ds_materials(bAnimContext *ac, ListBase *anim_data
Material *base = give_current_material(ob, a);
Material *ma = give_node_material(base);
- /* add channels from the nested material if it exists */
- if (ma)
+ /* add channels from the nested material if it exists
+ * - skip if the same material is referenced in its node tree
+ * (which is common for BI materials) as that results in
+ * confusing duplicates
+ */
+ if ((ma) && (ma != base)) {
items += animdata_filter_ds_material(ac, anim_data, ads, ma, filter_mode);
+ }
}
}
diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c
index 370e2960709..4bbccec7f9d 100644
--- a/source/blender/editors/interface/interface_ops.c
+++ b/source/blender/editors/interface/interface_ops.c
@@ -334,7 +334,7 @@ static int copy_to_selected_button_exec(bContext *C, wmOperator *op)
{
PointerRNA ptr, lptr, idptr;
PropertyRNA *prop, *lprop;
- int success = 0;
+ bool success = false;
int index;
const bool all = RNA_boolean_get(op->ptr, "all");
@@ -349,7 +349,7 @@ static int copy_to_selected_button_exec(bContext *C, wmOperator *op)
ListBase lb;
if (!copy_to_selected_list(C, &ptr, &lb, &use_path))
- return success;
+ return OPERATOR_CANCELLED;
if (!use_path || (path = RNA_path_from_ID_to_property(&ptr, prop))) {
for (link = lb.first; link; link = link->next) {
@@ -368,7 +368,7 @@ static int copy_to_selected_button_exec(bContext *C, wmOperator *op)
if (RNA_property_editable(&lptr, lprop)) {
if (RNA_property_copy(&lptr, &ptr, prop, (all) ? -1 : index)) {
RNA_property_update(C, &lptr, prop);
- success = 1;
+ success = true;
}
}
}
diff --git a/source/blender/editors/mask/mask_shapekey.c b/source/blender/editors/mask/mask_shapekey.c
index cea350219c0..30c960bda0f 100644
--- a/source/blender/editors/mask/mask_shapekey.c
+++ b/source/blender/editors/mask/mask_shapekey.c
@@ -272,16 +272,18 @@ static int mask_shape_key_rekey_exec(bContext *C, wmOperator *op)
}
if (masklay->splines_shapes.first) {
- MaskLayerShape *masklay_shape;
+ MaskLayerShape *masklay_shape, *masklay_shape_next;
MaskLayerShape *masklay_shape_lastsel = NULL;
for (masklay_shape = masklay->splines_shapes.first;
masklay_shape;
- masklay_shape = masklay_shape->next)
+ masklay_shape = masklay_shape_next)
{
MaskLayerShape *masklay_shape_a = NULL;
MaskLayerShape *masklay_shape_b = NULL;
+ masklay_shape_next = masklay_shape->next;
+
/* find contiguous selections */
if (masklay_shape->flag & MASK_SHAPE_SELECT) {
if (masklay_shape_lastsel == NULL) {
@@ -293,6 +295,9 @@ static int mask_shape_key_rekey_exec(bContext *C, wmOperator *op)
masklay_shape_a = masklay_shape_lastsel;
masklay_shape_b = masklay_shape;
masklay_shape_lastsel = NULL;
+
+ /* this will be freed below, step over selection */
+ masklay_shape_next = masklay_shape->next;
}
}
diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c
index c762c82442e..772fe7d306e 100644
--- a/source/blender/editors/mesh/editmesh_knife.c
+++ b/source/blender/editors/mesh/editmesh_knife.c
@@ -77,7 +77,7 @@
#define KNIFE_FLT_EPS 0.00001f
#define KNIFE_FLT_EPS_SQUARED (KNIFE_FLT_EPS * KNIFE_FLT_EPS)
-#define KNIFE_FLT_EPSBIG 0.001f
+#define KNIFE_FLT_EPSBIG 0.0005f
typedef struct KnifeColors {
unsigned char line[3];
@@ -653,7 +653,7 @@ static void knife_add_single_cut(KnifeTool_OpData *kcd, KnifeLineHit *lh1, Knife
}
/* Check if edge actually lies within face (might not, if this face is concave) */
- if (lh1->v && lh2->v) {
+ if ((lh1->v && !lh1->kfe) && (lh2->v && !lh2->kfe)) {
if (!knife_verts_edge_in_face(lh1->v, lh2->v, f)) {
return;
}
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index a2101716dbf..b29fafea90d 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -1298,6 +1298,11 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base,
BKE_free_animdata(&ob->id);
ob->adt = NULL;
+ /* Proxies are not to be copied. */
+ ob->proxy_from = NULL;
+ ob->proxy_group = NULL;
+ ob->proxy = NULL;
+
ob->parent = NULL;
BLI_listbase_clear(&ob->constraints);
ob->curve_cache = NULL;
@@ -1453,10 +1458,24 @@ static EnumPropertyItem convert_target_items[] = {
{0, NULL, 0, NULL, NULL}
};
-static void curvetomesh(Object *ob)
+static void convert_ensure_curve_cache(Main *bmain, Scene *scene, Object *ob)
{
- BLI_assert(ob->curve_cache != NULL);
+ if (ob->curve_cache == NULL) {
+ /* Force creation. This is normally not needed but on operator
+ * redo we might end up with an object which isn't evaluated yet.
+ */
+ if (ELEM3(ob->type, OB_SURF, OB_CURVE, OB_FONT)) {
+ BKE_displist_make_curveTypes(scene, ob, FALSE);
+ }
+ else if (ob->type == OB_MBALL) {
+ BKE_displist_make_mball(bmain->eval_ctx, scene, ob);
+ }
+ }
+}
+static void curvetomesh(Main *bmain, Scene *scene, Object *ob)
+{
+ convert_ensure_curve_cache(bmain, scene, ob);
BKE_mesh_from_nurbs(ob); /* also does users */
if (ob->type == OB_MESH)
@@ -1508,7 +1527,7 @@ static int convert_exec(bContext *C, wmOperator *op)
MetaBall *mb;
Mesh *me;
const short target = RNA_enum_get(op->ptr, "target");
- const short keep_original = RNA_boolean_get(op->ptr, "keep_original");
+ const bool keep_original = RNA_boolean_get(op->ptr, "keep_original");
int a, mballConverted = 0;
/* don't forget multiple users! */
@@ -1667,7 +1686,7 @@ static int convert_exec(bContext *C, wmOperator *op)
BKE_curve_curve_dimension_update(cu);
if (target == OB_MESH) {
- curvetomesh(newob);
+ curvetomesh(bmain, scene, newob);
/* meshes doesn't use displist */
BKE_object_free_curve_cache(newob);
@@ -1691,7 +1710,7 @@ static int convert_exec(bContext *C, wmOperator *op)
newob = ob;
}
- curvetomesh(newob);
+ curvetomesh(bmain, scene, newob);
/* meshes doesn't use displist */
BKE_object_free_curve_cache(newob);
@@ -1729,6 +1748,7 @@ static int convert_exec(bContext *C, wmOperator *op)
for (a = 0; a < newob->totcol; a++) id_us_plus((ID *)me->mat[a]);
}
+ convert_ensure_curve_cache(bmain, scene, baseob);
BKE_mesh_from_metaball(&baseob->curve_cache->disp, newob->data);
if (obact->type == OB_MBALL) {
diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c
index 55296aeda18..12eb1524515 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex.c
@@ -189,6 +189,7 @@ static VPaint *new_vpaint(int wpaint)
VPaint *vp = MEM_callocN(sizeof(VPaint), "VPaint");
vp->flag = (wpaint) ? 0 : VP_SPRAY;
+ vp->paint.flags |= PAINT_SHOW_BRUSH;
return vp;
}
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 5d4037a2bd3..d74e9c9e17b 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -2195,7 +2195,7 @@ static void do_layer_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
mul_v3_v3fl(val, offset, *disp);
- if (ss->layer_co && (brush->flag & BRUSH_PERSISTENT)) {
+ if (!ss->multires && !ss->bm && ss->layer_co && (brush->flag & BRUSH_PERSISTENT)) {
int index = vd.vert_indices[vd.i];
/* persistent base */
@@ -3953,6 +3953,12 @@ static void sculpt_update_cache_invariants(bContext *C, Sculpt *sd, SculptSessio
}
}
}
+
+ if (ss->bm) {
+ /* Free any remaining layer displacements from nodes. If not and topology changes
+ * from using another tool, then next layer toolstroke can access past disp array bounds */
+ BKE_pbvh_free_layer_disp(ss->pbvh);
+ }
}
/* Make copies of the mesh vertex locations and normals for some tools */
@@ -5119,6 +5125,7 @@ static int sculpt_mode_toggle_exec(bContext *C, wmOperator *op)
/* Turn on X plane mirror symmetry by default */
ts->sculpt->paint.symmetry_flags |= PAINT_SYMM_X;
+ ts->sculpt->paint.flags |= PAINT_SHOW_BRUSH;
/* Make sure at least dyntopo subdivision is enabled */
ts->sculpt->flags |= SCULPT_DYNTOPO_SUBDIVIDE;
diff --git a/source/blender/editors/sculpt_paint/sculpt_uv.c b/source/blender/editors/sculpt_paint/sculpt_uv.c
index 4dc2c87ca0a..da2b62bce8b 100644
--- a/source/blender/editors/sculpt_paint/sculpt_uv.c
+++ b/source/blender/editors/sculpt_paint/sculpt_uv.c
@@ -194,6 +194,8 @@ void ED_space_image_uv_sculpt_update(wmWindowManager *wm, ToolSettings *settings
settings->uv_sculpt_tool = UV_SCULPT_TOOL_GRAB;
settings->uv_sculpt_settings = UV_SCULPT_LOCK_BORDERS | UV_SCULPT_ALL_ISLANDS;
settings->uv_relax_method = UV_SCULPT_TOOL_RELAX_LAPLACIAN;
+ /* Uv sculpting does not include explicit brush view control yet, always enable */
+ settings->uvsculpt->paint.flags |= PAINT_SHOW_BRUSH;
}
BKE_paint_init(&settings->uvsculpt->paint, PAINT_CURSOR_SCULPT);
diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c
index e2ca45bbdc9..4c2cb16bdd1 100644
--- a/source/blender/editors/space_action/action_edit.c
+++ b/source/blender/editors/space_action/action_edit.c
@@ -368,7 +368,7 @@ static int actkeys_viewall(bContext *C, const bool only_sel, const bool only_xax
{
bAnimContext ac;
View2D *v2d;
- float extra;
+ float extra, min, max;
bool found;
/* get editor data */
@@ -377,11 +377,14 @@ static int actkeys_viewall(bContext *C, const bool only_sel, const bool only_xax
v2d = &ac.ar->v2d;
/* set the horizontal range, with an extra offset so that the extreme keys will be in view */
- found = get_keyframe_extents(&ac, &v2d->cur.xmin, &v2d->cur.xmax, only_sel);
+ found = get_keyframe_extents(&ac, &min, &max, only_sel);
if (only_sel && (found == false))
return OPERATOR_CANCELLED;
-
+
+ v2d->cur.xmin = min;
+ v2d->cur.xmax = max;
+
extra = 0.1f * BLI_rctf_size_x(&v2d->cur);
v2d->cur.xmin -= extra;
v2d->cur.xmax += extra;
diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c
index 0543e348b5b..18652aabefe 100644
--- a/source/blender/editors/space_clip/clip_editor.c
+++ b/source/blender/editors/space_clip/clip_editor.c
@@ -765,12 +765,18 @@ static void *do_prefetch_thread(void *data_v)
MovieClipUser user = {0};
int flag = IB_rect | IB_alphamode_detect;
int result;
+ char *colorspace_name = NULL;
user.framenr = current_frame;
user.render_size = data->queue->render_size;
user.render_flag = data->queue->render_flag;
- ibuf = IMB_ibImageFromMemory(mem, size, flag, clip->colorspace_settings.name, "prefetch frame");
+ /* Proxies are stored in the display space. */
+ if (data->queue->render_flag & MCLIP_USE_PROXY) {
+ colorspace_name = clip->colorspace_settings.name;
+ }
+
+ ibuf = IMB_ibImageFromMemory(mem, size, flag, colorspace_name, "prefetch frame");
result = BKE_movieclip_put_frame_if_possible(data->clip, &user, ibuf);
diff --git a/source/blender/editors/space_clip/clip_ops.c b/source/blender/editors/space_clip/clip_ops.c
index 7a6c4268aab..bb6c50d6224 100644
--- a/source/blender/editors/space_clip/clip_ops.c
+++ b/source/blender/editors/space_clip/clip_ops.c
@@ -1002,7 +1002,7 @@ static void do_movie_proxy(void *pjv, int *UNUSED(build_sizes), int UNUSED(build
}
else {
sfra = 1;
- efra = IMB_anim_get_duration(clip->anim, IMB_TC_NONE);
+ efra = clip->len;
}
if (build_undistort_count) {
@@ -1118,7 +1118,8 @@ static void *do_proxy_thread(void *data_v)
while ((mem = proxy_thread_next_frame(data->queue, data->clip, &size, &cfra))) {
ImBuf *ibuf;
- ibuf = IMB_ibImageFromMemory(mem, size, IB_rect | IB_multilayer | IB_alphamode_detect, NULL, "proxy frame");
+ ibuf = IMB_ibImageFromMemory(mem, size, IB_rect | IB_multilayer | IB_alphamode_detect,
+ data->clip->colorspace_settings.name, "proxy frame");
BKE_movieclip_build_proxy_frame_for_ibuf(data->clip, ibuf, NULL, cfra,
data->build_sizes, data->build_count, false);
diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c
index 5c9fd233a5c..14fd486c546 100644
--- a/source/blender/editors/space_image/space_image.c
+++ b/source/blender/editors/space_image/space_image.c
@@ -512,18 +512,21 @@ static void image_listener(bScreen *sc, ScrArea *sa, wmNotifier *wmn)
}
case NC_OBJECT:
{
- Object *ob = OBACT;
switch (wmn->data) {
case ND_TRANSFORM:
case ND_MODIFIER:
- if (ob == (Object *)wmn->reference && (ob->mode & OB_MODE_EDIT)) {
+ {
+ Object *ob = OBACT;
+ if (ob && (ob == wmn->reference) && (ob->mode & OB_MODE_EDIT)) {
if (sima->lock && (sima->flag & SI_DRAWSHADOW)) {
ED_area_tag_refresh(sa);
ED_area_tag_redraw(sa);
}
}
break;
+ }
}
+
break;
}
}
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index b0eb8d20554..c1adbafe413 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -4649,8 +4649,8 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
else
pa_health = -1.0;
- r_tilt = 2.0f * (PSYS_FRAND(a + 21) - 0.5f);
- r_length = PSYS_FRAND(a + 22);
+ r_tilt = 2.0f * (psys_frand(psys, a + 21) - 0.5f);
+ r_length = psys_frand(psys, a + 22);
if (part->draw_col > PART_DRAW_COL_MAT) {
switch (part->draw_col) {
@@ -4677,8 +4677,8 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
pa_health = -1.0;
- r_tilt = 2.0f * (PSYS_FRAND(a + 21) - 0.5f);
- r_length = PSYS_FRAND(a + 22);
+ r_tilt = 2.0f * (psys_frand(psys, a + 21) - 0.5f);
+ r_length = psys_frand(psys, a + 22);
}
drawn = 0;
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 18f3d150eb2..ad54e8a5eff 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -3262,9 +3262,11 @@ static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const
glEnable(GL_MULTISAMPLE_ARB);
}
-
- /* needs to be done always, gridview is adjusted in drawgrid() now */
+ /* needs to be done always, gridview is adjusted in drawgrid() now, but only for ortho views. */
rv3d->gridview = v3d->grid;
+ if (scene->unit.system) {
+ rv3d->gridview /= scene->unit.scale_length;
+ }
if ((rv3d->view == RV3D_VIEW_USER) || (rv3d->persp != RV3D_ORTHO)) {
if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) {
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index 47f30e3e279..1c355889398 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -568,8 +568,10 @@ static void do_lasso_select_curve(ViewContext *vc, const int mcords[][2], short
view3d_userdata_lassoselect_init(&data, vc, &rect, mcords, moves, select);
- if (extend == false && select)
- ED_curve_deselect_all(vc->obedit->data);
+ if (extend == false && select) {
+ Curve *curve = (Curve *) vc->obedit->data;
+ ED_curve_deselect_all(curve->editnurb);
+ }
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
nurbs_foreachScreenVert(vc, do_lasso_select_curve__doSelect, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
@@ -1735,8 +1737,10 @@ static int do_nurbs_box_select(ViewContext *vc, rcti *rect, bool select, bool ex
view3d_userdata_boxselect_init(&data, vc, rect, select);
- if (extend == false && select)
- ED_curve_deselect_all(vc->obedit->data);
+ if (extend == false && select) {
+ Curve *curve = (Curve *) vc->obedit->data;
+ ED_curve_deselect_all(curve->editnurb);
+ }
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
nurbs_foreachScreenVert(vc, do_nurbs_box_select__doSelect, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index beb49a5443e..8dc0c6ddaa8 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -3001,6 +3001,34 @@ static void createTransNlaData(bContext *C, TransInfo *t)
/* ********************* ACTION EDITOR ****************** */
+static int gpf_cmp_frame(void *thunk, void *a, void *b)
+{
+ bGPDframe *frame_a = a;
+ bGPDframe *frame_b = b;
+
+ if (frame_a->framenum < frame_b->framenum) return -1;
+ if (frame_a->framenum > frame_b->framenum) return 1;
+ *((bool *)thunk) = true;
+ /* selected last */
+ if ((frame_a->flag & GP_FRAME_SELECT) &&
+ ((frame_b->flag & GP_FRAME_SELECT) == 0)) return 1;
+ return 0;
+}
+
+static int masklay_shape_cmp_frame(void *thunk, void *a, void *b)
+{
+ MaskLayerShape *frame_a = a;
+ MaskLayerShape *frame_b = b;
+
+ if (frame_a->frame < frame_b->frame) return -1;
+ if (frame_a->frame > frame_b->frame) return 1;
+ *((bool *)thunk) = true;
+ /* selected last */
+ if ((frame_a->flag & MASK_SHAPE_SELECT) &&
+ ((frame_b->flag & MASK_SHAPE_SELECT) == 0)) return 1;
+ return 0;
+}
+
/* Called by special_aftertrans_update to make sure selected gp-frames replace
* any other gp-frames which may reside on that frame (that are not selected).
* It also makes sure gp-frames are still stored in chronological order after
@@ -3011,175 +3039,52 @@ static void posttrans_gpd_clean(bGPdata *gpd)
bGPDlayer *gpl;
for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
- ListBase sel_buffer = {NULL, NULL};
bGPDframe *gpf, *gpfn;
- bGPDframe *gfs, *gfsn;
-
- /* loop 1: loop through and isolate selected gp-frames to buffer
- * (these need to be sorted as they are isolated)
- */
- for (gpf = gpl->frames.first; gpf; gpf = gpfn) {
- short added = 0;
- gpfn = gpf->next;
-
- if (gpf->flag & GP_FRAME_SELECT) {
- BLI_remlink(&gpl->frames, gpf);
-
- /* find place to add them in buffer
- * - go backwards as most frames will still be in order,
- * so doing it this way will be faster
- */
- for (gfs = sel_buffer.last; gfs; gfs = gfs->prev) {
- /* if current (gpf) occurs after this one in buffer, add! */
- if (gfs->framenum < gpf->framenum) {
- BLI_insertlinkafter(&sel_buffer, gfs, gpf);
- added = 1;
- break;
- }
- }
- if (added == 0)
- BLI_addhead(&sel_buffer, gpf);
- }
- }
-
- /* error checking: it is unlikely, but may be possible to have none selected */
- if (BLI_listbase_is_empty(&sel_buffer))
- continue;
-
- /* if all were selected (i.e. gpl->frames is empty), then just transfer sel-buf over */
- if (BLI_listbase_is_empty(&gpl->frames)) {
- gpl->frames.first = sel_buffer.first;
- gpl->frames.last = sel_buffer.last;
-
- continue;
- }
-
- /* loop 2: remove duplicates of frames in buffers */
- for (gpf = gpl->frames.first; gpf && sel_buffer.first; gpf = gpfn) {
- gpfn = gpf->next;
-
- /* loop through sel_buffer, emptying stuff from front of buffer if ok */
- for (gfs = sel_buffer.first; gfs && gpf; gfs = gfsn) {
- gfsn = gfs->next;
-
- /* if this buffer frame needs to go before current, add it! */
- if (gfs->framenum < gpf->framenum) {
- /* transfer buffer frame to frames list (before current) */
- BLI_remlink(&sel_buffer, gfs);
- BLI_insertlinkbefore(&gpl->frames, gpf, gfs);
- }
- /* if this buffer frame is on same frame, replace current with it and stop */
- else if (gfs->framenum == gpf->framenum) {
- /* transfer buffer frame to frames list (before current) */
- BLI_remlink(&sel_buffer, gfs);
- BLI_insertlinkbefore(&gpl->frames, gpf, gfs);
-
- /* get rid of current frame */
+ bool is_double = false;
+
+ BLI_sortlist_r(&gpl->frames, &is_double, gpf_cmp_frame);
+
+ if (is_double) {
+ for (gpf = gpl->frames.first; gpf; gpf = gpfn) {
+ gpfn = gpf->next;
+ if (gpfn && gpf->framenum == gpfn->framenum) {
gpencil_layer_delframe(gpl, gpf);
}
}
}
-
- /* if anything is still in buffer, append to end */
- for (gfs = sel_buffer.first; gfs; gfs = gfsn) {
- gfsn = gfs->next;
-
- BLI_remlink(&sel_buffer, gfs);
- BLI_addtail(&gpl->frames, gfs);
+
+#ifdef DEBUG
+ for (gpf = gpl->frames.first; gpf; gpf = gpf->next) {
+ BLI_assert(!gpf->next || gpf->framenum < gpf->next->framenum);
}
+#endif
}
}
-
-/* Called by special_aftertrans_update to make sure selected gp-frames replace
- * any other gp-frames which may reside on that frame (that are not selected).
- * It also makes sure sorted are still stored in chronological order after
- * transform.
- */
static void posttrans_mask_clean(Mask *mask)
{
MaskLayer *masklay;
for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
- ListBase sel_buffer = {NULL, NULL};
- MaskLayerShape *masklay_shape, *masklay_shape_new;
- MaskLayerShape *masklay_shape_sort, *masklay_shape_sort_new;
-
- /* loop 1: loop through and isolate selected gp-frames to buffer
- * (these need to be sorted as they are isolated)
- */
- for (masklay_shape = masklay->splines_shapes.first; masklay_shape; masklay_shape = masklay_shape_new) {
- short added = 0;
- masklay_shape_new = masklay_shape->next;
+ MaskLayerShape *masklay_shape, *masklay_shape_next;
+ bool is_double = false;
- if (masklay_shape->flag & MASK_SHAPE_SELECT) {
- BLI_remlink(&masklay->splines_shapes, masklay_shape);
+ BLI_sortlist_r(&masklay->splines_shapes, &is_double, masklay_shape_cmp_frame);
- /* find place to add them in buffer
- * - go backwards as most frames will still be in order,
- * so doing it this way will be faster
- */
- for (masklay_shape_sort = sel_buffer.last; masklay_shape_sort; masklay_shape_sort = masklay_shape_sort->prev) {
- /* if current (masklay_shape) occurs after this one in buffer, add! */
- if (masklay_shape_sort->frame < masklay_shape->frame) {
- BLI_insertlinkafter(&sel_buffer, masklay_shape_sort, masklay_shape);
- added = 1;
- break;
- }
- }
- if (added == 0)
- BLI_addhead(&sel_buffer, masklay_shape);
- }
- }
-
- /* error checking: it is unlikely, but may be possible to have none selected */
- if (BLI_listbase_is_empty(&sel_buffer))
- continue;
-
- /* if all were selected (i.e. masklay->splines_shapes is empty), then just transfer sel-buf over */
- if (BLI_listbase_is_empty(&masklay->splines_shapes)) {
- masklay->splines_shapes.first = sel_buffer.first;
- masklay->splines_shapes.last = sel_buffer.last;
-
- continue;
- }
-
- /* loop 2: remove duplicates of splines_shapes in buffers */
- for (masklay_shape = masklay->splines_shapes.first; masklay_shape && sel_buffer.first; masklay_shape = masklay_shape_new) {
- masklay_shape_new = masklay_shape->next;
-
- /* loop through sel_buffer, emptying stuff from front of buffer if ok */
- for (masklay_shape_sort = sel_buffer.first; masklay_shape_sort && masklay_shape; masklay_shape_sort = masklay_shape_sort_new) {
- masklay_shape_sort_new = masklay_shape_sort->next;
-
- /* if this buffer frame needs to go before current, add it! */
- if (masklay_shape_sort->frame < masklay_shape->frame) {
- /* transfer buffer frame to splines_shapes list (before current) */
- BLI_remlink(&sel_buffer, masklay_shape_sort);
- BLI_insertlinkbefore(&masklay->splines_shapes, masklay_shape, masklay_shape_sort);
- }
- /* if this buffer frame is on same frame, replace current with it and stop */
- else if (masklay_shape_sort->frame == masklay_shape->frame) {
- /* transfer buffer frame to splines_shapes list (before current) */
- BLI_remlink(&sel_buffer, masklay_shape_sort);
- BLI_insertlinkbefore(&masklay->splines_shapes, masklay_shape, masklay_shape_sort);
-
- /* get rid of current frame */
+ if (is_double) {
+ for (masklay_shape = masklay->splines_shapes.first; masklay_shape; masklay_shape = masklay_shape_next) {
+ masklay_shape_next = masklay_shape->next;
+ if (masklay_shape_next && masklay_shape->frame == masklay_shape_next->frame) {
BKE_mask_layer_shape_unlink(masklay, masklay_shape);
}
}
}
- /* if anything is still in buffer, append to end */
- for (masklay_shape_sort = sel_buffer.first; masklay_shape_sort; masklay_shape_sort = masklay_shape_sort_new) {
- masklay_shape_sort_new = masklay_shape_sort->next;
-
- BLI_remlink(&sel_buffer, masklay_shape_sort);
- BLI_addtail(&masklay->splines_shapes, masklay_shape_sort);
+#ifdef DEBUG
+ for (masklay_shape = masklay->splines_shapes.first; masklay_shape; masklay_shape = masklay_shape->next) {
+ BLI_assert(!masklay_shape->next || masklay_shape->frame < masklay_shape->next->frame);
}
-
- /* NOTE: this is the only difference to grease pencil code above */
- BKE_mask_layer_shape_sort(masklay);
+#endif
}
}