Refactor: Sculpt: Extract pose brush preview data
Removes the SculptPoseIKChain and SculptPoseIKChainSegment structs from BKE_paint.hh, substituting them for the bare minimum vertex data needed to draw the overlay using the pose brush. Moves the needed structs into sculpt_intern.hh, ideally they should be local to sculpt_pose.cc, but the chain is needed in StrokeCache, so further refactoring is needed before it can be reduced in scope. Pull Request: https://projects.blender.org/blender/blender/pulls/126009
This commit is contained in:
@@ -290,28 +290,10 @@ void BKE_paint_blend_read_data(BlendDataReader *reader, const Scene *scene, Pain
|
||||
|
||||
#define SCULPT_FACE_SET_NONE 0
|
||||
|
||||
/** Pose Brush IK Chain. */
|
||||
struct SculptPoseIKChainSegment {
|
||||
blender::float3 orig;
|
||||
blender::float3 head;
|
||||
|
||||
blender::float3 initial_orig;
|
||||
blender::float3 initial_head;
|
||||
float len;
|
||||
blender::float3 scale;
|
||||
float rot[4];
|
||||
blender::Array<float> weights;
|
||||
|
||||
/* Store a 4x4 transform matrix for each of the possible combinations of enabled XYZ symmetry
|
||||
* axis. */
|
||||
std::array<blender::float4x4, PAINT_SYMM_AREAS> trans_mat;
|
||||
std::array<blender::float4x4, PAINT_SYMM_AREAS> pivot_mat;
|
||||
std::array<blender::float4x4, PAINT_SYMM_AREAS> pivot_mat_inv;
|
||||
};
|
||||
|
||||
struct SculptPoseIKChain {
|
||||
blender::Array<SculptPoseIKChainSegment> segments;
|
||||
blender::float3 grab_delta_offset;
|
||||
/* Data used for displaying extra visuals while using the Pose brush */
|
||||
struct SculptPoseIKChainPreview {
|
||||
blender::Array<blender::float3> initial_orig_coords;
|
||||
blender::Array<blender::float3> initial_head_coords;
|
||||
};
|
||||
|
||||
struct SculptVertexInfo {
|
||||
@@ -528,7 +510,7 @@ struct SculptSession : blender::NonCopyable, blender::NonMovable {
|
||||
|
||||
/* Pose Brush Preview */
|
||||
blender::float3 pose_origin;
|
||||
std::unique_ptr<SculptPoseIKChain> pose_ik_chain_preview;
|
||||
std::unique_ptr<SculptPoseIKChainPreview> pose_ik_chain_preview;
|
||||
|
||||
/* Boundary Brush Preview */
|
||||
std::unique_ptr<SculptBoundaryPreview> boundary_preview;
|
||||
|
||||
@@ -1683,10 +1683,13 @@ static void paint_cursor_pose_brush_segments_draw(PaintCursorContext *pcontext)
|
||||
immUniformColor4f(1.0f, 1.0f, 1.0f, 0.8f);
|
||||
GPU_line_width(2.0f);
|
||||
|
||||
immBegin(GPU_PRIM_LINES, ss.pose_ik_chain_preview->segments.size() * 2);
|
||||
for (const int i : ss.pose_ik_chain_preview->segments.index_range()) {
|
||||
immVertex3fv(pcontext->pos, ss.pose_ik_chain_preview->segments[i].initial_orig);
|
||||
immVertex3fv(pcontext->pos, ss.pose_ik_chain_preview->segments[i].initial_head);
|
||||
BLI_assert(ss.pose_ik_chain_preview->initial_head_coords.size() ==
|
||||
ss.pose_ik_chain_preview->initial_orig_coords.size());
|
||||
|
||||
immBegin(GPU_PRIM_LINES, ss.pose_ik_chain_preview->initial_head_coords.size() * 2);
|
||||
for (const int i : ss.pose_ik_chain_preview->initial_head_coords.index_range()) {
|
||||
immVertex3fv(pcontext->pos, ss.pose_ik_chain_preview->initial_orig_coords[i]);
|
||||
immVertex3fv(pcontext->pos, ss.pose_ik_chain_preview->initial_head_coords[i]);
|
||||
}
|
||||
|
||||
immEnd();
|
||||
@@ -1697,10 +1700,10 @@ static void paint_cursor_pose_brush_origins_draw(PaintCursorContext *pcontext)
|
||||
|
||||
SculptSession &ss = *pcontext->ss;
|
||||
immUniformColor4f(1.0f, 1.0f, 1.0f, 0.8f);
|
||||
for (const int i : ss.pose_ik_chain_preview->segments.index_range()) {
|
||||
for (const int i : ss.pose_ik_chain_preview->initial_orig_coords.index_range()) {
|
||||
cursor_draw_point_screen_space(pcontext->pos,
|
||||
pcontext->region,
|
||||
ss.pose_ik_chain_preview->segments[i].initial_orig,
|
||||
ss.pose_ik_chain_preview->initial_orig_coords[i],
|
||||
pcontext->vc.obact->object_to_world().ptr(),
|
||||
3);
|
||||
}
|
||||
@@ -1802,7 +1805,7 @@ static void paint_cursor_draw_3d_view_brush_cursor_inactive(PaintCursorContext *
|
||||
}
|
||||
|
||||
/* Generate a new pose brush preview from the current cursor location. */
|
||||
ss.pose_ik_chain_preview = pose::ik_chain_init(
|
||||
ss.pose_ik_chain_preview = pose::preview_ik_chain_init(
|
||||
*pcontext->vc.obact, ss, brush, pcontext->location, pcontext->radius);
|
||||
}
|
||||
|
||||
|
||||
@@ -287,17 +287,41 @@ struct Cache {
|
||||
|
||||
}
|
||||
|
||||
/** Pose Brush IK Chain. */
|
||||
struct SculptPoseIKChainSegment {
|
||||
float3 orig;
|
||||
float3 head;
|
||||
|
||||
float3 initial_orig;
|
||||
float3 initial_head;
|
||||
float len;
|
||||
float3 scale;
|
||||
float rot[4];
|
||||
Array<float> weights;
|
||||
|
||||
/* Store a 4x4 transform matrix for each of the possible combinations of enabled XYZ symmetry
|
||||
* axis. */
|
||||
std::array<float4x4, PAINT_SYMM_AREAS> trans_mat;
|
||||
std::array<float4x4, PAINT_SYMM_AREAS> pivot_mat;
|
||||
std::array<float4x4, PAINT_SYMM_AREAS> pivot_mat_inv;
|
||||
};
|
||||
|
||||
struct SculptPoseIKChain {
|
||||
Array<SculptPoseIKChainSegment> segments;
|
||||
float3 grab_delta_offset;
|
||||
};
|
||||
|
||||
struct SculptBoundary {
|
||||
/* Vertex indices of the active boundary. */
|
||||
blender::Vector<int> verts;
|
||||
Vector<int> verts;
|
||||
|
||||
/* Distance from a vertex in the boundary to initial vertex indexed by vertex index, taking into
|
||||
* account the length of all edges between them. Any vertex that is not in the boundary will have
|
||||
* a distance of 0. */
|
||||
blender::Map<int, float> distance;
|
||||
Map<int, float> distance;
|
||||
|
||||
/* Data for drawing the preview. */
|
||||
blender::Vector<std::pair<blender::float3, blender::float3>> edges;
|
||||
Vector<std::pair<float3, float3>> edges;
|
||||
|
||||
/* Initial vertex index in the boundary which is closest to the current sculpt active vertex. */
|
||||
int initial_vert_i;
|
||||
@@ -305,12 +329,12 @@ struct SculptBoundary {
|
||||
/* Vertex that at max_propagation_steps from the boundary and closest to the original active
|
||||
* vertex that was used to initialize the boundary. This is used as a reference to check how much
|
||||
* the deformation will go into the mesh and to calculate the strength of the brushes. */
|
||||
blender::float3 pivot_position;
|
||||
float3 pivot_position;
|
||||
|
||||
/* Stores the initial positions of the pivot and boundary initial vertex as they may be deformed
|
||||
* during the brush action. This allows to use them as a reference positions and vectors for some
|
||||
* brush effects. */
|
||||
blender::float3 initial_vert_position;
|
||||
float3 initial_vert_position;
|
||||
|
||||
/* Maximum number of topology steps that were calculated from the boundary. */
|
||||
int max_propagation_steps;
|
||||
@@ -319,30 +343,30 @@ struct SculptBoundary {
|
||||
*/
|
||||
struct {
|
||||
/* Vertex index from where the topology propagation reached this vertex. */
|
||||
blender::Array<int> original_vertex_i;
|
||||
Array<int> original_vertex_i;
|
||||
|
||||
/* How many steps were needed to reach this vertex from the boundary. */
|
||||
blender::Array<int> propagation_steps_num;
|
||||
Array<int> propagation_steps_num;
|
||||
|
||||
/* Strength that is used to deform this vertex. */
|
||||
blender::Array<float> strength_factor;
|
||||
Array<float> strength_factor;
|
||||
} edit_info;
|
||||
|
||||
/* Bend Deform type. */
|
||||
struct {
|
||||
blender::Array<blender::float3> pivot_rotation_axis;
|
||||
blender::Array<blender::float3> pivot_positions;
|
||||
Array<float3> pivot_rotation_axis;
|
||||
Array<float3> pivot_positions;
|
||||
} bend;
|
||||
|
||||
/* Slide Deform type. */
|
||||
struct {
|
||||
blender::Array<blender::float3> directions;
|
||||
Array<float3> directions;
|
||||
} slide;
|
||||
|
||||
/* Twist Deform type. */
|
||||
struct {
|
||||
blender::float3 rotation_axis;
|
||||
blender::float3 pivot_position;
|
||||
float3 rotation_axis;
|
||||
float3 pivot_position;
|
||||
} twist;
|
||||
};
|
||||
|
||||
@@ -2094,11 +2118,11 @@ void calc_pose_data(Object &ob,
|
||||
float3 &r_pose_origin,
|
||||
MutableSpan<float> r_pose_factor);
|
||||
void pose_brush_init(Object &ob, SculptSession &ss, const Brush &brush);
|
||||
std::unique_ptr<SculptPoseIKChain> ik_chain_init(Object &ob,
|
||||
SculptSession &ss,
|
||||
const Brush &brush,
|
||||
const float3 &initial_location,
|
||||
float radius);
|
||||
std::unique_ptr<SculptPoseIKChainPreview> preview_ik_chain_init(Object &ob,
|
||||
SculptSession &ss,
|
||||
const Brush &brush,
|
||||
const float3 &initial_location,
|
||||
float radius);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1023,11 +1023,11 @@ static std::unique_ptr<SculptPoseIKChain> pose_ik_chain_init_face_sets_fk(
|
||||
return ik_chain;
|
||||
}
|
||||
|
||||
std::unique_ptr<SculptPoseIKChain> ik_chain_init(Object &ob,
|
||||
SculptSession &ss,
|
||||
const Brush &brush,
|
||||
const float3 &initial_location,
|
||||
const float radius)
|
||||
static std::unique_ptr<SculptPoseIKChain> ik_chain_init(Object &ob,
|
||||
SculptSession &ss,
|
||||
const Brush &brush,
|
||||
const float3 &initial_location,
|
||||
const float radius)
|
||||
{
|
||||
std::unique_ptr<SculptPoseIKChain> ik_chain;
|
||||
|
||||
@@ -1080,6 +1080,25 @@ void pose_brush_init(Object &ob, SculptSession &ss, const Brush &brush)
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<SculptPoseIKChainPreview> preview_ik_chain_init(Object &ob,
|
||||
SculptSession &ss,
|
||||
const Brush &brush,
|
||||
const float3 &initial_location,
|
||||
const float radius)
|
||||
{
|
||||
const SculptPoseIKChain chain = *ik_chain_init(ob, ss, brush, initial_location, radius);
|
||||
std::unique_ptr<SculptPoseIKChainPreview> preview = std::make_unique<SculptPoseIKChainPreview>();
|
||||
|
||||
preview->initial_head_coords.reinitialize(chain.segments.size());
|
||||
preview->initial_orig_coords.reinitialize(chain.segments.size());
|
||||
for (const int i : chain.segments.index_range()) {
|
||||
preview->initial_head_coords[i] = chain.segments[i].initial_head;
|
||||
preview->initial_orig_coords[i] = chain.segments[i].initial_orig;
|
||||
}
|
||||
|
||||
return preview;
|
||||
}
|
||||
|
||||
static void sculpt_pose_do_translate_deform(SculptSession &ss, const Brush &brush)
|
||||
{
|
||||
SculptPoseIKChain &ik_chain = *ss.cache->pose_ik_chain;
|
||||
|
||||
Reference in New Issue
Block a user