Sculpt: move more brush settings to brush channels
This commit is contained in:
parent
7e220dc3f0
commit
c6a51c1259
|
@ -95,7 +95,7 @@ typedef struct BrushMappingData {
|
|||
typedef struct BrushEnumDef {
|
||||
int value;
|
||||
const char identifier[64];
|
||||
char icon[32];
|
||||
char icon[32]; // don't forget when writing literals that icon here is a string, not an int!
|
||||
const char name[64];
|
||||
const char description[512];
|
||||
} BrushEnumDef;
|
||||
|
|
|
@ -340,6 +340,12 @@ typedef struct SculptClothSimulation {
|
|||
float damping;
|
||||
float softbody_strength;
|
||||
|
||||
// cache some values here to avoid
|
||||
// brush channel lookups inside of inner loops
|
||||
float sim_limit;
|
||||
int simulation_area_type;
|
||||
float sim_falloff;
|
||||
|
||||
float (*acceleration)[3];
|
||||
float (*pos)[3];
|
||||
float (*init_pos)[3];
|
||||
|
@ -476,6 +482,8 @@ typedef struct SculptBoundary {
|
|||
float (*origin)[3];
|
||||
float *radius;
|
||||
} circle;
|
||||
|
||||
int deform_target;
|
||||
} SculptBoundary;
|
||||
|
||||
/* Array Brush. */
|
||||
|
|
|
@ -538,7 +538,7 @@ void BKE_pbvh_bmesh_regen_node_verts(PBVH *pbvh);
|
|||
void BKE_pbvh_bmesh_mark_node_regen(PBVH *pbvh, PBVHNode *node);
|
||||
|
||||
// now generated PBVHTris
|
||||
void BKE_pbvh_bmesh_after_stroke(PBVH *pbvh);
|
||||
void BKE_pbvh_bmesh_after_stroke(PBVH *pbvh, bool force_balance);
|
||||
|
||||
/* Update Bounding Box/Redraw and clear flags */
|
||||
|
||||
|
|
|
@ -216,32 +216,28 @@ MAKE_FLOAT(multiplane_scrape_angle, "Plane Angle", "Angle between the planes of
|
|||
|
||||
MAKE_BOOL(use_persistent, "Persistent", "Sculpt on a persistent layer of the mesh", false)
|
||||
MAKE_ENUM(cloth_deform_type, "Deformation", "Deformation type that is used in the brush", BRUSH_CLOTH_DEFORM_DRAG, _({
|
||||
{BRUSH_CLOTH_DEFORM_DRAG, "DRAG", 0, "Drag", ""},
|
||||
{BRUSH_CLOTH_DEFORM_PUSH, "PUSH", 0, "Push", ""},
|
||||
{BRUSH_CLOTH_DEFORM_PINCH_POINT, "PINCH_POINT", 0, "Pinch Point", ""},
|
||||
{BRUSH_CLOTH_DEFORM_PINCH_PERPENDICULAR,
|
||||
"PINCH_PERPENDICULAR",
|
||||
0,
|
||||
"Pinch Perpendicular",
|
||||
""},
|
||||
{BRUSH_CLOTH_DEFORM_INFLATE, "INFLATE", 0, "Inflate", ""},
|
||||
{BRUSH_CLOTH_DEFORM_GRAB, "GRAB", 0, "Grab", ""},
|
||||
{BRUSH_CLOTH_DEFORM_EXPAND, "EXPAND", 0, "Expand", ""},
|
||||
{BRUSH_CLOTH_DEFORM_SNAKE_HOOK, "SNAKE_HOOK", 0, "Snake Hook", ""},
|
||||
{BRUSH_CLOTH_DEFORM_ELASTIC_DRAG, "ELASTIC", 0, "Elastic Drag", ""},
|
||||
{BRUSH_CLOTH_DEFORM_DRAG, "DRAG", "NONE", "Drag", ""},
|
||||
{BRUSH_CLOTH_DEFORM_PUSH, "PUSH", "NONE", "Push", ""},
|
||||
{BRUSH_CLOTH_DEFORM_PINCH_POINT, "PINCH_POINT", "NONE", "Pinch Point", ""},
|
||||
{BRUSH_CLOTH_DEFORM_PINCH_PERPENDICULAR, "PINCH_PERPENDICULAR", "NONE", "Pinch Perpendicular", ""},
|
||||
{BRUSH_CLOTH_DEFORM_INFLATE, "INFLATE", "NONE", "Inflate", ""},
|
||||
{BRUSH_CLOTH_DEFORM_GRAB, "GRAB", "NONE", "Grab", ""},
|
||||
{BRUSH_CLOTH_DEFORM_EXPAND, "EXPAND", "NONE", "Expand", ""},
|
||||
{BRUSH_CLOTH_DEFORM_SNAKE_HOOK, "SNAKE_HOOK", "NONE", "Snake Hook", ""},
|
||||
{BRUSH_CLOTH_DEFORM_ELASTIC_DRAG, "ELASTIC", "NONE", "Elastic Drag", ""},
|
||||
{-1}
|
||||
}))
|
||||
|
||||
MAKE_ENUM(cloth_simulation_area_type, "Simulation Area", "Part of the mesh that is going to be simulated when the stroke is active", BRUSH_CLOTH_SIMULATION_AREA_LOCAL, _({
|
||||
{BRUSH_CLOTH_SIMULATION_AREA_LOCAL,
|
||||
"LOCAL",
|
||||
0,
|
||||
"NONE",
|
||||
"Local",
|
||||
"Simulates only a specific area around the brush limited by a fixed radius"},
|
||||
{BRUSH_CLOTH_SIMULATION_AREA_GLOBAL, "GLOBAL", 0, "Global", "Simulates the entire mesh"},
|
||||
{BRUSH_CLOTH_SIMULATION_AREA_GLOBAL, "GLOBAL", "NONE", "Global", "Simulates the entire mesh"},
|
||||
{BRUSH_CLOTH_SIMULATION_AREA_DYNAMIC,
|
||||
"DYNAMIC",
|
||||
0,
|
||||
"NONE",
|
||||
"Dynamic",
|
||||
"The active simulation area moves with the brush"},
|
||||
{-1}
|
||||
|
@ -249,8 +245,8 @@ MAKE_ENUM(cloth_simulation_area_type, "Simulation Area", "Part of the mesh that
|
|||
|
||||
MAKE_ENUM(cloth_force_falloff_type, "Force Falloff", "Shape used in the brush to apply force to the cloth",
|
||||
BRUSH_CLOTH_FORCE_FALLOFF_RADIAL, _({
|
||||
{BRUSH_CLOTH_FORCE_FALLOFF_RADIAL, "RADIAL", 0, "Radial", ""},
|
||||
{BRUSH_CLOTH_FORCE_FALLOFF_PLANE, "PLANE", 0, "Plane", ""},
|
||||
{BRUSH_CLOTH_FORCE_FALLOFF_RADIAL, "RADIAL", "NONE", "Radial", ""},
|
||||
{BRUSH_CLOTH_FORCE_FALLOFF_PLANE, "PLANE", "NONE", "Plane", ""},
|
||||
{-1}
|
||||
}))
|
||||
|
||||
|
@ -262,7 +258,64 @@ MAKE_FLOAT(cloth_sim_falloff, "Simulation Falloff",
|
|||
"Area to apply deformation falloff to the effects of the simulation", 0.75f, 0.0f, 1.0f)
|
||||
MAKE_FLOAT(cloth_constraint_softbody_strength, "Soft Body Plasticity",
|
||||
"How much the cloth preserves the original shape, acting as a soft body", 0.0f, 0.0f, 1.0f)
|
||||
MAKE_BOOL(cloth_use_collision, "Enable Collision", "Collide with objects during the simulation", false)
|
||||
|
||||
MAKE_BOOL(use_frontface, "Use Front-Face", "Brush only affects vertexes that face the viewer", false)
|
||||
MAKE_BOOL(cloth_pin_simulation_boundary, "Pin Simulation Boundary",
|
||||
"Lock the position of the vertices in the simulation falloff area to avoid artifacts and "
|
||||
"create a softer transition with unaffected areas", false)
|
||||
|
||||
MAKE_FLOAT(boundary_offset, "Boundary Origin Offset",
|
||||
"Offset of the boundary origin in relation to the brush radius", 0.05f, 0.0f, 1.0f)
|
||||
MAKE_ENUM(boundary_deform_type, "Deformation", "Deformation type that is used in the brush", BRUSH_BOUNDARY_DEFORM_BEND, _({
|
||||
{BRUSH_BOUNDARY_DEFORM_BEND, "BEND", "NONE", "Bend", ""},
|
||||
{BRUSH_BOUNDARY_DEFORM_EXPAND, "EXPAND", "NONE", "Expand", ""},
|
||||
{BRUSH_BOUNDARY_DEFORM_INFLATE, "INFLATE", "NONE", "Inflate", ""},
|
||||
{BRUSH_BOUNDARY_DEFORM_GRAB, "GRAB", "NONE", "Grab", ""},
|
||||
{BRUSH_BOUNDARY_DEFORM_TWIST, "TWIST", "NONE", "Twist", ""},
|
||||
{BRUSH_BOUNDARY_DEFORM_SMOOTH, "SMOOTH", "NONE", "Smooth", ""},
|
||||
{BRUSH_BOUNDARY_DEFORM_CIRCLE, "CIRCLE", "NONE", "Circle", ""},
|
||||
{-1}
|
||||
}))
|
||||
|
||||
MAKE_ENUM(boundary_falloff_type, "Boundary Falloff", "How the brush falloff is applied across the boundary", BRUSH_BOUNDARY_FALLOFF_CONSTANT, _({
|
||||
{BRUSH_BOUNDARY_FALLOFF_CONSTANT,
|
||||
"CONSTANT",
|
||||
"NONE",
|
||||
"Constant",
|
||||
"Applies the same deformation in the entire boundary"},
|
||||
{BRUSH_BOUNDARY_FALLOFF_RADIUS,
|
||||
"RADIUS",
|
||||
"NONE",
|
||||
"Brush Radius",
|
||||
"Applies the deformation in a localized area limited by the brush radius"},
|
||||
{BRUSH_BOUNDARY_FALLOFF_LOOP,
|
||||
"LOOP",
|
||||
"NONE",
|
||||
"Loop",
|
||||
"Applies the brush falloff in a loop pattern"},
|
||||
{BRUSH_BOUNDARY_FALLOFF_LOOP_INVERT,
|
||||
"LOOP_INVERT",
|
||||
"NONE",
|
||||
"Loop and Invert",
|
||||
"Applies the falloff radius in a loop pattern, inverting the displacement direction in "
|
||||
"each pattern repetition"},
|
||||
{-1}
|
||||
}))
|
||||
|
||||
MAKE_ENUM(deform_target, "Deformation Target", "How the deformation of the brush will affect the object", BRUSH_DEFORM_TARGET_GEOMETRY, _({
|
||||
{BRUSH_DEFORM_TARGET_GEOMETRY,
|
||||
"GEOMETRY",
|
||||
"NONE",
|
||||
"Geometry",
|
||||
"Brush deformation displaces the vertices of the mesh"},
|
||||
{BRUSH_DEFORM_TARGET_CLOTH_SIM,
|
||||
"CLOTH_SIM",
|
||||
"NONE",
|
||||
"Cloth Simulation",
|
||||
"Brush deforms the mesh by deforming the constraints of a cloth simulation"},
|
||||
{-1}
|
||||
}))
|
||||
|
||||
/* clang-format on */
|
||||
#if defined(BRUSH_CHANNEL_DEFINE_TYPES) || defined(BRUSH_CHANNEL_DEFINE_EXTERNAL)
|
||||
|
|
|
@ -160,6 +160,7 @@ That includes per-brush enums and bitflags!
|
|||
|
||||
BrushChannelType brush_builtin_channels[] = {
|
||||
#include "brush_channel_define.h"
|
||||
|
||||
};
|
||||
|
||||
/* clang-format on */
|
||||
|
@ -270,6 +271,10 @@ static BrushSettingsMap brush_settings_map[] = {
|
|||
DEF(cloth_sim_limit, cloth_sim_limit, FLOAT, FLOAT)
|
||||
DEF(cloth_sim_falloff, cloth_sim_falloff, FLOAT, FLOAT)
|
||||
DEF(cloth_constraint_softbody_strength, cloth_constraint_softbody_strength, FLOAT, FLOAT)
|
||||
DEF(boundary_offset, boundary_offset, FLOAT, FLOAT)
|
||||
DEF(boundary_deform_type, boundary_deform_type, INT, INT)
|
||||
DEF(boundary_falloff_type, boundary_falloff_type, INT, INT)
|
||||
DEF(deform_target, deform_target, INT, INT)
|
||||
};
|
||||
|
||||
static const int brush_settings_map_len = ARRAY_SIZE(brush_settings_map);
|
||||
|
@ -325,6 +330,8 @@ BrushFlagMap brush_flags_map[] = {
|
|||
DEF(flag2, show_multiplane_scrape_planes_preview, BRUSH_MULTIPLANE_SCRAPE_PLANES_PREVIEW)
|
||||
DEF(flag, use_persistent, BRUSH_PERSISTENT)
|
||||
DEF(flag, use_frontface, BRUSH_FRONTFACE)
|
||||
DEF(flag2, cloth_use_collision, BRUSH_CLOTH_USE_COLLISION)
|
||||
DEF(flag2, cloth_pin_simulation_boundary, BRUSH_CLOTH_PIN_SIMULATION_BOUNDARY)
|
||||
};
|
||||
|
||||
int brush_flags_map_len = ARRAY_SIZE(brush_flags_map);
|
||||
|
@ -669,15 +676,23 @@ void BKE_brush_builtin_patch(Brush *brush, int tool)
|
|||
ADDCH(fset_slide);
|
||||
|
||||
ADDCH(direction);
|
||||
ADDCH(dash_ratio);
|
||||
ADDCH(smooth_stroke_factor);
|
||||
ADDCH(smooth_stroke_radius);
|
||||
|
||||
switch (tool) {
|
||||
case SCULPT_TOOL_DRAW: {
|
||||
case SCULPT_TOOL_DRAW:
|
||||
break;
|
||||
}
|
||||
|
||||
case SCULPT_TOOL_PAINT: {
|
||||
ADDCH(color);
|
||||
ADDCH(secondary_color);
|
||||
ADDCH(wet_mix);
|
||||
ADDCH(wet_persistence);
|
||||
ADDCH(density);
|
||||
ADDCH(tip_scale_x);
|
||||
ADDCH(flow);
|
||||
ADDCH(rate);
|
||||
|
||||
break;
|
||||
}
|
||||
case SCULPT_TOOL_SLIDE_RELAX:
|
||||
|
@ -692,7 +707,18 @@ void BKE_brush_builtin_patch(Brush *brush, int tool)
|
|||
ADDCH(cloth_force_falloff_type);
|
||||
ADDCH(cloth_simulation_area_type);
|
||||
ADDCH(cloth_deform_type);
|
||||
ADDCH(cloth_use_collision);
|
||||
ADDCH(cloth_pin_simulation_boundary);
|
||||
|
||||
break;
|
||||
case SCULPT_TOOL_BOUNDARY:
|
||||
ADDCH(boundary_offset);
|
||||
ADDCH(boundary_deform_type);
|
||||
ADDCH(boundary_falloff_type);
|
||||
ADDCH(deform_target);
|
||||
break;
|
||||
case SCULPT_TOOL_POSE:
|
||||
ADDCH(deform_target);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -772,6 +798,20 @@ ATTR_NO_OPT void BKE_brush_channelset_ui_init(Brush *brush, int tool)
|
|||
SHOWWRK(cloth_deform_type);
|
||||
SHOWWRK(cloth_force_falloff_type);
|
||||
SHOWWRK(cloth_simulation_area_type);
|
||||
SHOWWRK(cloth_mass);
|
||||
SHOWWRK(cloth_damping);
|
||||
SHOWWRK(cloth_constraint_softbody_strength);
|
||||
SHOWWRK(cloth_sim_limit);
|
||||
SHOWWRK(cloth_sim_falloff);
|
||||
SHOWWRK(cloth_constraint_softbody_strength);
|
||||
SHOWWRK(cloth_use_collision);
|
||||
SHOWWRK(cloth_pin_simulation_boundary);
|
||||
|
||||
break;
|
||||
case SCULPT_TOOL_BOUNDARY:
|
||||
SHOWWRK(boundary_offset);
|
||||
SHOWWRK(boundary_deform_type);
|
||||
SHOWWRK(boundary_falloff_type);
|
||||
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -2902,7 +2902,7 @@ static void pbvh_bmesh_balance_tree(PBVH *pbvh)
|
|||
|
||||
// printf("volume: %.4f overlap: %.4f ratio: %.3f\n", volume, overlap, overlap / volume);
|
||||
|
||||
if (overlap > volume * 0.25) {
|
||||
if (overlap > volume * 0.1) {
|
||||
modified = true;
|
||||
// printf(" DELETE!\n");
|
||||
|
||||
|
@ -3186,7 +3186,7 @@ static void pbvh_bmesh_join_nodes(PBVH *bvh)
|
|||
MEM_freeN(map);
|
||||
}
|
||||
|
||||
void BKE_pbvh_bmesh_after_stroke(PBVH *pbvh)
|
||||
void BKE_pbvh_bmesh_after_stroke(PBVH *pbvh, bool force_balance)
|
||||
{
|
||||
int totnode = pbvh->totnode;
|
||||
|
||||
|
@ -3198,7 +3198,7 @@ void BKE_pbvh_bmesh_after_stroke(PBVH *pbvh)
|
|||
|
||||
BKE_pbvh_update_bounds(pbvh, (PBVH_UpdateBB | PBVH_UpdateOriginalBB | PBVH_UpdateRedraw));
|
||||
|
||||
if (pbvh->balance_counter++ == 10) {
|
||||
if (force_balance || pbvh->balance_counter++ == 10) {
|
||||
pbvh_bmesh_balance_tree(pbvh);
|
||||
pbvh_bmesh_check_nodes(pbvh);
|
||||
pbvh->balance_counter = 0;
|
||||
|
|
|
@ -1833,8 +1833,16 @@ static void paint_cursor_draw_3d_view_brush_cursor_inactive(PaintCursorContext *
|
|||
/* This functions sets its own drawing space in order to draw the simulation limits when the
|
||||
* cursor is active. When used here, this cursor overlay is already in cursor space, so its
|
||||
* position and normal should be set to 0. */
|
||||
SCULPT_cloth_simulation_limits_draw(
|
||||
pcontext->pos, brush, zero_v, zero_v, pcontext->radius, 1.0f, white, 0.25f);
|
||||
SCULPT_cloth_simulation_limits_draw(pcontext->ss,
|
||||
pcontext->sd,
|
||||
pcontext->pos,
|
||||
brush,
|
||||
zero_v,
|
||||
zero_v,
|
||||
pcontext->radius,
|
||||
1.0f,
|
||||
white,
|
||||
0.25f);
|
||||
}
|
||||
|
||||
/* Layer brush height. */
|
||||
|
@ -1918,7 +1926,9 @@ static void paint_cursor_cursor_draw_3d_view_brush_cursor_active(PaintCursorCont
|
|||
if (len_v3v3(ss->cache->true_location, ss->cache->true_initial_location) >
|
||||
ss->cache->radius * (1.0f + brush->cloth_sim_limit)) {
|
||||
const float red[3] = {1.0f, 0.2f, 0.2f};
|
||||
SCULPT_cloth_simulation_limits_draw(pcontext->pos,
|
||||
SCULPT_cloth_simulation_limits_draw(pcontext->ss,
|
||||
pcontext->sd,
|
||||
pcontext->pos,
|
||||
brush,
|
||||
ss->cache->true_initial_location,
|
||||
ss->cache->true_initial_normal,
|
||||
|
|
|
@ -8463,6 +8463,7 @@ void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSettings
|
|||
SCULPT_TOOL_CLOTH,
|
||||
SCULPT_TOOL_SIMPLIFY,
|
||||
SCULPT_TOOL_SNAKE_HOOK,
|
||||
SCULPT_TOOL_INFLATE,
|
||||
SCULPT_TOOL_PAINT,
|
||||
SCULPT_TOOL_SMEAR)) {
|
||||
|
||||
|
@ -11259,7 +11260,7 @@ void SCULPT_flush_update_done(const bContext *C, Object *ob, SculptUpdateType up
|
|||
}
|
||||
|
||||
if (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) {
|
||||
BKE_pbvh_bmesh_after_stroke(ss->pbvh);
|
||||
BKE_pbvh_bmesh_after_stroke(ss->pbvh, false);
|
||||
#if 0
|
||||
if (update_flags & SCULPT_UPDATE_COLOR) {
|
||||
PBVHNode **nodes;
|
||||
|
|
|
@ -834,10 +834,8 @@ static void sculpt_boundary_edit_data_init(SculptSession *ss,
|
|||
/* This functions assigns a falloff factor to each one of the SculptBoundaryEditInfo structs based
|
||||
* on the brush curve and its propagation steps. The falloff goes from the boundary into the mesh.
|
||||
*/
|
||||
static void sculpt_boundary_falloff_factor_init(SculptSession *ss,
|
||||
SculptBoundary *boundary,
|
||||
Brush *brush,
|
||||
const float radius)
|
||||
static void sculpt_boundary_falloff_factor_init(
|
||||
SculptSession *ss, Sculpt *sd, SculptBoundary *boundary, Brush *brush, const float radius)
|
||||
{
|
||||
const int totvert = SCULPT_vertex_count_get(ss);
|
||||
BKE_curvemapping_init(brush->curve);
|
||||
|
@ -865,7 +863,7 @@ static void sculpt_boundary_falloff_factor_init(SculptSession *ss,
|
|||
float falloff_distance = 0.0f;
|
||||
float direction = 1.0f;
|
||||
|
||||
switch (brush->boundary_falloff_type) {
|
||||
switch (SCULPT_get_int(ss, boundary_falloff_type, sd, brush)) {
|
||||
case BRUSH_BOUNDARY_FALLOFF_RADIUS:
|
||||
falloff_distance = boundary_distance;
|
||||
break;
|
||||
|
@ -895,7 +893,8 @@ static void sculpt_boundary_falloff_factor_init(SculptSession *ss,
|
|||
|
||||
/* Main function to get SculptBoundary data both for brush deformation and viewport preview. Can
|
||||
* return NULL if there is no boundary from the given vertex using the given radius. */
|
||||
SculptBoundary *SCULPT_boundary_data_init(Object *object,
|
||||
SculptBoundary *SCULPT_boundary_data_init(Sculpt *sd,
|
||||
Object *object,
|
||||
Brush *brush,
|
||||
const SculptVertRef initial_vertex,
|
||||
const float radius)
|
||||
|
@ -929,11 +928,17 @@ SculptBoundary *SCULPT_boundary_data_init(Object *object,
|
|||
|
||||
SculptBoundary *boundary = MEM_callocN(sizeof(SculptBoundary) * TSTN, "Boundary edit data");
|
||||
|
||||
const bool init_boundary_distances = brush ? brush->boundary_falloff_type !=
|
||||
BRUSH_BOUNDARY_FALLOFF_CONSTANT :
|
||||
false;
|
||||
boundary->deform_target = SCULPT_get_int(ss, deform_target, sd, brush);
|
||||
|
||||
const float boundary_radius = brush ? radius * (1.0f + brush->boundary_offset) : radius;
|
||||
const bool init_boundary_distances = brush ?
|
||||
SCULPT_get_int(ss, boundary_falloff_type, sd, brush) !=
|
||||
BRUSH_BOUNDARY_FALLOFF_CONSTANT :
|
||||
false;
|
||||
|
||||
const float boundary_radius = brush ?
|
||||
radius *
|
||||
(1.0f + SCULPT_get_float(ss, boundary_offset, sd, brush)) :
|
||||
radius;
|
||||
|
||||
sculpt_boundary_indices_init(
|
||||
object, ss, boundary, init_boundary_distances, boundary_initial_vertex, boundary_radius);
|
||||
|
@ -1650,7 +1655,7 @@ static void do_boundary_brush_bend_task_cb_ex(void *__restrict userdata,
|
|||
const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
|
||||
const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.vertex);
|
||||
float t_orig_co[3];
|
||||
float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
|
||||
float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, boundary->deform_target, &vd);
|
||||
|
||||
sub_v3_v3v3(t_orig_co, orig_data.co, boundary->bend.pivot_positions[vd.index]);
|
||||
rotate_v3_v3v3fl(target_co,
|
||||
|
@ -1698,7 +1703,7 @@ static void do_boundary_brush_slide_task_cb_ex(void *__restrict userdata,
|
|||
|
||||
const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
|
||||
const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.vertex);
|
||||
float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
|
||||
float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, boundary->deform_target, &vd);
|
||||
madd_v3_v3v3fl(target_co,
|
||||
orig_data.co,
|
||||
boundary->slide.directions[vd.index],
|
||||
|
@ -1746,7 +1751,7 @@ static void do_boundary_brush_inflate_task_cb_ex(void *__restrict userdata,
|
|||
const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.vertex);
|
||||
float normal[3];
|
||||
normal_short_to_float_v3(normal, orig_data.no);
|
||||
float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
|
||||
float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, boundary->deform_target, &vd);
|
||||
madd_v3_v3v3fl(target_co,
|
||||
orig_data.co,
|
||||
normal,
|
||||
|
@ -1790,7 +1795,7 @@ static void do_boundary_brush_grab_task_cb_ex(void *__restrict userdata,
|
|||
|
||||
const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
|
||||
const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.vertex);
|
||||
float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
|
||||
float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, boundary->deform_target, &vd);
|
||||
madd_v3_v3v3fl(target_co,
|
||||
orig_data.co,
|
||||
ss->cache->grab_delta_symmetry,
|
||||
|
@ -1842,7 +1847,7 @@ static void do_boundary_brush_twist_task_cb_ex(void *__restrict userdata,
|
|||
const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
|
||||
const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.vertex);
|
||||
float t_orig_co[3];
|
||||
float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
|
||||
float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, boundary->deform_target, &vd);
|
||||
sub_v3_v3v3(t_orig_co, orig_data.co, boundary->twist.pivot_position);
|
||||
rotate_v3_v3v3fl(target_co,
|
||||
t_orig_co,
|
||||
|
@ -1905,7 +1910,7 @@ static void do_boundary_brush_smooth_task_cb_ex(void *__restrict userdata,
|
|||
const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
|
||||
mul_v3_v3fl(avg, coord_accum, 1.0f / total_neighbors);
|
||||
sub_v3_v3v3(disp, avg, vd.co);
|
||||
float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
|
||||
float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, boundary->deform_target, &vd);
|
||||
madd_v3_v3v3fl(
|
||||
target_co, vd.co, disp, boundary->edit_info[vd.index].strength_factor * mask * strength);
|
||||
|
||||
|
@ -1955,7 +1960,7 @@ static void do_boundary_brush_circle_task_cb_ex(void *__restrict userdata,
|
|||
|
||||
float disp[3];
|
||||
sub_v3_v3v3(disp, target_circle_co, vd.co);
|
||||
float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
|
||||
float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, boundary->deform_target, &vd);
|
||||
const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
|
||||
const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.vertex);
|
||||
madd_v3_v3v3fl(target_co,
|
||||
|
@ -2026,8 +2031,7 @@ static void SCULPT_boundary_autosmooth(SculptSession *ss, SculptBoundary *bounda
|
|||
SCULPT_neighbor_coords_average_interior(
|
||||
ss, sco, vd.vertex, projection, slide_fset, bound_smooth, NULL, false);
|
||||
|
||||
float *co = SCULPT_brush_deform_target_vertex_co_get(
|
||||
ss, ss->cache->brush->deform_target, &vd);
|
||||
float *co = SCULPT_brush_deform_target_vertex_co_get(ss, boundary->deform_target, &vd);
|
||||
|
||||
interp_v3_v3v3(co, co, sco, strength * fac);
|
||||
BKE_pbvh_node_mark_update(node);
|
||||
|
@ -2068,8 +2072,7 @@ static void SCULPT_boundary_build_smoothco(SculptSession *ss, SculptBoundary *bo
|
|||
SCULPT_neighbor_coords_average_interior(
|
||||
ss, sco, vd.vertex, projection, slide_fset, bound_smooth, NULL, false);
|
||||
|
||||
float *co = SCULPT_brush_deform_target_vertex_co_get(
|
||||
ss, ss->cache->brush->deform_target, &vd);
|
||||
float *co = SCULPT_brush_deform_target_vertex_co_get(ss, boundary->deform_target, &vd);
|
||||
|
||||
interp_v3_v3v3(sco, sco, co, 0.25);
|
||||
BKE_pbvh_node_mark_update(node);
|
||||
|
@ -2092,7 +2095,10 @@ void SCULPT_do_boundary_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totn
|
|||
SCULPT_cotangents_begin(ob, ss);
|
||||
|
||||
const float radius = ss->cache->radius;
|
||||
const float boundary_radius = brush ? radius * (1.0f + brush->boundary_offset) : radius;
|
||||
const float boundary_radius = brush ?
|
||||
radius *
|
||||
(1.0f + SCULPT_get_float(ss, boundary_offset, sd, brush)) :
|
||||
radius;
|
||||
|
||||
const int symm_area = ss->cache->mirror_symmetry_pass;
|
||||
if (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) {
|
||||
|
@ -2110,10 +2116,10 @@ void SCULPT_do_boundary_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totn
|
|||
}
|
||||
|
||||
ss->cache->boundaries[symm_area] = SCULPT_boundary_data_init(
|
||||
ob, brush, initial_vertex, ss->cache->initial_radius);
|
||||
sd, ob, brush, initial_vertex, ss->cache->initial_radius);
|
||||
|
||||
if (ss->cache->boundaries[symm_area]) {
|
||||
switch (brush->boundary_deform_type) {
|
||||
switch (SCULPT_get_int(ss, boundary_deform_type, sd, brush)) {
|
||||
case BRUSH_BOUNDARY_DEFORM_BEND:
|
||||
sculpt_boundary_bend_data_init(ss, ss->cache->boundaries[symm_area], boundary_radius);
|
||||
break;
|
||||
|
@ -2133,7 +2139,7 @@ void SCULPT_do_boundary_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totn
|
|||
}
|
||||
|
||||
sculpt_boundary_falloff_factor_init(
|
||||
ss, ss->cache->boundaries[symm_area], brush, ss->cache->initial_radius);
|
||||
ss, sd, ss->cache->boundaries[symm_area], brush, ss->cache->initial_radius);
|
||||
}
|
||||
|
||||
if (ss->bm && ss->cache->boundaries[symm_area] &&
|
||||
|
@ -2179,7 +2185,7 @@ void SCULPT_do_boundary_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totn
|
|||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
|
||||
switch (brush->boundary_deform_type) {
|
||||
switch (SCULPT_get_int(ss, boundary_deform_type, sd, brush)) {
|
||||
case BRUSH_BOUNDARY_DEFORM_BEND:
|
||||
BLI_task_parallel_range(0, totnode, &data, do_boundary_brush_bend_task_cb_ex, &settings);
|
||||
break;
|
||||
|
@ -2203,7 +2209,7 @@ void SCULPT_do_boundary_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totn
|
|||
break;
|
||||
}
|
||||
|
||||
if (brush->autosmooth_factor > 0.0f) {
|
||||
if (SCULPT_get_float(ss, autosmooth, sd, brush) > 0.0f) {
|
||||
BKE_pbvh_update_normals(ss->pbvh, ss->subdiv_ccg);
|
||||
|
||||
SCULPT_boundary_autosmooth(ss, ss->cache->boundaries[symm_area]);
|
||||
|
|
|
@ -116,7 +116,8 @@ static void cloth_brush_simulation_location_get(SculptSession *ss,
|
|||
return;
|
||||
}
|
||||
|
||||
if (brush->cloth_simulation_area_type == BRUSH_CLOTH_SIMULATION_AREA_LOCAL) {
|
||||
if (SCULPT_get_int(ss, cloth_simulation_area_type, NULL, brush) ==
|
||||
BRUSH_CLOTH_SIMULATION_AREA_LOCAL) {
|
||||
copy_v3_v3(r_location, ss->cache->initial_location);
|
||||
return;
|
||||
}
|
||||
|
@ -128,14 +129,15 @@ PBVHNode **SCULPT_cloth_brush_affected_nodes_gather(SculptSession *ss,
|
|||
int *r_totnode)
|
||||
{
|
||||
BLI_assert(ss->cache);
|
||||
BLI_assert(brush->sculpt_tool == SCULPT_TOOL_CLOTH);
|
||||
// BLI_assert(brush->sculpt_tool == SCULPT_TOOL_CLOTH);
|
||||
PBVHNode **nodes = NULL;
|
||||
|
||||
switch (brush->cloth_simulation_area_type) {
|
||||
switch (SCULPT_get_int(ss, cloth_simulation_area_type, NULL, brush)) {
|
||||
case BRUSH_CLOTH_SIMULATION_AREA_LOCAL: {
|
||||
SculptSearchSphereData data = {
|
||||
.ss = ss,
|
||||
.radius_squared = square_f(ss->cache->initial_radius * (1.0 + brush->cloth_sim_limit)),
|
||||
.radius_squared = square_f(ss->cache->initial_radius *
|
||||
(1.0 + SCULPT_get_float(ss, cloth_sim_limit, NULL, brush))),
|
||||
.original = false,
|
||||
.ignore_fully_ineffective = false,
|
||||
.center = ss->cache->initial_location,
|
||||
|
@ -148,7 +150,8 @@ PBVHNode **SCULPT_cloth_brush_affected_nodes_gather(SculptSession *ss,
|
|||
case BRUSH_CLOTH_SIMULATION_AREA_DYNAMIC: {
|
||||
SculptSearchSphereData data = {
|
||||
.ss = ss,
|
||||
.radius_squared = square_f(ss->cache->radius * (1.0 + brush->cloth_sim_limit)),
|
||||
.radius_squared = square_f(ss->cache->radius *
|
||||
(1.0 + SCULPT_get_float(ss, cloth_sim_limit, NULL, brush))),
|
||||
.original = false,
|
||||
.ignore_fully_ineffective = false,
|
||||
.center = ss->cache->location,
|
||||
|
@ -160,24 +163,27 @@ PBVHNode **SCULPT_cloth_brush_affected_nodes_gather(SculptSession *ss,
|
|||
return nodes;
|
||||
}
|
||||
|
||||
static float cloth_brush_simulation_falloff_get(const Brush *brush,
|
||||
static float cloth_brush_simulation_falloff_get(const SculptClothSimulation *cloth_sim,
|
||||
const Brush *brush,
|
||||
const float radius,
|
||||
const float location[3],
|
||||
const float co[3])
|
||||
{
|
||||
if (brush->sculpt_tool != SCULPT_TOOL_CLOTH) {
|
||||
/* All brushes that are not the cloth brush do not use simulation areas. */
|
||||
/* All brushes that are not the cloth brush do not use simulation areas.
|
||||
TODO: new command list situation may change this, investigate
|
||||
*/
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
/* Global simulation does not have any falloff as the entire mesh is being simulated. */
|
||||
if (brush->cloth_simulation_area_type == BRUSH_CLOTH_SIMULATION_AREA_GLOBAL) {
|
||||
if (cloth_sim->simulation_area_type == BRUSH_CLOTH_SIMULATION_AREA_GLOBAL) {
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
const float distance = len_v3v3(location, co);
|
||||
const float limit = radius + (radius * brush->cloth_sim_limit);
|
||||
const float falloff = radius + (radius * brush->cloth_sim_limit * brush->cloth_sim_falloff);
|
||||
const float limit = radius + (radius * cloth_sim->sim_limit);
|
||||
const float falloff = radius + (radius * cloth_sim->sim_limit * cloth_sim->sim_falloff);
|
||||
|
||||
if (distance > limit) {
|
||||
/* Outside the limits. */
|
||||
|
@ -462,7 +468,7 @@ static void do_cloth_brush_build_constraints_task_cb_ex(
|
|||
|
||||
if (pin_simulation_boundary) {
|
||||
const float sim_falloff = cloth_brush_simulation_falloff_get(
|
||||
brush, ss->cache->initial_radius, ss->cache->location, vd.co);
|
||||
data->cloth_sim, brush, ss->cache->initial_radius, ss->cache->location, vd.co);
|
||||
/* Vertex is inside the area of the simulation without any falloff applied. */
|
||||
if (sim_falloff < 1.0f) {
|
||||
/* Create constraints with more strength the closer the vertex is to the simulation
|
||||
|
@ -554,7 +560,7 @@ static void do_cloth_brush_apply_forces_task_cb_ex(void *__restrict userdata,
|
|||
float sim_location[3];
|
||||
cloth_brush_simulation_location_get(ss, brush, sim_location);
|
||||
const float sim_factor = cloth_brush_simulation_falloff_get(
|
||||
brush, ss->cache->radius, sim_location, cloth_sim->init_pos[vd.index]);
|
||||
cloth_sim, brush, ss->cache->radius, sim_location, cloth_sim->init_pos[vd.index]);
|
||||
|
||||
float current_vertex_location[3];
|
||||
if (brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_GRAB) {
|
||||
|
@ -848,9 +854,10 @@ static void do_cloth_brush_solve_simulation_task_cb_ex(
|
|||
float sim_location[3];
|
||||
cloth_brush_simulation_location_get(ss, brush, sim_location);
|
||||
const float sim_factor =
|
||||
ss->cache ? cloth_brush_simulation_falloff_get(
|
||||
brush, ss->cache->radius, sim_location, cloth_sim->init_pos[vd.index]) :
|
||||
1.0f;
|
||||
ss->cache ?
|
||||
cloth_brush_simulation_falloff_get(
|
||||
cloth_sim, brush, ss->cache->radius, sim_location, cloth_sim->init_pos[vd.index]) :
|
||||
1.0f;
|
||||
if (sim_factor <= 0.0f) {
|
||||
continue;
|
||||
}
|
||||
|
@ -956,13 +963,15 @@ static void cloth_brush_satisfy_constraints(SculptSession *ss,
|
|||
cloth_brush_simulation_location_get(ss, brush, sim_location);
|
||||
|
||||
const float sim_factor_v1 = ss->cache ?
|
||||
cloth_brush_simulation_falloff_get(brush,
|
||||
cloth_brush_simulation_falloff_get(cloth_sim,
|
||||
brush,
|
||||
ss->cache->radius,
|
||||
sim_location,
|
||||
cloth_sim->init_pos[v1]) :
|
||||
1.0f;
|
||||
const float sim_factor_v2 = ss->cache ?
|
||||
cloth_brush_simulation_falloff_get(brush,
|
||||
cloth_brush_simulation_falloff_get(cloth_sim,
|
||||
brush,
|
||||
ss->cache->radius,
|
||||
sim_location,
|
||||
cloth_sim->init_pos[v2]) :
|
||||
|
@ -1145,6 +1154,10 @@ SculptClothSimulation *SCULPT_cloth_brush_simulation_create(SculptSession *ss,
|
|||
|
||||
cloth_sim = MEM_callocN(sizeof(SculptClothSimulation), "cloth constraints");
|
||||
|
||||
cloth_sim->simulation_area_type = SCULPT_get_int(ss, cloth_simulation_area_type, NULL, NULL);
|
||||
cloth_sim->sim_falloff = SCULPT_get_float(ss, cloth_sim_falloff, NULL, NULL);
|
||||
cloth_sim->sim_limit = SCULPT_get_float(ss, cloth_sim_limit, NULL, NULL);
|
||||
|
||||
if (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) {
|
||||
cloth_sim->cd_pers_co = SCULPT_dyntopo_get_templayer(ss, CD_PROP_FLOAT3, SCULPT_LAYER_PERS_CO);
|
||||
cloth_sim->cd_pers_no = SCULPT_dyntopo_get_templayer(ss, CD_PROP_FLOAT3, SCULPT_LAYER_PERS_NO);
|
||||
|
@ -1291,7 +1304,7 @@ static void sculpt_cloth_ensure_constraints_in_simulation_area(Sculpt *sd,
|
|||
SculptSession *ss = ob->sculpt;
|
||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
const float radius = ss->cache->initial_radius;
|
||||
const float limit = radius + (radius * brush->cloth_sim_limit);
|
||||
const float limit = radius + (radius * SCULPT_get_float(ss, cloth_sim_limit, sd, brush));
|
||||
float sim_location[3];
|
||||
cloth_brush_simulation_location_get(ss, brush, sim_location);
|
||||
SCULPT_cloth_brush_ensure_nodes_constraints(
|
||||
|
@ -1313,15 +1326,16 @@ void SCULPT_do_cloth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
|
|||
if (SCULPT_stroke_is_first_brush_step(ss->cache) || !ss->cache->cloth_sim) {
|
||||
ss->cache->cloth_sim = SCULPT_cloth_brush_simulation_create(
|
||||
ss,
|
||||
brush->cloth_mass,
|
||||
brush->cloth_damping,
|
||||
brush->cloth_constraint_softbody_strength,
|
||||
(brush->flag2 & BRUSH_CLOTH_USE_COLLISION),
|
||||
SCULPT_get_float(ss, cloth_mass, sd, brush),
|
||||
SCULPT_get_float(ss, cloth_damping, sd, brush),
|
||||
SCULPT_get_float(ss, cloth_constraint_softbody_strength, sd, brush),
|
||||
SCULPT_get_bool(ss, cloth_use_collision, sd, brush),
|
||||
SCULPT_is_cloth_deform_brush(brush));
|
||||
SCULPT_cloth_brush_simulation_init(ss, ss->cache->cloth_sim);
|
||||
}
|
||||
|
||||
if (brush->cloth_simulation_area_type == BRUSH_CLOTH_SIMULATION_AREA_LOCAL) {
|
||||
if (SCULPT_get_int(ss, cloth_simulation_area_type, sd, brush) ==
|
||||
BRUSH_CLOTH_SIMULATION_AREA_LOCAL) {
|
||||
/* When using simulation a fixed local simulation area, constraints are created only using
|
||||
* the initial stroke position and initial radius (per symmetry pass) instead of per node.
|
||||
* This allows to skip unnecessary constraints that will never be simulated, making the
|
||||
|
@ -1376,7 +1390,9 @@ void SCULPT_cloth_simulation_free(struct SculptClothSimulation *cloth_sim)
|
|||
}
|
||||
|
||||
/* Cursor drawing function. */
|
||||
void SCULPT_cloth_simulation_limits_draw(const uint gpuattr,
|
||||
void SCULPT_cloth_simulation_limits_draw(const SculptSession *ss,
|
||||
const Sculpt *sd,
|
||||
const uint gpuattr,
|
||||
const Brush *brush,
|
||||
const float location[3],
|
||||
const float normal[3],
|
||||
|
@ -1398,10 +1414,15 @@ void SCULPT_cloth_simulation_limits_draw(const uint gpuattr,
|
|||
|
||||
GPU_line_width(line_width);
|
||||
immUniformColor3fvAlpha(outline_col, alpha * 0.5f);
|
||||
imm_draw_circle_dashed_3d(
|
||||
gpuattr, 0, 0, rds + (rds * brush->cloth_sim_limit * brush->cloth_sim_falloff), 320);
|
||||
imm_draw_circle_dashed_3d(gpuattr,
|
||||
0,
|
||||
0,
|
||||
rds + (rds * SCULPT_get_float(ss, cloth_sim_limit, sd, brush) *
|
||||
SCULPT_get_float(ss, cloth_sim_falloff, sd, brush)),
|
||||
320);
|
||||
immUniformColor3fvAlpha(outline_col, alpha * 0.7f);
|
||||
imm_draw_circle_wire_3d(gpuattr, 0, 0, rds + rds * brush->cloth_sim_limit, 80);
|
||||
imm_draw_circle_wire_3d(
|
||||
gpuattr, 0, 0, rds + rds * SCULPT_get_float(ss, cloth_sim_limit, sd, brush), 80);
|
||||
GPU_matrix_pop();
|
||||
}
|
||||
|
||||
|
@ -1413,7 +1434,7 @@ void SCULPT_cloth_plane_falloff_preview_draw(const uint gpuattr,
|
|||
float local_mat[4][4];
|
||||
copy_m4_m4(local_mat, ss->cache->stroke_local_mat);
|
||||
|
||||
if (ss->cache->brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_GRAB) {
|
||||
if (SCULPT_get_int(ss, cloth_deform_type, NULL, ss->cache->brush) == BRUSH_CLOTH_DEFORM_GRAB) {
|
||||
add_v3_v3v3(local_mat[3], ss->cache->true_location, ss->cache->grab_delta);
|
||||
}
|
||||
|
||||
|
|
|
@ -272,6 +272,7 @@ int SCULPT_get_int_intern(const SculptSession *ss,
|
|||
const Brush *br);
|
||||
#define SCULPT_get_int(ss, idname, sd, br) \
|
||||
SCULPT_get_int_intern(ss, BRUSH_BUILTIN_##idname, sd, br)
|
||||
#define SCULPT_get_bool(ss, idname, sd, br) SCULPT_get_int(ss, idname, sd, br)
|
||||
|
||||
SculptCornerType SCULPT_vertex_is_corner(const SculptSession *ss,
|
||||
const SculptVertRef index,
|
||||
|
@ -553,7 +554,9 @@ void SCULPT_cloth_brush_ensure_nodes_constraints(struct Sculpt *sd,
|
|||
float initial_location[3],
|
||||
const float radius);
|
||||
|
||||
void SCULPT_cloth_simulation_limits_draw(const uint gpuattr,
|
||||
void SCULPT_cloth_simulation_limits_draw(const SculptSession *ss,
|
||||
const Sculpt *sd,
|
||||
const uint gpuattr,
|
||||
const struct Brush *brush,
|
||||
const float location[3],
|
||||
const float normal[3],
|
||||
|
|
|
@ -696,7 +696,7 @@ static void sculpt_undo_bmesh_restore_generic(SculptUndoNode *unode, Object *ob,
|
|||
}
|
||||
|
||||
if (data.balance_pbvh) {
|
||||
BKE_pbvh_bmesh_after_stroke(ss->pbvh);
|
||||
BKE_pbvh_bmesh_after_stroke(ss->pbvh, true);
|
||||
}
|
||||
|
||||
pbvh_bmesh_check_nodes(ss->pbvh);
|
||||
|
|
|
@ -884,7 +884,6 @@ static void rna_def_sculpt(BlenderRNA *brna)
|
|||
RNA_def_property_boolean_sdna(prop, NULL, "flags", SCULPT_DYNTOPO_ENABLED);
|
||||
RNA_def_property_ui_text(prop, "DynTopo", "Enable DynTopo remesher in dynamic topology mode.");
|
||||
RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
|
||||
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Sculpt_update");
|
||||
|
||||
prop = RNA_def_property(srna, "detail_size", PROP_FLOAT, PROP_PIXEL);
|
||||
RNA_def_property_ui_range(prop, 0.5, 40.0, 0.1, 2);
|
||||
|
|
Loading…
Reference in New Issue