Fix #139846: Plane brushes behave incorrectly with constant falloff
When constant falloff is used, `BKE_brush_calc_curve_factors` doesn't do any extra filtering of the given distances. The Plane brush previously didn't filter the distances, leading to incorrect deformations when the constant falloff was used. To fix this, this commit makes a number of changes: * `BKE_brush_calc_curve_factors` no longer sets the factor for an element to 0 if it is outside of the provided distance. This is replaced with an assert. * The Plane brush and Cloth brush have an explicit `filter_distances_with_radius` added. Pull Request: https://projects.blender.org/blender/blender/pulls/139851
This commit is contained in:
@@ -105,6 +105,9 @@ void BKE_brush_curve_preset(Brush *b, eCurveMappingPreset preset);
|
||||
|
||||
/**
|
||||
* Combine the brush strength based on the distances and brush settings with the existing factors.
|
||||
*
|
||||
* \note Unlike BKE_brush_curve_strength, if a given distance is greater the brush radius, it does
|
||||
* not result in a factor of 0 for the corresponding element.
|
||||
*/
|
||||
void BKE_brush_calc_curve_factors(eBrushCurvePreset preset,
|
||||
const CurveMapping *cumap,
|
||||
|
||||
@@ -1385,16 +1385,15 @@ void BKE_brush_calc_curve_factors(const eBrushCurvePreset preset,
|
||||
const blender::MutableSpan<float> factors)
|
||||
{
|
||||
BLI_assert(factors.size() == distances.size());
|
||||
for (const int i : distances.index_range()) {
|
||||
BLI_assert(distances[i] < brush_radius || factors[i] == 0.0f);
|
||||
}
|
||||
|
||||
const float radius_rcp = blender::math::rcp(brush_radius);
|
||||
switch (preset) {
|
||||
case BRUSH_CURVE_CUSTOM: {
|
||||
for (const int i : distances.index_range()) {
|
||||
const float distance = distances[i];
|
||||
if (distance >= brush_radius) {
|
||||
factors[i] = 0.0f;
|
||||
continue;
|
||||
}
|
||||
factors[i] *= BKE_curvemapping_evaluateF(cumap, 0, distance * radius_rcp);
|
||||
}
|
||||
break;
|
||||
@@ -1402,10 +1401,6 @@ void BKE_brush_calc_curve_factors(const eBrushCurvePreset preset,
|
||||
case BRUSH_CURVE_SHARP: {
|
||||
for (const int i : distances.index_range()) {
|
||||
const float distance = distances[i];
|
||||
if (distance >= brush_radius) {
|
||||
factors[i] = 0.0f;
|
||||
continue;
|
||||
}
|
||||
const float factor = 1.0f - distance * radius_rcp;
|
||||
factors[i] *= factor * factor;
|
||||
}
|
||||
@@ -1414,10 +1409,6 @@ void BKE_brush_calc_curve_factors(const eBrushCurvePreset preset,
|
||||
case BRUSH_CURVE_SMOOTH: {
|
||||
for (const int i : distances.index_range()) {
|
||||
const float distance = distances[i];
|
||||
if (distance >= brush_radius) {
|
||||
factors[i] = 0.0f;
|
||||
continue;
|
||||
}
|
||||
const float factor = 1.0f - distance * radius_rcp;
|
||||
factors[i] *= 3.0f * factor * factor - 2.0f * factor * factor * factor;
|
||||
}
|
||||
@@ -1426,10 +1417,6 @@ void BKE_brush_calc_curve_factors(const eBrushCurvePreset preset,
|
||||
case BRUSH_CURVE_SMOOTHER: {
|
||||
for (const int i : distances.index_range()) {
|
||||
const float distance = distances[i];
|
||||
if (distance >= brush_radius) {
|
||||
factors[i] = 0.0f;
|
||||
continue;
|
||||
}
|
||||
const float factor = 1.0f - distance * radius_rcp;
|
||||
factors[i] *= pow3f(factor) * (factor * (factor * 6.0f - 15.0f) + 10.0f);
|
||||
}
|
||||
@@ -1438,10 +1425,6 @@ void BKE_brush_calc_curve_factors(const eBrushCurvePreset preset,
|
||||
case BRUSH_CURVE_ROOT: {
|
||||
for (const int i : distances.index_range()) {
|
||||
const float distance = distances[i];
|
||||
if (distance >= brush_radius) {
|
||||
factors[i] = 0.0f;
|
||||
continue;
|
||||
}
|
||||
const float factor = 1.0f - distance * radius_rcp;
|
||||
factors[i] *= sqrtf(factor);
|
||||
}
|
||||
@@ -1450,10 +1433,6 @@ void BKE_brush_calc_curve_factors(const eBrushCurvePreset preset,
|
||||
case BRUSH_CURVE_LIN: {
|
||||
for (const int i : distances.index_range()) {
|
||||
const float distance = distances[i];
|
||||
if (distance >= brush_radius) {
|
||||
factors[i] = 0.0f;
|
||||
continue;
|
||||
}
|
||||
const float factor = 1.0f - distance * radius_rcp;
|
||||
factors[i] *= factor;
|
||||
}
|
||||
@@ -1465,10 +1444,6 @@ void BKE_brush_calc_curve_factors(const eBrushCurvePreset preset,
|
||||
case BRUSH_CURVE_SPHERE: {
|
||||
for (const int i : distances.index_range()) {
|
||||
const float distance = distances[i];
|
||||
if (distance >= brush_radius) {
|
||||
factors[i] = 0.0f;
|
||||
continue;
|
||||
}
|
||||
const float factor = 1.0f - distance * radius_rcp;
|
||||
factors[i] *= sqrtf(2 * factor - factor * factor);
|
||||
}
|
||||
@@ -1477,10 +1452,6 @@ void BKE_brush_calc_curve_factors(const eBrushCurvePreset preset,
|
||||
case BRUSH_CURVE_POW4: {
|
||||
for (const int i : distances.index_range()) {
|
||||
const float distance = distances[i];
|
||||
if (distance >= brush_radius) {
|
||||
factors[i] = 0.0f;
|
||||
continue;
|
||||
}
|
||||
const float factor = 1.0f - distance * radius_rcp;
|
||||
factors[i] *= factor * factor * factor * factor;
|
||||
}
|
||||
@@ -1489,10 +1460,6 @@ void BKE_brush_calc_curve_factors(const eBrushCurvePreset preset,
|
||||
case BRUSH_CURVE_INVSQUARE: {
|
||||
for (const int i : distances.index_range()) {
|
||||
const float distance = distances[i];
|
||||
if (distance >= brush_radius) {
|
||||
factors[i] = 0.0f;
|
||||
continue;
|
||||
}
|
||||
const float factor = 1.0f - distance * radius_rcp;
|
||||
factors[i] *= factor * (2.0f - factor);
|
||||
}
|
||||
|
||||
@@ -231,6 +231,7 @@ static void calc_faces(const Depsgraph &depsgraph,
|
||||
tls.distances.resize(verts.size());
|
||||
const MutableSpan<float> distances = tls.distances;
|
||||
calc_local_distances(height, depth, local_positions, distances);
|
||||
filter_distances_with_radius(1.0f, distances, factors);
|
||||
|
||||
apply_hardness_to_distances(1.0f, cache.hardness, distances);
|
||||
BKE_brush_calc_curve_factors(
|
||||
@@ -284,6 +285,7 @@ static void calc_grids(const Depsgraph &depsgraph,
|
||||
tls.distances.resize(positions.size());
|
||||
const MutableSpan<float> distances = tls.distances;
|
||||
calc_local_distances(height, depth, local_positions, distances);
|
||||
filter_distances_with_radius(1.0f, distances, factors);
|
||||
|
||||
apply_hardness_to_distances(1.0f, cache.hardness, distances);
|
||||
BKE_brush_calc_curve_factors(
|
||||
@@ -335,6 +337,7 @@ static void calc_bmesh(const Depsgraph &depsgraph,
|
||||
tls.distances.resize(positions.size());
|
||||
const MutableSpan<float> distances = tls.distances;
|
||||
calc_local_distances(height, depth, local_positions, distances);
|
||||
filter_distances_with_radius(1.0f, distances, factors);
|
||||
|
||||
apply_hardness_to_distances(1.0f, cache.hardness, distances);
|
||||
BKE_brush_calc_curve_factors(
|
||||
|
||||
@@ -808,6 +808,7 @@ static void calc_forces_mesh(const Depsgraph &depsgraph,
|
||||
calc_brush_distances(
|
||||
ss, current_positions, eBrushFalloffShape(brush.falloff_shape), distances);
|
||||
}
|
||||
filter_distances_with_radius(cache.radius, distances, factors);
|
||||
apply_hardness_to_distances(cache, distances);
|
||||
calc_brush_strength_factors(cache, brush, distances, factors);
|
||||
|
||||
@@ -918,6 +919,7 @@ static void calc_forces_grids(const Depsgraph &depsgraph,
|
||||
calc_brush_distances(
|
||||
ss, current_positions, eBrushFalloffShape(brush.falloff_shape), distances);
|
||||
}
|
||||
filter_distances_with_radius(cache.radius, distances, factors);
|
||||
apply_hardness_to_distances(cache, distances);
|
||||
calc_brush_strength_factors(cache, brush, distances, factors);
|
||||
|
||||
@@ -1026,6 +1028,7 @@ static void calc_forces_bmesh(const Depsgraph &depsgraph,
|
||||
calc_brush_distances(
|
||||
ss, current_positions, eBrushFalloffShape(brush.falloff_shape), distances);
|
||||
}
|
||||
filter_distances_with_radius(cache.radius, distances, factors);
|
||||
apply_hardness_to_distances(cache, distances);
|
||||
calc_brush_strength_factors(cache, brush, distances, factors);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user