256 const float brush_radius_cu,
261 const float brush_radius_sq_cu =
pow2f(brush_radius_cu);
265 for (
const int curve_i : segment) {
266 const int first_point_i = offsets[curve_i];
267 const float3 old_pos_cu =
self_->initial_deformed_positions_cu_[first_point_i];
269 if (dist_to_brush_sq_cu > brush_radius_sq_cu) {
273 const float dist_to_brush_cu = std::sqrt(dist_to_brush_sq_cu);
275 brush_, dist_to_brush_cu, brush_radius_cu);
277 const float2 uv = surface_uv_coords[curve_i];
279 if (
result.type != ReverseUVSampler::ResultType::Ok) {
292 r_curves_to_slide.
append({curve_i, radius_falloff, normal_cu});
329 for (const SlideCurveInfo &slide_curve_info : slide_curves.slice(range)) {
330 const int curve_i = slide_curve_info.curve_i;
331 const IndexRange points = points_by_curve[curve_i];
332 const int first_point_i = points[0];
334 const float3 old_first_pos_eval_cu = self_->initial_deformed_positions_cu_[first_point_i];
335 const float3 old_first_symm_pos_eval_cu = math::transform_point(brush_transform_inv,
336 old_first_pos_eval_cu);
337 const float3 old_first_pos_eval_su = math::transform_point(transforms_.curves_to_surface,
338 old_first_pos_eval_cu);
340 const float2 old_first_symm_pos_eval_re = ED_view3d_project_float_v2_m4(
341 ctx_.region, old_first_symm_pos_eval_cu, projection);
343 const float radius_falloff = slide_curve_info.radius_falloff;
344 const float curve_weight = brush_strength_ * radius_falloff * curve_factors_[curve_i];
345 const float2 new_first_symm_pos_eval_re = old_first_symm_pos_eval_re +
346 curve_weight * brush_pos_diff_re;
349 float3 ray_start_wo, ray_end_wo;
350 ED_view3d_win_to_segment_clipped(ctx_.depsgraph,
353 new_first_symm_pos_eval_re,
357 const float3 ray_start_su = math::transform_point(world_to_surface_with_symmetry_mat,
359 const float3 ray_end_su = math::transform_point(world_to_surface_with_symmetry_mat,
361 const float3 ray_direction_su = math::normalize(ray_end_su - ray_start_su);
365 float3 hit_pos_eval_su;
366 if (!this->find_closest_ray_hit(ray_start_su,
368 old_first_pos_eval_su,
376 const int3 &tri_eval = surface_corner_tris_eval_[tri_index_eval];
377 const float3 bary_weights_eval = bke::mesh_surface_sample::compute_bary_coord_in_triangle(
378 surface_positions_eval_, surface_corner_verts_eval_, tri_eval, hit_pos_eval_su);
379 const float2 uv = bke::attribute_math::mix3(bary_weights_eval,
380 surface_uv_map_eval_[tri_eval[0]],
381 surface_uv_map_eval_[tri_eval[1]],
382 surface_uv_map_eval_[tri_eval[2]]);
385 const ReverseUVSampler::Result result = reverse_uv_sampler_orig.sample(uv);
386 if (result.type != ReverseUVSampler::ResultType::Ok) {
387 found_invalid_uv_mapping_.store(true);
390 const int3 &tri_orig = surface_corner_tris_orig_[result.tri_index];
391 const float3 &bary_weights_orig = result.bary_weights;
394 const float3 &initial_normal_cu = slide_curve_info.initial_normal_cu;
395 const float3 new_normal_cu = math::normalize(
396 math::transform_point(transforms_.surface_to_curves_normal,
397 geometry::compute_surface_point_normal(
398 tri_orig, result.bary_weights, corner_normals_orig_su_)));
401 const float3 new_first_pos_orig_su = bke::attribute_math::mix3<float3>(
403 positions_orig_su[corner_verts_orig[tri_orig[0]]],
404 positions_orig_su[corner_verts_orig[tri_orig[1]]],
405 positions_orig_su[corner_verts_orig[tri_orig[2]]]);
406 const float3 old_first_pos_orig_cu = self_->initial_positions_cu_[first_point_i];
407 const float3 new_first_pos_orig_cu = math::transform_point(transforms_.surface_to_curves,
408 new_first_pos_orig_su);
411 const float4x4 slide_transform = this->get_slide_transform(
412 old_first_pos_orig_cu, new_first_pos_orig_cu, initial_normal_cu, new_normal_cu);
413 for (const int point_i : points) {
414 positions_orig_cu[point_i] = math::transform_point(
415 slide_transform, self_->initial_positions_cu_[point_i]);
417 surface_uv_coords[curve_i] = uv;