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:
authorPablo Dobarro <pablodp606@gmail.com>2021-03-24 22:55:05 +0300
committerPablo Dobarro <pablodp606@gmail.com>2021-03-24 22:55:05 +0300
commit20f4fe138e33e1709cc68e3f297c0c60bdbfb6df (patch)
treea1dd030a4344ece3b2b5585797752469e75bb2ee /source/blender/editors
parentecbf642dddc6c29f0e4f04e28055645efa6fc332 (diff)
parent9ac7946dd03fb75bab591c5ed0a742c00b80286b (diff)
Merge branch 'master' into sculpt-dev
Diffstat (limited to 'source/blender/editors')
-rw-r--r--source/blender/editors/curve/editcurve_select.c4
-rw-r--r--source/blender/editors/gpencil/gpencil_utils.c15
-rw-r--r--source/blender/editors/include/ED_gpencil.h1
-rw-r--r--source/blender/editors/interface/interface.c33
-rw-r--r--source/blender/editors/interface/interface_eyedropper.c2
-rw-r--r--source/blender/editors/interface/interface_handlers.c2
-rw-r--r--source/blender/editors/interface/interface_intern.h6
-rw-r--r--source/blender/editors/interface/interface_query.c7
-rw-r--r--source/blender/editors/interface/interface_style.c1
-rw-r--r--source/blender/editors/interface/interface_template_search_menu.c1
-rw-r--r--source/blender/editors/io/CMakeLists.txt15
-rw-r--r--source/blender/editors/io/io_gpencil.h45
-rw-r--r--source/blender/editors/io/io_gpencil_export.c430
-rw-r--r--source/blender/editors/io/io_gpencil_import.c195
-rw-r--r--source/blender/editors/io/io_gpencil_utils.c64
-rw-r--r--source/blender/editors/io/io_ops.c11
-rw-r--r--source/blender/editors/object/object_add.c36
-rw-r--r--source/blender/editors/space_file/filelist.c2
-rw-r--r--source/blender/editors/space_node/drawnode.c4
-rw-r--r--source/blender/editors/space_node/node_add.c15
-rw-r--r--source/blender/editors/space_outliner/tree/tree_display_view_layer.cc8
-rw-r--r--source/blender/editors/space_outliner/tree/tree_element_overrides.hh2
-rw-r--r--source/blender/editors/transform/transform_convert_mesh.c217
-rw-r--r--source/blender/editors/util/ed_util.c2
-rw-r--r--source/blender/editors/util/select_utils.c4
-rw-r--r--source/blender/editors/uvedit/uvedit_rip.c4
-rw-r--r--source/blender/editors/uvedit/uvedit_select.c2
27 files changed, 956 insertions, 172 deletions
diff --git a/source/blender/editors/curve/editcurve_select.c b/source/blender/editors/curve/editcurve_select.c
index d362ec23370..e3fc8b73172 100644
--- a/source/blender/editors/curve/editcurve_select.c
+++ b/source/blender/editors/curve/editcurve_select.c
@@ -578,8 +578,8 @@ static int de_select_all_exec(bContext *C, wmOperator *op)
changed = ED_curve_deselect_all(cu->editnurb);
break;
case SEL_INVERT:
- changed = ED_curve_select_swap(cu->editnurb,
- v3d->overlay.handle_display == CURVE_HANDLE_NONE);
+ changed = ED_curve_select_swap(
+ cu->editnurb, (v3d && (v3d->overlay.handle_display == CURVE_HANDLE_NONE)));
break;
}
diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c
index 5c041134a74..574670de7ca 100644
--- a/source/blender/editors/gpencil/gpencil_utils.c
+++ b/source/blender/editors/gpencil/gpencil_utils.c
@@ -596,6 +596,21 @@ bool ED_gpencil_stroke_material_editable(Object *ob, const bGPDlayer *gpl, const
return true;
}
+/* Check whether given stroke is visible for the current material. */
+bool ED_gpencil_stroke_material_visible(Object *ob, const bGPDstroke *gps)
+{
+ /* check if the color is editable */
+ MaterialGPencilStyle *gp_style = BKE_gpencil_material_settings(ob, gps->mat_nr + 1);
+
+ if (gp_style != NULL) {
+ if (gp_style->flag & GP_MATERIAL_HIDE) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
/* ******************************************************** */
/* Space Conversion */
diff --git a/source/blender/editors/include/ED_gpencil.h b/source/blender/editors/include/ED_gpencil.h
index f3b5abb1072..e9ac21f60cf 100644
--- a/source/blender/editors/include/ED_gpencil.h
+++ b/source/blender/editors/include/ED_gpencil.h
@@ -150,6 +150,7 @@ bool ED_gpencil_stroke_can_use(const struct bContext *C, const struct bGPDstroke
bool ED_gpencil_stroke_material_editable(struct Object *ob,
const struct bGPDlayer *gpl,
const struct bGPDstroke *gps);
+bool ED_gpencil_stroke_material_visible(struct Object *ob, const struct bGPDstroke *gps);
/* ----------- Grease Pencil Operators ----------------- */
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index fbd7dcd61f2..279239fcc65 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -1816,6 +1816,29 @@ static void ui_but_validate(const uiBut *but)
}
#endif
+/**
+ * Check if the operator \a ot poll is successfull with the context given by \a but (optionally).
+ * \param but: The button that might store context. Can be NULL for convenience (e.g. if there is
+ * no button to take context from, but we still want to poll the operator).
+ */
+bool ui_but_context_poll_operator(bContext *C, wmOperatorType *ot, const uiBut *but)
+{
+ bool result;
+ int opcontext = but ? but->opcontext : WM_OP_INVOKE_DEFAULT;
+
+ if (but && but->context) {
+ CTX_store_set(C, but->context);
+ }
+
+ result = WM_operator_poll_context(C, ot, opcontext);
+
+ if (but && but->context) {
+ CTX_store_set(C, NULL);
+ }
+
+ return result;
+}
+
void UI_block_end_ex(const bContext *C, uiBlock *block, const int xy[2], int r_xy[2])
{
wmWindow *window = CTX_wm_window(C);
@@ -1841,17 +1864,9 @@ void UI_block_end_ex(const bContext *C, uiBlock *block, const int xy[2], int r_x
if (but->optype) {
wmOperatorType *ot = but->optype;
- if (but->context) {
- CTX_store_set((bContext *)C, but->context);
- }
-
- if (ot == NULL || WM_operator_poll_context((bContext *)C, ot, but->opcontext) == 0) {
+ if (ot == NULL || !ui_but_context_poll_operator((bContext *)C, ot, but)) {
but->flag |= UI_BUT_DISABLED;
}
-
- if (but->context) {
- CTX_store_set((bContext *)C, NULL);
- }
}
const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(
diff --git a/source/blender/editors/interface/interface_eyedropper.c b/source/blender/editors/interface/interface_eyedropper.c
index fb8d32b3b84..178f663ff58 100644
--- a/source/blender/editors/interface/interface_eyedropper.c
+++ b/source/blender/editors/interface/interface_eyedropper.c
@@ -153,7 +153,7 @@ uiBut *eyedropper_get_property_button_under_mouse(bContext *C, const wmEvent *ev
{
bScreen *screen = CTX_wm_screen(C);
ScrArea *area = BKE_screen_find_area_xy(screen, SPACE_TYPE_ANY, event->x, event->y);
- ARegion *region = BKE_area_find_region_xy(area, RGN_TYPE_ANY, event->x, event->y);
+ const ARegion *region = BKE_area_find_region_xy(area, RGN_TYPE_ANY, event->x, event->y);
uiBut *but = ui_but_find_mouse_over(region, event);
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index ee5c3f53f5e..a5a5a69728e 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -1594,7 +1594,7 @@ static int ui_handler_region_drag_toggle(bContext *C, const wmEvent *event, void
if (done) {
wmWindow *win = CTX_wm_window(C);
- ARegion *region = CTX_wm_region(C);
+ const ARegion *region = CTX_wm_region(C);
uiBut *but = ui_but_find_mouse_over_ex(
region, drag_info->xy_init[0], drag_info->xy_init[1], true);
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index 1d4a44e0c76..4c96512b4f3 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -647,6 +647,8 @@ extern bool ui_but_menu_draw_as_popover(const uiBut *but);
void ui_but_range_set_hard(uiBut *but);
void ui_but_range_set_soft(uiBut *but);
+bool ui_but_context_poll_operator(struct bContext *C, struct wmOperatorType *ot, const uiBut *but);
+
extern void ui_but_update(uiBut *but);
extern void ui_but_update_edited(uiBut *but);
extern bool ui_but_is_float(const uiBut *but) ATTR_WARN_UNUSED_RESULT;
@@ -1108,11 +1110,11 @@ bool ui_but_contains_point_px(const uiBut *but, const struct ARegion *region, in
uiBut *ui_list_find_mouse_over(struct ARegion *region,
const struct wmEvent *event) ATTR_WARN_UNUSED_RESULT;
-uiBut *ui_but_find_mouse_over_ex(struct ARegion *region,
+uiBut *ui_but_find_mouse_over_ex(const struct ARegion *region,
const int x,
const int y,
const bool labeledit) ATTR_WARN_UNUSED_RESULT;
-uiBut *ui_but_find_mouse_over(struct ARegion *region,
+uiBut *ui_but_find_mouse_over(const struct ARegion *region,
const struct wmEvent *event) ATTR_WARN_UNUSED_RESULT;
uiBut *ui_but_find_rect_over(const struct ARegion *region,
const rcti *rect_px) ATTR_WARN_UNUSED_RESULT;
diff --git a/source/blender/editors/interface/interface_query.c b/source/blender/editors/interface/interface_query.c
index 83e48fad157..aa10d092f5e 100644
--- a/source/blender/editors/interface/interface_query.c
+++ b/source/blender/editors/interface/interface_query.c
@@ -265,7 +265,10 @@ bool ui_but_contains_point_px_icon(const uiBut *but, ARegion *region, const wmEv
}
/* x and y are only used in case event is NULL... */
-uiBut *ui_but_find_mouse_over_ex(ARegion *region, const int x, const int y, const bool labeledit)
+uiBut *ui_but_find_mouse_over_ex(const ARegion *region,
+ const int x,
+ const int y,
+ const bool labeledit)
{
uiBut *butover = NULL;
@@ -303,7 +306,7 @@ uiBut *ui_but_find_mouse_over_ex(ARegion *region, const int x, const int y, cons
return butover;
}
-uiBut *ui_but_find_mouse_over(ARegion *region, const wmEvent *event)
+uiBut *ui_but_find_mouse_over(const ARegion *region, const wmEvent *event)
{
return ui_but_find_mouse_over_ex(region, event->x, event->y, event->ctrl != 0);
}
diff --git a/source/blender/editors/interface/interface_style.c b/source/blender/editors/interface/interface_style.c
index eaefc2c3736..ad0c523a594 100644
--- a/source/blender/editors/interface/interface_style.c
+++ b/source/blender/editors/interface/interface_style.c
@@ -23,6 +23,7 @@
#include <limits.h>
#include <math.h>
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
diff --git a/source/blender/editors/interface/interface_template_search_menu.c b/source/blender/editors/interface/interface_template_search_menu.c
index 74668b2f3a3..ff42d434f29 100644
--- a/source/blender/editors/interface/interface_template_search_menu.c
+++ b/source/blender/editors/interface/interface_template_search_menu.c
@@ -21,6 +21,7 @@
* Accessed via the #WM_OT_search_menu operator.
*/
+#include <stdio.h>
#include <string.h>
#include "MEM_guardedalloc.h"
diff --git a/source/blender/editors/io/CMakeLists.txt b/source/blender/editors/io/CMakeLists.txt
index e7effd05d34..d45c7ca9b75 100644
--- a/source/blender/editors/io/CMakeLists.txt
+++ b/source/blender/editors/io/CMakeLists.txt
@@ -24,6 +24,7 @@ set(INC
../../depsgraph
../../io/alembic
../../io/collada
+ ../../io/gpencil
../../io/usd
../../makesdna
../../makesrna
@@ -39,12 +40,16 @@ set(SRC
io_alembic.c
io_cache.c
io_collada.c
+ io_gpencil_import.c
+ io_gpencil_export.c
+ io_gpencil_utils.c
io_ops.c
io_usd.c
io_alembic.h
io_cache.h
io_collada.h
+ io_gpencil.h
io_ops.h
io_usd.h
)
@@ -79,4 +84,14 @@ if(WITH_INTERNATIONAL)
add_definitions(-DWITH_INTERNATIONAL)
endif()
+if(WITH_PUGIXML)
+ add_definitions(-DWITH_PUGIXML)
+endif()
+
+if(WITH_HARU)
+ add_definitions(-DWITH_HARU)
+endif()
+
+list(APPEND LIB bf_gpencil)
+
blender_add_lib(bf_editor_io "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/editors/io/io_gpencil.h b/source/blender/editors/io/io_gpencil.h
new file mode 100644
index 00000000000..98cb8b13310
--- /dev/null
+++ b/source/blender/editors/io/io_gpencil.h
@@ -0,0 +1,45 @@
+/*
+ * 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) 2020 Blender Foundation.
+ * All rights reserved.
+ */
+
+#ifndef __IO_GPENCIL_H__
+#define __IO_GPENCIL_H__
+
+/** \file
+ * \ingroup editor/io
+ */
+
+struct ARegion;
+struct bContext;
+struct View3D;
+struct wmOperator;
+struct wmOperatorType;
+
+void WM_OT_gpencil_import_svg(struct wmOperatorType *ot);
+
+#ifdef WITH_PUGIXML
+void WM_OT_gpencil_export_svg(struct wmOperatorType *ot);
+#endif
+#ifdef WITH_HARU
+void WM_OT_gpencil_export_pdf(struct wmOperatorType *ot);
+#endif
+
+struct ARegion *get_invoke_region(struct bContext *C);
+struct View3D *get_invoke_view3d(struct bContext *C);
+
+#endif /* __IO_GPENCIL_H__ */
diff --git a/source/blender/editors/io/io_gpencil_export.c b/source/blender/editors/io/io_gpencil_export.c
new file mode 100644
index 00000000000..98e30f51116
--- /dev/null
+++ b/source/blender/editors/io/io_gpencil_export.c
@@ -0,0 +1,430 @@
+/*
+ * 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) 2020 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup editor/io
+ */
+
+#include "BLI_path_util.h"
+#include "BLI_string.h"
+
+#include "DNA_gpencil_types.h"
+#include "DNA_space_types.h"
+
+#include "BKE_gpencil.h"
+#include "BKE_main.h"
+#include "BKE_report.h"
+#include "BKE_screen.h"
+
+#include "BLT_translation.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
+
+#include "io_gpencil.h"
+
+#include "gpencil_io.h"
+
+/* Definition of enum elements to export. */
+/* Common props for exporting. */
+static void gpencil_export_common_props_definition(wmOperatorType *ot)
+{
+ static const EnumPropertyItem select_items[] = {
+ {GP_EXPORT_ACTIVE, "ACTIVE", 0, "Active", "Include only the active object"},
+ {GP_EXPORT_SELECTED, "SELECTED", 0, "Selected", "Include selected objects"},
+ {GP_EXPORT_VISIBLE, "VISIBLE", 0, "Visible", "Include all visible objects"},
+ {0, NULL, 0, NULL, NULL},
+ };
+
+ RNA_def_boolean(ot->srna, "use_fill", true, "Fill", "Export strokes with fill enabled");
+ RNA_def_enum(ot->srna,
+ "selected_object_type",
+ select_items,
+ GP_EXPORT_SELECTED,
+ "Object",
+ "Which objects to include in the export");
+ RNA_def_float(ot->srna,
+ "stroke_sample",
+ 0.0f,
+ 0.0f,
+ 100.0f,
+ "Sampling",
+ "Precision of stroke sampling. Low values mean a more precise result, and zero "
+ "disables sampling",
+ 0.0f,
+ 100.0f);
+ RNA_def_boolean(ot->srna,
+ "use_normalized_thickness",
+ false,
+ "Normalize",
+ "Export strokes with constant thickness");
+}
+
+static void set_export_filepath(bContext *C, wmOperator *op, const char *extension)
+{
+ if (!RNA_struct_property_is_set(op->ptr, "filepath")) {
+ Main *bmain = CTX_data_main(C);
+ char filepath[FILE_MAX];
+
+ if (BKE_main_blendfile_path(bmain)[0] == '\0') {
+ BLI_strncpy(filepath, "untitled", sizeof(filepath));
+ }
+ else {
+ BLI_strncpy(filepath, BKE_main_blendfile_path(bmain), sizeof(filepath));
+ }
+
+ BLI_path_extension_replace(filepath, sizeof(filepath), extension);
+ RNA_string_set(op->ptr, "filepath", filepath);
+ }
+}
+
+/* <-------- SVG single frame export. --------> */
+#ifdef WITH_PUGIXML
+static bool wm_gpencil_export_svg_common_check(bContext *UNUSED(C), wmOperator *op)
+{
+ char filepath[FILE_MAX];
+ RNA_string_get(op->ptr, "filepath", filepath);
+
+ if (!BLI_path_extension_check(filepath, ".svg")) {
+ BLI_path_extension_ensure(filepath, FILE_MAX, ".svg");
+ RNA_string_set(op->ptr, "filepath", filepath);
+ return true;
+ }
+
+ return false;
+}
+
+static int wm_gpencil_export_svg_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+{
+ set_export_filepath(C, op, ".svg");
+
+ WM_event_add_fileselect(C, op);
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+static int wm_gpencil_export_svg_exec(bContext *C, wmOperator *op)
+{
+ Scene *scene = CTX_data_scene(C);
+ Object *ob = CTX_data_active_object(C);
+
+ if (!RNA_struct_property_is_set(op->ptr, "filepath")) {
+ BKE_report(op->reports, RPT_ERROR, "No filename given");
+ return OPERATOR_CANCELLED;
+ }
+
+ ARegion *region = get_invoke_region(C);
+ if (region == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "Unable to find valid 3D View area");
+ return OPERATOR_CANCELLED;
+ }
+ View3D *v3d = get_invoke_view3d(C);
+
+ char filename[FILE_MAX];
+ RNA_string_get(op->ptr, "filepath", filename);
+
+ const bool use_fill = RNA_boolean_get(op->ptr, "use_fill");
+ const bool use_norm_thickness = RNA_boolean_get(op->ptr, "use_normalized_thickness");
+ const eGpencilExportSelect select_mode = RNA_enum_get(op->ptr, "selected_object_type");
+
+ const bool use_clip_camera = RNA_boolean_get(op->ptr, "use_clip_camera");
+
+ /* Set flags. */
+ int flag = 0;
+ SET_FLAG_FROM_TEST(flag, use_fill, GP_EXPORT_FILL);
+ SET_FLAG_FROM_TEST(flag, use_norm_thickness, GP_EXPORT_NORM_THICKNESS);
+ SET_FLAG_FROM_TEST(flag, use_clip_camera, GP_EXPORT_CLIP_CAMERA);
+
+ GpencilIOParams params = {.C = C,
+ .region = region,
+ .v3d = v3d,
+ .ob = ob,
+ .mode = GP_EXPORT_TO_SVG,
+ .frame_start = CFRA,
+ .frame_end = CFRA,
+ .frame_cur = CFRA,
+ .flag = flag,
+ .scale = 1.0f,
+ .select_mode = select_mode,
+ .frame_mode = GP_EXPORT_FRAME_ACTIVE,
+ .stroke_sample = RNA_float_get(op->ptr, "stroke_sample"),
+ .resolution = 1.0f};
+
+ /* Do export. */
+ WM_cursor_wait(true);
+ const bool done = gpencil_io_export(filename, &params);
+ WM_cursor_wait(false);
+
+ if (!done) {
+ BKE_report(op->reports, RPT_WARNING, "Unable to export SVG");
+ }
+
+ return OPERATOR_FINISHED;
+}
+
+static void ui_gpencil_export_svg_settings(uiLayout *layout, PointerRNA *imfptr)
+{
+ uiLayout *box, *row;
+
+ uiLayoutSetPropSep(layout, true);
+ uiLayoutSetPropDecorate(layout, false);
+
+ box = uiLayoutBox(layout);
+
+ row = uiLayoutRow(box, false);
+ uiItemL(row, IFACE_("Scene Options"), ICON_NONE);
+
+ row = uiLayoutRow(box, false);
+ uiItemR(row, imfptr, "selected_object_type", 0, NULL, ICON_NONE);
+
+ box = uiLayoutBox(layout);
+ row = uiLayoutRow(box, false);
+ uiItemL(row, IFACE_("Export Options"), ICON_NONE);
+
+ uiLayout *col = uiLayoutColumn(box, false);
+ uiItemR(col, imfptr, "stroke_sample", 0, NULL, ICON_NONE);
+ uiItemR(col, imfptr, "use_fill", 0, NULL, ICON_NONE);
+ uiItemR(col, imfptr, "use_normalized_thickness", 0, NULL, ICON_NONE);
+ uiItemR(col, imfptr, "use_clip_camera", 0, NULL, ICON_NONE);
+}
+
+static void wm_gpencil_export_svg_draw(bContext *UNUSED(C), wmOperator *op)
+{
+ PointerRNA ptr;
+
+ RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr);
+
+ ui_gpencil_export_svg_settings(op->layout, &ptr);
+}
+
+static bool wm_gpencil_export_svg_poll(bContext *C)
+{
+ if ((CTX_wm_window(C) == NULL) || (CTX_data_mode_enum(C) != CTX_MODE_OBJECT)) {
+ return false;
+ }
+
+ return true;
+}
+
+void WM_OT_gpencil_export_svg(wmOperatorType *ot)
+{
+ ot->name = "Export to SVG";
+ ot->description = "Export grease pencil to SVG";
+ ot->idname = "WM_OT_gpencil_export_svg";
+
+ ot->invoke = wm_gpencil_export_svg_invoke;
+ ot->exec = wm_gpencil_export_svg_exec;
+ ot->poll = wm_gpencil_export_svg_poll;
+ ot->ui = wm_gpencil_export_svg_draw;
+ ot->check = wm_gpencil_export_svg_common_check;
+
+ WM_operator_properties_filesel(ot,
+ FILE_TYPE_OBJECT_IO,
+ FILE_BLENDER,
+ FILE_SAVE,
+ WM_FILESEL_FILEPATH | WM_FILESEL_SHOW_PROPS,
+ FILE_DEFAULTDISPLAY,
+ FILE_SORT_ALPHA);
+
+ gpencil_export_common_props_definition(ot);
+
+ RNA_def_boolean(ot->srna,
+ "use_clip_camera",
+ false,
+ "Clip Camera",
+ "Clip drawings to camera size when export in camera view");
+}
+#endif
+
+/* <-------- PDF single frame export. --------> */
+#ifdef WITH_HARU
+static bool wm_gpencil_export_pdf_common_check(bContext *UNUSED(C), wmOperator *op)
+{
+
+ char filepath[FILE_MAX];
+ RNA_string_get(op->ptr, "filepath", filepath);
+
+ if (!BLI_path_extension_check(filepath, ".pdf")) {
+ BLI_path_extension_ensure(filepath, FILE_MAX, ".pdf");
+ RNA_string_set(op->ptr, "filepath", filepath);
+ return true;
+ }
+
+ return false;
+}
+
+static int wm_gpencil_export_pdf_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+{
+ set_export_filepath(C, op, ".pdf");
+
+ WM_event_add_fileselect(C, op);
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+static int wm_gpencil_export_pdf_exec(bContext *C, wmOperator *op)
+{
+ Scene *scene = CTX_data_scene(C);
+ Object *ob = CTX_data_active_object(C);
+
+ if (!RNA_struct_property_is_set(op->ptr, "filepath")) {
+ BKE_report(op->reports, RPT_ERROR, "No filename given");
+ return OPERATOR_CANCELLED;
+ }
+
+ ARegion *region = get_invoke_region(C);
+ if (region == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "Unable to find valid 3D View area");
+ return OPERATOR_CANCELLED;
+ }
+ View3D *v3d = get_invoke_view3d(C);
+
+ char filename[FILE_MAX];
+ RNA_string_get(op->ptr, "filepath", filename);
+
+ const bool use_fill = RNA_boolean_get(op->ptr, "use_fill");
+ const bool use_norm_thickness = RNA_boolean_get(op->ptr, "use_normalized_thickness");
+ const short select_mode = RNA_enum_get(op->ptr, "selected_object_type");
+ const short frame_mode = RNA_enum_get(op->ptr, "frame_mode");
+
+ /* Set flags. */
+ int flag = 0;
+ SET_FLAG_FROM_TEST(flag, use_fill, GP_EXPORT_FILL);
+ SET_FLAG_FROM_TEST(flag, use_norm_thickness, GP_EXPORT_NORM_THICKNESS);
+
+ GpencilIOParams params = {.C = C,
+ .region = region,
+ .v3d = v3d,
+ .ob = ob,
+ .mode = GP_EXPORT_TO_PDF,
+ .frame_start = SFRA,
+ .frame_end = EFRA,
+ .frame_cur = CFRA,
+ .flag = flag,
+ .scale = 1.0f,
+ .select_mode = select_mode,
+ .frame_mode = frame_mode,
+ .stroke_sample = RNA_float_get(op->ptr, "stroke_sample"),
+ .resolution = 1.0f};
+
+ /* Do export. */
+ WM_cursor_wait(true);
+ const bool done = gpencil_io_export(filename, &params);
+ WM_cursor_wait(false);
+
+ if (!done) {
+ BKE_report(op->reports, RPT_WARNING, "Unable to export PDF");
+ }
+
+ return OPERATOR_FINISHED;
+}
+
+static void ui_gpencil_export_pdf_settings(uiLayout *layout, PointerRNA *imfptr)
+{
+ uiLayout *box, *row, *col, *sub;
+
+ uiLayoutSetPropSep(layout, true);
+ uiLayoutSetPropDecorate(layout, false);
+
+ box = uiLayoutBox(layout);
+
+ row = uiLayoutRow(box, false);
+ uiItemL(row, IFACE_("Scene Options"), ICON_NONE);
+
+ row = uiLayoutRow(box, false);
+ uiItemR(row, imfptr, "selected_object_type", 0, NULL, ICON_NONE);
+
+ box = uiLayoutBox(layout);
+ row = uiLayoutRow(box, false);
+ uiItemL(row, IFACE_("Export Options"), ICON_NONE);
+
+ col = uiLayoutColumn(box, false);
+ sub = uiLayoutColumn(col, true);
+ uiItemR(sub, imfptr, "frame_mode", 0, IFACE_("Frame"), ICON_NONE);
+
+ uiLayoutSetPropSep(box, true);
+
+ sub = uiLayoutColumn(col, true);
+ uiItemR(sub, imfptr, "stroke_sample", 0, NULL, ICON_NONE);
+ uiItemR(sub, imfptr, "use_fill", 0, NULL, ICON_NONE);
+ uiItemR(sub, imfptr, "use_normalized_thickness", 0, NULL, ICON_NONE);
+}
+
+static void wm_gpencil_export_pdf_draw(bContext *UNUSED(C), wmOperator *op)
+{
+ PointerRNA ptr;
+
+ RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr);
+
+ ui_gpencil_export_pdf_settings(op->layout, &ptr);
+}
+
+static bool wm_gpencil_export_pdf_poll(bContext *C)
+{
+ if ((CTX_wm_window(C) == NULL) || (CTX_data_mode_enum(C) != CTX_MODE_OBJECT)) {
+ return false;
+ }
+
+ return true;
+}
+
+void WM_OT_gpencil_export_pdf(wmOperatorType *ot)
+{
+ ot->name = "Export to PDF";
+ ot->description = "Export grease pencil to PDF";
+ ot->idname = "WM_OT_gpencil_export_pdf";
+
+ ot->invoke = wm_gpencil_export_pdf_invoke;
+ ot->exec = wm_gpencil_export_pdf_exec;
+ ot->poll = wm_gpencil_export_pdf_poll;
+ ot->ui = wm_gpencil_export_pdf_draw;
+ ot->check = wm_gpencil_export_pdf_common_check;
+
+ WM_operator_properties_filesel(ot,
+ FILE_TYPE_OBJECT_IO,
+ FILE_BLENDER,
+ FILE_SAVE,
+ WM_FILESEL_FILEPATH | WM_FILESEL_SHOW_PROPS,
+ FILE_DEFAULTDISPLAY,
+ FILE_SORT_ALPHA);
+
+ static const EnumPropertyItem gpencil_export_frame_items[] = {
+ {GP_EXPORT_FRAME_ACTIVE, "ACTIVE", 0, "Active", "Include only active frame"},
+ {GP_EXPORT_FRAME_SELECTED, "SELECTED", 0, "Selected", "Include selected frames"},
+ {0, NULL, 0, NULL, NULL},
+ };
+
+ gpencil_export_common_props_definition(ot);
+ ot->prop = RNA_def_enum(ot->srna,
+ "frame_mode",
+ gpencil_export_frame_items,
+ GP_EXPORT_ACTIVE,
+ "Frames",
+ "Which frames to include in the export");
+}
+#endif
diff --git a/source/blender/editors/io/io_gpencil_import.c b/source/blender/editors/io/io_gpencil_import.c
new file mode 100644
index 00000000000..9768da85940
--- /dev/null
+++ b/source/blender/editors/io/io_gpencil_import.c
@@ -0,0 +1,195 @@
+/*
+ * 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) 2020 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup editor/io
+ */
+
+#include "BLI_path_util.h"
+
+#include "DNA_gpencil_types.h"
+#include "DNA_space_types.h"
+
+#include "BKE_context.h"
+#include "BKE_gpencil.h"
+#include "BKE_report.h"
+
+#include "BLT_translation.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
+
+#include "ED_gpencil.h"
+
+#include "io_gpencil.h"
+
+#include "gpencil_io.h"
+
+/* <-------- SVG single frame import. --------> */
+static bool wm_gpencil_import_svg_common_check(bContext *UNUSED(C), wmOperator *op)
+{
+
+ char filepath[FILE_MAX];
+ RNA_string_get(op->ptr, "filepath", filepath);
+
+ if (!BLI_path_extension_check(filepath, ".svg")) {
+ BLI_path_extension_ensure(filepath, FILE_MAX, ".svg");
+ RNA_string_set(op->ptr, "filepath", filepath);
+ return true;
+ }
+
+ return false;
+}
+
+static int wm_gpencil_import_svg_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+{
+ WM_event_add_fileselect(C, op);
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+static int wm_gpencil_import_svg_exec(bContext *C, wmOperator *op)
+{
+ Scene *scene = CTX_data_scene(C);
+
+ if (!RNA_struct_property_is_set(op->ptr, "filepath")) {
+ BKE_report(op->reports, RPT_ERROR, "No filename given");
+ return OPERATOR_CANCELLED;
+ }
+
+ ARegion *region = get_invoke_region(C);
+ if (region == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "Unable to find valid 3D View area");
+ return OPERATOR_CANCELLED;
+ }
+ View3D *v3d = get_invoke_view3d(C);
+
+ char filename[FILE_MAX];
+ RNA_string_get(op->ptr, "filepath", filename);
+
+ /* Set flags. */
+ int flag = 0;
+
+ const int resolution = RNA_int_get(op->ptr, "resolution");
+ const float scale = RNA_float_get(op->ptr, "scale");
+
+ GpencilIOParams params = {
+ .C = C,
+ .region = region,
+ .v3d = v3d,
+ .ob = NULL,
+ .mode = GP_IMPORT_FROM_SVG,
+ .frame_start = CFRA,
+ .frame_end = CFRA,
+ .frame_cur = CFRA,
+ .flag = flag,
+ .scale = scale,
+ .select_mode = 0,
+ .frame_mode = 0,
+ .stroke_sample = 0.0f,
+ .resolution = resolution,
+ };
+
+ /* Do Import. */
+ WM_cursor_wait(1);
+ const bool done = gpencil_io_import(filename, &params);
+ WM_cursor_wait(0);
+
+ if (!done) {
+ BKE_report(op->reports, RPT_WARNING, "Unable to import SVG");
+ }
+
+ return OPERATOR_FINISHED;
+}
+
+static void ui_gpencil_import_svg_settings(uiLayout *layout, PointerRNA *imfptr)
+{
+ uiLayoutSetPropSep(layout, true);
+ uiLayoutSetPropDecorate(layout, false);
+ uiLayout *col = uiLayoutColumn(layout, false);
+ uiItemR(col, imfptr, "resolution", 0, NULL, ICON_NONE);
+ uiItemR(col, imfptr, "scale", 0, NULL, ICON_NONE);
+}
+
+static void wm_gpencil_import_svg_draw(bContext *UNUSED(C), wmOperator *op)
+{
+ PointerRNA ptr;
+ RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr);
+
+ ui_gpencil_import_svg_settings(op->layout, &ptr);
+}
+
+static bool wm_gpencil_import_svg_poll(bContext *C)
+{
+ if ((CTX_wm_window(C) == NULL) || (CTX_data_mode_enum(C) != CTX_MODE_OBJECT)) {
+ return false;
+ }
+
+ return true;
+}
+
+void WM_OT_gpencil_import_svg(wmOperatorType *ot)
+{
+ ot->name = "Import SVG";
+ ot->description = "Import SVG into grease pencil";
+ ot->idname = "WM_OT_gpencil_import_svg";
+
+ ot->invoke = wm_gpencil_import_svg_invoke;
+ ot->exec = wm_gpencil_import_svg_exec;
+ ot->poll = wm_gpencil_import_svg_poll;
+ ot->ui = wm_gpencil_import_svg_draw;
+ ot->check = wm_gpencil_import_svg_common_check;
+
+ WM_operator_properties_filesel(ot,
+ FILE_TYPE_OBJECT_IO,
+ FILE_BLENDER,
+ FILE_OPENFILE,
+ WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH | WM_FILESEL_SHOW_PROPS,
+ FILE_DEFAULTDISPLAY,
+ FILE_SORT_DEFAULT);
+
+ RNA_def_int(ot->srna,
+ "resolution",
+ 10,
+ 1,
+ 30,
+ "Resolution",
+ "Resolution of the generated strokes",
+ 1,
+ 20);
+
+ RNA_def_float(ot->srna,
+ "scale",
+ 10.0f,
+ 0.001f,
+ 100.0f,
+ "Scale",
+ "Scale of the final strokes",
+ 0.001f,
+ 100.0f);
+}
diff --git a/source/blender/editors/io/io_gpencil_utils.c b/source/blender/editors/io/io_gpencil_utils.c
new file mode 100644
index 00000000000..259a669519a
--- /dev/null
+++ b/source/blender/editors/io/io_gpencil_utils.c
@@ -0,0 +1,64 @@
+/*
+ * 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) 2020 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup editor/io
+ */
+
+#include "DNA_space_types.h"
+
+#include "BKE_context.h"
+#include "BKE_screen.h"
+
+#include "WM_api.h"
+
+#include "io_gpencil.h"
+
+ARegion *get_invoke_region(bContext *C)
+{
+ bScreen *screen = CTX_wm_screen(C);
+ if (screen == NULL) {
+ return NULL;
+ }
+ ScrArea *area = BKE_screen_find_big_area(screen, SPACE_VIEW3D, 0);
+ if (area == NULL) {
+ return NULL;
+ }
+
+ ARegion *region = BKE_area_find_region_type(area, RGN_TYPE_WINDOW);
+
+ return region;
+}
+
+View3D *get_invoke_view3d(bContext *C)
+{
+ bScreen *screen = CTX_wm_screen(C);
+ if (screen == NULL) {
+ return NULL;
+ }
+ ScrArea *area = BKE_screen_find_big_area(screen, SPACE_VIEW3D, 0);
+ if (area == NULL) {
+ return NULL;
+ }
+ if (area) {
+ return area->spacedata.first;
+ }
+
+ return NULL;
+}
diff --git a/source/blender/editors/io/io_ops.c b/source/blender/editors/io/io_ops.c
index acb511a414d..9fa34a1c55d 100644
--- a/source/blender/editors/io/io_ops.c
+++ b/source/blender/editors/io/io_ops.c
@@ -38,6 +38,7 @@
#endif
#include "io_cache.h"
+#include "io_gpencil.h"
void ED_operatortypes_io(void)
{
@@ -54,6 +55,16 @@ void ED_operatortypes_io(void)
WM_operatortype_append(WM_OT_usd_export);
#endif
+ WM_operatortype_append(WM_OT_gpencil_import_svg);
+
+#ifdef WITH_PUGIXML
+ WM_operatortype_append(WM_OT_gpencil_export_svg);
+#endif
+
+#ifdef WITH_HARU
+ WM_operatortype_append(WM_OT_gpencil_export_pdf);
+#endif
+
WM_operatortype_append(CACHEFILE_OT_open);
WM_operatortype_append(CACHEFILE_OT_reload);
}
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index e4527740164..50dc1af5ca8 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -1440,41 +1440,6 @@ static int object_gpencil_add_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static const EnumPropertyItem *object_gpencil_add_options(bContext *C,
- PointerRNA *UNUSED(ptr),
- PropertyRNA *UNUSED(prop),
- bool *r_free)
-{
- EnumPropertyItem *item = NULL;
- const EnumPropertyItem *item_ref = rna_enum_object_gpencil_type_items;
- int totitem = 0;
- int i = 0;
- int orig_count = RNA_enum_items_count(item_ref);
-
- /* Default types. */
- for (i = 0; i < orig_count; i++) {
- if (item_ref[i].value == GP_LRT_OBJECT || item_ref[i].value == GP_LRT_COLLECTION ||
- item_ref[i].value == GP_LRT_SCENE) {
- if (item_ref[i].value == GP_LRT_SCENE) {
- /* separator before line art types */
- RNA_enum_item_add_separator(&item, &totitem);
- }
- else if (item_ref[i].value == GP_LRT_OBJECT) {
- Object *ob = CTX_data_active_object(C);
- if (!ob || ob->type != OB_MESH) {
- continue;
- }
- }
- }
- RNA_enum_item_add(&item, &totitem, &item_ref[i]);
- }
-
- RNA_enum_item_end(&item, &totitem);
- *r_free = true;
-
- return item;
-}
-
void OBJECT_OT_gpencil_add(wmOperatorType *ot)
{
/* identifiers */
@@ -1495,7 +1460,6 @@ void OBJECT_OT_gpencil_add(wmOperatorType *ot)
ED_object_add_generic_props(ot, false);
ot->prop = RNA_def_enum(ot->srna, "type", rna_enum_object_gpencil_type_items, 0, "Type", "");
- RNA_def_enum_funcs(ot->prop, object_gpencil_add_options);
}
/** \} */
diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c
index f5ec9a0e8a1..4c9f80bfa64 100644
--- a/source/blender/editors/space_file/filelist.c
+++ b/source/blender/editors/space_file/filelist.c
@@ -2543,7 +2543,7 @@ int ED_path_extension_type(const char *path)
if (BLI_path_extension_check(path, ".zip")) {
return FILE_TYPE_ARCHIVE;
}
- if (BLI_path_extension_check_n(path, ".obj", ".3ds", ".fbx", ".glb", ".gltf", NULL)) {
+ if (BLI_path_extension_check_n(path, ".obj", ".3ds", ".fbx", ".glb", ".gltf", ".svg", NULL)) {
return FILE_TYPE_OBJECT_IO;
}
if (BLI_path_extension_check_array(path, imb_ext_image)) {
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index 1354c06305c..6864d34885a 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -3429,13 +3429,13 @@ static void std_node_socket_draw(
}
break;
case SOCK_RGBA: {
- uiLayout *row = uiLayoutSplit(layout, 0.5f, false);
+ uiLayout *row = uiLayoutSplit(layout, 0.4f, false);
uiItemL(row, text, 0);
uiItemR(row, ptr, "default_value", DEFAULT_FLAGS, "", 0);
break;
}
case SOCK_STRING: {
- uiLayout *row = uiLayoutSplit(layout, 0.5f, false);
+ uiLayout *row = uiLayoutSplit(layout, 0.4f, false);
uiItemL(row, text, 0);
const bNodeTree *node_tree = (const bNodeTree *)node_ptr->owner_id;
diff --git a/source/blender/editors/space_node/node_add.c b/source/blender/editors/space_node/node_add.c
index a646804e0fd..c4fe9e9e531 100644
--- a/source/blender/editors/space_node/node_add.c
+++ b/source/blender/editors/space_node/node_add.c
@@ -472,6 +472,8 @@ static int node_add_object_exec(bContext *C, wmOperator *op)
snode_notify(C, snode);
snode_dag_update(C, snode);
+ ED_node_tag_update_nodetree(bmain, ntree, object_node);
+
return OPERATOR_FINISHED;
}
@@ -496,7 +498,8 @@ static int node_add_object_invoke(bContext *C, wmOperator *op, const wmEvent *ev
static bool node_add_object_poll(bContext *C)
{
const SpaceNode *snode = CTX_wm_space_node(C);
- return ED_operator_node_editable(C) && ELEM(snode->nodetree->type, NTREE_GEOMETRY);
+ return ED_operator_node_editable(C) && ELEM(snode->nodetree->type, NTREE_GEOMETRY) &&
+ !UI_but_active_drop_name(C);
}
void NODE_OT_add_object(wmOperatorType *ot)
@@ -568,6 +571,8 @@ static int node_add_texture_exec(bContext *C, wmOperator *op)
snode_notify(C, snode);
snode_dag_update(C, snode);
+ ED_node_tag_update_nodetree(bmain, ntree, texture_node);
+
return OPERATOR_FINISHED;
}
@@ -592,7 +597,8 @@ static int node_add_texture_invoke(bContext *C, wmOperator *op, const wmEvent *e
static bool node_add_texture_poll(bContext *C)
{
const SpaceNode *snode = CTX_wm_space_node(C);
- return ED_operator_node_editable(C) && ELEM(snode->nodetree->type, NTREE_GEOMETRY);
+ return ED_operator_node_editable(C) && ELEM(snode->nodetree->type, NTREE_GEOMETRY) &&
+ !UI_but_active_drop_name(C);
}
void NODE_OT_add_texture(wmOperatorType *ot)
@@ -670,6 +676,8 @@ static int node_add_collection_exec(bContext *C, wmOperator *op)
snode_notify(C, snode);
snode_dag_update(C, snode);
+ ED_node_tag_update_nodetree(bmain, ntree, collection_node);
+
return OPERATOR_FINISHED;
}
@@ -694,7 +702,8 @@ static int node_add_collection_invoke(bContext *C, wmOperator *op, const wmEvent
static bool node_add_collection_poll(bContext *C)
{
const SpaceNode *snode = CTX_wm_space_node(C);
- return ED_operator_node_editable(C) && ELEM(snode->nodetree->type, NTREE_GEOMETRY);
+ return ED_operator_node_editable(C) && ELEM(snode->nodetree->type, NTREE_GEOMETRY) &&
+ !UI_but_active_drop_name(C);
}
void NODE_OT_add_collection(wmOperatorType *ot)
diff --git a/source/blender/editors/space_outliner/tree/tree_display_view_layer.cc b/source/blender/editors/space_outliner/tree/tree_display_view_layer.cc
index 89c9960a24f..f00cf3c34c0 100644
--- a/source/blender/editors/space_outliner/tree/tree_display_view_layer.cc
+++ b/source/blender/editors/space_outliner/tree/tree_display_view_layer.cc
@@ -148,6 +148,14 @@ void TreeDisplayViewLayer::add_layer_collections_recursive(ListBase &tree,
if (!exclude && show_objects_) {
add_layer_collection_objects(ten->subtree, *lc, *ten);
}
+
+ const bool lib_overrides_visible = !SUPPORT_FILTER_OUTLINER(&space_outliner_) ||
+ ((space_outliner_.filter & SO_FILTER_NO_LIB_OVERRIDE) == 0);
+
+ if (lib_overrides_visible && ID_IS_OVERRIDE_LIBRARY_REAL(&lc->collection->id)) {
+ outliner_add_element(
+ &space_outliner_, &ten->subtree, &lc->collection->id, ten, TSE_LIBRARY_OVERRIDE_BASE, 0);
+ }
}
}
diff --git a/source/blender/editors/space_outliner/tree/tree_element_overrides.hh b/source/blender/editors/space_outliner/tree/tree_element_overrides.hh
index b5c772f5b33..4f7025610ed 100644
--- a/source/blender/editors/space_outliner/tree/tree_element_overrides.hh
+++ b/source/blender/editors/space_outliner/tree/tree_element_overrides.hh
@@ -39,7 +39,7 @@ class TreeElementOverridesBase final : public AbstractTreeElement {
};
class TreeElementOverridesProperty final : public AbstractTreeElement {
- ID &id_;
+ [[maybe_unused]] ID &id_;
IDOverrideLibraryProperty &override_prop_;
public:
diff --git a/source/blender/editors/transform/transform_convert_mesh.c b/source/blender/editors/transform/transform_convert_mesh.c
index 7270763c4e4..93c36645873 100644
--- a/source/blender/editors/transform/transform_convert_mesh.c
+++ b/source/blender/editors/transform/transform_convert_mesh.c
@@ -60,127 +60,133 @@ void transform_convert_mesh_islands_calc(struct BMEditMesh *em,
const bool calc_island_axismtx,
struct TransIslandData *r_island_data)
{
+ struct TransIslandData data = {NULL};
+
BMesh *bm = em->bm;
char htype;
char itype;
int i;
/* group vars */
- float(*center)[3] = NULL;
- float(*axismtx)[3][3] = NULL;
- int *groups_array;
- int(*group_index)[2];
- int group_tot;
- void **ele_array;
+ int *groups_array = NULL;
+ int(*group_index)[2] = NULL;
- int *vert_map;
+ bool has_only_single_islands = bm->totedgesel == 0 && bm->totfacesel == 0;
+ if (has_only_single_islands && !calc_single_islands) {
+ return;
+ }
- if (em->selectmode & (SCE_SELECT_VERTEX | SCE_SELECT_EDGE)) {
- groups_array = MEM_mallocN(sizeof(*groups_array) * bm->totedgesel, __func__);
- group_tot = BM_mesh_calc_edge_groups(
- bm, groups_array, &group_index, NULL, NULL, BM_ELEM_SELECT);
+ data.island_vert_map = MEM_mallocN(sizeof(*data.island_vert_map) * bm->totvert, __func__);
+ /* we shouldn't need this, but with incorrect selection flushing
+ * its possible we have a selected vertex that's not in a face,
+ * for now best not crash in that case. */
+ copy_vn_i(data.island_vert_map, bm->totvert, -1);
- htype = BM_EDGE;
- itype = BM_VERTS_OF_EDGE;
- }
- else { /* (bm->selectmode & SCE_SELECT_FACE) */
- groups_array = MEM_mallocN(sizeof(*groups_array) * bm->totfacesel, __func__);
- group_tot = BM_mesh_calc_face_groups(
- bm, groups_array, &group_index, NULL, NULL, NULL, BM_ELEM_SELECT, BM_VERT);
+ if (!has_only_single_islands) {
+ if (em->selectmode & (SCE_SELECT_VERTEX | SCE_SELECT_EDGE)) {
+ groups_array = MEM_mallocN(sizeof(*groups_array) * bm->totedgesel, __func__);
+ data.island_tot = BM_mesh_calc_edge_groups(
+ bm, groups_array, &group_index, NULL, NULL, BM_ELEM_SELECT);
- htype = BM_FACE;
- itype = BM_VERTS_OF_FACE;
- }
+ htype = BM_EDGE;
+ itype = BM_VERTS_OF_EDGE;
+ }
+ else { /* (bm->selectmode & SCE_SELECT_FACE) */
+ groups_array = MEM_mallocN(sizeof(*groups_array) * bm->totfacesel, __func__);
+ data.island_tot = BM_mesh_calc_face_groups(
+ bm, groups_array, &group_index, NULL, NULL, NULL, BM_ELEM_SELECT, BM_VERT);
- if (calc_island_center) {
- center = MEM_mallocN(sizeof(*center) * group_tot, __func__);
- }
+ htype = BM_FACE;
+ itype = BM_VERTS_OF_FACE;
+ }
- if (calc_island_axismtx) {
- axismtx = MEM_mallocN(sizeof(*axismtx) * group_tot, __func__);
- }
+ BLI_assert(data.island_tot);
+ if (calc_island_center) {
+ data.center = MEM_mallocN(sizeof(*data.center) * data.island_tot, __func__);
+ }
- vert_map = MEM_mallocN(sizeof(*vert_map) * bm->totvert, __func__);
- /* we shouldn't need this, but with incorrect selection flushing
- * its possible we have a selected vertex that's not in a face,
- * for now best not crash in that case. */
- copy_vn_i(vert_map, bm->totvert, -1);
+ if (calc_island_axismtx) {
+ data.axismtx = MEM_mallocN(sizeof(*data.axismtx) * data.island_tot, __func__);
+ }
- BM_mesh_elem_table_ensure(bm, htype);
- ele_array = (htype == BM_FACE) ? (void **)bm->ftable : (void **)bm->etable;
+ BM_mesh_elem_table_ensure(bm, htype);
- BM_mesh_elem_index_ensure(bm, BM_VERT);
+ void **ele_array;
+ ele_array = (htype == BM_FACE) ? (void **)bm->ftable : (void **)bm->etable;
- /* may be an edge OR a face array */
- for (i = 0; i < group_tot; i++) {
- BMEditSelection ese = {NULL};
+ BM_mesh_elem_index_ensure(bm, BM_VERT);
- const int fg_sta = group_index[i][0];
- const int fg_len = group_index[i][1];
- float co[3], no[3], tangent[3];
- int j;
+ /* may be an edge OR a face array */
+ for (i = 0; i < data.island_tot; i++) {
+ BMEditSelection ese = {NULL};
- zero_v3(co);
- zero_v3(no);
- zero_v3(tangent);
+ const int fg_sta = group_index[i][0];
+ const int fg_len = group_index[i][1];
+ float co[3], no[3], tangent[3];
+ int j;
- ese.htype = htype;
+ zero_v3(co);
+ zero_v3(no);
+ zero_v3(tangent);
- /* loop on each face or edge in this group:
- * - assign r_vert_map
- * - calculate (co, no)
- */
- for (j = 0; j < fg_len; j++) {
- ese.ele = ele_array[groups_array[fg_sta + j]];
+ ese.htype = htype;
- if (center) {
- float tmp_co[3];
- BM_editselection_center(&ese, tmp_co);
- add_v3_v3(co, tmp_co);
- }
+ /* loop on each face or edge in this group:
+ * - assign r_vert_map
+ * - calculate (co, no)
+ */
+ for (j = 0; j < fg_len; j++) {
+ ese.ele = ele_array[groups_array[fg_sta + j]];
- if (axismtx) {
- float tmp_no[3], tmp_tangent[3];
- BM_editselection_normal(&ese, tmp_no);
- BM_editselection_plane(&ese, tmp_tangent);
- add_v3_v3(no, tmp_no);
- add_v3_v3(tangent, tmp_tangent);
- }
+ if (data.center) {
+ float tmp_co[3];
+ BM_editselection_center(&ese, tmp_co);
+ add_v3_v3(co, tmp_co);
+ }
- {
- /* setup vertex map */
- BMIter iter;
- BMVert *v;
+ if (data.axismtx) {
+ float tmp_no[3], tmp_tangent[3];
+ BM_editselection_normal(&ese, tmp_no);
+ BM_editselection_plane(&ese, tmp_tangent);
+ add_v3_v3(no, tmp_no);
+ add_v3_v3(tangent, tmp_tangent);
+ }
- /* connected edge-verts */
- BM_ITER_ELEM (v, &iter, ese.ele, itype) {
- vert_map[BM_elem_index_get(v)] = i;
+ {
+ /* setup vertex map */
+ BMIter iter;
+ BMVert *v;
+
+ /* connected edge-verts */
+ BM_ITER_ELEM (v, &iter, ese.ele, itype) {
+ data.island_vert_map[BM_elem_index_get(v)] = i;
+ }
}
}
- }
- if (center) {
- mul_v3_v3fl(center[i], co, 1.0f / (float)fg_len);
- }
-
- if (axismtx) {
- if (createSpaceNormalTangent(axismtx[i], no, tangent)) {
- /* pass */
+ if (data.center) {
+ mul_v3_v3fl(data.center[i], co, 1.0f / (float)fg_len);
}
- else {
- if (normalize_v3(no) != 0.0f) {
- axis_dominant_v3_to_m3(axismtx[i], no);
- invert_m3(axismtx[i]);
+
+ if (data.axismtx) {
+ if (createSpaceNormalTangent(data.axismtx[i], no, tangent)) {
+ /* pass */
}
else {
- unit_m3(axismtx[i]);
+ if (normalize_v3(no) != 0.0f) {
+ axis_dominant_v3_to_m3(data.axismtx[i], no);
+ invert_m3(data.axismtx[i]);
+ }
+ else {
+ unit_m3(data.axismtx[i]);
+ }
}
}
}
- }
- MEM_freeN(groups_array);
- MEM_freeN(group_index);
+ MEM_freeN(groups_array);
+ MEM_freeN(group_index);
+ }
/* for PET we need islands of 1 so connected vertices can use it with V3D_AROUND_LOCAL_ORIGINS */
if (calc_single_islands) {
@@ -189,45 +195,44 @@ void transform_convert_mesh_islands_calc(struct BMEditMesh *em,
int group_tot_single = 0;
BM_ITER_MESH_INDEX (v, &viter, bm, BM_VERTS_OF_MESH, i) {
- if (BM_elem_flag_test(v, BM_ELEM_SELECT) && (vert_map[i] == -1)) {
+ if (BM_elem_flag_test(v, BM_ELEM_SELECT) && (data.island_vert_map[i] == -1)) {
group_tot_single += 1;
}
}
if (group_tot_single != 0) {
- if (center) {
- center = MEM_reallocN(center, sizeof(*center) * (group_tot + group_tot_single));
+ if (calc_island_center) {
+ data.center = MEM_reallocN(data.center,
+ sizeof(*data.center) * (data.island_tot + group_tot_single));
}
- if (axismtx) {
- axismtx = MEM_reallocN(axismtx, sizeof(*axismtx) * (group_tot + group_tot_single));
+ if (calc_island_axismtx) {
+ data.axismtx = MEM_reallocN(data.axismtx,
+ sizeof(*data.axismtx) * (data.island_tot + group_tot_single));
}
BM_ITER_MESH_INDEX (v, &viter, bm, BM_VERTS_OF_MESH, i) {
- if (BM_elem_flag_test(v, BM_ELEM_SELECT) && (vert_map[i] == -1)) {
- vert_map[i] = group_tot;
- if (center) {
- copy_v3_v3(center[group_tot], v->co);
+ if (BM_elem_flag_test(v, BM_ELEM_SELECT) && (data.island_vert_map[i] == -1)) {
+ data.island_vert_map[i] = data.island_tot;
+ if (data.center) {
+ copy_v3_v3(data.center[data.island_tot], v->co);
}
- if (axismtx) {
- if (is_zero_v3(v->no) != 0.0f) {
- axis_dominant_v3_to_m3(axismtx[group_tot], v->no);
- invert_m3(axismtx[group_tot]);
+ if (data.axismtx) {
+ if (is_zero_v3(v->no) == false) {
+ axis_dominant_v3_to_m3(data.axismtx[data.island_tot], v->no);
+ invert_m3(data.axismtx[data.island_tot]);
}
else {
- unit_m3(axismtx[group_tot]);
+ unit_m3(data.axismtx[data.island_tot]);
}
}
- group_tot += 1;
+ data.island_tot += 1;
}
}
}
}
- r_island_data->axismtx = axismtx;
- r_island_data->center = center;
- r_island_data->island_tot = group_tot;
- r_island_data->island_vert_map = vert_map;
+ *r_island_data = data;
}
void transform_convert_mesh_islanddata_free(struct TransIslandData *island_data)
diff --git a/source/blender/editors/util/ed_util.c b/source/blender/editors/util/ed_util.c
index 9903711834a..da94eef4917 100644
--- a/source/blender/editors/util/ed_util.c
+++ b/source/blender/editors/util/ed_util.c
@@ -146,7 +146,7 @@ void ED_editors_init(bContext *C)
ED_object_wpaintmode_enter_ex(bmain, depsgraph, scene, ob);
}
else {
- BLI_assert(0);
+ BLI_assert_unreachable();
}
}
else {
diff --git a/source/blender/editors/util/select_utils.c b/source/blender/editors/util/select_utils.c
index 85f48e6d397..14a6d751bb1 100644
--- a/source/blender/editors/util/select_utils.c
+++ b/source/blender/editors/util/select_utils.c
@@ -94,7 +94,7 @@ int ED_select_similar_compare_float(const float delta, const float thresh, const
case SIM_CMP_LT:
return ((delta - thresh) < FLT_EPSILON);
default:
- BLI_assert(0);
+ BLI_assert_unreachable();
return 0;
}
}
@@ -124,7 +124,7 @@ bool ED_select_similar_compare_float_tree(const KDTree_1d *tree,
nearest_edge_length = FLT_MAX;
break;
default:
- BLI_assert(0);
+ BLI_assert_unreachable();
return false;
}
diff --git a/source/blender/editors/uvedit/uvedit_rip.c b/source/blender/editors/uvedit/uvedit_rip.c
index c8aa21191ba..e1b9a287457 100644
--- a/source/blender/editors/uvedit/uvedit_rip.c
+++ b/source/blender/editors/uvedit/uvedit_rip.c
@@ -169,7 +169,7 @@ static BMLoop *bm_loop_find_other_fan_loop_with_visible_face(BMLoop *l_src,
l_other = l_other->prev;
}
else {
- BLI_assert(0);
+ BLI_assert_unreachable();
}
}
return l_other;
@@ -189,7 +189,7 @@ static BMLoop *bm_vert_step_fan_loop_uv(BMLoop *l, BMEdge **e_step, const int cd
l_next = l;
}
else {
- BLI_assert(0);
+ BLI_assert_unreachable();
return NULL;
}
diff --git a/source/blender/editors/uvedit/uvedit_select.c b/source/blender/editors/uvedit/uvedit_select.c
index f46975c9378..c10e132a4e2 100644
--- a/source/blender/editors/uvedit/uvedit_select.c
+++ b/source/blender/editors/uvedit/uvedit_select.c
@@ -2213,7 +2213,7 @@ static int uv_mouse_select_loop_generic_multi(bContext *C,
flush = uv_select_edgering(sima, scene, obedit, &hit, extend);
}
else {
- BLI_assert(0);
+ BLI_assert_unreachable();
}
if (ts->uv_flag & UV_SYNC_SELECTION) {