40 const float initial_target[3],
41 const bool use_anchor)
52 for (
int i = 0; i < tot_segments; i++) {
53 float initial_orientation[3];
54 float current_orientation[3];
55 float current_head_position[3];
56 float current_origin_position[3];
59 sub_v3_v3v3(current_orientation, target, segments[i].orig);
61 sub_v3_v3v3(initial_orientation, segments[i].initial_head, segments[i].initial_orig);
66 madd_v3_v3v3fl(current_head_position, segments[i].orig, current_orientation, segments[i].
len);
69 sub_v3_v3v3(current_origin_position, target, current_head_position);
72 copy_v3_v3(segments[i].head, current_head_position);
73 add_v3_v3(segments[i].orig, current_origin_position);
83 anchor_diff, segments[tot_segments - 1].initial_orig, segments[tot_segments - 1].orig);
85 for (
int i = 0; i < tot_segments; i++) {
99 for (
int i = 0; i < tot_segments; i++) {
100 float initial_orientation[3];
101 float initial_rotation[4];
102 float current_rotation[4];
104 sub_v3_v3v3(initial_orientation, segments[i].initial_head, segments[i].initial_orig);
123 for (
int i = 0; i < tot_segments; i++) {
125 add_v3_v3v3(segments[i].head, segments[i].initial_head, delta);
126 add_v3_v3v3(segments[i].orig, segments[i].initial_orig, delta);
138 for (
int i = 0; i < tot_segments; i++) {
155 float disp[3], new_co[3];
175 mul_m4_v3(segments[ik].pivot_mat_inv[(
int)symm_area], new_co);
176 mul_m4_v3(segments[ik].trans_mat[(
int)symm_area], new_co);
177 mul_m4_v3(segments[ik].pivot_mat[(
int)symm_area], new_co);
225 float vmask_f =
data->prev_mask[ni.
index];
244 void *__restrict chunk_join,
245 void *__restrict chunk)
258 float pose_origin[3],
259 float pose_target[3],
261 float *r_pose_origin,
274 .pose_factor = pose_factor,
277 data.pose_initial_co = pose_target;
287 bool grow_next_iteration =
true;
288 float prev_len = FLT_MAX;
290 while (grow_next_iteration) {
303 if (
len < prev_len) {
305 grow_next_iteration =
true;
308 grow_next_iteration =
false;
318 grow_next_iteration =
true;
321 grow_next_iteration =
false;
333 grow_next_iteration =
false;
342 const float br_co[3],
346 for (
char i = 0; i <= symm; ++i) {
350 if (
len_v3v3(location, vertex) < radius) {
406 if (
data->pose_factor) {
407 data->pose_factor[to_v] = 1.0f;
434 const int index = to_v;
435 bool visit_next =
false;
439 co,
data->pose_initial_co,
data->symm) &&
446 data->pose_factor[index] = 1.0f;
454 else if (symmetry_check) {
464 bool is_vertex_valid =
false;
465 if (
data->is_first_iteration) {
476 if (!is_vertex_valid) {
481 data->pose_factor[index] = 1.0f;
487 if (symmetry_check) {
489 data->fallback_count++;
498 bool count_as_boundary =
false;
507 if (!
data->next_face_set_found) {
508 data->next_face_set = next_face_set_candidate;
510 data->next_face_set_found =
true;
512 count_as_boundary =
true;
518 if (count_as_boundary) {
530 float initial_location[3],
533 float *r_pose_origin,
534 float *r_pose_factor)
546 .pose_factor = r_pose_factor,
571 if (pose_offset != 0.0f && r_pose_factor) {
595 data->pose_factor[vd.
index] = avg / total;
607 "Pose IK Chain Segments");
608 for (
int i = 0; i < totsegments; i++) {
616 const float initial_location[3])
655 const float initial_location[3],
659 const float chain_segment_len = radius * (1.0f + br->
pose_offset);
660 float next_chain_segment_target[3];
669 float *pose_factor_grow =
MEM_callocN(totvert *
sizeof(
float),
"Pose Factor Grow");
672 float *pose_factor_grow_prev =
MEM_callocN(totvert *
sizeof(
float),
673 "Pose Factor Grow Prev Iteration");
675 pose_factor_grow[nearest_vertex_index] = 1.0f;
681 copy_v3_v3(next_chain_segment_target, initial_location);
685 next_chain_segment_target,
695 for (
int j = 0; j < totvert; j++) {
697 pose_factor_grow_prev[j] = pose_factor_grow[j];
708 next_chain_segment_target,
716 for (
int j = 0; j < totvert; j++) {
717 ik_chain->
segments[i].
weights[j] = pose_factor_grow[j] - pose_factor_grow_prev[j];
719 pose_factor_grow_prev[j] = pose_factor_grow[j];
764 .current_face_set = current_face_set,
765 .prev_face_set = prev_face_set,
766 .visited_face_sets = visited_face_sets,
767 .is_weighted = is_weighted,
768 .next_face_set_found =
false,
769 .is_first_iteration = s == 0,
804 SculptSession *ss,
int from_v,
int to_v,
bool is_duplicate,
void *userdata)
809 data->floodfill_it[to_v] =
data->floodfill_it[from_v] + 1;
812 data->floodfill_it[to_v] =
data->floodfill_it[from_v];
823 if (
data->floodfill_it[to_v] >=
data->masked_face_set_it) {
824 data->masked_face_set = to_face_set;
825 data->masked_face_set_it =
data->floodfill_it[to_v];
829 data->target_face_set = to_face_set;
841 data->fk_weights[to_v] = 1.0f;
870 int origin_count = 0;
871 float origin_acc[3] = {0.0f};
872 for (
int i = 0; i < totvert; i++) {
880 int target_count = 0;
881 float target_acc[3] = {0.0f};
883 for (
int i = 0; i < totvert; i++) {
895 if (origin_count > 0) {
903 if (target_count > 0) {
926 const float initial_location[3],
933 if (use_fake_neighbors) {
950 if (use_fake_neighbors) {
1001 float segment_dir[3];
1005 const float segment_len = ik_chain->
segments[0].
len;
1083 scale[0] = scale[1] =
sqrtf(1.0f / scale[2]);
1093 const float grab_location[3])
1095 float segment_origin_head[3];
1105 sub_v3_v3v3(segment_origin_head, symm_head, symm_orig);
1146 float symm_initial_orig[3];
1160 float pivot_local_space[4][4];
1177 for (
int scale_i = 0; scale_i < 3; scale_i++) {
1183 symm_orig[0] - symm_initial_orig[0],
1184 symm_orig[1] - symm_initial_orig[1],
1185 symm_orig[2] - symm_initial_orig[2]);
1189 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, 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_vert_tag_update_normal(PBVH *pbvh, int index)
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_NEW(_num, _alloc_string)
#define BLI_BITMAP_TEST(_bitmap, _index)
#define BLI_BITMAP_ENABLE(_bitmap, _index)
GSet * BLI_gset_int_new_ex(const char *info, unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
bool BLI_gset_haskey(const GSet *gs, const void *key) ATTR_WARN_UNUSED_RESULT
#define GSET_ITER(gs_iter_, gset_)
void BLI_gset_free(GSet *gs, GSetKeyFreeFP keyfreefp)
BLI_INLINE void * BLI_gsetIterator_getKey(GSetIterator *gsi)
bool BLI_gset_add(GSet *gs, void *key)
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], 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(int start, 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)
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)
Segment< FEdge *, Vec3r > segment
BLI_INLINE void flip_v3_v3(float out[3], const float in[3], const 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)
void SCULPT_orig_vert_data_init(SculptOrigVertData *data, Object *ob, PBVHNode *node, SculptUndoType type)
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)
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_flip_quat_by_symm_area(float quat[4], const ePaintSymmetryFlags symm, const ePaintSymmetryAreas symmarea, const float pivot[3])
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