Curves: add initial sculpt mode

This adds a new sculpt mode to the experimental new curves object.
Currently, this mode can only be entered and exited, nothing else.
The main initial purpose of this node will be to use it for hair grooming.

The patch also adds the `editors/curves/` directory for the new curves
object, which will be necessary for many other things as well.

I added a completely new mode (`OB_MODE_SCULPT_CURVES`), because
`OB_MODE_SCULPT` seems to be rather specific to meshes, and reusing
it doesn't seem worth the trouble. The tools/brushes used in mesh vs.
curves sculpt mode are quite distinct as well.

I had to add DNA_userdef_enums.h to make the patch compile with C++
(forward declaration of enums isn't allowed). This follows the same
pattern that we use for other enums in dna.

Differential Revision: https://developer.blender.org/D14107
This commit is contained in:
Jacques Lucke 2022-02-15 12:32:15 +01:00
parent 07ed869b94
commit 07032dd218
20 changed files with 211 additions and 42 deletions

View File

@ -823,7 +823,7 @@ class VIEW3D_MT_editor_menus(Menu):
layout.menu("VIEW3D_MT_select_paint_mask")
elif mesh.use_paint_mask_vertex and mode_string in {'PAINT_WEIGHT', 'PAINT_VERTEX'}:
layout.menu("VIEW3D_MT_select_paint_mask_vertex")
elif mode_string != 'SCULPT':
elif mode_string not in ('SCULPT', 'SCULPT_CURVES'):
layout.menu("VIEW3D_MT_select_%s" % mode_string.lower())
if gp_edit:
@ -866,7 +866,7 @@ class VIEW3D_MT_editor_menus(Menu):
layout.menu("VIEW3D_MT_edit_curve_segments")
elif obj:
if mode_string != 'PAINT_TEXTURE':
if mode_string not in ('PAINT_TEXTURE', 'SCULPT_CURVES'):
layout.menu("VIEW3D_MT_%s" % mode_string.lower())
if mode_string == 'SCULPT':
layout.menu("VIEW3D_MT_mask")

View File

@ -74,6 +74,7 @@ set(SRC_DNA_INC
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_text_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_texture_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_tracking_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_userdef_enums.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_userdef_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_uuid_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_vec_types.h

View File

@ -118,8 +118,9 @@ typedef enum eContextObjectMode {
CTX_MODE_SCULPT_GPENCIL,
CTX_MODE_WEIGHT_GPENCIL,
CTX_MODE_VERTEX_GPENCIL,
CTX_MODE_SCULPT_CURVES,
} eContextObjectMode;
#define CTX_MODE_NUM (CTX_MODE_VERTEX_GPENCIL + 1)
#define CTX_MODE_NUM (CTX_MODE_SCULPT_CURVES + 1)
/* Context */

View File

@ -1198,6 +1198,9 @@ enum eContextObjectMode CTX_data_mode_enum_ex(const Object *obedit,
if (object_mode & OB_MODE_VERTEX_GPENCIL) {
return CTX_MODE_VERTEX_GPENCIL;
}
if (object_mode & OB_MODE_SCULPT_CURVES) {
return CTX_MODE_SCULPT_CURVES;
}
}
}
@ -1217,11 +1220,27 @@ enum eContextObjectMode CTX_data_mode_enum(const bContext *C)
* \note Must be aligned with above enum.
*/
static const char *data_mode_strings[] = {
"mesh_edit", "curve_edit", "surface_edit", "text_edit",
"armature_edit", "mball_edit", "lattice_edit", "posemode",
"sculpt_mode", "weightpaint", "vertexpaint", "imagepaint",
"particlemode", "objectmode", "greasepencil_paint", "greasepencil_edit",
"greasepencil_sculpt", "greasepencil_weight", "greasepencil_vertex", NULL,
"mesh_edit",
"curve_edit",
"surface_edit",
"text_edit",
"armature_edit",
"mball_edit",
"lattice_edit",
"posemode",
"sculpt_mode",
"weightpaint",
"vertexpaint",
"imagepaint",
"particlemode",
"objectmode",
"greasepencil_paint",
"greasepencil_edit",
"greasepencil_sculpt",
"greasepencil_weight",
"greasepencil_vertex",
"curves_sculpt",
NULL,
};
BLI_STATIC_ASSERT(ARRAY_SIZE(data_mode_strings) == CTX_MODE_NUM + 1,
"Must have a string for each context mode")

View File

@ -9,6 +9,7 @@ if(WITH_BLENDER)
add_subdirectory(armature)
add_subdirectory(asset)
add_subdirectory(curve)
add_subdirectory(curves)
add_subdirectory(geometry)
add_subdirectory(gizmo_library)
add_subdirectory(gpencil)

View File

@ -0,0 +1,24 @@
# SPDX-License-Identifier: GPL-2.0-or-later
set(INC
../include
../../blenkernel
../../blenlib
../../blentranslation
../../depsgraph
../../makesdna
../../makesrna
../../windowmanager
../../../../intern/guardedalloc
)
set(SRC
intern/curves_ops.cc
)
set(LIB
bf_blenkernel
bf_blenlib
)
blender_add_lib(bf_editor_curves "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")

View File

@ -0,0 +1,70 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup edcurves
*/
#include "BLI_utildefines.h"
#include "ED_curves.h"
#include "ED_object.h"
#include "WM_api.h"
#include "WM_types.h"
#include "BKE_context.h"
#include "RNA_access.h"
#include "RNA_define.h"
#include "RNA_types.h"
static bool curves_sculptmode_toggle_poll(bContext *C)
{
Object *ob = CTX_data_active_object(C);
if (ob == nullptr) {
return false;
}
if (ob->type != OB_CURVES) {
return false;
}
return true;
}
static int curves_sculptmode_toggle_exec(bContext *C, wmOperator *op)
{
Object *ob = CTX_data_active_object(C);
const bool is_mode_set = ob->mode == OB_MODE_SCULPT_CURVES;
if (is_mode_set) {
if (!ED_object_mode_compat_set(C, ob, OB_MODE_SCULPT_CURVES, op->reports)) {
return OPERATOR_CANCELLED;
}
}
if (is_mode_set) {
ob->mode = OB_MODE_OBJECT;
}
else {
ob->mode = OB_MODE_SCULPT_CURVES;
}
WM_event_add_notifier(C, NC_SCENE | ND_MODE, nullptr);
return OPERATOR_CANCELLED;
}
static void CURVES_OT_sculptmode_toggle(wmOperatorType *ot)
{
ot->name = "Curve Sculpt Mode Toggle";
ot->idname = "CURVES_OT_sculptmode_toggle";
ot->description = "Enter/Exit sculpt mode for curves";
ot->exec = curves_sculptmode_toggle_exec;
ot->poll = curves_sculptmode_toggle_poll;
ot->flag = OPTYPE_UNDO | OPTYPE_REGISTER;
}
void ED_operatortypes_curves()
{
WM_operatortype_append(CURVES_OT_sculptmode_toggle);
}

View File

@ -0,0 +1,17 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup editors
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
void ED_operatortypes_curves(void);
#ifdef __cplusplus
}
#endif

View File

@ -9,6 +9,7 @@
#include "BLI_compiler_attrs.h"
#include "DNA_object_enums.h"
#include "DNA_userdef_enums.h"
#ifdef __cplusplus
extern "C" {

View File

@ -2354,6 +2354,7 @@ int UI_icon_from_object_mode(const int mode)
return ICON_EDITMODE_HLT;
case OB_MODE_SCULPT:
case OB_MODE_SCULPT_GPENCIL:
case OB_MODE_SCULPT_CURVES:
return ICON_SCULPTMODE_HLT;
case OB_MODE_VERTEX_PAINT:
case OB_MODE_VERTEX_GPENCIL:

View File

@ -94,6 +94,9 @@ static const char *object_mode_op_string(eObjectMode mode)
if (mode == OB_MODE_VERTEX_GPENCIL) {
return "GPENCIL_OT_vertexmode_toggle";
}
if (mode == OB_MODE_SCULPT_CURVES) {
return "CURVES_OT_sculptmode_toggle";
}
return NULL;
}
@ -139,6 +142,11 @@ bool ED_object_mode_compat_test(const Object *ob, eObjectMode mode)
return true;
}
break;
case OB_CURVES:
if (mode & (OB_MODE_SCULPT_CURVES)) {
return true;
}
break;
}
return false;

View File

@ -28,6 +28,7 @@
#include "ED_asset.h"
#include "ED_clip.h"
#include "ED_curve.h"
#include "ED_curves.h"
#include "ED_fileselect.h"
#include "ED_geometry.h"
#include "ED_gizmo_library.h"
@ -99,6 +100,7 @@ void ED_spacetypes_init(void)
ED_operatortypes_paint();
ED_operatortypes_physics();
ED_operatortypes_curve();
ED_operatortypes_curves();
ED_operatortypes_armature();
ED_operatortypes_marker();
ED_operatortypes_metaball();

View File

@ -39,6 +39,7 @@ set(SRC
../include/ED_buttons.h
../include/ED_clip.h
../include/ED_curve.h
../include/ED_curves.h
../include/ED_datafiles.h
../include/ED_file_indexer.h
../include/ED_fileselect.h

View File

@ -27,6 +27,7 @@ typedef enum eObjectMode {
OB_MODE_SCULPT_GPENCIL = 1 << 9,
OB_MODE_WEIGHT_GPENCIL = 1 << 10,
OB_MODE_VERTEX_GPENCIL = 1 << 11,
OB_MODE_SCULPT_CURVES = 1 << 12,
} eObjectMode;
/** #Object.dt, #View3DShading.type */
@ -60,7 +61,7 @@ typedef enum eDrawType {
#define OB_MODE_ALL_MODE_DATA \
(OB_MODE_EDIT | OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_SCULPT | OB_MODE_POSE | \
OB_MODE_PAINT_GPENCIL | OB_MODE_EDIT_GPENCIL | OB_MODE_SCULPT_GPENCIL | \
OB_MODE_WEIGHT_GPENCIL | OB_MODE_VERTEX_GPENCIL)
OB_MODE_WEIGHT_GPENCIL | OB_MODE_VERTEX_GPENCIL | OB_MODE_SCULPT_CURVES)
#ifdef __cplusplus
}

View File

@ -0,0 +1,48 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup DNA
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/** #UserDef.dupflag */
typedef enum eDupli_ID_Flags {
USER_DUP_MESH = (1 << 0),
USER_DUP_CURVE = (1 << 1),
USER_DUP_SURF = (1 << 2),
USER_DUP_FONT = (1 << 3),
USER_DUP_MBALL = (1 << 4),
USER_DUP_LAMP = (1 << 5),
/* USER_DUP_FCURVE = (1 << 6), */ /* UNUSED, keep because we may implement. */
USER_DUP_MAT = (1 << 7),
/* USER_DUP_TEX = (1 << 8), */ /* UNUSED, keep because we may implement. */
USER_DUP_ARM = (1 << 9),
USER_DUP_ACT = (1 << 10),
USER_DUP_PSYS = (1 << 11),
USER_DUP_LIGHTPROBE = (1 << 12),
USER_DUP_GPENCIL = (1 << 13),
USER_DUP_CURVES = (1 << 14),
USER_DUP_POINTCLOUD = (1 << 15),
USER_DUP_VOLUME = (1 << 16),
USER_DUP_LATTICE = (1 << 17),
USER_DUP_CAMERA = (1 << 18),
USER_DUP_SPEAKER = (1 << 19),
USER_DUP_OBDATA = (~0) & ((1 << 24) - 1),
/* Those are not exposed as user preferences, only used internally. */
USER_DUP_OBJECT = (1 << 24),
/* USER_DUP_COLLECTION = (1 << 25), */ /* UNUSED, keep because we may implement. */
/* Duplicate (and hence make local) linked data. */
USER_DUP_LINKED_ID = (1 << 30),
} eDupli_ID_Flags;
#ifdef __cplusplus
}
#endif

View File

@ -9,6 +9,7 @@
#include "DNA_listBase.h"
#include "DNA_texture_types.h" /* ColorBand */
#include "DNA_userdef_enums.h"
#ifdef __cplusplus
extern "C" {
@ -1220,39 +1221,6 @@ typedef enum eUserpref_Translation_Flags {
USER_TR_NEWDATANAME = (1 << 8),
} eUserpref_Translation_Flags;
/** #UserDef.dupflag */
typedef enum eDupli_ID_Flags {
USER_DUP_MESH = (1 << 0),
USER_DUP_CURVE = (1 << 1),
USER_DUP_SURF = (1 << 2),
USER_DUP_FONT = (1 << 3),
USER_DUP_MBALL = (1 << 4),
USER_DUP_LAMP = (1 << 5),
/* USER_DUP_FCURVE = (1 << 6), */ /* UNUSED, keep because we may implement. */
USER_DUP_MAT = (1 << 7),
/* USER_DUP_TEX = (1 << 8), */ /* UNUSED, keep because we may implement. */
USER_DUP_ARM = (1 << 9),
USER_DUP_ACT = (1 << 10),
USER_DUP_PSYS = (1 << 11),
USER_DUP_LIGHTPROBE = (1 << 12),
USER_DUP_GPENCIL = (1 << 13),
USER_DUP_CURVES = (1 << 14),
USER_DUP_POINTCLOUD = (1 << 15),
USER_DUP_VOLUME = (1 << 16),
USER_DUP_LATTICE = (1 << 17),
USER_DUP_CAMERA = (1 << 18),
USER_DUP_SPEAKER = (1 << 19),
USER_DUP_OBDATA = (~0) & ((1 << 24) - 1),
/* Those are not exposed as user preferences, only used internally. */
USER_DUP_OBJECT = (1 << 24),
/* USER_DUP_COLLECTION = (1 << 25), */ /* UNUSED, keep because we may implement. */
/* Duplicate (and hence make local) linked data. */
USER_DUP_LINKED_ID = (1 << 30),
} eDupli_ID_Flags;
/**
* Text Editor options
* #UserDef.text_flag

View File

@ -427,6 +427,7 @@ set(LIB
bf_editor_armature
bf_editor_asset
bf_editor_curve
bf_editor_curves
bf_editor_gizmo_library
bf_editor_gpencil
bf_editor_io

View File

@ -39,6 +39,7 @@ const EnumPropertyItem rna_enum_context_mode_items[] = {
{CTX_MODE_SCULPT_GPENCIL, "SCULPT_GPENCIL", 0, "Grease Pencil Sculpt", ""},
{CTX_MODE_WEIGHT_GPENCIL, "WEIGHT_GPENCIL", 0, "Grease Pencil Weight Paint", ""},
{CTX_MODE_VERTEX_GPENCIL, "VERTEX_GPENCIL", 0, "Grease Pencil Vertex Paint", ""},
{CTX_MODE_SCULPT_CURVES, "SCULPT_CURVES", 0, "Curves Sculpt", ""},
{0, NULL, 0, NULL, NULL},
};

View File

@ -84,6 +84,7 @@ const EnumPropertyItem rna_enum_object_mode_items[] = {
ICON_VPAINT_HLT,
"Vertex Paint",
"Grease Pencil Vertex Paint Strokes"},
{OB_MODE_SCULPT_CURVES, "SCULPT_CURVES", ICON_SCULPTMODE_HLT, "Sculpt Mode", ""},
{0, NULL, 0, NULL, NULL},
};

View File

@ -157,6 +157,9 @@ wmKeyMap *WM_keymap_guess_from_context(const bContext *C)
case CTX_MODE_VERTEX_GPENCIL:
km_id = "Grease Pencil Stroke Vertex Mode";
break;
case CTX_MODE_SCULPT_CURVES:
km_id = "Curves Sculpt Mode";
break;
}
}
else if (sl->spacetype == SPACE_IMAGE) {