Sculpt Scene Project: Add option to use vertex normals and brush normal
This commit is contained in:
parent
f91a2a0831
commit
940fb3c044
|
@ -756,6 +756,10 @@ def brush_settings(layout, context, brush, popover=False):
|
|||
col.prop(brush, "use_multiplane_scrape_dynamic")
|
||||
col.prop(brush, "show_multiplane_scrape_planes_preview")
|
||||
|
||||
elif sculpt_tool == 'SCENE_PROJECT':
|
||||
col = layout.column()
|
||||
col.prop(brush, "scene_project_direction_type")
|
||||
|
||||
elif sculpt_tool == 'SMOOTH':
|
||||
col = layout.column()
|
||||
col.prop(brush, "smooth_deform_type")
|
||||
|
|
|
@ -1240,6 +1240,7 @@ static int sculpt_brush_needs_normal(const SculptSession *ss, const Brush *brush
|
|||
SCULPT_TOOL_CREASE,
|
||||
SCULPT_TOOL_DRAW,
|
||||
SCULPT_TOOL_DRAW_SHARP,
|
||||
SCULPT_TOOL_SCENE_PROJECT,
|
||||
SCULPT_TOOL_CLOTH,
|
||||
SCULPT_TOOL_LAYER,
|
||||
SCULPT_TOOL_NUDGE,
|
||||
|
@ -3573,6 +3574,95 @@ static void sculpt_stroke_cache_snap_context_init(bContext *C, Object *ob)
|
|||
cache->depsgraph = depsgraph;
|
||||
}
|
||||
|
||||
|
||||
static void sculpt_scene_project_view_ray_init(Object *ob, const int vertex_index, float r_ray_normal[3], float r_ray_origin[3]) {
|
||||
SculptSession *ss = ob->sculpt;
|
||||
float world_space_vertex_co[3];
|
||||
mul_v3_m4v3(world_space_vertex_co, ob->obmat, SCULPT_vertex_co_get(ss, vertex_index));
|
||||
sub_v3_v3v3(r_ray_normal, world_space_vertex_co, ss->cache->view_origin);
|
||||
normalize_v3(r_ray_normal);
|
||||
copy_v3_v3(r_ray_origin, ss->cache->view_origin);
|
||||
}
|
||||
|
||||
static void sculpt_scene_project_vertex_normal_ray_init(Object *ob, const int vertex_index, float r_ray_normal[3], float r_ray_origin[3]) {
|
||||
SculptSession *ss = ob->sculpt;
|
||||
float vertex_normal[3];
|
||||
SCULPT_vertex_normal_get(ss, vertex_index, vertex_normal);
|
||||
mul_v3_m4v3(r_ray_normal, ob->obmat, vertex_normal);
|
||||
normalize_v3(r_ray_normal);
|
||||
|
||||
mul_v3_m4v3(r_ray_origin, ob->obmat, SCULPT_vertex_co_get(ss, vertex_index));
|
||||
}
|
||||
|
||||
static void sculpt_scene_project_brush_normal_ray_init(Object *ob, const int vertex_index, float r_ray_normal[3], float r_ray_origin[3]) {
|
||||
SculptSession *ss = ob->sculpt;
|
||||
mul_v3_m4v3(r_ray_origin, ob->obmat, SCULPT_vertex_co_get(ss, vertex_index));
|
||||
mul_v3_m4v3(r_ray_normal, ob->obmat, ss->cache->sculpt_normal);
|
||||
normalize_v3(r_ray_normal);
|
||||
}
|
||||
|
||||
static bool sculpt_scene_project_raycast(SculptSession *ss, const float ray_normal[3], const float ray_origin[3], const bool use_both_directions, float r_loc[3]) {
|
||||
float hit_co[2][3];
|
||||
float hit_len_squared[2];
|
||||
bool any_hit = false;
|
||||
bool hit = false;
|
||||
hit = ED_transform_snap_object_project_ray(ss->cache->snap_context,
|
||||
ss->cache->depsgraph,
|
||||
&(const struct SnapObjectParams){
|
||||
.snap_select = SNAP_NOT_ACTIVE,
|
||||
.use_object_edit_cage = true,
|
||||
},
|
||||
ray_origin,
|
||||
ray_normal,
|
||||
NULL,
|
||||
hit_co[0],
|
||||
NULL);
|
||||
if (hit) {
|
||||
hit_len_squared[0] = len_squared_v3v3(hit_co[0], ray_origin);
|
||||
any_hit |= hit;
|
||||
}
|
||||
else {
|
||||
hit_len_squared[0] = FLT_MAX;
|
||||
}
|
||||
|
||||
|
||||
if (!use_both_directions) {
|
||||
copy_v3_v3(r_loc, hit_co[0]);
|
||||
return any_hit;
|
||||
}
|
||||
|
||||
float ray_normal_flip[3];
|
||||
mul_v3_v3fl(ray_normal_flip, ray_normal, -1.0f);
|
||||
|
||||
hit = ED_transform_snap_object_project_ray(ss->cache->snap_context,
|
||||
ss->cache->depsgraph,
|
||||
&(const struct SnapObjectParams){
|
||||
.snap_select = SNAP_NOT_ACTIVE,
|
||||
.use_object_edit_cage = true,
|
||||
},
|
||||
ray_origin,
|
||||
ray_normal_flip,
|
||||
NULL,
|
||||
hit_co[1],
|
||||
NULL);
|
||||
if (hit) {
|
||||
hit_len_squared[1] = len_squared_v3v3(hit_co[1], ray_origin);
|
||||
any_hit |= hit;
|
||||
}
|
||||
else {
|
||||
hit_len_squared[1] = FLT_MAX;
|
||||
}
|
||||
|
||||
if (hit_len_squared[0] <= hit_len_squared[1]) {
|
||||
copy_v3_v3(r_loc, hit_co[0]);
|
||||
}
|
||||
else {
|
||||
copy_v3_v3(r_loc, hit_co[1]);
|
||||
}
|
||||
return any_hit;
|
||||
|
||||
}
|
||||
|
||||
static void do_scene_project_brush_task_cb_ex(void *__restrict userdata,
|
||||
const int n,
|
||||
const TaskParallelTLS *__restrict tls)
|
||||
|
@ -3610,25 +3700,25 @@ static void do_scene_project_brush_task_cb_ex(void *__restrict userdata,
|
|||
}
|
||||
|
||||
float ray_normal[3];
|
||||
float ray_origin[3];
|
||||
bool use_both_directions = false;
|
||||
switch (brush->scene_project_direction_type) {
|
||||
case BRUSH_SCENE_PROJECT_DIRECTION_VIEW:
|
||||
sculpt_scene_project_view_ray_init(data->ob, vd.index, ray_normal, ray_origin);
|
||||
break;
|
||||
case BRUSH_SCENE_PROJECT_DIRECTION_VERTEX_NORMAL:
|
||||
sculpt_scene_project_vertex_normal_ray_init(data->ob, vd.index, ray_normal, ray_origin);
|
||||
use_both_directions = true;
|
||||
break;
|
||||
case BRUSH_SCENE_PROJECT_DIRECTION_BRUSH_NORMAL:
|
||||
sculpt_scene_project_brush_normal_ray_init(data->ob, vd.index, ray_normal, ray_origin);
|
||||
use_both_directions = true;
|
||||
break;
|
||||
}
|
||||
|
||||
float world_space_hit_co[3];
|
||||
float hit_co[3];
|
||||
float world_space_vertex_co[3];
|
||||
mul_v3_m4v3(world_space_vertex_co, data->ob->obmat, vd.co);
|
||||
sub_v3_v3v3(ray_normal, world_space_vertex_co, ss->cache->view_origin);
|
||||
normalize_v3(ray_normal);
|
||||
|
||||
const bool hit = ED_transform_snap_object_project_ray(ss->cache->snap_context,
|
||||
ss->cache->depsgraph,
|
||||
&(const struct SnapObjectParams){
|
||||
.snap_select = SNAP_NOT_ACTIVE,
|
||||
.use_object_edit_cage = true,
|
||||
},
|
||||
ss->cache->view_origin,
|
||||
ray_normal,
|
||||
NULL,
|
||||
world_space_hit_co,
|
||||
NULL);
|
||||
|
||||
const bool hit = sculpt_scene_project_raycast(ss, ray_normal, ray_origin, use_both_directions, world_space_hit_co);
|
||||
if (!hit) {
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -284,6 +284,12 @@ typedef enum eBrushBoundaryFalloffType {
|
|||
BRUSH_BOUNDARY_FALLOFF_LOOP_INVERT = 3,
|
||||
} eBrushBoundaryFalloffType;
|
||||
|
||||
typedef enum eBrushSceneProjectDirectionType {
|
||||
BRUSH_SCENE_PROJECT_DIRECTION_VIEW = 0,
|
||||
BRUSH_SCENE_PROJECT_DIRECTION_VERTEX_NORMAL = 1,
|
||||
BRUSH_SCENE_PROJECT_DIRECTION_BRUSH_NORMAL = 2,
|
||||
} eBrushSceneProjectDirectionType;
|
||||
|
||||
typedef enum eBrushSnakeHookDeformType {
|
||||
BRUSH_SNAKE_HOOK_DEFORM_FALLOFF = 0,
|
||||
BRUSH_SNAKE_HOOK_DEFORM_ELASTIC = 1,
|
||||
|
|
|
@ -268,7 +268,7 @@ typedef struct Brush {
|
|||
char gpencil_sculpt_tool;
|
||||
/** Active grease pencil weight tool. */
|
||||
char gpencil_weight_tool;
|
||||
char _pad1[6];
|
||||
char _pad1[2];
|
||||
|
||||
float autosmooth_factor;
|
||||
|
||||
|
@ -345,6 +345,9 @@ typedef struct Brush {
|
|||
/* slide/relax */
|
||||
int slide_deform_type;
|
||||
|
||||
/* scene_project */
|
||||
int scene_project_direction_type;
|
||||
|
||||
/* overlay */
|
||||
int texture_overlay_alpha;
|
||||
int mask_overlay_alpha;
|
||||
|
|
|
@ -2223,6 +2223,13 @@ static void rna_def_brush(BlenderRNA *brna)
|
|||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
|
||||
static const EnumPropertyItem brush_scene_project_direction_type_items[] = {
|
||||
{BRUSH_SCENE_PROJECT_DIRECTION_VIEW, "VIEW", 0, "View", ""},
|
||||
{BRUSH_SCENE_PROJECT_DIRECTION_VERTEX_NORMAL, "VERTEX_NORMAL", 0, "Vertex Normal", ""},
|
||||
{BRUSH_SCENE_PROJECT_DIRECTION_BRUSH_NORMAL, "BRUSH_NORMAL", 0, "Brush Normal", ""},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
|
||||
srna = RNA_def_struct(brna, "Brush", "ID");
|
||||
RNA_def_struct_ui_text(
|
||||
srna, "Brush", "Brush data-block for storing brush settings for painting and sculpting");
|
||||
|
@ -2395,6 +2402,11 @@ static void rna_def_brush(BlenderRNA *brna)
|
|||
"Method to set the rotation origins for the segments of the brush");
|
||||
RNA_def_property_update(prop, 0, "rna_Brush_update");
|
||||
|
||||
prop = RNA_def_property(srna, "scene_project_direction_type", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_items(prop, brush_scene_project_direction_type_items);
|
||||
RNA_def_property_ui_text(prop, "Project Direction", "Direction that is going to be used to project the vertices into the scene");
|
||||
RNA_def_property_update(prop, 0, "rna_Brush_update");
|
||||
|
||||
prop = RNA_def_property(srna, "jitter_unit", PROP_ENUM, PROP_NONE); /* as an enum */
|
||||
RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag");
|
||||
RNA_def_property_enum_items(prop, brush_jitter_unit_items);
|
||||
|
|
Loading…
Reference in New Issue