Cleanup: Simplify sculpt affected node gathering
- Move functions to C++ namespace - Use two functions with simpler responsibilities instead - Use C++ math functions - Remove arguments structs left over from before C++ transition - Return ray distance precalculation by value
This commit is contained in:
@@ -2368,16 +2368,13 @@ void clip_ray_ortho(
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
struct FindNearestRayData {
|
||||
DistRayAABB_Precalc dist_ray_to_aabb_precalc;
|
||||
bool original;
|
||||
};
|
||||
|
||||
static bool nearest_to_ray_aabb_dist_sq(PBVHNode *node, FindNearestRayData *rcd)
|
||||
static bool nearest_to_ray_aabb_dist_sq(PBVHNode *node,
|
||||
const DistRayAABB_Precalc &dist_ray_to_aabb_precalc,
|
||||
const bool original)
|
||||
{
|
||||
const float *bb_min, *bb_max;
|
||||
|
||||
if (rcd->original) {
|
||||
if (original) {
|
||||
/* BKE_pbvh_node_get_original_BB */
|
||||
bb_min = node->orig_vb.min;
|
||||
bb_max = node->orig_vb.max;
|
||||
@@ -2390,7 +2387,7 @@ static bool nearest_to_ray_aabb_dist_sq(PBVHNode *node, FindNearestRayData *rcd)
|
||||
|
||||
float co_dummy[3], depth;
|
||||
node->tmin = dist_squared_ray_to_aabb_v3(
|
||||
&rcd->dist_ray_to_aabb_precalc, bb_min, bb_max, co_dummy, &depth);
|
||||
&dist_ray_to_aabb_precalc, bb_min, bb_max, co_dummy, &depth);
|
||||
/* Ideally we would skip distances outside the range. */
|
||||
return depth > 0.0f;
|
||||
}
|
||||
@@ -2399,15 +2396,17 @@ void find_nearest_to_ray(PBVH *pbvh,
|
||||
const FunctionRef<void(PBVHNode &node, float *tmin)> fn,
|
||||
const float ray_start[3],
|
||||
const float ray_normal[3],
|
||||
bool original)
|
||||
const bool original)
|
||||
{
|
||||
FindNearestRayData ncd;
|
||||
|
||||
dist_squared_ray_to_aabb_v3_precalc(&ncd.dist_ray_to_aabb_precalc, ray_start, ray_normal);
|
||||
ncd.original = original;
|
||||
const DistRayAABB_Precalc ray_dist_precalc = dist_squared_ray_to_aabb_v3_precalc(ray_start,
|
||||
ray_normal);
|
||||
|
||||
search_callback_occluded(
|
||||
pbvh, [&](PBVHNode &node) { return nearest_to_ray_aabb_dist_sq(&node, &ncd); }, fn);
|
||||
pbvh,
|
||||
[&](PBVHNode &node) {
|
||||
return nearest_to_ray_aabb_dist_sq(&node, ray_dist_precalc, original);
|
||||
},
|
||||
fn);
|
||||
}
|
||||
|
||||
static bool pbvh_faces_node_nearest_to_ray(PBVH *pbvh,
|
||||
|
||||
@@ -250,9 +250,8 @@ struct DistRayAABB_Precalc {
|
||||
float ray_direction[3];
|
||||
float ray_inv_dir[3];
|
||||
};
|
||||
void dist_squared_ray_to_aabb_v3_precalc(struct DistRayAABB_Precalc *neasrest_precalc,
|
||||
const float ray_origin[3],
|
||||
const float ray_direction[3]);
|
||||
struct DistRayAABB_Precalc dist_squared_ray_to_aabb_v3_precalc(const float ray_origin[3],
|
||||
const float ray_direction[3]);
|
||||
/**
|
||||
* Returns the distance from a ray to a bound-box (projected on ray)
|
||||
*/
|
||||
|
||||
@@ -655,18 +655,19 @@ void aabb_get_near_far_from_plane(const float plane_no[3],
|
||||
/** \name dist_squared_to_ray_to_aabb and helpers
|
||||
* \{ */
|
||||
|
||||
void dist_squared_ray_to_aabb_v3_precalc(DistRayAABB_Precalc *neasrest_precalc,
|
||||
const float ray_origin[3],
|
||||
const float ray_direction[3])
|
||||
DistRayAABB_Precalc dist_squared_ray_to_aabb_v3_precalc(const float ray_origin[3],
|
||||
const float ray_direction[3])
|
||||
{
|
||||
copy_v3_v3(neasrest_precalc->ray_origin, ray_origin);
|
||||
copy_v3_v3(neasrest_precalc->ray_direction, ray_direction);
|
||||
DistRayAABB_Precalc nearest_precalc{};
|
||||
copy_v3_v3(nearest_precalc.ray_origin, ray_origin);
|
||||
copy_v3_v3(nearest_precalc.ray_direction, ray_direction);
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
neasrest_precalc->ray_inv_dir[i] = (neasrest_precalc->ray_direction[i] != 0.0f) ?
|
||||
(1.0f / neasrest_precalc->ray_direction[i]) :
|
||||
FLT_MAX;
|
||||
nearest_precalc.ray_inv_dir[i] = (nearest_precalc.ray_direction[i] != 0.0f) ?
|
||||
(1.0f / nearest_precalc.ray_direction[i]) :
|
||||
FLT_MAX;
|
||||
}
|
||||
return nearest_precalc;
|
||||
}
|
||||
|
||||
float dist_squared_ray_to_aabb_v3(const DistRayAABB_Precalc *data,
|
||||
@@ -765,8 +766,7 @@ float dist_squared_ray_to_aabb_v3_simple(const float ray_origin[3],
|
||||
float r_point[3],
|
||||
float *r_depth)
|
||||
{
|
||||
DistRayAABB_Precalc data;
|
||||
dist_squared_ray_to_aabb_v3_precalc(&data, ray_origin, ray_direction);
|
||||
const DistRayAABB_Precalc data = dist_squared_ray_to_aabb_v3_precalc(ray_origin, ray_direction);
|
||||
return dist_squared_ray_to_aabb_v3(&data, bb_min, bb_max, r_point, r_depth);
|
||||
}
|
||||
|
||||
|
||||
@@ -282,14 +282,9 @@ Vector<PBVHNode *> pbvh_gather_generic(Object *ob, VPaint *wp, Sculpt *sd, Brush
|
||||
|
||||
/* Build a list of all nodes that are potentially within the brush's area of influence */
|
||||
if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE) {
|
||||
SculptSearchSphereData data = {nullptr};
|
||||
data.ss = ss;
|
||||
data.sd = sd;
|
||||
data.radius_squared = ss->cache->radius_squared;
|
||||
data.original = true;
|
||||
|
||||
nodes = blender::bke::pbvh::search_gather(
|
||||
ss->pbvh, [&](PBVHNode &node) { return SCULPT_search_sphere(&node, &data); });
|
||||
nodes = bke::pbvh::search_gather(ss->pbvh, [&](PBVHNode &node) {
|
||||
return node_in_sphere(node, ss->cache->location, ss->cache->radius_squared, true);
|
||||
});
|
||||
|
||||
if (use_normal) {
|
||||
SCULPT_pbvh_calc_area_normal(brush, ob, nodes, ss->cache->sculpt_normal_symm);
|
||||
@@ -299,18 +294,12 @@ Vector<PBVHNode *> pbvh_gather_generic(Object *ob, VPaint *wp, Sculpt *sd, Brush
|
||||
}
|
||||
}
|
||||
else {
|
||||
DistRayAABB_Precalc dist_ray_to_aabb_precalc;
|
||||
dist_squared_ray_to_aabb_v3_precalc(
|
||||
&dist_ray_to_aabb_precalc, ss->cache->location, ss->cache->view_normal);
|
||||
SculptSearchCircleData data = {nullptr};
|
||||
data.ss = ss;
|
||||
data.sd = sd;
|
||||
data.radius_squared = ss->cache->radius_squared;
|
||||
data.original = true;
|
||||
data.dist_ray_to_aabb_precalc = &dist_ray_to_aabb_precalc;
|
||||
|
||||
nodes = blender::bke::pbvh::search_gather(
|
||||
ss->pbvh, [&](PBVHNode &node) { return SCULPT_search_circle(&node, &data); });
|
||||
const DistRayAABB_Precalc ray_dist_precalc = dist_squared_ray_to_aabb_v3_precalc(
|
||||
ss->cache->location, ss->cache->view_normal);
|
||||
nodes = bke::pbvh::search_gather(ss->pbvh, [&](PBVHNode &node) {
|
||||
return node_in_cylinder(
|
||||
ray_dist_precalc, node, ss->cache->location, ss->cache->radius_squared, true);
|
||||
});
|
||||
|
||||
if (use_normal) {
|
||||
copy_v3_v3(ss->cache->sculpt_normal_symm, ss->cache->view_normal);
|
||||
|
||||
@@ -906,22 +906,18 @@ PBVHVertRef SCULPT_nearest_vertex_get(
|
||||
Sculpt *sd, Object *ob, const float co[3], float max_distance, bool use_original)
|
||||
{
|
||||
using namespace blender;
|
||||
using namespace blender::ed::sculpt_paint;
|
||||
SculptSession *ss = ob->sculpt;
|
||||
|
||||
SculptSearchSphereData data{};
|
||||
data.sd = sd;
|
||||
data.radius_squared = max_distance * max_distance;
|
||||
data.original = use_original;
|
||||
data.center = co;
|
||||
const float max_distance_sq = max_distance * max_distance;
|
||||
|
||||
Vector<PBVHNode *> nodes = blender::bke::pbvh::search_gather(
|
||||
ss->pbvh, [&](PBVHNode &node) { return SCULPT_search_sphere(&node, &data); });
|
||||
Vector<PBVHNode *> nodes = blender::bke::pbvh::search_gather(ss->pbvh, [&](PBVHNode &node) {
|
||||
return node_in_sphere(node, co, max_distance_sq, use_original);
|
||||
});
|
||||
if (nodes.is_empty()) {
|
||||
return BKE_pbvh_make_vref(PBVH_REF_NONE);
|
||||
}
|
||||
|
||||
const float max_distance_sq = max_distance * max_distance;
|
||||
|
||||
return threading::parallel_reduce(
|
||||
nodes.index_range(),
|
||||
1,
|
||||
@@ -2481,69 +2477,49 @@ void SCULPT_calc_vertex_displacement(SculptSession *ss,
|
||||
flip_v3_v3(r_offset, rgba, ss->cache->mirror_symmetry_pass);
|
||||
}
|
||||
|
||||
bool SCULPT_search_sphere(PBVHNode *node, SculptSearchSphereData *data)
|
||||
namespace blender::ed::sculpt_paint {
|
||||
|
||||
bool node_fully_masked_or_hidden(const PBVHNode &node)
|
||||
{
|
||||
using namespace blender;
|
||||
const float *center;
|
||||
float nearest[3];
|
||||
if (data->center) {
|
||||
center = data->center;
|
||||
if (BKE_pbvh_node_fully_hidden_get(&node)) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
center = data->ss->cache ? data->ss->cache->location : data->ss->cursor_location;
|
||||
if (BKE_pbvh_node_fully_masked_get(&node)) {
|
||||
return true;
|
||||
}
|
||||
float t[3];
|
||||
|
||||
if (data->ignore_fully_ineffective) {
|
||||
if (BKE_pbvh_node_fully_hidden_get(node)) {
|
||||
return false;
|
||||
}
|
||||
if (BKE_pbvh_node_fully_masked_get(node)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const Bounds<float3> bounds = (data->original) ? BKE_pbvh_node_get_original_BB(node) :
|
||||
BKE_pbvh_node_get_BB(node);
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (bounds.min[i] > center[i]) {
|
||||
nearest[i] = bounds.min[i];
|
||||
}
|
||||
else if (bounds.max[i] < center[i]) {
|
||||
nearest[i] = bounds.max[i];
|
||||
}
|
||||
else {
|
||||
nearest[i] = center[i];
|
||||
}
|
||||
}
|
||||
|
||||
sub_v3_v3v3(t, center, nearest);
|
||||
|
||||
return len_squared_v3(t) < data->radius_squared;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SCULPT_search_circle(PBVHNode *node, SculptSearchCircleData *data)
|
||||
bool node_in_sphere(const PBVHNode &node,
|
||||
const float3 &location,
|
||||
const float radius_sq,
|
||||
const bool original)
|
||||
{
|
||||
using namespace blender;
|
||||
if (data->ignore_fully_ineffective) {
|
||||
if (BKE_pbvh_node_fully_masked_get(node)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
const Bounds<float3> bounds = original ? BKE_pbvh_node_get_original_BB(&node) :
|
||||
BKE_pbvh_node_get_BB(&node);
|
||||
const float3 nearest = math::clamp(location, bounds.min, bounds.max);
|
||||
return math::distance_squared(location, nearest) < radius_sq;
|
||||
}
|
||||
|
||||
const Bounds<float3> bounds = (data->original) ? BKE_pbvh_node_get_original_BB(node) :
|
||||
BKE_pbvh_node_get_BB(node);
|
||||
bool node_in_cylinder(const DistRayAABB_Precalc &ray_dist_precalc,
|
||||
const PBVHNode &node,
|
||||
const float3 &location,
|
||||
float radius_sq,
|
||||
bool original)
|
||||
{
|
||||
const Bounds<float3> bounds = (original) ? BKE_pbvh_node_get_original_BB(&node) :
|
||||
BKE_pbvh_node_get_BB(&node);
|
||||
|
||||
float dummy_co[3], dummy_depth;
|
||||
const float dist_sq = dist_squared_ray_to_aabb_v3(
|
||||
data->dist_ray_to_aabb_precalc, bounds.min, bounds.max, dummy_co, &dummy_depth);
|
||||
&ray_dist_precalc, bounds.min, bounds.max, dummy_co, &dummy_depth);
|
||||
|
||||
/* Seems like debug code.
|
||||
* Maybe this function can just return true if the node is not fully masked. */
|
||||
return dist_sq < data->radius_squared || true;
|
||||
/* TODO: Solve issues and enable distance check. */
|
||||
return dist_sq < radius_sq || true;
|
||||
}
|
||||
|
||||
} // namespace blender::ed::sculpt_paint
|
||||
|
||||
void SCULPT_clip(Sculpt *sd, SculptSession *ss, float co[3], const float val[3])
|
||||
{
|
||||
for (int i = 0; i < 3; i++) {
|
||||
@@ -2575,23 +2551,20 @@ void SCULPT_clip(Sculpt *sd, SculptSession *ss, float co[3], const float val[3])
|
||||
}
|
||||
}
|
||||
|
||||
namespace blender::ed::sculpt_paint {
|
||||
|
||||
static Vector<PBVHNode *> sculpt_pbvh_gather_cursor_update(Object *ob,
|
||||
Sculpt *sd,
|
||||
bool use_original)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
SculptSearchSphereData data{};
|
||||
data.ss = ss;
|
||||
data.sd = sd;
|
||||
data.radius_squared = ss->cursor_radius;
|
||||
data.original = use_original;
|
||||
data.ignore_fully_ineffective = false;
|
||||
data.center = nullptr;
|
||||
|
||||
return blender::bke::pbvh::search_gather(
|
||||
ss->pbvh, [&](PBVHNode &node) { return SCULPT_search_sphere(&node, &data); });
|
||||
const float3 center = ss->cache ? ss->cache->location : ss->cursor_location;
|
||||
return bke::pbvh::search_gather(ss->pbvh, [&](PBVHNode &node) {
|
||||
return node_in_sphere(node, center, ss->cursor_radius, use_original);
|
||||
});
|
||||
}
|
||||
|
||||
/** \return All nodes that are potentially within the cursor or brush's area of influence. */
|
||||
static Vector<PBVHNode *> sculpt_pbvh_gather_generic_intern(Object *ob,
|
||||
Sculpt *sd,
|
||||
const Brush *brush,
|
||||
@@ -2600,43 +2573,44 @@ static Vector<PBVHNode *> sculpt_pbvh_gather_generic_intern(Object *ob,
|
||||
PBVHNodeFlags flag)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
Vector<PBVHNode *> nodes;
|
||||
PBVHNodeFlags leaf_flag = PBVH_Leaf;
|
||||
|
||||
PBVHNodeFlags leaf_flag = PBVH_Leaf;
|
||||
if (flag & PBVH_TexLeaf) {
|
||||
leaf_flag = PBVH_TexLeaf;
|
||||
}
|
||||
|
||||
/* Build a list of all nodes that are potentially within the cursor or brush's area of influence.
|
||||
*/
|
||||
if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE) {
|
||||
SculptSearchSphereData data{};
|
||||
data.ss = ss;
|
||||
data.sd = sd;
|
||||
data.radius_squared = square_f(ss->cache->radius * radius_scale);
|
||||
data.original = use_original;
|
||||
data.ignore_fully_ineffective = brush->sculpt_tool != SCULPT_TOOL_MASK;
|
||||
data.center = nullptr;
|
||||
nodes = blender::bke::pbvh::search_gather(
|
||||
ss->pbvh, [&](PBVHNode &node) { return SCULPT_search_sphere(&node, &data); }, leaf_flag);
|
||||
}
|
||||
else {
|
||||
DistRayAABB_Precalc dist_ray_to_aabb_precalc;
|
||||
dist_squared_ray_to_aabb_v3_precalc(
|
||||
&dist_ray_to_aabb_precalc, ss->cache->location, ss->cache->view_normal);
|
||||
SculptSearchCircleData data{};
|
||||
data.ss = ss;
|
||||
data.sd = sd;
|
||||
data.radius_squared = ss->cache ? square_f(ss->cache->radius * radius_scale) :
|
||||
ss->cursor_radius;
|
||||
data.original = use_original;
|
||||
data.dist_ray_to_aabb_precalc = &dist_ray_to_aabb_precalc;
|
||||
data.ignore_fully_ineffective = brush->sculpt_tool != SCULPT_TOOL_MASK;
|
||||
nodes = blender::bke::pbvh::search_gather(
|
||||
ss->pbvh, [&](PBVHNode &node) { return SCULPT_search_circle(&node, &data); }, leaf_flag);
|
||||
const float3 center = ss->cache->location;
|
||||
const float radius_sq = math::square(ss->cache->radius * radius_scale);
|
||||
const bool ignore_ineffective = brush->sculpt_tool != SCULPT_TOOL_MASK;
|
||||
switch (brush->falloff_shape) {
|
||||
case PAINT_FALLOFF_SHAPE_SPHERE: {
|
||||
return bke::pbvh::search_gather(
|
||||
ss->pbvh,
|
||||
[&](PBVHNode &node) {
|
||||
if (ignore_ineffective && node_fully_masked_or_hidden(node)) {
|
||||
return false;
|
||||
}
|
||||
return node_in_sphere(node, center, radius_sq, use_original);
|
||||
},
|
||||
leaf_flag);
|
||||
}
|
||||
|
||||
case PAINT_FALLOFF_SHAPE_TUBE: {
|
||||
const DistRayAABB_Precalc ray_dist_precalc = dist_squared_ray_to_aabb_v3_precalc(
|
||||
center, ss->cache->view_normal);
|
||||
return bke::pbvh::search_gather(
|
||||
ss->pbvh,
|
||||
[&](PBVHNode &node) {
|
||||
if (ignore_ineffective && node_fully_masked_or_hidden(node)) {
|
||||
return false;
|
||||
}
|
||||
return node_in_cylinder(ray_dist_precalc, node, center, radius_sq, use_original);
|
||||
},
|
||||
leaf_flag);
|
||||
}
|
||||
}
|
||||
|
||||
return nodes;
|
||||
return {};
|
||||
}
|
||||
|
||||
static Vector<PBVHNode *> sculpt_pbvh_gather_generic(
|
||||
@@ -2687,7 +2661,7 @@ static void calc_sculpt_normal(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes, f
|
||||
static void update_sculpt_normal(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes)
|
||||
{
|
||||
const Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
blender::ed::sculpt_paint::StrokeCache *cache = ob->sculpt->cache;
|
||||
StrokeCache *cache = ob->sculpt->cache;
|
||||
/* Grab brush does not update the sculpt normal during a stroke. */
|
||||
const bool update_normal =
|
||||
!(brush->flag & BRUSH_ORIGINAL_NORMAL) && !(brush->sculpt_tool == SCULPT_TOOL_GRAB) &&
|
||||
@@ -2735,7 +2709,7 @@ static void calc_brush_local_mat(const float rotation,
|
||||
float local_mat[4][4],
|
||||
float local_mat_inv[4][4])
|
||||
{
|
||||
const blender::ed::sculpt_paint::StrokeCache *cache = ob->sculpt->cache;
|
||||
const StrokeCache *cache = ob->sculpt->cache;
|
||||
float tmat[4][4];
|
||||
float mat[4][4];
|
||||
float scale[4][4];
|
||||
@@ -2795,6 +2769,8 @@ static void calc_brush_local_mat(const float rotation,
|
||||
invert_m4_m4(local_mat, tmat);
|
||||
}
|
||||
|
||||
} // namespace blender::ed::sculpt_paint
|
||||
|
||||
#define SCULPT_TILT_SENSITIVITY 0.7f
|
||||
void SCULPT_tilt_apply_to_normal(float r_normal[3],
|
||||
blender::ed::sculpt_paint::StrokeCache *cache,
|
||||
@@ -2822,7 +2798,8 @@ void SCULPT_tilt_effective_normal_get(const SculptSession *ss, const Brush *brus
|
||||
|
||||
static void update_brush_local_mat(Sculpt *sd, Object *ob)
|
||||
{
|
||||
blender::ed::sculpt_paint::StrokeCache *cache = ob->sculpt->cache;
|
||||
using namespace blender::ed::sculpt_paint;
|
||||
StrokeCache *cache = ob->sculpt->cache;
|
||||
|
||||
if (cache->mirror_symmetry_pass == 0 && cache->radial_symmetry_pass == 0) {
|
||||
const Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
@@ -4909,6 +4886,7 @@ bool SCULPT_cursor_geometry_info_update(bContext *C,
|
||||
bool use_sampled_normal)
|
||||
{
|
||||
using namespace blender;
|
||||
using namespace blender::ed::sculpt_paint;
|
||||
Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
Sculpt *sd = scene->toolsettings->sculpt;
|
||||
@@ -5899,23 +5877,20 @@ static PBVHVertRef SCULPT_fake_neighbor_search(Sculpt *sd,
|
||||
float max_distance)
|
||||
{
|
||||
using namespace blender;
|
||||
using namespace blender::ed::sculpt_paint;
|
||||
SculptSession *ss = ob->sculpt;
|
||||
|
||||
SculptSearchSphereData data{};
|
||||
data.ss = ss;
|
||||
data.sd = sd;
|
||||
data.radius_squared = max_distance * max_distance;
|
||||
data.original = false;
|
||||
data.center = SCULPT_vertex_co_get(ss, vertex);
|
||||
const float3 center = SCULPT_vertex_co_get(ss, vertex);
|
||||
const float max_distance_sq = max_distance * max_distance;
|
||||
|
||||
Vector<PBVHNode *> nodes = blender::bke::pbvh::search_gather(
|
||||
ss->pbvh, [&](PBVHNode &node) { return SCULPT_search_sphere(&node, &data); });
|
||||
Vector<PBVHNode *> nodes = bke::pbvh::search_gather(ss->pbvh, [&](PBVHNode &node) {
|
||||
return node_in_sphere(node, center, max_distance_sq, false);
|
||||
});
|
||||
if (nodes.is_empty()) {
|
||||
return BKE_pbvh_make_vref(PBVH_REF_NONE);
|
||||
}
|
||||
|
||||
const float3 nearest_vertex_search_co = SCULPT_vertex_co_get(ss, vertex);
|
||||
const float max_distance_sq = max_distance * max_distance;
|
||||
|
||||
NearestVertexFakeNeighborData nvtd;
|
||||
nvtd.nearest_vertex.i = -1;
|
||||
@@ -6197,6 +6172,7 @@ void SCULPT_topology_islands_ensure(Object *ob)
|
||||
|
||||
void SCULPT_cube_tip_init(Sculpt * /*sd*/, Object *ob, Brush *brush, float mat[4][4])
|
||||
{
|
||||
using namespace blender::ed::sculpt_paint;
|
||||
SculptSession *ss = ob->sculpt;
|
||||
float scale[4][4];
|
||||
float tmat[4][4];
|
||||
|
||||
@@ -79,31 +79,25 @@ Vector<PBVHNode *> brush_affected_nodes_gather(SculptSession *ss, Brush *brush)
|
||||
|
||||
switch (brush->cloth_simulation_area_type) {
|
||||
case BRUSH_CLOTH_SIMULATION_AREA_LOCAL: {
|
||||
SculptSearchSphereData data{};
|
||||
data.ss = ss;
|
||||
data.radius_squared = square_f(ss->cache->initial_radius * (1.0 + brush->cloth_sim_limit));
|
||||
data.original = false;
|
||||
data.ignore_fully_ineffective = false;
|
||||
data.center = ss->cache->initial_location;
|
||||
return bke::pbvh::search_gather(
|
||||
ss->pbvh, [&](PBVHNode &node) { return SCULPT_search_sphere(&node, &data); });
|
||||
const float radius_squared = math::square(ss->cache->initial_radius *
|
||||
(1.0 + brush->cloth_sim_limit));
|
||||
return bke::pbvh::search_gather(ss->pbvh, [&](PBVHNode &node) {
|
||||
return node_in_sphere(node, ss->cache->initial_location, radius_squared, false);
|
||||
});
|
||||
}
|
||||
case BRUSH_CLOTH_SIMULATION_AREA_GLOBAL:
|
||||
return bke::pbvh::search_gather(ss->pbvh, {});
|
||||
case BRUSH_CLOTH_SIMULATION_AREA_DYNAMIC: {
|
||||
SculptSearchSphereData data{};
|
||||
data.ss = ss;
|
||||
data.radius_squared = square_f(ss->cache->radius * (1.0 + brush->cloth_sim_limit));
|
||||
data.original = false;
|
||||
data.ignore_fully_ineffective = false;
|
||||
data.center = ss->cache->location;
|
||||
return bke::pbvh::search_gather(
|
||||
ss->pbvh, [&](PBVHNode &node) { return SCULPT_search_sphere(&node, &data); });
|
||||
const float radius_squared = math::square(ss->cache->radius *
|
||||
(1.0 + brush->cloth_sim_limit));
|
||||
return bke::pbvh::search_gather(ss->pbvh, [&](PBVHNode &node) {
|
||||
return node_in_sphere(node, ss->cache->location, radius_squared, false);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
BLI_assert_unreachable();
|
||||
return Vector<PBVHNode *>();
|
||||
return {};
|
||||
}
|
||||
|
||||
bool is_cloth_deform_brush(const Brush *brush)
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
#include "BLI_hash.h"
|
||||
#include "BLI_index_range.hh"
|
||||
#include "BLI_math_base.hh"
|
||||
#include "BLI_math_matrix.h"
|
||||
#include "BLI_math_vector.h"
|
||||
#include "BLI_math_vector_types.hh"
|
||||
@@ -115,15 +116,8 @@ void cache_init(bContext *C,
|
||||
BKE_pbvh_ensure_node_loops(ss->pbvh);
|
||||
}
|
||||
|
||||
const float center[3] = {0.0f};
|
||||
SculptSearchSphereData search_data{};
|
||||
search_data.original = true;
|
||||
search_data.center = center;
|
||||
search_data.radius_squared = FLT_MAX;
|
||||
search_data.ignore_fully_ineffective = true;
|
||||
|
||||
ss->filter_cache->nodes = bke::pbvh::search_gather(
|
||||
pbvh, [&](PBVHNode &node) { return SCULPT_search_sphere(&node, &search_data); });
|
||||
pbvh, [&](PBVHNode &node) { return !node_fully_masked_or_hidden(node); });
|
||||
|
||||
for (PBVHNode *node : ss->filter_cache->nodes) {
|
||||
BKE_pbvh_node_mark_normals_update(node);
|
||||
@@ -177,14 +171,10 @@ void cache_init(bContext *C,
|
||||
radius = paint_calc_object_space_radius(&vc, co, float(ups->size) * area_normal_radius);
|
||||
}
|
||||
|
||||
SculptSearchSphereData search_data2{};
|
||||
search_data2.original = true;
|
||||
search_data2.center = co;
|
||||
search_data2.radius_squared = radius * radius;
|
||||
search_data2.ignore_fully_ineffective = true;
|
||||
|
||||
nodes = bke::pbvh::search_gather(
|
||||
pbvh, [&](PBVHNode &node) { return SCULPT_search_sphere(&node, &search_data2); });
|
||||
const float radius_sq = math::square(radius);
|
||||
nodes = bke::pbvh::search_gather(pbvh, [&](PBVHNode &node) {
|
||||
return !node_fully_masked_or_hidden(node) && node_in_sphere(node, co, radius_sq, true);
|
||||
});
|
||||
|
||||
if (BKE_paint_brush(&sd->paint) &&
|
||||
SCULPT_pbvh_calc_area_normal(brush, ob, nodes, ss->filter_cache->initial_normal))
|
||||
|
||||
@@ -269,25 +269,6 @@ struct SculptBrushTest {
|
||||
|
||||
using SculptBrushTestFn = bool (*)(SculptBrushTest *test, const float co[3]);
|
||||
|
||||
struct SculptSearchSphereData {
|
||||
Sculpt *sd;
|
||||
SculptSession *ss;
|
||||
float radius_squared;
|
||||
const float *center;
|
||||
bool original;
|
||||
/* This ignores fully masked and fully hidden nodes. */
|
||||
bool ignore_fully_ineffective;
|
||||
};
|
||||
|
||||
struct SculptSearchCircleData {
|
||||
Sculpt *sd;
|
||||
SculptSession *ss;
|
||||
float radius_squared;
|
||||
bool original;
|
||||
bool ignore_fully_ineffective;
|
||||
DistRayAABB_Precalc *dist_ray_to_aabb_precalc;
|
||||
};
|
||||
|
||||
/* Sculpt Filters */
|
||||
enum SculptFilterOrientation {
|
||||
SCULPT_FILTER_ORIENTATION_LOCAL = 0,
|
||||
@@ -1106,14 +1087,18 @@ bool SCULPT_brush_test_cube(SculptBrushTest *test,
|
||||
const float roundness,
|
||||
const float tip_scale_x);
|
||||
bool SCULPT_brush_test_circle_sq(SculptBrushTest *test, const float co[3]);
|
||||
/**
|
||||
* Test AABB against sphere.
|
||||
*/
|
||||
bool SCULPT_search_sphere(PBVHNode *node, SculptSearchSphereData *data);
|
||||
/**
|
||||
* 2D projection (distance to line).
|
||||
*/
|
||||
bool SCULPT_search_circle(PBVHNode *node, SculptSearchCircleData *data);
|
||||
|
||||
namespace blender::ed::sculpt_paint {
|
||||
|
||||
bool node_fully_masked_or_hidden(const PBVHNode &node);
|
||||
bool node_in_sphere(const PBVHNode &node, const float3 &location, float radius_sq, bool original);
|
||||
bool node_in_cylinder(const DistRayAABB_Precalc &dist_ray_precalc,
|
||||
const PBVHNode &node,
|
||||
const float3 &location,
|
||||
float radius_sq,
|
||||
bool original);
|
||||
|
||||
}
|
||||
|
||||
void SCULPT_combine_transform_proxies(Sculpt *sd, Object *ob);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user