diff options
author | Jacques Lucke <jacques@blender.org> | 2022-03-21 20:54:31 +0300 |
---|---|---|
committer | Jacques Lucke <jacques@blender.org> | 2022-03-21 20:59:03 +0300 |
commit | a58be397e2bfbefa0324dbe861b018dd2784ee0d (patch) | |
tree | 4ad14d927e10974e95d3be0a32436888a5260a91 /source/blender/blenkernel | |
parent | f8d19ec5a3d8c14d0c71464867ad1af10ee50eb5 (diff) |
Curves: new Add brush
This adds a new Add brush for the new curves object type in sculpt mode.
The brush is used to insert new curves (typically hair) on the surface object.
Supported features:
* Add single curve exactly at the cursor position when `Add Amount` is 1.
* Front faces only.
* Independent interpolate shape and interpolate length settings.
* Smooth and flat shading affects curve shape interpolation.
* Spherical and projection brush.
This also adds the `surface_triangle_index` and `surface_triangle_coordinate`
attributes. Those store information about what position on the surface each
added curve is attached to:
* `surface_triangle_index` (`int`): Index of the internal triangle that a curve
is attached to. `-1` when the curve is not attached to the surface.
* `surface_triangle_coordinate` (`float2`): First two numbers of a barycentric
coordinate that reference a specific position within the triangle.
Ref T96444.
Differential Revision: https://developer.blender.org/D14340
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r-- | source/blender/blenkernel/BKE_brush.h | 3 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_curves.hh | 18 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/brush.c | 23 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/curves_geometry.cc | 22 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/paint.c | 1 |
5 files changed, 67 insertions, 0 deletions
diff --git a/source/blender/blenkernel/BKE_brush.h b/source/blender/blenkernel/BKE_brush.h index 4b84c0cfe23..a98f4802991 100644 --- a/source/blender/blenkernel/BKE_brush.h +++ b/source/blender/blenkernel/BKE_brush.h @@ -52,6 +52,9 @@ bool BKE_brush_delete(struct Main *bmain, struct Brush *brush); * Add grease pencil settings. */ void BKE_brush_init_gpencil_settings(struct Brush *brush); + +void BKE_brush_init_curves_sculpt_settings(struct Brush *brush); + struct Brush *BKE_brush_first_search(struct Main *bmain, eObjectMode ob_mode); void BKE_brush_sculpt_reset(struct Brush *brush); diff --git a/source/blender/blenkernel/BKE_curves.hh b/source/blender/blenkernel/BKE_curves.hh index ea378c5a0a5..eb4f8f5d5c8 100644 --- a/source/blender/blenkernel/BKE_curves.hh +++ b/source/blender/blenkernel/BKE_curves.hh @@ -203,6 +203,24 @@ class CurvesGeometry : public ::CurvesGeometry { MutableSpan<float> nurbs_weights(); /** + * The index of a triangle (#MLoopTri) that a curve is attached to. + * The index is -1, if the curve is not attached. + */ + VArray<int> surface_triangle_indices() const; + MutableSpan<int> surface_triangle_indices(); + + /** + * Barycentric coordinates of the attachment point within a triangle. + * Only the first two coordinates are stored. The third coordinate can be derived because the sum + * of the three coordinates is 1. + * + * When the triangle index is -1, this coordinate should be ignored. + * The span can be empty, when all triangle indices are -1. + */ + Span<float2> surface_triangle_coords() const; + MutableSpan<float2> surface_triangle_coords(); + + /** * Calculate the largest and smallest position values, only including control points * (rather than evaluated points). The existing values of `min` and `max` are taken into account. * diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index 6ee6ff7f41d..ff07d061a20 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -94,6 +94,9 @@ static void brush_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_src, c brush_dst->gpencil_settings->curve_rand_value = BKE_curvemapping_copy( brush_src->gpencil_settings->curve_rand_value); } + if (brush_src->curves_sculpt_settings != NULL) { + brush_dst->curves_sculpt_settings = MEM_dupallocN(brush_src->curves_sculpt_settings); + } /* enable fake user by default */ id_fake_user_set(&brush_dst->id); @@ -121,6 +124,9 @@ static void brush_free_data(ID *id) MEM_SAFE_FREE(brush->gpencil_settings); } + if (brush->curves_sculpt_settings != NULL) { + MEM_freeN(brush->curves_sculpt_settings); + } MEM_SAFE_FREE(brush->gradient); @@ -236,6 +242,9 @@ static void brush_blend_write(BlendWriter *writer, ID *id, const void *id_addres BKE_curvemapping_blend_write(writer, brush->gpencil_settings->curve_rand_value); } } + if (brush->curves_sculpt_settings) { + BLO_write_struct(writer, BrushCurvesSculptSettings, brush->curves_sculpt_settings); + } if (brush->gradient) { BLO_write_struct(writer, ColorBand, brush->gradient); } @@ -308,6 +317,8 @@ static void brush_blend_read_data(BlendDataReader *reader, ID *id) } } + BLO_read_data_address(reader, &brush->curves_sculpt_settings); + brush->preview = NULL; brush->icon_imbuf = NULL; } @@ -489,6 +500,10 @@ Brush *BKE_brush_add(Main *bmain, const char *name, const eObjectMode ob_mode) brush->ob_mode = ob_mode; + if (ob_mode == OB_MODE_SCULPT_CURVES) { + BKE_brush_init_curves_sculpt_settings(brush); + } + return brush; } @@ -1537,6 +1552,14 @@ void BKE_brush_gpencil_weight_presets(Main *bmain, ToolSettings *ts, const bool } } +void BKE_brush_init_curves_sculpt_settings(Brush *brush) +{ + if (brush->curves_sculpt_settings == NULL) { + brush->curves_sculpt_settings = MEM_callocN(sizeof(BrushCurvesSculptSettings), __func__); + } + brush->curves_sculpt_settings->add_amount = 1; +} + struct Brush *BKE_brush_first_search(struct Main *bmain, const eObjectMode ob_mode) { Brush *brush; diff --git a/source/blender/blenkernel/intern/curves_geometry.cc b/source/blender/blenkernel/intern/curves_geometry.cc index 45f3bf36381..db69fbc4063 100644 --- a/source/blender/blenkernel/intern/curves_geometry.cc +++ b/source/blender/blenkernel/intern/curves_geometry.cc @@ -31,6 +31,8 @@ static const std::string ATTR_HANDLE_POSITION_RIGHT = "handle_right"; static const std::string ATTR_NURBS_ORDER = "nurbs_order"; static const std::string ATTR_NURBS_WEIGHT = "nurbs_weight"; static const std::string ATTR_NURBS_KNOTS_MODE = "knots_mode"; +static const std::string ATTR_SURFACE_TRIANGLE_INDEX = "surface_triangle_index"; +static const std::string ATTR_SURFACE_TRIANGLE_COORDINATE = "surface_triangle_coordinate"; /* -------------------------------------------------------------------- */ /** \name Constructors/Destructor @@ -378,6 +380,26 @@ MutableSpan<int8_t> CurvesGeometry::nurbs_knots_modes() return get_mutable_attribute<int8_t>(*this, ATTR_DOMAIN_CURVE, ATTR_NURBS_KNOTS_MODE); } +VArray<int> CurvesGeometry::surface_triangle_indices() const +{ + return get_varray_attribute<int>(*this, ATTR_DOMAIN_CURVE, ATTR_SURFACE_TRIANGLE_INDEX, -1); +} + +MutableSpan<int> CurvesGeometry::surface_triangle_indices() +{ + return get_mutable_attribute<int>(*this, ATTR_DOMAIN_CURVE, ATTR_SURFACE_TRIANGLE_INDEX); +} + +Span<float2> CurvesGeometry::surface_triangle_coords() const +{ + return get_span_attribute<float2>(*this, ATTR_DOMAIN_CURVE, ATTR_SURFACE_TRIANGLE_COORDINATE); +} + +MutableSpan<float2> CurvesGeometry::surface_triangle_coords() +{ + return get_mutable_attribute<float2>(*this, ATTR_DOMAIN_CURVE, ATTR_SURFACE_TRIANGLE_COORDINATE); +} + /** \} */ /* -------------------------------------------------------------------- */ diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c index 238cf1ad74e..1c58173f570 100644 --- a/source/blender/blenkernel/intern/paint.c +++ b/source/blender/blenkernel/intern/paint.c @@ -1099,6 +1099,7 @@ bool BKE_paint_ensure(ToolSettings *ts, struct Paint **r_paint) } else if ((CurvesSculpt **)r_paint == &ts->curves_sculpt) { CurvesSculpt *data = MEM_callocN(sizeof(*data), __func__); + data->curve_length = 0.3f; paint = &data->paint; } else if (*r_paint == &ts->imapaint.paint) { |