Vector displacement for the sculpting draw brush #104481
|
@ -37,6 +37,7 @@
|
||||||
#include "WM_api.h"
|
#include "WM_api.h"
|
||||||
#include "wm_cursors.h"
|
#include "wm_cursors.h"
|
||||||
|
|
||||||
|
#include "IMB_colormanagement.h"
|
||||||
#include "IMB_imbuf_types.h"
|
#include "IMB_imbuf_types.h"
|
||||||
|
|
||||||
#include "ED_image.h"
|
#include "ED_image.h"
|
||||||
|
@ -56,7 +57,6 @@
|
||||||
/* still needed for sculpt_stroke_get_location, should be
|
/* still needed for sculpt_stroke_get_location, should be
|
||||||
* removed eventually (TODO) */
|
* removed eventually (TODO) */
|
||||||
#include "sculpt_intern.h"
|
#include "sculpt_intern.h"
|
||||||
#include "IMB_colormanagement.h"
|
|
||||||
|
|
||||||
/* TODOs:
|
/* TODOs:
|
||||||
*
|
*
|
||||||
|
|
|
@ -356,8 +356,13 @@ float paint_calc_object_space_radius(struct ViewContext *vc,
|
||||||
/**
|
/**
|
||||||
* Returns true when a color was sampled and false when a value was sampled.
|
* Returns true when a color was sampled and false when a value was sampled.
|
||||||
*/
|
*/
|
||||||
bool paint_get_tex_pixel(
|
bool paint_get_tex_pixel(const struct MTex *mtex,
|
||||||
const struct MTex *mtex, float u, float v, struct ImagePool *pool, int thread, float *r_intensity, float r_rgba[4]);
|
float u,
|
||||||
|
float v,
|
||||||
|
struct ImagePool *pool,
|
||||||
|
int thread,
|
||||||
|
float *r_intensity,
|
||||||
|
float r_rgba[4]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used for both 3D view and image window.
|
* Used for both 3D view and image window.
|
||||||
|
|
|
@ -157,7 +157,8 @@ bool paint_get_tex_pixel(const MTex *mtex,
|
||||||
{
|
{
|
||||||
const float co[3] = {u, v, 0.0f};
|
const float co[3] = {u, v, 0.0f};
|
||||||
float intensity;
|
float intensity;
|
||||||
const bool has_rgb = RE_texture_evaluate(mtex, co, thread, pool, false, false, &intensity, r_rgba);
|
const bool has_rgb = RE_texture_evaluate(
|
||||||
|
mtex, co, thread, pool, false, false, &intensity, r_rgba);
|
||||||
*r_intensity = intensity;
|
*r_intensity = intensity;
|
||||||
|
|
||||||
if (!has_rgb) {
|
if (!has_rgb) {
|
||||||
|
|
|
@ -2630,12 +2630,13 @@ static void sculpt_apply_texture(const SculptSession *ss,
|
||||||
|
|
||||||
paint_get_tex_pixel(mtex, x, y, ss->tex_pool, thread_id, r_value, r_rgba);
|
paint_get_tex_pixel(mtex, x, y, ss->tex_pool, thread_id, r_value, r_rgba);
|
||||||
|
|
||||||
add_v3_fl(r_rgba, brush->texture_sample_bias); // v3 -> Ignore alpha
|
add_v3_fl(r_rgba, brush->texture_sample_bias); // v3 -> Ignore alpha
|
||||||
*r_value -= brush->texture_sample_bias;
|
*r_value -= brush->texture_sample_bias;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
float point_2d[2];
|
float point_2d[2];
|
||||||
ED_view3d_project_float_v2_m4(cache->vc->region, symm_point, point_2d, cache->projection_mat);
|
ED_view3d_project_float_v2_m4(
|
||||||
|
cache->vc->region, symm_point, point_2d, cache->projection_mat);
|
||||||
const float point_3d[3] = {point_2d[0], point_2d[1], 0.0f};
|
const float point_3d[3] = {point_2d[0], point_2d[1], 0.0f};
|
||||||
*r_value = BKE_brush_sample_tex_3d(scene, brush, mtex, point_3d, r_rgba, 0, ss->tex_pool);
|
*r_value = BKE_brush_sample_tex_3d(scene, brush, mtex, point_3d, r_rgba, 0, ss->tex_pool);
|
||||||
}
|
}
|
||||||
|
@ -2696,38 +2697,45 @@ void SCULPT_brush_strength_color(struct SculptSession *ss,
|
||||||
const float final_len = sculpt_apply_hardness(ss, len);
|
const float final_len = sculpt_apply_hardness(ss, len);
|
||||||
|
|
||||||
/* Falloff curve. */
|
/* Falloff curve. */
|
||||||
const float falloff = BKE_brush_curve_strength(brush, final_len, cache->radius)
|
const float falloff = BKE_brush_curve_strength(brush, final_len, cache->radius) *
|
||||||
* frontface(brush, cache->view_normal, vno, fno);
|
frontface(brush, cache->view_normal, vno, fno);
|
||||||
|
|
||||||
/* Paint mask. */
|
/* Paint mask. */
|
||||||
const float paint_mask = 1.0f - mask;
|
const float paint_mask = 1.0f - mask;
|
||||||
|
|
||||||
/* Auto-masking. */
|
/* Auto-masking. */
|
||||||
const float automasking_factor = SCULPT_automasking_factor_get(cache->automasking, ss, vertex, automask_data);
|
const float automasking_factor = SCULPT_automasking_factor_get(
|
||||||
|
cache->automasking, ss, vertex, automask_data);
|
||||||
|
|
||||||
const float masks_combined = falloff * paint_mask * automasking_factor;
|
const float masks_combined = falloff * paint_mask * automasking_factor;
|
||||||
|
|
||||||
mul_v4_fl(r_rgba, masks_combined);
|
mul_v4_fl(r_rgba, masks_combined);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SCULPT_calc_vertex_displacement(SculptSession *ss, const struct Brush *brush, float rgba[4], float out_offset[3])
|
void SCULPT_calc_vertex_displacement(SculptSession *ss,
|
||||||
|
const struct Brush *brush,
|
||||||
|
float rgba[4],
|
||||||
|
float out_offset[3])
|
||||||
{
|
{
|
||||||
mul_v3_fl(rgba, ss->cache->bstrength);
|
mul_v3_fl(rgba, ss->cache->bstrength);
|
||||||
if(ss->cache->bstrength < 0) {
|
if (ss->cache->bstrength < 0) {
|
||||||
rgba[0] *= -1;
|
rgba[0] *= -1;
|
||||||
rgba[1] *= -1;
|
rgba[1] *= -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
rgba[0] *= 1.0f / (brush->mtex.size[0] == 0.0f ? 1.0f : brush->mtex.size[0] * brush->mtex.size[0]);
|
rgba[0] *= 1.0f /
|
||||||
robin.hohni marked this conversation as resolved
|
|||||||
rgba[1] *= 1.0f / (brush->mtex.size[1] == 0.0f ? 1.0f : brush->mtex.size[1] * brush->mtex.size[1]);
|
(brush->mtex.size[0] == 0.0f ? 1.0f : brush->mtex.size[0] * brush->mtex.size[0]);
|
||||||
rgba[2] *= 1.0f / (brush->mtex.size[2] == 0.0f ? 1.0f : brush->mtex.size[2] * brush->mtex.size[2]);
|
rgba[1] *= 1.0f /
|
||||||
|
(brush->mtex.size[1] == 0.0f ? 1.0f : brush->mtex.size[1] * brush->mtex.size[1]);
|
||||||
|
rgba[2] *= 1.0f /
|
||||||
|
(brush->mtex.size[2] == 0.0f ? 1.0f : brush->mtex.size[2] * brush->mtex.size[2]);
|
||||||
|
|
||||||
mul_mat3_m4_v3(ss->cache->brush_local_mat_inv, rgba);
|
mul_mat3_m4_v3(ss->cache->brush_local_mat_inv, rgba);
|
||||||
|
|
||||||
if (ss->cache->radial_symmetry_pass) {
|
if (ss->cache->radial_symmetry_pass) {
|
||||||
mul_m4_v3(ss->cache->symm_rot_mat, rgba);
|
mul_m4_v3(ss->cache->symm_rot_mat, rgba);
|
||||||
}
|
}
|
||||||
flip_v3_v3(out_offset, rgba, ss->cache->mirror_symmetry_pass);
|
flip_v3_v3(out_offset, rgba, ss->cache->mirror_symmetry_pass);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SCULPT_search_sphere_cb(PBVHNode *node, void *data_v)
|
bool SCULPT_search_sphere_cb(PBVHNode *node, void *data_v)
|
||||||
|
@ -2997,7 +3005,10 @@ static void calc_local_y(ViewContext *vc, const float center[3], float y[3])
|
||||||
mul_m4_v3(ob->world_to_object, y);
|
mul_m4_v3(ob->world_to_object, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void calc_brush_local_mat(const MTex *mtex, Object *ob, float local_mat[4][4], float local_mat_inv[4][4])
|
static void calc_brush_local_mat(const MTex *mtex,
|
||||||
|
Object *ob,
|
||||||
|
float local_mat[4][4],
|
||||||
|
float local_mat_inv[4][4])
|
||||||
{
|
{
|
||||||
const StrokeCache *cache = ob->sculpt->cache;
|
const StrokeCache *cache = ob->sculpt->cache;
|
||||||
float tmat[4][4];
|
float tmat[4][4];
|
||||||
|
|
|
@ -265,8 +265,8 @@ static void do_draw_brush_task_cb_ex(void *__restrict userdata,
|
||||||
SCULPT_automasking_node_update(ss, &automask_data, &vd);
|
SCULPT_automasking_node_update(ss, &automask_data, &vd);
|
||||||
|
|
||||||
/* Offset vertex. */
|
/* Offset vertex. */
|
||||||
if(ss->cache->brush->flag2 & BRUSH_USE_COLOR_AS_DISPLACEMENT
|
if (ss->cache->brush->flag2 & BRUSH_USE_COLOR_AS_DISPLACEMENT &&
|
||||||
&& (brush->mtex.brush_map_mode == MTEX_MAP_MODE_AREA)) {
|
(brush->mtex.brush_map_mode == MTEX_MAP_MODE_AREA)) {
|
||||||
float r_rgba[4];
|
float r_rgba[4];
|
||||||
SCULPT_brush_strength_color(ss,
|
SCULPT_brush_strength_color(ss,
|
||||||
brush,
|
brush,
|
||||||
|
|
|
@ -1274,9 +1274,13 @@ void SCULPT_brush_strength_color(struct SculptSession *ss,
|
||||||
float r_rgba[4]);
|
float r_rgba[4]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates the vertex offset for a single vertex depending on the brush setting rgb as vector displacement.
|
* Calculates the vertex offset for a single vertex depending on the brush setting rgb as vector
|
||||||
|
* displacement.
|
||||||
*/
|
*/
|
||||||
void SCULPT_calc_vertex_displacement(SculptSession *ss, const struct Brush *brush, float rgba[3], float out_offset[3]);
|
void SCULPT_calc_vertex_displacement(SculptSession *ss,
|
||||||
|
const struct Brush *brush,
|
||||||
|
float rgba[3],
|
||||||
|
float out_offset[3]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tilts a normal by the x and y tilt values using the view axis.
|
* Tilts a normal by the x and y tilt values using the view axis.
|
||||||
|
|
|
@ -2901,8 +2901,10 @@ static void rna_def_brush(BlenderRNA *brna)
|
||||||
|
|
||||||
prop = RNA_def_property(srna, "use_color_as_displacement", PROP_BOOLEAN, PROP_NONE);
|
prop = RNA_def_property(srna, "use_color_as_displacement", PROP_BOOLEAN, PROP_NONE);
|
||||||
RNA_def_property_boolean_sdna(prop, NULL, "flag2", BRUSH_USE_COLOR_AS_DISPLACEMENT);
|
RNA_def_property_boolean_sdna(prop, NULL, "flag2", BRUSH_USE_COLOR_AS_DISPLACEMENT);
|
||||||
RNA_def_property_ui_text(prop, "Vector Displacement",
|
RNA_def_property_ui_text(prop,
|
||||||
"Handles each pixel color as individual vector for displacement. Works only with area plane mapping");
|
"Vector Displacement",
|
||||||
robin.hohni marked this conversation as resolved
Jeroen Bakker
commented
Can you ensure that you use the correct code formatting. You can install clang-format or run Can you ensure that you use the correct code formatting. You can install clang-format or run `make format` in the source folder.
|
|||||||
|
"Handles each pixel color as individual vector for displacement. Works "
|
||||||
|
"only with area plane mapping");
|
||||||
RNA_def_property_update(prop, 0, "rna_Brush_update");
|
RNA_def_property_update(prop, 0, "rna_Brush_update");
|
||||||
|
|
||||||
prop = RNA_def_property(srna, "normal_weight", PROP_FLOAT, PROP_FACTOR);
|
prop = RNA_def_property(srna, "normal_weight", PROP_FLOAT, PROP_FACTOR);
|
||||||
|
|
Loading…
Reference in New Issue
For readability would suggest to first square the size, and then do the inf check using
math::safe_divide
. Seems we currently don't have a safe divide in math for 2 vector types.rgba[i] *= math::safe_divide(1.0f, POW2(brush->mtex.size[i]));
perhaps?Thanks for the hint! Made a commit :)