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:
authorKévin Dietrich <kevin.dietrich@mailoo.org>2022-01-20 14:20:30 +0300
committerKévin Dietrich <kevin.dietrich@mailoo.org>2022-01-20 14:21:34 +0300
commit4425e0cd64ff23b77c553041858a150665a32ba3 (patch)
tree45c76d67d99499377dc719679c22e87effc86d8f /source/blender/editors
parent9b4c017031f94237d75320349e933462772d773e (diff)
Subdivision: add support for vertex creasing
This adds vertex creasing support for OpenSubDiv for modeling, rendering, Alembic and USD I/O. For modeling, vertex creasing follows the edge creasing implementation with an operator accessible through the Vertex menu in Edit Mode, and some parameter in the properties panel. The option in the Subsurf and Multires to use edge creasing also affects vertex creasing. The vertex crease data is stored as a CustomData layer, unlike edge creases which for now are stored in `MEdge`, but will in the future also be moved to a `CustomData` layer. See comments for details on the difference in behavior for the `CD_CREASE` layer between egdes and vertices. For Cycles this adds sockets on the Mesh node to hold data about which vertices are creased (one socket for the indices, one for the weigths). Viewport rendering of vertex creasing reuses the same color scheme as for edges and creased vertices are drawn bigger than uncreased vertices. For Alembic and USD, vertex crease support follows the edge crease implementation, they are always read, but only exported if a `Subsurf` modifier is present on the Mesh. Reviewed By: brecht, fclem, sergey, sybren, campbellbarton Differential Revision: https://developer.blender.org/D10145
Diffstat (limited to 'source/blender/editors')
-rw-r--r--source/blender/editors/include/ED_transform.h3
-rw-r--r--source/blender/editors/space_view3d/view3d_buttons.c66
-rw-r--r--source/blender/editors/transform/transform_convert_mesh.c9
-rw-r--r--source/blender/editors/transform/transform_convert_mesh_edge.c4
-rw-r--r--source/blender/editors/transform/transform_generics.c2
-rw-r--r--source/blender/editors/transform/transform_mode.c7
-rw-r--r--source/blender/editors/transform/transform_mode.h3
-rw-r--r--source/blender/editors/transform/transform_mode_edge_crease.c13
-rw-r--r--source/blender/editors/transform/transform_ops.c31
9 files changed, 113 insertions, 25 deletions
diff --git a/source/blender/editors/include/ED_transform.h b/source/blender/editors/include/ED_transform.h
index b76f882e706..573f9b4939b 100644
--- a/source/blender/editors/include/ED_transform.h
+++ b/source/blender/editors/include/ED_transform.h
@@ -54,7 +54,8 @@ typedef enum {
TFM_TILT,
TFM_TRACKBALL,
TFM_PUSHPULL,
- TFM_CREASE,
+ TFM_EDGE_CREASE,
+ TFM_VERT_CREASE,
TFM_MIRROR,
TFM_BONESIZE,
TFM_BONE_ENVELOPE,
diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c
index 5451aa5a2e0..243d4033cbc 100644
--- a/source/blender/editors/space_view3d/view3d_buttons.c
+++ b/source/blender/editors/space_view3d/view3d_buttons.c
@@ -87,7 +87,7 @@ typedef struct {
} TransformMedian_Generic;
typedef struct {
- float location[3], bv_weight, be_weight, skin[2], crease;
+ float location[3], bv_weight, v_crease, be_weight, skin[2], e_crease;
} TransformMedian_Mesh;
typedef struct {
@@ -319,6 +319,7 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
BMIter iter;
const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
+ const int cd_vert_crease_offset = CustomData_get_offset(&bm->vdata, CD_CREASE);
const int cd_vert_skin_offset = CustomData_get_offset(&bm->vdata, CD_MVERT_SKIN);
const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE);
@@ -335,6 +336,10 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
median->bv_weight += BM_ELEM_CD_GET_FLOAT(eve, cd_vert_bweight_offset);
}
+ if (cd_vert_crease_offset != -1) {
+ median->v_crease += BM_ELEM_CD_GET_FLOAT(eve, cd_vert_crease_offset);
+ }
+
if (has_skinradius) {
MVertSkin *vs = BM_ELEM_CD_GET_VOID_P(eve, cd_vert_skin_offset);
add_v2_v2(median->skin, vs->radius); /* Third val not used currently. */
@@ -352,7 +357,7 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
}
if (cd_edge_crease_offset != -1) {
- median->crease += BM_ELEM_CD_GET_FLOAT(eed, cd_edge_crease_offset);
+ median->e_crease += BM_ELEM_CD_GET_FLOAT(eed, cd_edge_crease_offset);
}
totedgedata++;
@@ -489,11 +494,12 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
if (has_meshdata) {
TransformMedian_Mesh *median = &median_basis.mesh;
if (totedgedata) {
- median->crease /= (float)totedgedata;
+ median->e_crease /= (float)totedgedata;
median->be_weight /= (float)totedgedata;
}
if (tot) {
median->bv_weight /= (float)tot;
+ median->v_crease /= (float)tot;
if (has_skinradius) {
median->skin[0] /= (float)tot;
median->skin[1] /= (float)tot;
@@ -683,6 +689,23 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
TIP_("Vertex weight used by Bevel modifier"));
UI_but_number_step_size_set(but, 1);
UI_but_number_precision_set(but, 2);
+ /* customdata layer added on demand */
+ but = uiDefButF(block,
+ UI_BTYPE_NUM,
+ B_TRANSFORM_PANEL_MEDIAN,
+ tot == 1 ? IFACE_("Vertex Crease:") : IFACE_("Mean Vertex Crease:"),
+ 0,
+ yi -= buth + but_margin,
+ butw,
+ buth,
+ &ve_median->v_crease,
+ 0.0,
+ 1.0,
+ 0,
+ 0,
+ TIP_("Weight used by the Subdivision Surface modifier"));
+ UI_but_number_step_size_set(but, 1);
+ UI_but_number_precision_set(but, 2);
}
if (has_skinradius) {
UI_block_align_begin(block);
@@ -761,7 +784,7 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
yi -= buth + but_margin,
butw,
buth,
- &ve_median->crease,
+ &ve_median->e_crease,
0.0,
1.0,
0,
@@ -958,8 +981,9 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
const bool apply_vcos = (tot == 1) || (len_squared_v3(median_basis.generic.location) != 0.0f);
if ((ob->type == OB_MESH) &&
- (apply_vcos || median_basis.mesh.bv_weight || median_basis.mesh.skin[0] ||
- median_basis.mesh.skin[1] || median_basis.mesh.be_weight || median_basis.mesh.crease)) {
+ (apply_vcos || median_basis.mesh.bv_weight || median_basis.mesh.v_crease ||
+ median_basis.mesh.skin[0] || median_basis.mesh.skin[1] || median_basis.mesh.be_weight ||
+ median_basis.mesh.e_crease)) {
const TransformMedian_Mesh *median = &median_basis.mesh, *ve_median = &ve_median_basis.mesh;
Mesh *me = ob->data;
BMEditMesh *em = me->edit_mesh;
@@ -969,18 +993,21 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
BMEdge *eed;
int cd_vert_bweight_offset = -1;
+ int cd_vert_crease_offset = -1;
int cd_vert_skin_offset = -1;
int cd_edge_bweight_offset = -1;
int cd_edge_crease_offset = -1;
float scale_bv_weight = 1.0f;
+ float scale_v_crease = 1.0f;
float scale_skin[2] = {1.0f, 1.0f};
float scale_be_weight = 1.0f;
- float scale_crease = 1.0f;
+ float scale_e_crease = 1.0f;
/* Vertices */
- if (apply_vcos || median->bv_weight || median->skin[0] || median->skin[1]) {
+ if (apply_vcos || median->bv_weight || median->v_crease || median->skin[0] ||
+ median->skin[1]) {
if (median->bv_weight) {
BM_mesh_cd_flag_ensure(bm, me, ME_CDFLAG_VERT_BWEIGHT);
cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
@@ -989,6 +1016,14 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
scale_bv_weight = compute_scale_factor(ve_median->bv_weight, median->bv_weight);
}
+ if (median->v_crease) {
+ BM_mesh_cd_flag_ensure(bm, me, ME_CDFLAG_VERT_CREASE);
+ cd_vert_crease_offset = CustomData_get_offset(&bm->vdata, CD_CREASE);
+ BLI_assert(cd_vert_crease_offset != -1);
+
+ scale_v_crease = compute_scale_factor(ve_median->v_crease, median->v_crease);
+ }
+
for (int i = 0; i < 2; i++) {
if (median->skin[i]) {
cd_vert_skin_offset = CustomData_get_offset(&bm->vdata, CD_MVERT_SKIN);
@@ -1011,6 +1046,11 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
apply_scale_factor_clamp(b_weight, tot, ve_median->bv_weight, scale_bv_weight);
}
+ if (cd_vert_crease_offset != -1) {
+ float *crease = BM_ELEM_CD_GET_VOID_P(eve, cd_vert_crease_offset);
+ apply_scale_factor_clamp(crease, tot, ve_median->v_crease, scale_v_crease);
+ }
+
if (cd_vert_skin_offset != -1) {
MVertSkin *vs = BM_ELEM_CD_GET_VOID_P(eve, cd_vert_skin_offset);
@@ -1033,7 +1073,7 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
/* Edges */
- if (median->be_weight || median->crease) {
+ if (median->be_weight || median->e_crease) {
if (median->be_weight) {
BM_mesh_cd_flag_ensure(bm, me, ME_CDFLAG_EDGE_BWEIGHT);
cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
@@ -1042,12 +1082,12 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
scale_be_weight = compute_scale_factor(ve_median->be_weight, median->be_weight);
}
- if (median->crease) {
+ if (median->e_crease) {
BM_mesh_cd_flag_ensure(bm, me, ME_CDFLAG_EDGE_CREASE);
cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE);
BLI_assert(cd_edge_crease_offset != -1);
- scale_crease = compute_scale_factor(ve_median->crease, median->crease);
+ scale_e_crease = compute_scale_factor(ve_median->e_crease, median->e_crease);
}
BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
@@ -1057,9 +1097,9 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
apply_scale_factor_clamp(b_weight, tot, ve_median->be_weight, scale_be_weight);
}
- if (median->crease != 0.0f) {
+ if (median->e_crease != 0.0f) {
float *crease = BM_ELEM_CD_GET_VOID_P(eed, cd_edge_crease_offset);
- apply_scale_factor_clamp(crease, tot, ve_median->crease, scale_crease);
+ apply_scale_factor_clamp(crease, tot, ve_median->e_crease, scale_e_crease);
}
}
}
diff --git a/source/blender/editors/transform/transform_convert_mesh.c b/source/blender/editors/transform/transform_convert_mesh.c
index c3d95e1ad98..55f2bfd37db 100644
--- a/source/blender/editors/transform/transform_convert_mesh.c
+++ b/source/blender/editors/transform/transform_convert_mesh.c
@@ -1465,7 +1465,7 @@ static void VertsToTransData(TransInfo *t,
td->ext = NULL;
td->val = NULL;
td->extra = eve;
- if (t->mode == TFM_BWEIGHT) {
+ if (t->mode == TFM_BWEIGHT || t->mode == TFM_VERT_CREASE) {
td->val = bweight;
td->ival = *bweight;
}
@@ -1606,10 +1606,15 @@ void createTransEditVerts(TransInfo *t)
}
int cd_vert_bweight_offset = -1;
+ int cd_vert_crease_offset = -1;
if (t->mode == TFM_BWEIGHT) {
BM_mesh_cd_flag_ensure(bm, BKE_mesh_from_object(tc->obedit), ME_CDFLAG_VERT_BWEIGHT);
cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
}
+ else if (t->mode == TFM_VERT_CREASE) {
+ BM_mesh_cd_flag_ensure(bm, BKE_mesh_from_object(tc->obedit), ME_CDFLAG_VERT_CREASE);
+ cd_vert_crease_offset = CustomData_get_offset(&bm->vdata, CD_CREASE);
+ }
TransData *tob = tc->data;
TransDataMirror *td_mirror = tc->data_mirror;
@@ -1645,6 +1650,8 @@ void createTransEditVerts(TransInfo *t)
else if (prop_mode || BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
float *bweight = (cd_vert_bweight_offset != -1) ?
BM_ELEM_CD_GET_VOID_P(eve, cd_vert_bweight_offset) :
+ (cd_vert_crease_offset != -1) ?
+ BM_ELEM_CD_GET_VOID_P(eve, cd_vert_crease_offset) :
NULL;
/* Do not use the island center in case we are using islands
diff --git a/source/blender/editors/transform/transform_convert_mesh_edge.c b/source/blender/editors/transform/transform_convert_mesh_edge.c
index 2db3e259153..2243f66cc7f 100644
--- a/source/blender/editors/transform/transform_convert_mesh_edge.c
+++ b/source/blender/editors/transform/transform_convert_mesh_edge.c
@@ -86,8 +86,8 @@ void createTransEdge(TransInfo *t)
BM_mesh_cd_flag_ensure(em->bm, BKE_mesh_from_object(tc->obedit), ME_CDFLAG_EDGE_BWEIGHT);
cd_edge_float_offset = CustomData_get_offset(&em->bm->edata, CD_BWEIGHT);
}
- else { /* if (t->mode == TFM_CREASE) { */
- BLI_assert(t->mode == TFM_CREASE);
+ else { /* if (t->mode == TFM_EDGE_CREASE) { */
+ BLI_assert(t->mode == TFM_EDGE_CREASE);
BM_mesh_cd_flag_ensure(em->bm, BKE_mesh_from_object(tc->obedit), ME_CDFLAG_EDGE_CREASE);
cd_edge_float_offset = CustomData_get_offset(&em->bm->edata, CD_CREASE);
}
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index 43d894d60f2..d1cbab9ff8a 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -260,7 +260,7 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
}
/* Crease needs edge flag */
- if (ELEM(t->mode, TFM_CREASE, TFM_BWEIGHT)) {
+ if (ELEM(t->mode, TFM_EDGE_CREASE, TFM_BWEIGHT)) {
t->options |= CTX_EDGE_DATA;
}
diff --git a/source/blender/editors/transform/transform_mode.c b/source/blender/editors/transform/transform_mode.c
index 2ab4cdff5e6..e1fea62ae54 100644
--- a/source/blender/editors/transform/transform_mode.c
+++ b/source/blender/editors/transform/transform_mode.c
@@ -1135,8 +1135,11 @@ void transform_mode_init(TransInfo *t, wmOperator *op, const int mode)
case TFM_PUSHPULL:
initPushPull(t);
break;
- case TFM_CREASE:
- initCrease(t);
+ case TFM_EDGE_CREASE:
+ initEgdeCrease(t);
+ break;
+ case TFM_VERT_CREASE:
+ initVertCrease(t);
break;
case TFM_BONESIZE:
initBoneSize(t);
diff --git a/source/blender/editors/transform/transform_mode.h b/source/blender/editors/transform/transform_mode.h
index cdcda5a8648..16b26724c67 100644
--- a/source/blender/editors/transform/transform_mode.h
+++ b/source/blender/editors/transform/transform_mode.h
@@ -106,7 +106,8 @@ void initCurveShrinkFatten(TransInfo *t);
void initBevelWeight(TransInfo *t);
/* transform_mode_edge_crease.c */
-void initCrease(TransInfo *t);
+void initEgdeCrease(TransInfo *t);
+void initVertCrease(TransInfo *t);
/* transform_mode_edge_rotate_normal.c */
void initNormalRotation(TransInfo *t);
diff --git a/source/blender/editors/transform/transform_mode_edge_crease.c b/source/blender/editors/transform/transform_mode_edge_crease.c
index debc2a1be3e..60b95a1d2da 100644
--- a/source/blender/editors/transform/transform_mode_edge_crease.c
+++ b/source/blender/editors/transform/transform_mode_edge_crease.c
@@ -157,9 +157,9 @@ static void applyCrease(TransInfo *t, const int UNUSED(mval[2]))
ED_area_status_text(t->area, str);
}
-void initCrease(TransInfo *t)
+static void initCrease_ex(TransInfo *t, int mode)
{
- t->mode = TFM_CREASE;
+ t->mode = mode;
t->transform = applyCrease;
initMouseInputMode(t, &t->mouse, INPUT_SPRING_DELTA);
@@ -176,4 +176,13 @@ void initCrease(TransInfo *t)
t->flag |= T_NO_CONSTRAINT | T_NO_PROJECT;
}
+void initEgdeCrease(TransInfo *t)
+{
+ initCrease_ex(t, TFM_EDGE_CREASE);
+}
+
+void initVertCrease(TransInfo *t)
+{
+ initCrease_ex(t, TFM_VERT_CREASE);
+}
/** \} */
diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c
index 5ed340abf97..80feb934f1a 100644
--- a/source/blender/editors/transform/transform_ops.c
+++ b/source/blender/editors/transform/transform_ops.c
@@ -78,6 +78,7 @@ static const char OP_BONE_SIZE[] = "TRANSFORM_OT_bbone_resize";
static const char OP_EDGE_SLIDE[] = "TRANSFORM_OT_edge_slide";
static const char OP_VERT_SLIDE[] = "TRANSFORM_OT_vert_slide";
static const char OP_EDGE_CREASE[] = "TRANSFORM_OT_edge_crease";
+static const char OP_VERT_CREASE[] = "TRANSFORM_OT_vert_crease";
static const char OP_EDGE_BWEIGHT[] = "TRANSFORM_OT_edge_bevelweight";
static const char OP_SEQ_SLIDE[] = "TRANSFORM_OT_seq_slide";
static const char OP_NORMAL_ROTATION[] = "TRANSFORM_OT_rotate_normal";
@@ -98,6 +99,7 @@ static void TRANSFORM_OT_bbone_resize(struct wmOperatorType *ot);
static void TRANSFORM_OT_edge_slide(struct wmOperatorType *ot);
static void TRANSFORM_OT_vert_slide(struct wmOperatorType *ot);
static void TRANSFORM_OT_edge_crease(struct wmOperatorType *ot);
+static void TRANSFORM_OT_vert_crease(struct wmOperatorType *ot);
static void TRANSFORM_OT_edge_bevelweight(struct wmOperatorType *ot);
static void TRANSFORM_OT_seq_slide(struct wmOperatorType *ot);
static void TRANSFORM_OT_rotate_normal(struct wmOperatorType *ot);
@@ -118,7 +120,8 @@ static TransformModeItem transform_modes[] = {
{OP_BONE_SIZE, TFM_BONESIZE, TRANSFORM_OT_bbone_resize},
{OP_EDGE_SLIDE, TFM_EDGE_SLIDE, TRANSFORM_OT_edge_slide},
{OP_VERT_SLIDE, TFM_VERT_SLIDE, TRANSFORM_OT_vert_slide},
- {OP_EDGE_CREASE, TFM_CREASE, TRANSFORM_OT_edge_crease},
+ {OP_EDGE_CREASE, TFM_EDGE_CREASE, TRANSFORM_OT_edge_crease},
+ {OP_VERT_CREASE, TFM_VERT_CREASE, TRANSFORM_OT_vert_crease},
{OP_EDGE_BWEIGHT, TFM_BWEIGHT, TRANSFORM_OT_edge_bevelweight},
{OP_SEQ_SLIDE, TFM_SEQ_SLIDE, TRANSFORM_OT_seq_slide},
{OP_NORMAL_ROTATION, TFM_NORMAL_ROTATION, TRANSFORM_OT_rotate_normal},
@@ -139,7 +142,8 @@ const EnumPropertyItem rna_enum_transform_mode_types[] = {
{TFM_TILT, "TILT", 0, "Tilt", ""},
{TFM_TRACKBALL, "TRACKBALL", 0, "Trackball", ""},
{TFM_PUSHPULL, "PUSHPULL", 0, "Push/Pull", ""},
- {TFM_CREASE, "CREASE", 0, "Crease", ""},
+ {TFM_EDGE_CREASE, "CREASE", 0, "Crease", ""},
+ {TFM_VERT_CREASE, "VERTEX_CREASE", 0, "Vertex Crease", ""},
{TFM_MIRROR, "MIRROR", 0, "Mirror", ""},
{TFM_BONESIZE, "BONE_SIZE", 0, "Bone Size", ""},
{TFM_BONE_ENVELOPE, "BONE_ENVELOPE", 0, "Bone Envelope", ""},
@@ -1196,6 +1200,29 @@ static void TRANSFORM_OT_edge_crease(struct wmOperatorType *ot)
Transform_Properties(ot, P_SNAP);
}
+static void TRANSFORM_OT_vert_crease(struct wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Vertex Crease";
+ ot->description = "Change the crease of vertices";
+ ot->idname = OP_VERT_CREASE;
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING;
+
+ /* api callbacks */
+ ot->invoke = transform_invoke;
+ ot->exec = transform_exec;
+ ot->modal = transform_modal;
+ ot->cancel = transform_cancel;
+ ot->poll = ED_operator_editmesh;
+ ot->poll_property = transform_poll_property;
+
+ RNA_def_float_factor(ot->srna, "value", 0, -1.0f, 1.0f, "Factor", "", -1.0f, 1.0f);
+
+ WM_operatortype_props_advanced_begin(ot);
+
+ Transform_Properties(ot, P_SNAP);
+}
+
static void TRANSFORM_OT_edge_bevelweight(struct wmOperatorType *ot)
{
/* identifiers */