[Bf-blender-cvs] [69668d62ba8] sculpt-dev: Array Brush: Working code for path and radial arrays
aousdfh
noreply at git.blender.org
Thu Jul 15 21:12:25 CEST 2021
Commit: 69668d62ba8fa00d328dc14d97ad14d54f77f9a4
Author: aousdfh
Date: Wed Jul 7 02:20:14 2021 +0200
Branches: sculpt-dev
https://developer.blender.org/rB69668d62ba8fa00d328dc14d97ad14d54f77f9a4
Array Brush: Working code for path and radial arrays
===================================================================
M source/blender/editors/sculpt_paint/sculpt_array.c
===================================================================
diff --git a/source/blender/editors/sculpt_paint/sculpt_array.c b/source/blender/editors/sculpt_paint/sculpt_array.c
index d69853fc93c..f90a9ae7d42 100644
--- a/source/blender/editors/sculpt_paint/sculpt_array.c
+++ b/source/blender/editors/sculpt_paint/sculpt_array.c
@@ -25,6 +25,7 @@
#include "BLI_blenlib.h"
#include "BLI_math.h"
+#include "BLI_hash.h"
#include "BLI_task.h"
#include "DNA_brush_types.h"
@@ -52,7 +53,10 @@
#include "GPU_matrix.h"
#include "GPU_state.h"
+#include "ED_sculpt.h"
+
#include "bmesh.h"
+#include "bmesh_tools.h"
#include <math.h>
#include <stdlib.h>
@@ -61,7 +65,7 @@
static const char array_symmetry_pass_cd_name[] = "v_symmetry_pass";
static const char array_instance_cd_name[] = "v_array_instance";
-#define SCULPT_ARRAY_COUNT 5
+#define SCULPT_ARRAY_COUNT 15
#define ARRAY_INSTANCE_ORIGINAL -1
@@ -133,6 +137,25 @@ static BMesh *sculpt_array_source_build(Object *ob, Brush *brush) {
/* TODO(pablodp606): Handle individual Face Sets for Face Set automasking. */
BM_mesh_delete_hflag_context(srcbm, BM_ELEM_TAG, DEL_VERTS);
+ const bool fill_holes = true;
+ BM_mesh_elem_hflag_disable_all(srcbm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_TAG, false);
+ BM_mesh_elem_hflag_enable_all(srcbm, BM_EDGE, BM_ELEM_TAG, false);
+ BM_mesh_edgenet(srcbm, false, true);
+ BM_mesh_normals_update(srcbm);
+ BMO_op_callf(srcbm,
+ (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE),
+ "triangulate faces=%hf quad_method=%i ngon_method=%i",
+ BM_ELEM_TAG,
+ 0,
+ 0);
+
+ BM_mesh_elem_hflag_enable_all(srcbm, BM_FACE, BM_ELEM_TAG, false);
+ BMO_op_callf(srcbm,
+ (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE),
+ "recalc_face_normals faces=%hf",
+ BM_ELEM_TAG);
+ BM_mesh_elem_hflag_disable_all(srcbm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_TAG, false);
+
return srcbm;
}
@@ -166,6 +189,10 @@ static void sculpt_array_final_mesh_write(Object *ob, BMesh *final_mesh) {
BKE_mesh_nomain_to_mesh(result, ob->data, ob, &CD_MASK_MESH, true);
BKE_mesh_free(result);
BKE_mesh_batch_cache_dirty_tag(ob->data, BKE_MESH_BATCH_DIRTY_ALL);
+
+ const int next_face_set_id = ED_sculpt_face_sets_find_next_available_id(ob->data);
+ ED_sculpt_face_sets_initialize_none_to_id(ob->data, next_face_set_id);
+
ss->needs_pbvh_rebuild = true;
}
@@ -250,34 +277,114 @@ static void sculpt_array_init(Object *ob, SculptArray *array) {
}
}
+
+static void sculpt_array_position_in_path_search(float *r_position, float *r_direction, SculptArray *array, const int index) {
+ const float path_length = array->path.points[array->path.tot_points-1].length;
+ const float step_distance = path_length / (float)SCULPT_ARRAY_COUNT;
+ const float copy_distance = step_distance * (index + 1);
+
+
+ if (array->path.tot_points == 1) {
+ zero_v3(r_position);
+ if (r_direction) {
+ zero_v3(r_direction);
+ }
+ return;
+ }
+
+ for (int i = 1; i < array->path.tot_points; i++) {
+ ScultpArrayPathPoint *path_point = &array->path.points[i];
+ if (copy_distance >= path_point->length) {
+ continue;
+ }
+ /* TODO: interpolate with prev. */
+ ScultpArrayPathPoint *prev_path_point = &array->path.points[i - 1];
+
+ const float remaining_dist = copy_distance - prev_path_point->length;
+ const float segment_length = path_point->length - prev_path_point->length;
+ interp_v3_v3v3(r_position, prev_path_point->co, path_point->co, remaining_dist / segment_length);
+ if (r_direction) {
+ copy_v3_v3(r_direction, path_point->direction);
+ }
+
+ return;
+ }
+
+ ScultpArrayPathPoint *last_path_point = &array->path.points[array->path.tot_points - 1];
+ copy_v3_v3(r_position, last_path_point->co);
+ if (r_direction) {
+ copy_v3_v3(r_direction, last_path_point->direction);
+ }
+
+}
+
+static void sculpt_array_linear_position_get(float *r_position, SculptArray *array, const int index) {
+
+}
+
static void sculpt_array_update_copy(StrokeCache *cache, SculptArray *array, SculptArrayCopy *copy) {
+ /*
const float fade = ((float)copy->index + 1.0f) / (float)(array->num_copies);
float delta[3];
flip_v3_v3(delta, cache->grab_delta, copy->symm_pass);
mul_v3_v3fl(copy->mat[3], delta, fade);
+ */
+
+ float copy_position[3];
+ unit_m4(copy->mat);
+
+ //sculpt_array_position_in_path_search(copy->mat[3], NULL, array, copy->index);
+
+ float pos[3];
+ const float fade = ((float)copy->index + 1.0f) / (float)(array->num_copies);
+ copy_v3_v3(pos, cache->grab_delta);
+ rotate_v3_v3v3fl(copy->mat[3], pos, cache->view_normal, fade * M_PI * 2.0f);
+
+ /*
+ copy->mat[3][0] += (BLI_hash_int_01(copy->index) * 2.0f - 0.5f) * cache->radius;
+ copy->mat[3][1] += (BLI_hash_int_01(copy->index + 1) * 2.0f - 0.5f) * cache->radius;
+ copy->mat[3][2] += (BLI_hash_int_01(copy->index + 2) * 2.0f - 0.5f) * cache->radius;
+ */
+
+/*
const float scale = cache->bstrength;
copy->mat[0][0] = scale;
copy->mat[1][1] = scale;
copy->mat[2][2] = scale;
+ */
}
-static void sculpt_array_update(Object *ob, Brush *brush, SculptArray *array) {
+
+static void sculpt_array_linear_update(Object *ob, Brush *brush, SculptArray *array) {
SculptSession *ss = ob->sculpt;
- for (int symm_pass = 0; symm_pass < PAINT_SYMM_AREAS; symm_pass++) {
+ /* Main symmetry pass. */
+ for (int copy_index = 0; copy_index < array->num_copies; copy_index++) {
+ SculptArrayCopy *copy = &array->copies[0][copy_index];
+ sculpt_array_update_copy(ss->cache, array, copy);
+ }
+
+ for (int symm_pass = 1; 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];
- sculpt_array_update_copy(ss->cache, array, copy);
+ SculptArrayCopy *copy = &array->copies[symm_pass][copy_index];
+ SculptArrayCopy *main_copy = &array->copies[0][copy_index];
+ unit_m4(copy->mat);
+ flip_v3_v3(copy->mat[3],main_copy->mat[3], symm_pass);
}
}
}
+static void sculpt_array_update(Object *ob, Brush *brush, SculptArray *array) {
+ sculpt_array_linear_update(ob, brush, array);
+}
+
static void do_array_deform_task_cb_ex(void *__restrict userdata,
const int n,
const TaskParallelTLS *__restrict tls)
@@ -302,12 +409,8 @@ static void do_array_deform_task_cb_ex(void *__restrict userdata,
if (array_index == -1) {
continue;
}
- const int array_symm_pass = cd_array_symm_pass[vd.index];
- if (array_symm_pass != ss->cache->mirror_symmetry_pass) {
- continue;
- }
-
+ const int array_symm_pass = cd_array_symm_pass[vd.index];
SculptArrayCopy *copy = &array->copies[array_symm_pass][array_index];
mul_v3_m4v3(vd.co, copy->mat, array->orco[vd.index]);
@@ -367,7 +470,11 @@ static void sculpt_array_stroke_sample_add(Object *ob, SculptArray *array) {
const int prev_point_index = current_point_index - 1;
ScultpArrayPathPoint *path_point = &array->path.points[current_point_index];
- add_v3_v3v3(path_point->co, ss->cache->true_initial_location, ss->cache->grab_delta);
+
+ //add_v3_v3v3(path_point->co, ss->cache->orig_grab_location, ss->cache->grab_delta);
+ copy_v3_v3(path_point->co, ss->cache->grab_delta);
+
+
if (current_point_index == 0) {
/* First point of the path. */
path_point->length = 0.0f;
@@ -375,7 +482,7 @@ static void sculpt_array_stroke_sample_add(Object *ob, SculptArray *array) {
else {
ScultpArrayPathPoint *prev_path_point = &array->path.points[prev_point_index];
sub_v3_v3v3(prev_path_point->direction, path_point->co, prev_path_point->co);
- path_point->length += normalize_v3(prev_path_point->direction);
+ path_point->length = prev_path_point->length + normalize_v3(prev_path_point->direction);
}
array->path.tot_points++;
@@ -392,9 +499,10 @@ void SCULPT_do_array_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
}
if (SCULPT_stroke_is_first_brush_step(ss->cache)) {
- sculpt_array_mesh_build(sd, ob);
ss->cache->array = sculpt_array_cache_create(ob, SCULPT_ARRAY_COUNT);
sculpt_array_init(ob, ss->cache->array);
+ sculpt_array_stroke_sample_add(ob, ss->cache->array);
+ sculpt_array_mesh_build(sd, ob);
/* 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;
}
@@ -406,9 +514,10 @@ void SCULPT_do_array_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
}
-void SCULPT_scultp_array_path_draw(const uint gpuattr,
+void SCULPT_array_path_draw(const uint gpuattr,
Brush *brush,
SculptSession *ss) {
+
SculptArray *array = ss->cache->array;
if (!array) {
return;
@@ -418,7 +527,7 @@ void SCULPT_scultp_array_path_draw(const uint gpuattr,
return;
}
- const int tot_points = array->path.tot_points - 1;
+ const int tot_points = array->path.tot_points;
immBegin(GPU_PRIM_LINE_STRIP, tot_points);
for (int i = 0; i < tot_points; i++) {
immVertex3fv(gpuattr, array->path.points[i].co);
More information about the Bf-blender-cvs
mailing list