Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPablo Dobarro <pablodp606@gmail.com>2020-09-18 02:17:33 +0300
committerPablo Dobarro <pablodp606@gmail.com>2020-09-18 20:10:40 +0300
commit5d728d38b94c2e48865de0e90fb433dbc1845fe0 (patch)
treedecce29be944cdf64959994e0135c8206a49e3ac /source/blender
parent8ac1ca13c852b8f35306d8aff7d2fa0f2a690ccf (diff)
Sculpt: Scale Cloth Filter
This filter scales the mesh as it was a softbody, producing folds in the surface. The orientation of the folds can be controlled using the filter axis and orientation. This is an example of a cloth filter that uses deform coordinates instead of forces, but probably it does not make much sense to expose it to the user in a different way and with different parameters. I'll remove FilterCache->enabled_force_axis in a later commit and use always enabled_axis in SCULPT_filter_zero_disabled_axis_components for both forces and deformation filters, so this function can also be used in the mesh filter. Reviewed By: sergey Differential Revision: https://developer.blender.org/D8661
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c3
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_cloth.c83
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_filter_mesh.c11
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_intern.h4
4 files changed, 82 insertions, 19 deletions
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index e6ea79a771a..a577760cf9b 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -5716,7 +5716,8 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe
if (brush->deform_target == BRUSH_DEFORM_TARGET_CLOTH_SIM) {
if (!ss->cache->cloth_sim) {
- ss->cache->cloth_sim = SCULPT_cloth_brush_simulation_create(ss, brush, 1.0f, 0.0f, false);
+ ss->cache->cloth_sim = SCULPT_cloth_brush_simulation_create(
+ ss, brush, 1.0f, 0.0f, false, true);
SCULPT_cloth_brush_simulation_init(ss, ss->cache->cloth_sim);
SCULPT_cloth_brush_build_nodes_constraints(
sd, ob, nodes, totnode, ss->cache->cloth_sim, ss->cache->location, FLT_MAX);
diff --git a/source/blender/editors/sculpt_paint/sculpt_cloth.c b/source/blender/editors/sculpt_paint/sculpt_cloth.c
index 0246e208bcb..d8fedecc61c 100644
--- a/source/blender/editors/sculpt_paint/sculpt_cloth.c
+++ b/source/blender/editors/sculpt_paint/sculpt_cloth.c
@@ -876,7 +876,8 @@ SculptClothSimulation *SCULPT_cloth_brush_simulation_create(SculptSession *ss,
Brush *brush,
const float cloth_mass,
const float cloth_damping,
- const bool use_collisions)
+ const bool use_collisions,
+ const bool needs_deform_coords)
{
const int totverts = SCULPT_vertex_count_get(ss);
SculptClothSimulation *cloth_sim;
@@ -898,9 +899,7 @@ SculptClothSimulation *SCULPT_cloth_brush_simulation_create(SculptSession *ss,
cloth_sim->length_constraint_tweak = MEM_calloc_arrayN(
totverts, sizeof(float), "cloth sim length tweak");
- /* Brush can be NULL for tools that need the solver but don't rely on constraint to deformation
- * positions. */
- if (brush && SCULPT_is_cloth_deform_brush(brush)) {
+ if (needs_deform_coords) {
cloth_sim->deformation_pos = MEM_calloc_arrayN(
totverts, sizeof(float[3]), "cloth sim deformation positions");
cloth_sim->deformation_strength = MEM_calloc_arrayN(
@@ -997,7 +996,8 @@ void SCULPT_do_cloth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
brush,
brush->cloth_mass,
brush->cloth_damping,
- (brush->flag2 & BRUSH_CLOTH_USE_COLLISION));
+ (brush->flag2 & BRUSH_CLOTH_USE_COLLISION),
+ SCULPT_is_cloth_deform_brush(brush));
SCULPT_cloth_brush_simulation_init(ss, ss->cache->cloth_sim);
}
@@ -1106,6 +1106,7 @@ typedef enum eSculpClothFilterType {
CLOTH_FILTER_INFLATE,
CLOTH_FILTER_EXPAND,
CLOTH_FILTER_PINCH,
+ CLOTH_FILTER_SCALE,
} eSculptClothFilterType;
static EnumPropertyItem prop_cloth_filter_type[] = {
@@ -1113,6 +1114,11 @@ static EnumPropertyItem prop_cloth_filter_type[] = {
{CLOTH_FILTER_INFLATE, "INFLATE", 0, "Inflate", "Inflates the cloth"},
{CLOTH_FILTER_EXPAND, "EXPAND", 0, "Expand", "Expands the cloth's dimensions"},
{CLOTH_FILTER_PINCH, "PINCH", 0, "Pinch", "Pulls the cloth to the cursor's start position"},
+ {CLOTH_FILTER_SCALE,
+ "SCALE",
+ 0,
+ "Scale",
+ "Scales the mesh as a softbody using the origin of the object as scale"},
{0, NULL, 0, NULL, NULL},
};
@@ -1148,6 +1154,35 @@ static EnumPropertyItem prop_cloth_filter_force_axis_items[] = {
{0, NULL, 0, NULL, NULL},
};
+static bool cloth_filter_is_deformation_filter(eSculptClothFilterType filter_type)
+{
+ return ELEM(filter_type, CLOTH_FILTER_SCALE);
+}
+
+static void cloth_filter_apply_displacement_to_deform_co(const int v_index,
+ const float disp[3],
+ FilterCache *filter_cache)
+{
+ float final_disp[3];
+ copy_v3_v3(final_disp, disp);
+ SCULPT_filter_zero_disabled_axis_components(final_disp, filter_cache);
+ add_v3_v3v3(filter_cache->cloth_sim->deformation_pos[v_index],
+ filter_cache->cloth_sim->init_pos[v_index],
+ final_disp);
+}
+
+static void cloth_filter_apply_forces_to_vertices(const int v_index,
+ const float force[3],
+ const float gravity[3],
+ FilterCache *filter_cache)
+{
+ float final_force[3];
+ copy_v3_v3(final_force, force);
+ SCULPT_filter_zero_disabled_axis_components(final_force, filter_cache);
+ add_v3_v3(final_force, gravity);
+ cloth_brush_apply_force_to_vertex(NULL, filter_cache->cloth_sim, final_force, v_index);
+}
+
static void cloth_filter_apply_forces_task_cb(void *__restrict userdata,
const int i,
const TaskParallelTLS *__restrict UNUSED(tls))
@@ -1158,7 +1193,9 @@ static void cloth_filter_apply_forces_task_cb(void *__restrict userdata,
PBVHNode *node = data->nodes[i];
SculptClothSimulation *cloth_sim = ss->filter_cache->cloth_sim;
- const int filter_type = data->filter_type;
+
+ const eSculptClothFilterType filter_type = data->filter_type;
+ const bool is_deformation_filter = cloth_filter_is_deformation_filter(filter_type);
float sculpt_gravity[3] = {0.0f};
if (sd->gravity_object) {
@@ -1175,6 +1212,7 @@ static void cloth_filter_apply_forces_task_cb(void *__restrict userdata,
float fade = vd.mask ? *vd.mask : 0.0f;
fade = 1.0f - fade;
float force[3] = {0.0f, 0.0f, 0.0f};
+ float disp[3], temp[3], transform[3][3];
if (ss->filter_cache->active_face_set != SCULPT_FACE_SET_NONE) {
if (!SCULPT_vertex_has_face_set(ss, vd.index, ss->filter_cache->active_face_set)) {
@@ -1208,19 +1246,23 @@ static void cloth_filter_apply_forces_task_cb(void *__restrict userdata,
normalize_v3(force);
mul_v3_fl(force, fade * data->filter_strength);
break;
- }
+ case CLOTH_FILTER_SCALE:
+ unit_m3(transform);
+ scale_m3_fl(transform, 1.0f + (fade * data->filter_strength));
+ copy_v3_v3(temp, cloth_sim->init_pos[vd.index]);
+ mul_m3_v3(transform, temp);
+ sub_v3_v3v3(disp, temp, cloth_sim->init_pos[vd.index]);
+ zero_v3(force);
- SCULPT_filter_to_orientation_space(force, ss->filter_cache);
- for (int axis = 0; axis < 3; axis++) {
- if (!ss->filter_cache->enabled_force_axis[axis]) {
- force[axis] = 0.0f;
- }
+ break;
}
- SCULPT_filter_to_object_space(force, ss->filter_cache);
- add_v3_v3(force, sculpt_gravity);
-
- cloth_brush_apply_force_to_vertex(ss, cloth_sim, force, vd.index);
+ if (is_deformation_filter) {
+ cloth_filter_apply_displacement_to_deform_co(vd.index, disp, ss->filter_cache);
+ }
+ else {
+ cloth_filter_apply_forces_to_vertices(vd.index, force, sculpt_gravity, ss->filter_cache);
+ }
}
BKE_pbvh_vertex_iter_end;
@@ -1291,6 +1333,8 @@ static int sculpt_cloth_filter_invoke(bContext *C, wmOperator *op, const wmEvent
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
SculptSession *ss = ob->sculpt;
+ const eSculptClothFilterType filter_type = RNA_enum_get(op->ptr, "type");
+
/* Update the active vertex */
float mouse[2];
SculptCursorGeometryInfo sgi;
@@ -1310,7 +1354,12 @@ static int sculpt_cloth_filter_invoke(bContext *C, wmOperator *op, const wmEvent
const float cloth_damping = RNA_float_get(op->ptr, "cloth_damping");
const bool use_collisions = RNA_boolean_get(op->ptr, "use_collisions");
ss->filter_cache->cloth_sim = SCULPT_cloth_brush_simulation_create(
- ss, NULL, cloth_mass, cloth_damping, use_collisions);
+ ss,
+ NULL,
+ cloth_mass,
+ cloth_damping,
+ use_collisions,
+ cloth_filter_is_deformation_filter(filter_type));
copy_v3_v3(ss->filter_cache->cloth_sim_pinch_point, SCULPT_active_vertex_co_get(ss));
diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c b/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c
index 1cbf9275a56..c2e90638994 100644
--- a/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c
+++ b/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c
@@ -97,6 +97,17 @@ void SCULPT_filter_to_object_space(float r_v[3], struct FilterCache *filter_cach
}
}
+void SCULPT_filter_zero_disabled_axis_components(float r_v[3], struct FilterCache *filter_cache)
+{
+ SCULPT_filter_to_orientation_space(r_v, filter_cache);
+ for (int axis = 0; axis < 3; axis++) {
+ if (!filter_cache->enabled_force_axis[axis]) {
+ r_v[axis] = 0.0f;
+ }
+ }
+ SCULPT_filter_to_object_space(r_v, filter_cache);
+}
+
static void filter_cache_init_task_cb(void *__restrict userdata,
const int i,
const TaskParallelTLS *__restrict UNUSED(tls))
diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h
index 620033422b2..53641dae447 100644
--- a/source/blender/editors/sculpt_paint/sculpt_intern.h
+++ b/source/blender/editors/sculpt_paint/sculpt_intern.h
@@ -366,7 +366,8 @@ struct SculptClothSimulation *SCULPT_cloth_brush_simulation_create(struct Sculpt
struct Brush *brush,
const float cloth_mass,
const float cloth_damping,
- const bool use_collisions);
+ const bool use_collisions,
+ const bool needs_deform_coords);
void SCULPT_cloth_brush_simulation_init(struct SculptSession *ss,
struct SculptClothSimulation *cloth_sim);
void SCULPT_cloth_brush_store_simulation_state(struct SculptSession *ss,
@@ -971,6 +972,7 @@ typedef enum SculptFilterOrientation {
void SCULPT_filter_to_orientation_space(float r_v[3], struct FilterCache *filter_cache);
void SCULPT_filter_to_object_space(float r_v[3], struct FilterCache *filter_cache);
+void SCULPT_filter_zero_disabled_axis_components(float r_v[3], struct FilterCache *filter_cache);
typedef struct FilterCache {
bool enabled_axis[3];