From e0c8d0913b96922844912d6c07aba099b42edd79 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Wed, 13 Apr 2022 09:27:54 +0200 Subject: Curves: remove Test1 brush This was one of multiple placeholder brushes to simplify development. Having it is not necessary anymore. It was a brush that could add new curves according to a specific density. This functionality will be brought back as a new brush later. Ref T97255. --- .../editors/sculpt_paint/curves_sculpt_ops.cc | 427 --------------------- source/blender/makesdna/DNA_brush_enums.h | 1 - source/blender/makesrna/intern/rna_brush.c | 1 - 3 files changed, 429 deletions(-) diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc b/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc index dcfda658bbd..992ac77803a 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc @@ -74,431 +74,6 @@ using blender::bke::CurvesGeometry; /** \name * SCULPT_CURVES_OT_brush_stroke * \{ */ -class DensityAddOperation : public CurvesSculptStrokeOperation { - private: - /** Contains the root points of the curves that existed before this operation started. */ - KDTree_3d *old_kdtree_ = nullptr; - /** Number of points in the kdtree above. */ - int old_kdtree_size_ = 0; - - /** - * Indicates that the corresponding curve has already been created and can't be changed by this - * operation anymore. - */ - static constexpr int ExistsAlreadyIndex = INT32_MAX; - - struct NewPointsData { - Vector bary_coords; - Vector looptri_indices; - Vector positions; - Vector normals; - }; - - public: - ~DensityAddOperation() override - { - if (old_kdtree_ != nullptr) { - BLI_kdtree_3d_free(old_kdtree_); - } - } - - void on_stroke_extended(bContext *C, const StrokeExtension &stroke_extension) override - { - Depsgraph &depsgraph = *CTX_data_depsgraph_pointer(C); - Scene &scene = *CTX_data_scene(C); - Object &object = *CTX_data_active_object(C); - ARegion *region = CTX_wm_region(C); - View3D *v3d = CTX_wm_view3d(C); - - Curves &curves_id = *static_cast(object.data); - CurvesGeometry &curves = CurvesGeometry::wrap(curves_id.geometry); - - if (curves_id.surface == nullptr || curves_id.surface->type != OB_MESH) { - return; - } - - const Object &surface_ob = *curves_id.surface; - const Mesh &surface = *static_cast(surface_ob.data); - const float4x4 surface_ob_mat = surface_ob.obmat; - const float4x4 surface_ob_imat = surface_ob_mat.inverted(); - - ToolSettings &tool_settings = *scene.toolsettings; - CurvesSculpt &curves_sculpt = *tool_settings.curves_sculpt; - Brush &brush = *BKE_paint_brush(&curves_sculpt.paint); - const float brush_radius_screen = BKE_brush_size_get(&scene, &brush); - const float strength = BKE_brush_alpha_get(&scene, &brush); - const float minimum_distance = curves_sculpt.distance; - - /* This is the main ray that is used to determine the brush position in 3D space. */ - float3 ray_start, ray_end; - ED_view3d_win_to_segment_clipped( - &depsgraph, region, v3d, stroke_extension.mouse_position, ray_start, ray_end, true); - ray_start = surface_ob_imat * ray_start; - ray_end = surface_ob_imat * ray_end; - const float3 ray_direction = math::normalize(ray_end - ray_start); - - /* This ray is used to determine the brush radius in 3d space. */ - float3 offset_ray_start, offset_ray_end; - ED_view3d_win_to_segment_clipped(&depsgraph, - region, - v3d, - stroke_extension.mouse_position + - float2(0, brush_radius_screen), - offset_ray_start, - offset_ray_end, - true); - offset_ray_start = surface_ob_imat * offset_ray_start; - offset_ray_end = surface_ob_imat * offset_ray_end; - - float4x4 ob_imat; - invert_m4_m4(ob_imat.values, object.obmat); - - const float4x4 transform = ob_imat * surface_ob_mat; - - BVHTreeFromMesh bvhtree; - BKE_bvhtree_from_mesh_get(&bvhtree, &surface, BVHTREE_FROM_LOOPTRI, 2); - - /* Do a raycast against the surface object to find the brush position. */ - BVHTreeRayHit ray_hit; - ray_hit.dist = FLT_MAX; - ray_hit.index = -1; - BLI_bvhtree_ray_cast(bvhtree.tree, - ray_start, - ray_direction, - 0.0f, - &ray_hit, - bvhtree.raycast_callback, - &bvhtree); - - if (ray_hit.index == -1) { - /* The ray did not hit the surface. */ - free_bvhtree_from_mesh(&bvhtree); - return; - } - /* Brush position in the space of the surface object. */ - const float3 brush_pos_3d_surface = ray_hit.co; - const float brush_radius_3d_surface = dist_to_line_v3( - brush_pos_3d_surface, offset_ray_start, offset_ray_end); - - /* Brush position in the space of the curves object. */ - const float3 brush_pos_3d_curves = transform * brush_pos_3d_surface; - const float brush_radius_3d_curves = dist_to_line_v3( - brush_pos_3d_curves, transform * offset_ray_start, transform * offset_ray_end); - - Vector looptri_indices = this->find_looptri_indices_to_consider( - bvhtree, brush_pos_3d_surface, brush_radius_3d_surface); - - free_bvhtree_from_mesh(&bvhtree); - - if (old_kdtree_ == nullptr && minimum_distance > 0.0f) { - old_kdtree_ = this->kdtree_from_curve_roots_and_positions(curves, curves.curves_range(), {}); - old_kdtree_size_ = curves.curves_num(); - } - - float density; - if (minimum_distance > 0.0f) { - /* Estimate the sampling density based on the target minimum distance. */ - density = strength * pow2f(1.0f / minimum_distance); - } - else { - /* Sample a somewhat constant amount of points based on the strength. */ - const float brush_circle_area_3d = M_PI * pow2f(brush_radius_3d_curves); - density = strength * 100.0f / brush_circle_area_3d; - } - - NewPointsData new_points = this->sample_new_points(density, - minimum_distance, - brush_radius_3d_curves, - brush_pos_3d_curves, - looptri_indices, - transform, - surface); - if (minimum_distance > 0.0f) { - this->eliminate_too_close_points(new_points, curves, minimum_distance); - } - this->insert_new_curves(new_points, curves); - - DEG_id_tag_update(&curves_id.id, ID_RECALC_GEOMETRY); - ED_region_tag_redraw(region); - } - - private: - Vector find_looptri_indices_to_consider(BVHTreeFromMesh &bvhtree, - const float3 &brush_pos, - const float brush_radius_3d) - { - Vector looptri_indices; - - struct RangeQueryUserData { - Vector &indices; - } range_query_user_data = {looptri_indices}; - - BLI_bvhtree_range_query( - bvhtree.tree, - brush_pos, - brush_radius_3d, - [](void *userdata, int index, const float co[3], float dist_sq) { - UNUSED_VARS(co, dist_sq); - RangeQueryUserData &data = *static_cast(userdata); - data.indices.append(index); - }, - &range_query_user_data); - - return looptri_indices; - } - - KDTree_3d *kdtree_from_curve_roots_and_positions(const CurvesGeometry &curves, - const IndexRange curves_range, - Span extra_positions) - { - const int tot_points = curves_range.size() + extra_positions.size(); - KDTree_3d *kdtree = BLI_kdtree_3d_new(tot_points); - for (const int curve_i : curves_range) { - const int first_point_i = curves.offsets()[curve_i]; - const float3 root_position = curves.positions()[first_point_i]; - BLI_kdtree_3d_insert(kdtree, ExistsAlreadyIndex, root_position); - } - for (const int i : extra_positions.index_range()) { - BLI_kdtree_3d_insert(kdtree, i, extra_positions[i]); - } - BLI_kdtree_3d_balance(kdtree); - return kdtree; - } - - bool is_too_close_to_existing_point(const float3 position, const float minimum_distance) const - { - if (old_kdtree_ == nullptr) { - return false; - } - KDTreeNearest_3d nearest; - nearest.index = -1; - BLI_kdtree_3d_find_nearest(old_kdtree_, position, &nearest); - if (nearest.index >= 0 && nearest.dist < minimum_distance) { - return true; - } - return false; - } - - NewPointsData sample_new_points(const float density, - const float minimum_distance, - const float brush_radius_3d, - const float3 &brush_pos, - const Span looptri_indices, - const float4x4 &transform, - const Mesh &surface) - { - const float brush_radius_3d_sq = brush_radius_3d * brush_radius_3d; - const float area_threshold = M_PI * brush_radius_3d_sq; - - const Span looptris{BKE_mesh_runtime_looptri_ensure(&surface), - BKE_mesh_runtime_looptri_len(&surface)}; - - threading::EnumerableThreadSpecific new_points_per_thread; - - const double time = PIL_check_seconds_timer(); - const uint64_t time_as_int = *reinterpret_cast(&time); - const uint32_t rng_base_seed = time_as_int ^ (time_as_int >> 32); - - RandomNumberGenerator rng{rng_base_seed}; - - threading::parallel_for(looptri_indices.index_range(), 512, [&](const IndexRange range) { - RandomNumberGenerator looptri_rng{rng_base_seed + (uint32_t)range.start()}; - - for (const int looptri_index : looptri_indices.slice(range)) { - const MLoopTri &looptri = looptris[looptri_index]; - const float3 &v0 = transform * float3(surface.mvert[surface.mloop[looptri.tri[0]].v].co); - const float3 &v1 = transform * float3(surface.mvert[surface.mloop[looptri.tri[1]].v].co); - const float3 &v2 = transform * float3(surface.mvert[surface.mloop[looptri.tri[2]].v].co); - const float looptri_area = area_tri_v3(v0, v1, v2); - - float3 normal; - normal_tri_v3(normal, v0, v1, v2); - - /* Use a different sampling strategy depending on whether the triangle is large or small - * compared to the brush size. When the triangle is small, points are distributed within - * the triangle directly. If the triangle is larger than the brush, distribute new points - * in a circle on the triangle plane. */ - if (looptri_area < area_threshold) { - const int amount = looptri_rng.round_probabilistic(looptri_area * density); - - threading::parallel_for(IndexRange(amount), 512, [&](const IndexRange amount_range) { - RandomNumberGenerator point_rng{rng_base_seed + looptri_index * 1000 + - (uint32_t)amount_range.start()}; - NewPointsData &new_points = new_points_per_thread.local(); - - for ([[maybe_unused]] const int i : amount_range) { - const float3 bary_coord = point_rng.get_barycentric_coordinates(); - const float3 point_pos = attribute_math::mix3(bary_coord, v0, v1, v2); - - if (math::distance(point_pos, brush_pos) > brush_radius_3d) { - continue; - } - if (minimum_distance > 0.0f && - this->is_too_close_to_existing_point(point_pos, minimum_distance)) { - continue; - } - - new_points.bary_coords.append(bary_coord); - new_points.looptri_indices.append(looptri_index); - new_points.positions.append(point_pos); - new_points.normals.append(normal); - } - }); - } - else { - float3 hit_pos_proj = brush_pos; - project_v3_plane(hit_pos_proj, normal, v0); - const float proj_distance_sq = math::distance_squared(hit_pos_proj, brush_pos); - const float brush_radius_factor_sq = 1.0f - - std::min(1.0f, - proj_distance_sq / brush_radius_3d_sq); - const float radius_proj_sq = brush_radius_3d_sq * brush_radius_factor_sq; - const float radius_proj = std::sqrt(radius_proj_sq); - const float circle_area = M_PI * radius_proj_sq; - - const int amount = rng.round_probabilistic(circle_area * density); - - const float3 axis_1 = math::normalize(v1 - v0) * radius_proj; - const float3 axis_2 = math::normalize( - math::cross(axis_1, math::cross(axis_1, v2 - v0))) * - radius_proj; - - threading::parallel_for(IndexRange(amount), 512, [&](const IndexRange amount_range) { - RandomNumberGenerator point_rng{rng_base_seed + looptri_index * 1000 + - (uint32_t)amount_range.start()}; - NewPointsData &new_points = new_points_per_thread.local(); - - for ([[maybe_unused]] const int i : amount_range) { - const float r = std::sqrt(rng.get_float()); - const float angle = rng.get_float() * 2 * M_PI; - const float x = r * std::cos(angle); - const float y = r * std::sin(angle); - - const float3 point_pos = hit_pos_proj + axis_1 * x + axis_2 * y; - - if (!isect_point_tri_prism_v3(point_pos, v0, v1, v2)) { - continue; - } - if (minimum_distance > 0.0f && - this->is_too_close_to_existing_point(point_pos, minimum_distance)) { - continue; - } - - float3 bary_coord; - interp_weights_tri_v3(bary_coord, v0, v1, v2, point_pos); - - new_points.bary_coords.append(bary_coord); - new_points.looptri_indices.append(looptri_index); - new_points.positions.append(point_pos); - new_points.normals.append(normal); - } - }); - } - } - }); - - NewPointsData new_points; - for (const NewPointsData &local_new_points : new_points_per_thread) { - new_points.bary_coords.extend(local_new_points.bary_coords); - new_points.looptri_indices.extend(local_new_points.looptri_indices); - new_points.positions.extend(local_new_points.positions); - new_points.normals.extend(local_new_points.normals); - } - return new_points; - } - - void eliminate_too_close_points(NewPointsData &points, - const CurvesGeometry &curves, - const float minimum_distance) - { - Array elimination_mask(points.positions.size(), false); - - const int curves_added_previously = curves.curves_num() - old_kdtree_size_; - KDTree_3d *new_points_kdtree = this->kdtree_from_curve_roots_and_positions( - curves, IndexRange(old_kdtree_size_, curves_added_previously), points.positions); - - Array> points_in_range(points.positions.size()); - threading::parallel_for(points.positions.index_range(), 256, [&](const IndexRange range) { - for (const int point_i : range) { - const float3 query_position = points.positions[point_i]; - - struct CallbackData { - int point_i; - Vector &found_indices; - MutableSpan elimination_mask; - } callback_data = {point_i, points_in_range[point_i], elimination_mask}; - - BLI_kdtree_3d_range_search_cb( - new_points_kdtree, - query_position, - minimum_distance, - [](void *user_data, int index, const float *UNUSED(co), float UNUSED(dist_sq)) { - CallbackData &data = *static_cast(user_data); - if (index == data.point_i) { - /* Ignore self. */ - return true; - } - if (index == ExistsAlreadyIndex) { - /* An already existing point is too close, so this new point will be eliminated. */ - data.elimination_mask[data.point_i] = true; - return false; - } - data.found_indices.append(index); - return true; - }, - &callback_data); - } - }); - - for (const int point_i : points.positions.index_range()) { - if (elimination_mask[point_i]) { - /* Point is eliminated already. */ - continue; - } - - for (const int other_point_i : points_in_range[point_i]) { - elimination_mask[other_point_i] = true; - } - } - - BLI_kdtree_3d_free(new_points_kdtree); - for (int i = points.positions.size() - 1; i >= 0; i--) { - if (elimination_mask[i]) { - points.positions.remove_and_reorder(i); - points.bary_coords.remove_and_reorder(i); - points.looptri_indices.remove_and_reorder(i); - points.normals.remove_and_reorder(i); - } - } - } - - void insert_new_curves(const NewPointsData &new_points, CurvesGeometry &curves) - { - const int tot_new_curves = new_points.positions.size(); - - const int points_per_curve = 8; - curves.resize(curves.points_num() + tot_new_curves * points_per_curve, - curves.curves_num() + tot_new_curves); - - MutableSpan offsets = curves.offsets_for_write(); - MutableSpan positions = curves.positions_for_write(); - - for (const int i : IndexRange(tot_new_curves)) { - const int curve_i = curves.curves_num() - tot_new_curves + i; - const int first_point_i = offsets[curve_i]; - offsets[curve_i + 1] = offsets[curve_i] + points_per_curve; - - const float3 root = new_points.positions[i]; - const float3 tip = root + 0.1f * new_points.normals[i]; - - for (const int j : IndexRange(points_per_curve)) { - positions[first_point_i + j] = math::interpolate( - root, tip, j / (float)(points_per_curve - 1)); - } - } - } -}; - static std::unique_ptr start_brush_operation(bContext *C, wmOperator *op) { @@ -518,8 +93,6 @@ static std::unique_ptr start_brush_operation(bConte return new_add_operation(); case CURVES_SCULPT_TOOL_GROW_SHRINK: return new_grow_shrink_operation(mode, C); - case CURVES_SCULPT_TOOL_TEST1: - return std::make_unique(); } BLI_assert_unreachable(); return {}; diff --git a/source/blender/makesdna/DNA_brush_enums.h b/source/blender/makesdna/DNA_brush_enums.h index 96a97648ac9..ee78b610276 100644 --- a/source/blender/makesdna/DNA_brush_enums.h +++ b/source/blender/makesdna/DNA_brush_enums.h @@ -462,7 +462,6 @@ typedef enum eBrushCurvesSculptTool { CURVES_SCULPT_TOOL_SNAKE_HOOK = 2, CURVES_SCULPT_TOOL_ADD = 3, CURVES_SCULPT_TOOL_GROW_SHRINK = 4, - CURVES_SCULPT_TOOL_TEST1 = 5, } eBrushCurvesSculptTool; /** When #BRUSH_ACCUMULATE is used */ diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c index 1b530780261..25dd87b1e74 100644 --- a/source/blender/makesrna/intern/rna_brush.c +++ b/source/blender/makesrna/intern/rna_brush.c @@ -249,7 +249,6 @@ const EnumPropertyItem rna_enum_brush_curves_sculpt_tool_items[] = { {CURVES_SCULPT_TOOL_SNAKE_HOOK, "SNAKE_HOOK", ICON_NONE, "Snake Hook", ""}, {CURVES_SCULPT_TOOL_ADD, "ADD", ICON_NONE, "Add", ""}, {CURVES_SCULPT_TOOL_GROW_SHRINK, "GROW_SHRINK", ICON_NONE, "Grow / Shrink", ""}, - {CURVES_SCULPT_TOOL_TEST1, "TEST1", ICON_NONE, "Test 1", ""}, {0, NULL, 0, NULL, NULL}, }; -- cgit v1.2.3