56 const float initial_target[3],
57 const bool use_anchor)
68 for (
int i = 0; i < tot_segments; i++) {
69 float initial_orientation[3];
70 float current_orientation[3];
71 float current_head_position[3];
72 float current_origin_position[3];
75 sub_v3_v3v3(current_orientation, target, segments[i].orig);
77 sub_v3_v3v3(initial_orientation, segments[i].initial_head, segments[i].initial_orig);
82 madd_v3_v3v3fl(current_head_position, segments[i].orig, current_orientation, segments[i].
len);
85 sub_v3_v3v3(current_origin_position, target, current_head_position);
88 copy_v3_v3(segments[i].head, current_head_position);
89 add_v3_v3(segments[i].orig, current_origin_position);
99 anchor_diff, segments[tot_segments - 1].initial_orig, segments[tot_segments - 1].orig);
101 for (
int i = 0; i < tot_segments; i++) {
102 add_v3_v3(segments[i].orig, anchor_diff);
103 add_v3_v3(segments[i].head, anchor_diff);
115 for (
int i = 0; i < tot_segments; i++) {
116 float initial_orientation[3];
117 float initial_rotation[4];
118 float current_rotation[4];
120 sub_v3_v3v3(initial_orientation, segments[i].initial_head, segments[i].initial_orig);
139 for (
int i = 0; i < tot_segments; i++) {
141 add_v3_v3v3(segments[i].head, segments[i].initial_head, delta);
142 add_v3_v3v3(segments[i].orig, segments[i].initial_orig, delta);
154 for (
int i = 0; i < tot_segments; i++) {
171 float disp[3], new_co[3];
191 mul_m4_v3(segments[ik].pivot_mat_inv[(
int)symm_area], new_co);
192 mul_m4_v3(segments[ik].trans_mat[(
int)symm_area], new_co);
193 mul_m4_v3(segments[ik].pivot_mat[(
int)symm_area], new_co);
241 float vmask_f =
data->prev_mask[ni.
index];
260 void *__restrict chunk_join,
261 void *__restrict chunk)
274 float pose_origin[3],
275 float pose_target[3],
277 float *r_pose_origin,
290 .pose_factor = pose_factor,
293 data.pose_initial_co = pose_target;
303 bool grow_next_iteration =
true;
304 float prev_len = FLT_MAX;
306 while (grow_next_iteration) {
319 if (
len < prev_len) {
321 grow_next_iteration =
true;
324 grow_next_iteration =
false;
334 grow_next_iteration =
true;
337 grow_next_iteration =
false;
349 grow_next_iteration =
false;
358 const float br_co[3],
362 for (
char i = 0; i <= symm; ++i) {
366 if (
len_v3v3(location, vertex) < radius) {
422 if (
data->pose_factor) {
423 data->pose_factor[to_v] = 1.0f;
450 const int index = to_v;
451 bool visit_next =
false;
455 co,
data->pose_initial_co,
data->symm) &&
462 data->pose_factor[index] = 1.0f;
470 else if (symmetry_check) {
480 bool is_vertex_valid =
false;
481 if (
data->is_first_iteration) {
492 if (!is_vertex_valid) {
497 data->pose_factor[index] = 1.0f;
503 if (symmetry_check) {
505 data->fallback_count++;
514 bool count_as_boundary =
false;
523 if (!
data->next_face_set_found) {
524 data->next_face_set = next_face_set_candidate;
526 data->next_face_set_found =
true;
528 count_as_boundary =
true;
534 if (count_as_boundary) {
553 float initial_location[3],
556 float *r_pose_origin,
557 float *r_pose_factor)
569 .pose_factor = r_pose_factor,
594 if (pose_offset != 0.0f && r_pose_factor) {
618 data->pose_factor[vd.
index] = avg / total;
630 "Pose IK Chain Segments");
631 for (
int i = 0; i < totsegments; i++) {
639 const float initial_location[3])
678 const float initial_location[3],
682 const float chain_segment_len = radius * (1.0f + br->
pose_offset);
683 float next_chain_segment_target[3];
692 float *pose_factor_grow =
MEM_callocN(totvert *
sizeof(
float),
"Pose Factor Grow");
695 float *pose_factor_grow_prev =
MEM_callocN(totvert *
sizeof(
float),
696 "Pose Factor Grow Prev Iteration");
698 pose_factor_grow[nearest_vertex_index] = 1.0f;
704 copy_v3_v3(next_chain_segment_target, initial_location);
708 next_chain_segment_target,
718 for (
int j = 0; j < totvert; j++) {
720 pose_factor_grow_prev[j] = pose_factor_grow[j];
731 next_chain_segment_target,
739 for (
int j = 0; j < totvert; j++) {
740 ik_chain->
segments[i].
weights[j] = pose_factor_grow[j] - pose_factor_grow_prev[j];
742 pose_factor_grow_prev[j] = pose_factor_grow[j];
787 .current_face_set = current_face_set,
788 .prev_face_set = prev_face_set,
789 .visited_face_sets = visited_face_sets,
790 .is_weighted = is_weighted,
791 .next_face_set_found =
false,
792 .is_first_iteration = s == 0,
827 SculptSession *ss,
int from_v,
int to_v,
bool is_duplicate,
void *userdata)
832 data->floodfill_it[to_v] =
data->floodfill_it[from_v] + 1;
835 data->floodfill_it[to_v] =
data->floodfill_it[from_v];
846 if (
data->floodfill_it[to_v] >=
data->masked_face_set_it) {
847 data->masked_face_set = to_face_set;
848 data->masked_face_set_it =
data->floodfill_it[to_v];
852 data->target_face_set = to_face_set;
864 data->fk_weights[to_v] = 1.0f;
893 int origin_count = 0;
894 float origin_acc[3] = {0.0f};
895 for (
int i = 0; i < totvert; i++) {
903 int target_count = 0;
904 float target_acc[3] = {0.0f};
906 for (
int i = 0; i < totvert; i++) {
918 if (origin_count > 0) {
926 if (target_count > 0) {
949 const float initial_location[3],
956 if (use_fake_neighbors) {
973 if (use_fake_neighbors) {
1024 float segment_dir[3];
1028 const float segment_len = ik_chain->
segments[0].
len;
1106 scale[0] = scale[1] =
sqrtf(1.0f / scale[2]);
1116 const float grab_location[3])
1118 float segment_origin_head[3];
1128 sub_v3_v3v3(segment_origin_head, symm_head, symm_orig);
1170 float symm_initial_orig[3];
1184 float pivot_local_space[4][4];
1201 for (
int scale_i = 0; scale_i < 3; scale_i++) {
1207 symm_orig[0] - symm_initial_orig[0],
1208 symm_orig[1] - symm_initial_orig[1],
1209 symm_orig[2] - symm_initial_orig[2]);
1213 ik_chain->
segments[i].
pivot_mat[symm_it], symm_orig[0], symm_orig[1], symm_orig[2]);
float BKE_brush_curve_strength(const struct Brush *br, float p, const float len)
General operations, lookup, etc. for blender objects.
struct Brush * BKE_paint_brush(struct Paint *paint)
#define SCULPT_FACE_SET_NONE
A BVH for high poly meshes.
#define BKE_pbvh_vertex_iter_begin(pbvh, node, vi, mode)
#define BKE_pbvh_vertex_iter_end
void BKE_pbvh_parallel_range_settings(struct TaskParallelSettings *settings, bool use_threading, int totnode)
void BKE_pbvh_search_gather(PBVH *pbvh, BKE_pbvh_SearchCallback scb, void *search_data, PBVHNode ***array, int *tot)
#define BLI_BITMAP_TEST(_bitmap, _index)
#define BLI_BITMAP_ENABLE(_bitmap, _index)
#define BLI_BITMAP_NEW(_tot, _alloc_string)
#define GSET_ITER(gs_iter_, gset_)
bool BLI_gset_haskey(GSet *gs, const void *key) ATTR_WARN_UNUSED_RESULT
void BLI_gset_free(GSet *gs, GSetKeyFreeFP keyfreefp)
BLI_INLINE void * BLI_gsetIterator_getKey(GSetIterator *gsi)
bool BLI_gset_add(GSet *gs, void *key)
GSet * BLI_gset_int_new_ex(const char *info, const unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
void plane_from_point_normal_v3(float r_plane[4], const float plane_co[3], const float plane_no[3])
float dist_signed_to_plane_v3(const float p[3], const float plane[4])
void unit_m4(float m[4][4])
void translate_m4(float mat[4][4], float tx, float ty, float tz)
bool invert_m4_m4(float R[4][4], const float A[4][4])
void mul_m4_v3(const float M[4][4], float r[3])
void mul_m4_m4_post(float R[4][4], const float B[4][4])
void rotation_between_quats_to_quat(float q[4], const float q1[4], const float q2[4])
void rotation_between_vecs_to_quat(float q[4], const float v1[3], const float v2[3])
void axis_angle_normalized_to_quat(float r[4], const float axis[3], const float angle)
void copy_qt_qt(float q[4], const float a[4])
void quat_to_mat4(float mat[4][4], const float q[4])
MINLINE float len_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f)
MINLINE float normalize_v3(float r[3])
MINLINE float len_squared_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void add_v3_v3v3(float r[3], const float a[3], const float b[3])
void ortho_basis_v3v3_v3(float r_n1[3], float r_n2[3], const float n[3])
MINLINE void copy_v3_fl(float r[3], float f)
MINLINE void madd_v3_v3v3fl(float r[3], const float a[3], const float b[3], float f)
MINLINE void zero_v3(float r[3])
MINLINE void add_v3_v3(float r[3], const float a[3])
void BLI_task_parallel_range(const int start, const int stop, void *userdata, TaskParallelRangeFunc func, const TaskParallelSettings *settings)
#define POINTER_FROM_INT(i)
#define POINTER_AS_INT(i)
@ BRUSH_POSE_DEFORM_SQUASH_STRETCH
@ BRUSH_POSE_DEFORM_ROTATE_TWIST
@ BRUSH_POSE_DEFORM_SCALE_TRASLATE
@ BRUSH_USE_CONNECTED_ONLY
@ BRUSH_POSE_USE_LOCK_ROTATION
@ BRUSH_POSE_ORIGIN_FACE_SETS_FK
@ BRUSH_POSE_ORIGIN_TOPOLOGY
@ BRUSH_POSE_ORIGIN_FACE_SETS
Object is a sort of wrapper for general info.
Read Guarded memory(de)allocation.
void(* MEM_freeN)(void *vmemh)
void *(* MEM_calloc_arrayN)(size_t len, size_t size, const char *str)
void *(* MEM_callocN)(size_t len, const char *str)
void *(* MEM_mallocN)(size_t len, const char *str)
Segment< FEdge *, Vec3r > segment
void flip_v3_v3(float out[3], const float in[3], const enum ePaintSymmetryFlags symm)
const float * SCULPT_vertex_co_get(SculptSession *ss, int index)
int SCULPT_vertex_count_get(SculptSession *ss)
void SCULPT_orig_vert_data_update(SculptOrigVertData *orig_data, PBVHVertexIter *iter)
void SCULPT_floodfill_add_initial_with_symmetry(Sculpt *sd, Object *ob, SculptSession *ss, SculptFloodFill *flood, int index, float radius)
int SCULPT_active_vertex_get(SculptSession *ss)
int SCULPT_nearest_vertex_get(Sculpt *sd, Object *ob, const float co[3], float max_distance, bool use_original)
void SCULPT_floodfill_init(SculptSession *ss, SculptFloodFill *flood)
void SCULPT_fake_neighbors_ensure(Sculpt *sd, Object *ob, const float max_dist)
bool SCULPT_vertex_has_face_set(SculptSession *ss, int index, int face_set)
bool SCULPT_vertex_has_unique_face_set(SculptSession *ss, int index)
void SCULPT_floodfill_add_initial(SculptFloodFill *flood, int index)
bool SCULPT_is_symmetry_iteration_valid(char i, char symm)
const float * SCULPT_active_vertex_co_get(SculptSession *ss)
void SCULPT_vertex_random_access_ensure(SculptSession *ss)
float * SCULPT_brush_deform_target_vertex_co_get(SculptSession *ss, const int deform_target, PBVHVertexIter *iter)
void SCULPT_flip_v3_by_symm_area(float v[3], const ePaintSymmetryFlags symm, const ePaintSymmetryAreas symmarea, const float pivot[3])
void SCULPT_floodfill_free(SculptFloodFill *flood)
void SCULPT_fake_neighbors_enable(Object *ob)
void SCULPT_flip_quat_by_symm_area(float quat[3], const ePaintSymmetryFlags symm, const ePaintSymmetryAreas symmarea, const float pivot[3])
int SCULPT_vertex_face_set_get(SculptSession *ss, int index)
void SCULPT_fake_neighbors_disable(Object *ob)
char SCULPT_mesh_symmetry_xyz_get(Object *object)
bool SCULPT_check_vertex_pivot_symmetry(const float vco[3], const float pco[3], const char symm)
void SCULPT_floodfill_add_active(Sculpt *sd, Object *ob, SculptSession *ss, SculptFloodFill *flood, float radius)
ePaintSymmetryAreas SCULPT_get_vertex_symm_area(const float co[3])
int SCULPT_active_face_set_get(SculptSession *ss)
void SCULPT_floodfill_execute(SculptSession *ss, SculptFloodFill *flood, bool(*func)(SculptSession *ss, int from_v, int to_v, bool is_duplicate, void *userdata), void *userdata)
void SCULPT_orig_vert_data_init(SculptOrigVertData *data, Object *ob, PBVHNode *node)
float SCULPT_automasking_factor_get(AutomaskingCache *automasking, SculptSession *ss, int vert)
#define SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN(ss, v_index, neighbor_iterator)
#define SCULPT_VERTEX_NEIGHBORS_ITER_END(neighbor_iterator)
static void sculpt_pose_do_twist_deform(SculptSession *ss, Brush *brush)
static void sculpt_pose_do_rotate_deform(SculptSession *ss, Brush *brush)
static void sculpt_pose_do_scale_deform(SculptSession *ss, Brush *brush)
static void pose_solve_translate_chain(SculptPoseIKChain *ik_chain, const float delta[3])
static void pose_solve_scale_chain(SculptPoseIKChain *ik_chain, const float scale[3])
static bool pose_face_sets_floodfill_cb(SculptSession *ss, int UNUSED(from_v), int to_v, bool is_duplicate, void *userdata)
static void sculpt_pose_do_translate_deform(SculptSession *ss, Brush *brush)
static int pose_brush_num_effective_segments(const Brush *brush)
static SculptPoseIKChain * pose_ik_chain_init_face_sets_fk(Sculpt *sd, Object *ob, SculptSession *ss, const float radius, const float *initial_location)
static void pose_brush_grow_factor_reduce(const void *__restrict UNUSED(userdata), void *__restrict chunk_join, void *__restrict chunk)
static void sculpt_pose_align_pivot_local_space(float r_mat[4][4], ePaintSymmetryFlags symm, ePaintSymmetryAreas symm_area, SculptPoseIKChainSegment *segment, const float grab_location[3])
SculptPoseIKChain * SCULPT_pose_ik_chain_init(Sculpt *sd, Object *ob, SculptSession *ss, Brush *br, const float initial_location[3], const float radius)
static SculptPoseIKChain * pose_ik_chain_init_face_sets(Sculpt *sd, Object *ob, SculptSession *ss, Brush *br, const float radius)
static bool pose_topology_floodfill_cb(SculptSession *ss, int UNUSED(from_v), int to_v, bool is_duplicate, void *userdata)
struct PoseGrowFactorTLSData PoseGrowFactorTLSData
void SCULPT_pose_ik_chain_free(SculptPoseIKChain *ik_chain)
void SCULPT_pose_brush_init(Sculpt *sd, Object *ob, SculptSession *ss, Brush *br)
static void pose_solve_roll_chain(SculptPoseIKChain *ik_chain, const Brush *brush, const float roll)
static void pose_ik_chain_origin_heads_init(SculptPoseIKChain *ik_chain, const float initial_location[3])
static void sculpt_pose_do_squash_stretch_deform(SculptSession *ss, Brush *UNUSED(brush))
static SculptPoseIKChain * pose_ik_chain_init_topology(Sculpt *sd, Object *ob, SculptSession *ss, Brush *br, const float initial_location[3], const float radius)
void SCULPT_pose_calc_pose_data(Sculpt *sd, Object *ob, SculptSession *ss, float initial_location[3], float radius, float pose_offset, float *r_pose_origin, float *r_pose_factor)
static void pose_brush_init_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict UNUSED(tls))
static bool pose_face_sets_fk_set_weights_floodfill_cb(SculptSession *ss, int UNUSED(from_v), int to_v, bool UNUSED(is_duplicate), void *userdata)
static void sculpt_pose_do_scale_translate_deform(SculptSession *ss, Brush *brush)
struct PoseFloodFillData PoseFloodFillData
static float sculpt_pose_get_scale_from_grab_delta(SculptSession *ss, const float ik_target[3])
void SCULPT_do_pose_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
static void sculpt_pose_grow_pose_factor(Sculpt *sd, Object *ob, SculptSession *ss, float pose_origin[3], float pose_target[3], float max_len, float *r_pose_origin, float *pose_factor)
static void do_pose_brush_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict UNUSED(tls))
static void pose_brush_grow_factor_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls)
static SculptPoseIKChain * pose_ik_chain_new(const int totsegments, const int totverts)
static void pose_solve_ik_chain(SculptPoseIKChain *ik_chain, const float initial_target[3], const bool use_anchor)
static void sculpt_pose_do_rotate_twist_deform(SculptSession *ss, Brush *brush)
static bool pose_face_sets_fk_find_masked_floodfill_cb(SculptSession *ss, int from_v, int to_v, bool is_duplicate, void *userdata)
static bool sculpt_pose_brush_is_vertex_inside_brush_radius(const float vertex[3], const float br_co[3], float radius, char symm)
int pose_smooth_iterations
struct CurveMapping * curve
float disconnected_distance_max
struct SculptSession * sculpt
float fallback_floodfill_origin[3]
float pivot_mat[PAINT_SYMM_AREAS][4][4]
float trans_mat[PAINT_SYMM_AREAS][4][4]
float pivot_mat_inv[PAINT_SYMM_AREAS][4][4]
SculptPoseIKChainSegment * segments
float grab_delta_offset[3]
struct StrokeCache * cache
float orig_grab_location[3]
struct SculptPoseIKChain * pose_ik_chain
AutomaskingCache * automasking
TaskParallelReduceFunc func_reduce
size_t userdata_chunk_size
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)