Array Brush: Path edit mode working

This commit is contained in:
Pablo Dobarro 2021-07-21 23:27:46 +02:00
parent 93305b97df
commit 2689124320
3 changed files with 141 additions and 20 deletions

View File

@ -453,6 +453,7 @@ typedef struct SculptArrayCopy {
int index;
int symm_pass;
float mat[4][4];
float imat[4][4];
float origin[3];
} SculptArrayCopy;
@ -460,6 +461,7 @@ typedef struct ScultpArrayPathPoint {
float length;
float strength;
float co[3];
float orco[3];
float direction[3];
} ScultpArrayPathPoint;
@ -476,6 +478,8 @@ typedef struct SculptArray {
} path;
float normal[3];
bool source_mat_valid;
float source_origin[3];
float source_mat[4][4];
@ -634,6 +638,9 @@ typedef struct SculptSession {
SculptVertexInfo vertex_info;
SculptFakeNeighbors fake_neighbors;
/* Array. */
SculptArray *array;
/* Transform operator */
float pivot_pos[3];
float pivot_rot[4];

View File

@ -68,6 +68,12 @@ static const char array_instance_cd_name[] = "v_array_instance";
#define ARRAY_INSTANCE_ORIGINAL -1
static void sculpt_vertex_array_data_get(SculptArray *array, const int vertex, int *r_copy, int *r_symmetry_pass) {
if (!array->copy_index) {
printf("NO ARRAY COPY\n");
*r_copy = ARRAY_INSTANCE_ORIGINAL;
*r_symmetry_pass = 0;
return;
}
*r_copy = array->copy_index[vertex];
*r_symmetry_pass = array->symmetry_pass[vertex];
}
@ -306,6 +312,7 @@ static SculptArray *sculpt_array_cache_create(Object *ob, const int num_copies)
}
static void sculpt_array_cache_free(SculptArray *array) {
return;
for (int symm_pass = 0; symm_pass < PAINT_SYMM_AREAS; symm_pass++) {
MEM_SAFE_FREE(array->copies[symm_pass]);
}
@ -314,8 +321,13 @@ static void sculpt_array_cache_free(SculptArray *array) {
MEM_freeN(array);
}
static void sculpt_array_init(Object *ob, SculptArray *array) {
static void sculpt_array_init(Object *ob, Brush *brush, SculptArray *array) {
SculptSession *ss = ob->sculpt;
/* TODO: add options. */
copy_v3_v3(array->normal, ss->cache->view_normal);
for (int symm_pass = 0; symm_pass < PAINT_SYMM_AREAS; symm_pass++) {
if (array->copies[symm_pass] == NULL) {
continue;
@ -388,11 +400,11 @@ static void sculpt_array_position_in_path_search(float *r_position, float *r_dir
}
}
static void scultp_array_basis_from_direction(float r_mat[4][4], StrokeCache *cache, const float direction[3]) {
static void scultp_array_basis_from_direction(float r_mat[4][4], SculptArray *array, const float direction[3]) {
float direction_normalized[3];
normalize_v3_v3(direction_normalized, direction);
copy_v3_v3(r_mat[0], direction_normalized);
copy_v3_v3(r_mat[2], cache->view_normal);
cross_v3_v3v3(r_mat[2], r_mat[0], array->normal);
cross_v3_v3v3(r_mat[1], r_mat[0], r_mat[2]);
normalize_v3(r_mat[0]);
normalize_v3(r_mat[1]);
@ -435,7 +447,7 @@ static void sculpt_array_update_copy(StrokeCache *cache, SculptArray *array, Scu
if (!(brush->flag2 & BRUSH_ARRAY_LOCK_ORIENTATION)) {
scultp_array_basis_from_direction(copy->mat, cache, direction);
scultp_array_basis_from_direction(copy->mat, array, direction);
}
@ -463,6 +475,7 @@ static void sculpt_array_update(Object *ob, Brush *brush, SculptArray *array) {
/* Main symmetry pass. */
for (int copy_index = 0; copy_index < array->num_copies; copy_index++) {
SculptArrayCopy *copy = &array->copies[0][copy_index];
unit_m4(copy->mat);
sculpt_array_update_copy(ss->cache, array, copy, brush);
}
@ -483,6 +496,19 @@ static void sculpt_array_update(Object *ob, Brush *brush, SculptArray *array) {
}
}
}
for (int symm_pass = 0; symm_pass < PAINT_SYMM_AREAS; symm_pass++) {
if (array->copies[symm_pass] == NULL) {
continue;
}
for (int copy_index = 0; copy_index < array->num_copies; copy_index++) {
SculptArrayCopy *copy = &array->copies[symm_pass][copy_index];
print_m4("cosa", copy->mat);
invert_m4_m4(copy->imat, copy->mat);
}
}
}
static void do_array_deform_task_cb_ex(void *__restrict userdata,
@ -491,7 +517,7 @@ static void do_array_deform_task_cb_ex(void *__restrict userdata,
{
SculptThreadedTaskData *data = userdata;
SculptSession *ss = data->ob->sculpt;
SculptArray *array = ss->cache->array;
SculptArray *array = ss->array;
Mesh *mesh = BKE_object_get_original_mesh(data->ob);
@ -508,9 +534,9 @@ static void do_array_deform_task_cb_ex(void *__restrict userdata,
}
SculptArrayCopy *copy = &array->copies[array_symm_pass][array_index];
//printf("ARRAY COPY %d %d\n", array_index, array_symm_pass);
float co[3];
copy_v3_v3(co, array->orco[vd.index]);
mul_v3_m4v3(co, array->source_imat, array->orco[vd.index]);
mul_v3_m4v3(co, copy->mat, co);
float source_origin_symm[3];
@ -585,7 +611,7 @@ static void sculpt_array_ensure_base_transform(Sculpt *sd, Object *ob, SculptArr
return;
}
scultp_array_basis_from_direction(array->source_mat, ss->cache, ss->cache->grab_delta);
scultp_array_basis_from_direction(array->source_mat, array, ss->cache->grab_delta);
copy_v3_v3(array->source_mat[3], array->source_origin);
invert_m4_m4(array->source_imat, array->source_mat);
@ -593,6 +619,23 @@ static void sculpt_array_ensure_base_transform(Sculpt *sd, Object *ob, SculptArr
return;
}
static void sculpt_array_path_point_update(SculptArray *array, const int path_point_index) {
if (path_point_index == 0) {
return;
}
const int prev_path_point_index = path_point_index - 1;
ScultpArrayPathPoint *path_point = &array->path.points[path_point_index];
ScultpArrayPathPoint *prev_path_point = &array->path.points[prev_path_point_index];
if (len_v3v3(prev_path_point->co, path_point->co) <= 0.0001f) {
return;
}
sub_v3_v3v3(prev_path_point->direction, path_point->co, prev_path_point->co);
path_point->length = prev_path_point->length + normalize_v3(prev_path_point->direction);
}
static void sculpt_array_stroke_sample_add(Object *ob, SculptArray *array) {
SculptSession *ss = ob->sculpt;
@ -632,6 +675,76 @@ void SCULPT_do_array_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
Brush *brush = BKE_paint_brush(&sd->paint);
if (ss->cache->invert) {
if (!ss->array) {
return;
}
if (SCULPT_stroke_is_first_brush_step(ss->cache)) {
/* Update Array Path Orco. */
SculptArray *array = ss->array;
for (int i = 0; i < array->path.tot_points; i++) {
ScultpArrayPathPoint *point = &array->path.points[i];
copy_v3_v3(point->orco, point->co);
}
/* Update Geometry Orco. */
const int totvert = SCULPT_vertex_count_get(ss);
for (int i = 0; i < totvert; i++) {
int array_index = ARRAY_INSTANCE_ORIGINAL;
int array_symm_pass = 0;
sculpt_vertex_array_data_get(array, i, &array_index, &array_symm_pass);
if (array_index == ARRAY_INSTANCE_ORIGINAL) {
continue;
}
SculptArrayCopy *copy = &array->copies[array_symm_pass][array_index];
//sub_v3_v3v3(array->orco[i], SCULPT_vertex_co_get(ss, i), copy->mat[3]);
float co[3];
float source_origin_symm[3];
flip_v3_v3(source_origin_symm, array->source_origin, array_symm_pass);
sub_v3_v3v3(co, SCULPT_vertex_co_get(ss, i), source_origin_symm);
mul_v3_m4v3(co, copy->imat, co);
mul_v3_m4v3(co, array->source_imat, co);
copy_v3_v3(array->orco[i], co);
}
}
SculptArray *array = ss->array;
for (int i = 0; i < array->path.tot_points; i++) {
ScultpArrayPathPoint *point = &array->path.points[i];
float point_co[3];
add_v3_v3v3(point_co, point->orco, array->source_origin);
const float len = len_v3v3(ss->cache->true_location, point_co);
const float fade = ss->cache->bstrength * BKE_brush_curve_strength(brush, len, ss->cache->radius);
if (fade <= 0.0f) {
continue;
}
madd_v3_v3v3fl(point->co, point->orco, ss->cache->grab_delta, fade);
}
for (int i = 0; i < array->path.tot_points; i++) {
sculpt_array_path_point_update(array, i);
}
sculpt_array_update(ob, brush, ss->array);
sculpt_array_deform(sd, ob, nodes, totnode);
return;
}
if (brush->array_count == 0) {
return;
}
@ -642,22 +755,26 @@ void SCULPT_do_array_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
}
if (SCULPT_stroke_is_first_brush_step(ss->cache)) {
ss->cache->array = sculpt_array_cache_create(ob, brush->array_count);
sculpt_array_init(ob, ss->cache->array);
sculpt_array_stroke_sample_add(ob, ss->cache->array);
sculpt_array_mesh_build(sd, ob, ss->cache->array);
if (ss->array) {
sculpt_array_cache_free(ss->array);
}
ss->array = sculpt_array_cache_create(ob, brush->array_count);
sculpt_array_init(ob, brush, ss->array);
sculpt_array_stroke_sample_add(ob, ss->array);
sculpt_array_mesh_build(sd, ob, ss->array);
/* Original coordinates can't be stored yet as the SculptSession data needs to be updated after the mesh modifications performed when building the array geometry. */
return;
}
sculpt_array_ensure_base_transform(sd, ob, ss->cache->array);
sculpt_array_ensure_original_coordinates(ob, ss->cache->array);
sculpt_array_ensure_geometry_indices(ob, ss->cache->array);
sculpt_array_ensure_base_transform(sd, ob, ss->array);
sculpt_array_ensure_original_coordinates(ob, ss->array);
sculpt_array_ensure_geometry_indices(ob, ss->array);
sculpt_array_stroke_sample_add(ob, ss->cache->array);
sculpt_array_stroke_sample_add(ob, ss->array);
sculpt_array_update(ob, brush, ss->cache->array);
sculpt_array_update(ob, brush, ss->array);
sculpt_array_deform(sd, ob, nodes, totnode);
}
@ -666,7 +783,7 @@ void SCULPT_array_path_draw(const uint gpuattr,
Brush *brush,
SculptSession *ss) {
SculptArray *array = ss->cache->array;
SculptArray *array = ss->array;
/* Disable debug drawing. */

View File

@ -1091,9 +1091,6 @@ typedef struct StrokeCache {
/* Layer brush */
float *layer_displacement_factor;
/* Array Brush */
struct ArrayBrush *array;
float vertex_rotation; /* amount to rotate the vertices when using rotate brush */
struct Dial *dial;