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/sculpt_paint/curves_sculpt_comb.cc')
-rw-r--r--source/blender/editors/sculpt_paint/curves_sculpt_comb.cc119
1 files changed, 67 insertions, 52 deletions
diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_comb.cc b/source/blender/editors/sculpt_paint/curves_sculpt_comb.cc
index ae0a512c5ee..52f2ddc6550 100644
--- a/source/blender/editors/sculpt_paint/curves_sculpt_comb.cc
+++ b/source/blender/editors/sculpt_paint/curves_sculpt_comb.cc
@@ -13,12 +13,15 @@
#include "PIL_time.h"
#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
#include "BKE_attribute_math.hh"
#include "BKE_brush.h"
#include "BKE_bvhutils.h"
#include "BKE_context.h"
+#include "BKE_crazyspace.hh"
#include "BKE_curves.hh"
+#include "BKE_geometry_set.hh"
#include "BKE_mesh.h"
#include "BKE_mesh_runtime.h"
#include "BKE_paint.h"
@@ -88,9 +91,9 @@ struct CombOperationExecutor {
eBrushFalloffShape falloff_shape_;
- Object *object_ = nullptr;
- Curves *curves_id_ = nullptr;
- CurvesGeometry *curves_ = nullptr;
+ Object *curves_ob_orig_ = nullptr;
+ Curves *curves_id_orig_ = nullptr;
+ CurvesGeometry *curves_orig_ = nullptr;
VArray<float> point_factors_;
Vector<int64_t> selected_curve_indices_;
@@ -100,8 +103,7 @@ struct CombOperationExecutor {
float2 brush_pos_re_;
float2 brush_pos_diff_re_;
- float4x4 curves_to_world_mat_;
- float4x4 world_to_curves_mat_;
+ CurvesSurfaceTransforms transforms_;
CombOperationExecutor(const bContext &C) : ctx_(C)
{
@@ -113,7 +115,12 @@ struct CombOperationExecutor {
BLI_SCOPED_DEFER([&]() { self_->brush_pos_last_re_ = stroke_extension.mouse_position; });
- object_ = CTX_data_active_object(&C);
+ curves_ob_orig_ = CTX_data_active_object(&C);
+ curves_id_orig_ = static_cast<Curves *>(curves_ob_orig_->data);
+ curves_orig_ = &CurvesGeometry::wrap(curves_id_orig_->geometry);
+ if (curves_orig_->curves_num() == 0) {
+ return;
+ }
curves_sculpt_ = ctx_.scene->toolsettings->curves_sculpt;
brush_ = BKE_paint_brush_for_read(&curves_sculpt_->paint);
@@ -121,19 +128,12 @@ struct CombOperationExecutor {
brush_radius_factor_ = brush_radius_factor(*brush_, stroke_extension);
brush_strength_ = brush_strength_get(*ctx_.scene, *brush_, stroke_extension);
- curves_to_world_mat_ = object_->obmat;
- world_to_curves_mat_ = curves_to_world_mat_.inverted();
-
falloff_shape_ = static_cast<eBrushFalloffShape>(brush_->falloff_shape);
- curves_id_ = static_cast<Curves *>(object_->data);
- curves_ = &CurvesGeometry::wrap(curves_id_->geometry);
- if (curves_->curves_num() == 0) {
- return;
- }
+ transforms_ = CurvesSurfaceTransforms(*curves_ob_orig_, curves_id_orig_->surface);
- point_factors_ = get_point_selection(*curves_id_);
- curve_selection_ = retrieve_selected_curves(*curves_id_, selected_curve_indices_);
+ point_factors_ = get_point_selection(*curves_id_orig_);
+ curve_selection_ = retrieve_selected_curves(*curves_id_orig_, selected_curve_indices_);
brush_pos_prev_re_ = self_->brush_pos_last_re_;
brush_pos_re_ = stroke_extension.mouse_position;
@@ -162,9 +162,9 @@ struct CombOperationExecutor {
this->restore_segment_lengths(changed_curves);
- curves_->tag_positions_changed();
- DEG_id_tag_update(&curves_id_->id, ID_RECALC_GEOMETRY);
- WM_main_add_notifier(NC_GEOM | ND_DATA, &curves_id_->id);
+ curves_orig_->tag_positions_changed();
+ DEG_id_tag_update(&curves_id_orig_->id, ID_RECALC_GEOMETRY);
+ WM_main_add_notifier(NC_GEOM | ND_DATA, &curves_id_orig_->id);
ED_region_tag_redraw(ctx_.region);
}
@@ -174,7 +174,7 @@ struct CombOperationExecutor {
void comb_projected_with_symmetry(EnumerableThreadSpecific<Vector<int>> &r_changed_curves)
{
const Vector<float4x4> symmetry_brush_transforms = get_symmetry_brush_transforms(
- eCurvesSymmetryType(curves_id_->symmetry));
+ eCurvesSymmetryType(curves_id_orig_->symmetry));
for (const float4x4 &brush_transform : symmetry_brush_transforms) {
this->comb_projected(r_changed_curves, brush_transform);
}
@@ -185,10 +185,12 @@ struct CombOperationExecutor {
{
const float4x4 brush_transform_inv = brush_transform.inverted();
- MutableSpan<float3> positions_cu = curves_->positions_for_write();
+ MutableSpan<float3> positions_cu_orig = curves_orig_->positions_for_write();
+ const bke::crazyspace::GeometryDeformation deformation =
+ bke::crazyspace::get_evaluated_curves_deformation(*ctx_.depsgraph, *curves_ob_orig_);
float4x4 projection;
- ED_view3d_ob_project_mat_get(ctx_.rv3d, object_, projection.values);
+ ED_view3d_ob_project_mat_get(ctx_.rv3d, curves_ob_orig_, projection.values);
const float brush_radius_re = brush_radius_base_re_ * brush_radius_factor_;
const float brush_radius_sq_re = pow2f(brush_radius_re);
@@ -197,16 +199,18 @@ struct CombOperationExecutor {
Vector<int> &local_changed_curves = r_changed_curves.local();
for (const int curve_i : curve_selection_.slice(range)) {
bool curve_changed = false;
- const IndexRange points = curves_->points_for_curve(curve_i);
+ const IndexRange points = curves_orig_->points_for_curve(curve_i);
for (const int point_i : points.drop_front(1)) {
- const float3 old_pos_cu = brush_transform_inv * positions_cu[point_i];
+ const float3 old_pos_cu = deformation.positions[point_i];
+ const float3 old_symm_pos_cu = brush_transform_inv * old_pos_cu;
/* Find the position of the point in screen space. */
- float2 old_pos_re;
- ED_view3d_project_float_v2_m4(ctx_.region, old_pos_cu, old_pos_re, projection.values);
+ float2 old_symm_pos_re;
+ ED_view3d_project_float_v2_m4(
+ ctx_.region, old_symm_pos_cu, old_symm_pos_re, projection.values);
const float distance_to_brush_sq_re = dist_squared_to_line_segment_v2(
- old_pos_re, brush_pos_prev_re_, brush_pos_re_);
+ old_symm_pos_re, brush_pos_prev_re_, brush_pos_re_);
if (distance_to_brush_sq_re > brush_radius_sq_re) {
/* Ignore the point because it's too far away. */
continue;
@@ -221,16 +225,20 @@ struct CombOperationExecutor {
/* Offset the old point position in screen space and transform it back into 3D space.
*/
- const float2 new_position_re = old_pos_re + brush_pos_diff_re_ * weight;
- float3 new_position_wo;
+ const float2 new_symm_pos_re = old_symm_pos_re + brush_pos_diff_re_ * weight;
+ float3 new_symm_pos_wo;
ED_view3d_win_to_3d(ctx_.v3d,
ctx_.region,
- curves_to_world_mat_ * old_pos_cu,
- new_position_re,
- new_position_wo);
- const float3 new_position_cu = brush_transform *
- (world_to_curves_mat_ * new_position_wo);
- positions_cu[point_i] = new_position_cu;
+ transforms_.curves_to_world * old_symm_pos_cu,
+ new_symm_pos_re,
+ new_symm_pos_wo);
+ const float3 new_pos_cu = brush_transform *
+ (transforms_.world_to_curves * new_symm_pos_wo);
+
+ const float3 translation_eval = new_pos_cu - old_pos_cu;
+ const float3 translation_orig = deformation.translation_from_deformed_to_original(
+ point_i, translation_eval);
+ positions_cu_orig[point_i] += translation_orig;
curve_changed = true;
}
@@ -247,26 +255,26 @@ struct CombOperationExecutor {
void comb_spherical_with_symmetry(EnumerableThreadSpecific<Vector<int>> &r_changed_curves)
{
float4x4 projection;
- ED_view3d_ob_project_mat_get(ctx_.rv3d, object_, projection.values);
+ ED_view3d_ob_project_mat_get(ctx_.rv3d, curves_ob_orig_, projection.values);
float3 brush_start_wo, brush_end_wo;
ED_view3d_win_to_3d(ctx_.v3d,
ctx_.region,
- curves_to_world_mat_ * self_->brush_3d_.position_cu,
+ transforms_.curves_to_world * self_->brush_3d_.position_cu,
brush_pos_prev_re_,
brush_start_wo);
ED_view3d_win_to_3d(ctx_.v3d,
ctx_.region,
- curves_to_world_mat_ * self_->brush_3d_.position_cu,
+ transforms_.curves_to_world * self_->brush_3d_.position_cu,
brush_pos_re_,
brush_end_wo);
- const float3 brush_start_cu = world_to_curves_mat_ * brush_start_wo;
- const float3 brush_end_cu = world_to_curves_mat_ * brush_end_wo;
+ const float3 brush_start_cu = transforms_.world_to_curves * brush_start_wo;
+ const float3 brush_end_cu = transforms_.world_to_curves * brush_end_wo;
const float brush_radius_cu = self_->brush_3d_.radius_cu * brush_radius_factor_;
const Vector<float4x4> symmetry_brush_transforms = get_symmetry_brush_transforms(
- eCurvesSymmetryType(curves_id_->symmetry));
+ eCurvesSymmetryType(curves_id_orig_->symmetry));
for (const float4x4 &brush_transform : symmetry_brush_transforms) {
this->comb_spherical(r_changed_curves,
brush_transform * brush_start_cu,
@@ -280,17 +288,20 @@ struct CombOperationExecutor {
const float3 &brush_end_cu,
const float brush_radius_cu)
{
- MutableSpan<float3> positions_cu = curves_->positions_for_write();
+ MutableSpan<float3> positions_cu = curves_orig_->positions_for_write();
const float brush_radius_sq_cu = pow2f(brush_radius_cu);
const float3 brush_diff_cu = brush_end_cu - brush_start_cu;
+ const bke::crazyspace::GeometryDeformation deformation =
+ bke::crazyspace::get_evaluated_curves_deformation(*ctx_.depsgraph, *curves_ob_orig_);
+
threading::parallel_for(curve_selection_.index_range(), 256, [&](const IndexRange range) {
Vector<int> &local_changed_curves = r_changed_curves.local();
for (const int curve_i : curve_selection_.slice(range)) {
bool curve_changed = false;
- const IndexRange points = curves_->points_for_curve(curve_i);
+ const IndexRange points = curves_orig_->points_for_curve(curve_i);
for (const int point_i : points.drop_front(1)) {
- const float3 pos_old_cu = positions_cu[point_i];
+ const float3 pos_old_cu = deformation.positions[point_i];
/* Compute distance to the brush. */
const float distance_to_brush_sq_cu = dist_squared_to_line_segment_v3(
@@ -308,8 +319,12 @@ struct CombOperationExecutor {
/* Combine the falloff and brush strength. */
const float weight = brush_strength_ * radius_falloff * point_factors_[point_i];
+ const float3 translation_eval_cu = weight * brush_diff_cu;
+ const float3 translation_orig_cu = deformation.translation_from_deformed_to_original(
+ point_i, translation_eval_cu);
+
/* Update the point position. */
- positions_cu[point_i] = pos_old_cu + weight * brush_diff_cu;
+ positions_cu[point_i] += translation_orig_cu;
curve_changed = true;
}
if (curve_changed) {
@@ -328,7 +343,7 @@ struct CombOperationExecutor {
*ctx_.region,
*ctx_.v3d,
*ctx_.rv3d,
- *object_,
+ *curves_ob_orig_,
brush_pos_re_,
brush_radius_base_re_);
if (brush_3d.has_value()) {
@@ -342,11 +357,11 @@ struct CombOperationExecutor {
*/
void initialize_segment_lengths()
{
- const Span<float3> positions_cu = curves_->positions();
- self_->segment_lengths_cu_.reinitialize(curves_->points_num());
- threading::parallel_for(curves_->curves_range(), 128, [&](const IndexRange range) {
+ const Span<float3> positions_cu = curves_orig_->positions();
+ self_->segment_lengths_cu_.reinitialize(curves_orig_->points_num());
+ threading::parallel_for(curves_orig_->curves_range(), 128, [&](const IndexRange range) {
for (const int curve_i : range) {
- const IndexRange points = curves_->points_for_curve(curve_i);
+ const IndexRange points = curves_orig_->points_for_curve(curve_i);
for (const int point_i : points.drop_back(1)) {
const float3 &p1_cu = positions_cu[point_i];
const float3 &p2_cu = positions_cu[point_i + 1];
@@ -363,12 +378,12 @@ struct CombOperationExecutor {
void restore_segment_lengths(EnumerableThreadSpecific<Vector<int>> &changed_curves)
{
const Span<float> expected_lengths_cu = self_->segment_lengths_cu_;
- MutableSpan<float3> positions_cu = curves_->positions_for_write();
+ MutableSpan<float3> positions_cu = curves_orig_->positions_for_write();
threading::parallel_for_each(changed_curves, [&](const Vector<int> &changed_curves) {
threading::parallel_for(changed_curves.index_range(), 256, [&](const IndexRange range) {
for (const int curve_i : changed_curves.as_span().slice(range)) {
- const IndexRange points = curves_->points_for_curve(curve_i);
+ const IndexRange points = curves_orig_->points_for_curve(curve_i);
for (const int segment_i : points.drop_back(1)) {
const float3 &p1_cu = positions_cu[segment_i];
float3 &p2_cu = positions_cu[segment_i + 1];