91 std::array<float4x4, 8> mats;
93 float3 final_pivot_pos, d_t, d_s;
95 float t_mat[4][4], r_mat[4][4], s_mat[4][4], pivot_mat[4][4], pivot_imat[4][4],
98 float start_pivot_pos[3], start_pivot_rot[4], start_pivot_scale[3];
141 translate_m4(pivot_mat, final_pivot_pos[0], final_pivot_pos[1], final_pivot_pos[2]);
164 const std::array<float4x4, 8> &transform_mats,
170 translations[
i] = transformed - positions[
i];
183 translations[
i].x = 0.0f;
186 translations[
i].y = 0.0f;
189 translations[
i].z = 0.0f;
195 const std::array<float4x4, 8> &transform_mats,
220 position_data.deform(translations,
verts);
224 const std::array<float4x4, 8> &transform_mats,
256 const std::array<float4x4, 8> &transform_mats,
302 switch (pbvh.
type()) {
346 r_translations[
i] = transformed - positions[
i];
351 const float3 &elastic_transform_pivot,
357 translations[
i], &
params, positions[
i], elastic_transform_pivot, translations[
i]);
363 const float4x4 &elastic_transform_mat,
364 const float3 &elastic_transform_pivot,
390 position_data.deform(translations,
verts);
395 const float4x4 &elastic_transform_mat,
396 const float3 &elastic_transform_pivot,
426 const float4x4 &elastic_transform_mat,
427 const float3 &elastic_transform_pivot,
456 const float transform_radius)
474 const float force = 1.0f;
475 const float shear_modulus = 1.0f;
476 const float poisson_ratio = 0.4f;
488 float4x4 elastic_transform_mat = transform_mats[symm_area];
489 switch (pbvh.
type()) {
499 elastic_transform_mat,
500 elastic_transform_pivot,
517 sd,
params, elastic_transform_mat, elastic_transform_pivot,
nodes[
i], ob, tls);
527 sd,
params, elastic_transform_mat, elastic_transform_pivot,
nodes[
i], ob, tls);
554 float transform_radius;
613 "Sets the pivot to the origin of the sculpt"},
618 "Sets the pivot position to the average position of the unmasked vertices"},
623 "Sets the pivot position to the center of the border of the mask"},
628 "Sets the pivot position to the active vertex position"},
633 "Sets the pivot position to the surface under the cursor"},
634 {0,
nullptr, 0,
nullptr,
nullptr},
689 switch (pbvh.
type()) {
692 const Mesh &
mesh = *
static_cast<const Mesh *
>(
object.data);
700 LocalData &tls = all_tls.local();
701 threading::isolate_task([&]() {
702 node_mask.slice(range).foreach_index([&](const int i) {
703 const Span<int> verts = nodes[i].verts();
705 tls.positions.resize(verts.size());
706 const MutableSpan<float3> positions = tls.positions;
707 array_utils::gather(vert_positions, verts, positions);
709 tls.factors.resize(verts.size());
710 const MutableSpan<float> factors = tls.factors;
711 fill_factor_from_hide_and_mask(
712 attribute_data.hide_vert, attribute_data.mask, verts, factors);
713 filter_verts_outside_symmetry_area(positions, pivot, symm, factors);
715 accumulate_weighted_average_position(positions, factors, sum);
731 LocalData &tls = all_tls.local();
732 node_mask.slice(range).foreach_index([&](const int i) {
733 const Span<int> grids = nodes[i].grids();
734 const MutableSpan positions = gather_grids_positions(
735 subdiv_ccg, grids, tls.positions);
737 tls.factors.resize(positions.size());
738 const MutableSpan<float> factors = tls.factors;
739 fill_factor_from_hide_and_mask(subdiv_ccg, grids, factors);
740 filter_verts_outside_symmetry_area(positions, pivot, symm, factors);
742 accumulate_weighted_average_position(positions, factors, sum);
752 node_mask.index_range(),
754 AveragePositionAccumulation{},
755 [&](
const IndexRange range, AveragePositionAccumulation
sum) {
756 LocalData &tls = all_tls.local();
757 node_mask.slice(range).foreach_index([&](const int i) {
758 const Set<BMVert *, 0> &verts = BKE_pbvh_bmesh_node_unique_verts(
759 &const_cast<bke::pbvh::BMeshNode &>(nodes[i]));
760 const MutableSpan positions = gather_bmesh_positions(verts, tls.positions);
762 tls.factors.resize(verts.size());
763 const MutableSpan<float> factors = tls.factors;
764 fill_factor_from_hide_and_mask(*ss.bm, verts, factors);
765 filter_verts_outside_symmetry_area(positions, pivot, symm, factors);
767 accumulate_weighted_average_position(positions, factors, sum);
782 constexpr float threshold = 0.2f;
785 if (std::abs(masks[
i] - 0.5f) > threshold) {
812 switch (pbvh.
type()) {
815 const Mesh &
mesh = *
static_cast<const Mesh *
>(
object.data);
826 LocalData &tls = all_tls.local();
827 node_mask.slice(range).foreach_index([&](const int i) {
828 const Span<int> verts = nodes[i].verts();
829 MutableSpan positions = gather_data_mesh(vert_positions, verts, tls.positions);
830 MutableSpan masks = gather_data_mesh(mask_attr, verts, tls.masks);
832 tls.factors.resize(verts.size());
833 const MutableSpan<float> factors = tls.factors;
834 fill_factor_from_hide(hide_vert, verts, factors);
836 mask_border_weight_calc(masks, factors);
837 filter_verts_outside_symmetry_area(positions, pivot, symm, factors);
839 accumulate_weighted_average_position(positions, factors, sum);
854 LocalData &tls = all_tls.local();
855 node_mask.slice(range).foreach_index([&](const int i) {
856 const Span<int> grids = nodes[i].grids();
857 const MutableSpan positions = gather_grids_positions(
858 subdiv_ccg, grids, tls.positions);
860 tls.masks.resize(positions.size());
861 const MutableSpan<float> masks = tls.masks;
862 mask::gather_mask_grids(subdiv_ccg, grids, masks);
864 tls.factors.resize(positions.size());
865 const MutableSpan<float> factors = tls.factors;
866 fill_factor_from_hide(subdiv_ccg, grids, factors);
867 mask_border_weight_calc(masks, factors);
868 filter_verts_outside_symmetry_area(positions, pivot, symm, factors);
870 accumulate_weighted_average_position(positions, factors, sum);
880 node_mask.index_range(),
882 AveragePositionAccumulation{},
883 [&](
const IndexRange range, AveragePositionAccumulation
sum) {
884 LocalData &tls = all_tls.local();
885 node_mask.slice(range).foreach_index([&](const int i) {
886 const Set<BMVert *, 0> &verts = BKE_pbvh_bmesh_node_unique_verts(
887 &const_cast<bke::pbvh::BMeshNode &>(nodes[i]));
888 const MutableSpan positions = gather_bmesh_positions(verts, tls.positions);
890 tls.masks.resize(verts.size());
891 const MutableSpan<float> masks = tls.masks;
892 mask::gather_mask_bmesh(*ss.bm, verts, masks);
894 tls.factors.resize(verts.size());
895 const MutableSpan<float> factors = tls.factors;
896 fill_factor_from_hide(verts, factors);
897 mask_border_weight_calc(masks, factors);
898 filter_verts_outside_symmetry_area(positions, pivot, symm, factors);
900 accumulate_weighted_average_position(positions, factors, sum);
904 combine_average_position_accumulation);
993 ot->name =
"Set Pivot Position";
994 ot->idname =
"SCULPT_OT_set_pivot_position";
995 ot->description =
"Sets the sculpt transform pivot position";
1017 "Position of the mouse used for \"Surface\" and \"Active Vertex\" mode",
1026 "Position of the mouse used for \"Surface\" and \"Active Vertex\" mode",
bool BKE_brush_use_locked_size(const Paint *paint, const Brush *brush)
float BKE_brush_radius_get(const Paint *paint, const Brush *brush)
float BKE_brush_unprojected_radius_get(const Paint *paint, const Brush *brush)
Depsgraph * CTX_data_ensure_evaluated_depsgraph(const bContext *C)
Depsgraph * CTX_data_depsgraph_pointer(const bContext *C)
Object * CTX_data_active_object(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
Base * CTX_data_active_base(const bContext *C)
ToolSettings * CTX_data_tool_settings(const bContext *C)
ARegion * CTX_wm_region(const bContext *C)
View3D * CTX_wm_view3d(const bContext *C)
void BKE_kelvinlet_grab_triscale(float radius_elem_disp[3], const KelvinletParams *params, const float elem_orig_co[3], const float brush_location[3], const float brush_delta[3])
void BKE_kelvinlet_init_params(KelvinletParams *params, float radius, float force, float shear_modulus, float poisson_ratio)
bool BKE_base_is_visible(const View3D *v3d, const Base *base)
std::variant< std::monostate, int, BMVert * > ActiveVert
const Brush * BKE_paint_brush_for_read(const Paint *paint)
void BKE_sculpt_update_object_for_edit(Depsgraph *depsgraph, Object *ob_orig, bool is_paint_tool)
Paint * BKE_paint_get_active_from_context(const bContext *C)
A BVH for high poly meshes.
const blender::Set< BMVert *, 0 > & BKE_pbvh_bmesh_node_unique_verts(blender::bke::pbvh::BMeshNode *node)
CCGKey BKE_subdiv_ccg_key_top_level(const SubdivCCG &subdiv_ccg)
#define BLI_assert_unreachable()
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
void translate_m4(float mat[4][4], float Tx, float Ty, float Tz)
void size_to_mat4(float R[4][4], const float size[3])
bool invert_m4_m4(float inverse[4][4], const float mat[4][4])
void unit_m4(float m[4][4])
void sub_qt_qtqt(float q[4], const float a[4], const float b[4])
float normalize_qt(float q[4])
void quat_to_mat4(float m[4][4], const float q[4])
MINLINE void copy_v4_v4(float r[4], const float a[4])
MINLINE void add_v3_fl(float r[3], float f)
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void copy_v3_v3(float r[3], const float a[3])
@ SCULPT_TRANSFORM_MODE_RADIUS_ELASTIC
@ SCULPT_TRANSFORM_MODE_ALL_VERTICES
void ED_region_tag_redraw(ARegion *region)
ViewContext ED_view3d_viewcontext_init(bContext *C, Depsgraph *depsgraph)
Read Guarded memory(de)allocation.
BPy_StructRNA * depsgraph
SIMD_FORCE_INLINE const btScalar & z() const
Return the z value.
static T sum(const btAlignedObjectArray< T > &items)
void resize(const int64_t new_size)
constexpr int64_t size() const
constexpr int64_t size() const
constexpr IndexRange index_range() const
GAttributeReader lookup_or_default(StringRef attribute_id, AttrDomain domain, AttrType data_type, const void *default_value=nullptr) const
GAttributeReader lookup(const StringRef attribute_id) const
void tag_positions_changed(const IndexMask &node_mask)
Span< NodeT > nodes() const
void update_bounds(const Depsgraph &depsgraph, const Object &object)
void flush_bounds_to_parents()
IndexRange index_range() const
void foreach_index(Fn &&fn) const
VecBase< float, 3 > float3
pbvh::Tree * pbvh_get(Object &object)
IndexMask search_nodes(const Tree &pbvh, IndexMaskMemory &memory, FunctionRef< bool(const Node &)> filter_fn)
void update_normals(const Depsgraph &depsgraph, Object &object_orig, Tree &pbvh)
void update_node_bounds_bmesh(BMeshNode &node)
void update_node_bounds_mesh(Span< float3 > positions, MeshNode &node)
void update_node_bounds_grids(int grid_area, Span< float3 > positions, GridsNode &node)
Span< float3 > vert_positions_eval(const Depsgraph &depsgraph, const Object &object_orig)
void cache_init(bContext *C, Object &ob, Sculpt &sd, undo::Type undo_type, const float mval_fl[2], float area_normal_radius, float start_strength)
void push_end(Object &ob)
void push_begin_ex(const Scene &, Object &ob, const char *name)
void restore_position_from_undo_step(const Depsgraph &depsgraph, Object &object)
bool stroke_get_location_bvh(bContext *C, float out[3], const float mval[2], const bool force_original)
static void elastic_transform_node_bmesh(const Sculpt &sd, const KelvinletParams ¶ms, const float4x4 &elastic_transform_mat, const float3 &elastic_transform_pivot, bke::pbvh::BMeshNode &node, Object &object, TransformLocalData &tls)
void fill_factor_from_hide_and_mask(Span< bool > hide_vert, Span< float > mask, Span< int > verts, MutableSpan< float > r_factors)
static BLI_NOINLINE void mask_border_weight_calc(const Span< float > masks, const MutableSpan< float > factors)
MutableSpan< float3 > gather_grids_positions(const SubdivCCG &subdiv_ccg, const Span< int > grids, Vector< float3 > &positions)
static wmOperatorStatus set_pivot_position_invoke(bContext *C, wmOperator *op, const wmEvent *event)
void gather_bmesh_positions(const Set< BMVert *, 0 > &verts, MutableSpan< float3 > positions)
static std::array< float4x4, 8 > transform_matrices_init(const SculptSession &ss, const ePaintSymmetryFlags symm, const TransformDisplacementMode t_mode)
static bool set_pivot_position_poll_property(const bContext *, wmOperator *op, const PropertyRNA *prop)
void update_modal_transform(bContext *C, Object &ob)
void vert_random_access_ensure(Object &object)
static void transform_node_mesh(const Sculpt &sd, const std::array< float4x4, 8 > &transform_mats, const MeshAttributeData &attribute_data, const bke::pbvh::MeshNode &node, Object &object, TransformLocalData &tls, const PositionDeformData &position_data)
bool node_fully_masked_or_hidden(const bke::pbvh::Node &node)
static void transform_node_grids(const Sculpt &sd, const std::array< float4x4, 8 > &transform_mats, const bke::pbvh::GridsNode &node, Object &object, TransformLocalData &tls)
float3 symmetry_flip(const float3 &src, const ePaintSymmetryFlags symm)
void orig_position_data_gather_bmesh(const BMLog &bm_log, const Set< BMVert *, 0 > &verts, MutableSpan< float3 > positions, MutableSpan< float3 > normals)
static BLI_NOINLINE void calc_symm_area_transform_translations(const Span< float3 > positions, const std::array< float4x4, 8 > &transform_mats, const MutableSpan< float3 > translations)
void scale_translations(MutableSpan< float3 > translations, Span< float > factors)
void end_transform(bContext *C, Object &ob)
static void elastic_transform_node_mesh(const Sculpt &sd, const KelvinletParams ¶ms, const float4x4 &elastic_transform_mat, const float3 &elastic_transform_pivot, const MeshAttributeData &attribute_data, const bke::pbvh::MeshNode &node, Object &object, TransformLocalData &tls, const PositionDeformData &position_data)
void init_transform(bContext *C, Object &ob, const float mval_fl[2], const char *undo_name)
static wmOperatorStatus set_pivot_position_exec(bContext *C, wmOperator *op)
void scale_factors(MutableSpan< float > factors, float strength)
void cancel_modal_transform(bContext *C, Object &ob)
static BLI_NOINLINE void filter_translations_with_symmetry(const Span< float3 > positions, const ePaintSymmetryFlags symm, const MutableSpan< float3 > translations)
void clip_and_lock_translations(const Sculpt &sd, const SculptSession &ss, Span< float3 > positions, Span< int > verts, MutableSpan< float3 > translations)
bool cursor_geometry_info_update(bContext *C, CursorGeometryInfo *out, const float2 &mval, const bool use_sampled_normal)
static BLI_NOINLINE void accumulate_weighted_average_position(const Span< float3 > positions, const Span< float > factors, AveragePositionAccumulation &total)
void flush_update_done(const bContext *C, Object &ob, const UpdateType update_type)
static void elastic_transform_node_grids(const Sculpt &sd, const KelvinletParams ¶ms, const float4x4 &elastic_transform_mat, const float3 &elastic_transform_pivot, const bke::pbvh::GridsNode &node, Object &object, TransformLocalData &tls)
static void transform_node_bmesh(const Sculpt &sd, const std::array< float4x4, 8 > &transform_mats, bke::pbvh::BMeshNode &node, Object &object, TransformLocalData &tls)
static constexpr float transform_mirror_max_distance_eps
void apply_translations(Span< float3 > translations, Span< int > verts, MutableSpan< float3 > positions)
OrigPositionData orig_position_data_get_mesh(const Object &object, const bke::pbvh::MeshNode &node)
void gather_data_mesh(Span< T > src, Span< int > indices, MutableSpan< T > dst)
OrigPositionData orig_position_data_get_grids(const Object &object, const bke::pbvh::GridsNode &node)
void flush_update_step(const bContext *C, const UpdateType update_type)
static void sculpt_transform_all_vertices(const Depsgraph &depsgraph, const Sculpt &sd, Object &ob)
static float3 average_unmasked_position(const Depsgraph &depsgraph, const Object &object, const float3 &pivot, const ePaintSymmetryFlags symm)
static BLI_NOINLINE void apply_kelvinet_to_translations(const KelvinletParams ¶ms, const float3 &elastic_transform_pivot, const Span< float3 > positions, const MutableSpan< float3 > translations)
static void transform_radius_elastic(const Depsgraph &depsgraph, const Sculpt &sd, Object &ob, const float transform_radius)
static BLI_NOINLINE void calc_transform_translations(const float4x4 &elastic_transform_mat, const Span< float3 > positions, const MutableSpan< float3 > r_translations)
static AveragePositionAccumulation combine_average_position_accumulation(const AveragePositionAccumulation &a, const AveragePositionAccumulation &b)
static float3 average_mask_border_position(const Depsgraph &depsgraph, const Object &object, const float3 &pivot, const ePaintSymmetryFlags symm)
static bool set_pivot_depends_on_cursor(bContext &, wmOperatorType &, PointerRNA *ptr)
static EnumPropertyItem prop_sculpt_pivot_position_types[]
TransformDisplacementMode
void SCULPT_OT_set_pivot_position(wmOperatorType *ot)
bool is_symmetry_iteration_valid(const char i, const char symm)
T safe_divide(const T &a, const T &b)
VecBase< T, 3 > transform_point(const CartesianBasis &basis, const VecBase< T, 3 > &v)
Value parallel_reduce(IndexRange range, int64_t grain_size, const Value &identity, const Function &function, const Reduction &reduction)
MatBase< float, 4, 4 > float4x4
VecBase< float, 2 > float2
VecBase< double, 3 > double3
VecBase< float, 3 > float3
float paint_calc_object_space_radius(const ViewContext &vc, const blender::float3 ¢er, float pixel_radius)
float RNA_float_get(PointerRNA *ptr, const char *name)
void RNA_float_set(PointerRNA *ptr, const char *name, float value)
int RNA_enum_get(PointerRNA *ptr, const char *name)
const char * RNA_property_identifier(const PropertyRNA *prop)
PropertyRNA * RNA_def_float(StructOrFunctionRNA *cont_, const char *identifier, const float default_value, const float hardmin, const float hardmax, const char *ui_name, const char *ui_description, const float softmin, const float softmax)
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, const int default_value, const char *ui_name, const char *ui_description)
ePaintSymmetryFlags SCULPT_mesh_symmetry_xyz_get(const Object &object)
float3 SCULPT_flip_v3_by_symm_area(const float3 &vector, const ePaintSymmetryFlags symm, const ePaintSymmetryAreas symmarea, const float3 &pivot)
bool SCULPT_mode_poll(bContext *C)
ePaintSymmetryAreas SCULPT_get_vertex_symm_area(const float co[3])
void SCULPT_flip_quat_by_symm_area(float quat[4], const ePaintSymmetryFlags symm, const ePaintSymmetryAreas symmarea, const float pivot[3])
struct SculptSession * sculpt
blender::float4 prev_pivot_rot
blender::ed::sculpt_paint::filter::Cache * filter_cache
blender::float3 prev_pivot_pos
blender::float4 pivot_rot
blender::float3 active_vert_position(const Depsgraph &depsgraph, const Object &object) const
blender::float3 pivot_pos
blender::float3 pivot_scale
blender::float3 init_pivot_pos
blender::float4 init_pivot_rot
blender::float3 prev_pivot_scale
blender::float3 init_pivot_scale
blender::Array< blender::float3 > positions
blender::float3 average_stroke_accum
int average_stroke_counter
Span< int > grids() const
Span< int > verts() const
VArraySpan< bool > hide_vert
TransformDisplacementMode transform_displacement_mode
void WM_event_add_notifier(const bContext *C, uint type, void *reference)