GPv3: Fix initialization of the DrawingPlacement struct from tool settings
The `DrawingPlacement` utility struct is initialized based on various tool settings, including the `gpencil_v3d_align` flag. This flag was used in a switch statement, but didn't handle all the potential flag combinations, leaving placement variables like the origin vector uninitialized and causing nan values when projecting. Pull Request: https://projects.blender.org/blender/blender/pulls/121246
This commit is contained in:
@@ -68,26 +68,35 @@ DrawingPlacement::DrawingPlacement(const Scene &scene,
|
||||
}
|
||||
}
|
||||
/* Initialize DrawingPlacementDepth from toolsettings. */
|
||||
switch (scene.toolsettings->gpencil_v3d_align) {
|
||||
case GP_PROJECT_VIEWSPACE:
|
||||
depth_ = DrawingPlacementDepth::ObjectOrigin;
|
||||
placement_loc_ = layer_space_to_world_space_.location();
|
||||
break;
|
||||
case (GP_PROJECT_VIEWSPACE | GP_PROJECT_CURSOR):
|
||||
const char align_flag = scene.toolsettings->gpencil_v3d_align;
|
||||
if (align_flag & GP_PROJECT_VIEWSPACE) {
|
||||
if (align_flag & GP_PROJECT_CURSOR) {
|
||||
depth_ = DrawingPlacementDepth::Cursor;
|
||||
surface_offset_ = 0.0f;
|
||||
placement_loc_ = float3(scene.cursor.location);
|
||||
break;
|
||||
case (GP_PROJECT_VIEWSPACE | GP_PROJECT_DEPTH_VIEW):
|
||||
}
|
||||
if (align_flag & GP_PROJECT_DEPTH_VIEW) {
|
||||
depth_ = DrawingPlacementDepth::Surface;
|
||||
surface_offset_ = scene.toolsettings->gpencil_surface_offset;
|
||||
/* Default to view placement with the object origin if we don't hit a surface. */
|
||||
placement_loc_ = layer_space_to_world_space_.location();
|
||||
break;
|
||||
case (GP_PROJECT_VIEWSPACE | GP_PROJECT_DEPTH_STROKE):
|
||||
}
|
||||
if (align_flag & GP_PROJECT_DEPTH_STROKE) {
|
||||
depth_ = DrawingPlacementDepth::NearestStroke;
|
||||
surface_offset_ = 0.0f;
|
||||
/* Default to view placement with the object origin if we don't hit a stroke. */
|
||||
placement_loc_ = layer_space_to_world_space_.location();
|
||||
break;
|
||||
}
|
||||
else {
|
||||
depth_ = DrawingPlacementDepth::ObjectOrigin;
|
||||
surface_offset_ = 0.0f;
|
||||
placement_loc_ = layer_space_to_world_space_.location();
|
||||
}
|
||||
}
|
||||
else {
|
||||
depth_ = DrawingPlacementDepth::ObjectOrigin;
|
||||
surface_offset_ = 0.0f;
|
||||
placement_loc_ = float3(0.0f);
|
||||
}
|
||||
|
||||
if (ELEM(plane_,
|
||||
|
||||
@@ -71,19 +71,19 @@ struct GreasePencilStrokeParams {
|
||||
int layer_index;
|
||||
int frame_number;
|
||||
float multi_frame_falloff;
|
||||
ed::greasepencil::DrawingPlacement placement;
|
||||
const ed::greasepencil::DrawingPlacement &placement;
|
||||
bke::greasepencil::Drawing &drawing;
|
||||
|
||||
/* Note: accessing region in worker threads will return null,
|
||||
* this has to be done on the main thread and passed explicitly. */
|
||||
static GreasePencilStrokeParams from_context(const Scene &scene,
|
||||
const Depsgraph &depsgraph,
|
||||
const ARegion ®ion,
|
||||
const View3D &view3d,
|
||||
Depsgraph &depsgraph,
|
||||
ARegion ®ion,
|
||||
Object &object,
|
||||
int layer_index,
|
||||
int frame_number,
|
||||
float multi_frame_falloff,
|
||||
const ed::greasepencil::DrawingPlacement &placement,
|
||||
bke::greasepencil::Drawing &drawing);
|
||||
};
|
||||
|
||||
@@ -105,6 +105,8 @@ class GreasePencilStrokeOperationCommon : public GreasePencilStrokeOperation {
|
||||
|
||||
BrushStrokeMode stroke_mode;
|
||||
|
||||
/* Initiali mouse sample position, used for placement origin. */
|
||||
float2 start_mouse_position;
|
||||
/* Previous mouse position for computing the direction. */
|
||||
float2 prev_mouse_position;
|
||||
|
||||
|
||||
@@ -153,20 +153,19 @@ bool is_brush_inverted(const Brush &brush, const BrushStrokeMode stroke_mode)
|
||||
|
||||
GreasePencilStrokeParams GreasePencilStrokeParams::from_context(
|
||||
const Scene &scene,
|
||||
const Depsgraph &depsgraph,
|
||||
const ARegion ®ion,
|
||||
const View3D &view3d,
|
||||
Depsgraph &depsgraph,
|
||||
ARegion ®ion,
|
||||
Object &object,
|
||||
const int layer_index,
|
||||
const int frame_number,
|
||||
const float multi_frame_falloff,
|
||||
const ed::greasepencil::DrawingPlacement &placement,
|
||||
bke::greasepencil::Drawing &drawing)
|
||||
{
|
||||
Object &ob_eval = *DEG_get_evaluated_object(&depsgraph, &object);
|
||||
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(object.data);
|
||||
|
||||
const bke::greasepencil::Layer &layer = *grease_pencil.layers()[layer_index];
|
||||
ed::greasepencil::DrawingPlacement placement(scene, region, view3d, ob_eval, layer);
|
||||
|
||||
return {*scene.toolsettings,
|
||||
region,
|
||||
@@ -176,7 +175,7 @@ GreasePencilStrokeParams GreasePencilStrokeParams::from_context(
|
||||
layer_index,
|
||||
frame_number,
|
||||
multi_frame_falloff,
|
||||
std::move(placement),
|
||||
placement,
|
||||
drawing};
|
||||
}
|
||||
|
||||
@@ -235,24 +234,36 @@ void GreasePencilStrokeOperationCommon::foreach_editable_drawing(
|
||||
using namespace blender::bke::greasepencil;
|
||||
|
||||
const Scene &scene = *CTX_data_scene(&C);
|
||||
const Depsgraph &depsgraph = *CTX_data_depsgraph_pointer(&C);
|
||||
const View3D &view3d = *CTX_wm_view3d(&C);
|
||||
const ARegion ®ion = *CTX_wm_region(&C);
|
||||
Depsgraph &depsgraph = *CTX_data_depsgraph_pointer(&C);
|
||||
View3D &view3d = *CTX_wm_view3d(&C);
|
||||
ARegion ®ion = *CTX_wm_region(&C);
|
||||
Object &object = *CTX_data_active_object(&C);
|
||||
Object &object_eval = *DEG_get_evaluated_object(&depsgraph, &object);
|
||||
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(object.data);
|
||||
|
||||
std::atomic<bool> changed = false;
|
||||
const Vector<MutableDrawingInfo> drawings = get_drawings_for_sculpt(C);
|
||||
threading::parallel_for_each(drawings, [&](const MutableDrawingInfo &info) {
|
||||
const Layer &layer = *grease_pencil.layers()[info.layer_index];
|
||||
|
||||
ed::greasepencil::DrawingPlacement placement(scene, region, view3d, object_eval, layer);
|
||||
if (placement.use_project_to_surface()) {
|
||||
placement.cache_viewport_depths(&depsgraph, ®ion, &view3d);
|
||||
}
|
||||
else if (placement.use_project_to_nearest_stroke()) {
|
||||
placement.cache_viewport_depths(&depsgraph, ®ion, &view3d);
|
||||
placement.set_origin_to_nearest_stroke(this->start_mouse_position);
|
||||
}
|
||||
|
||||
GreasePencilStrokeParams params = GreasePencilStrokeParams::from_context(
|
||||
scene,
|
||||
depsgraph,
|
||||
region,
|
||||
view3d,
|
||||
object,
|
||||
info.layer_index,
|
||||
info.frame_number,
|
||||
info.multi_frame_falloff,
|
||||
placement,
|
||||
info.drawing);
|
||||
if (fn(params)) {
|
||||
changed = true;
|
||||
@@ -273,6 +284,7 @@ void GreasePencilStrokeOperationCommon::init_stroke(const bContext &C,
|
||||
|
||||
init_brush(brush);
|
||||
|
||||
this->start_mouse_position = start_sample.mouse_position;
|
||||
this->prev_mouse_position = start_sample.mouse_position;
|
||||
}
|
||||
|
||||
|
||||
@@ -67,11 +67,15 @@ void GrabOperation::foreach_grabbed_drawing(
|
||||
const GreasePencilStrokeParams ¶ms, const IndexMask &mask, Span<float> weights)> fn)
|
||||
const
|
||||
{
|
||||
using bke::greasepencil::Drawing;
|
||||
using bke::greasepencil::Layer;
|
||||
|
||||
const Scene &scene = *CTX_data_scene(&C);
|
||||
const Depsgraph &depsgraph = *CTX_data_depsgraph_pointer(&C);
|
||||
const ARegion ®ion = *CTX_wm_region(&C);
|
||||
const View3D &view3d = *CTX_wm_view3d(&C);
|
||||
Depsgraph &depsgraph = *CTX_data_depsgraph_pointer(&C);
|
||||
ARegion ®ion = *CTX_wm_region(&C);
|
||||
View3D &view3d = *CTX_wm_view3d(&C);
|
||||
Object &object = *CTX_data_active_object(&C);
|
||||
Object &object_eval = *DEG_get_evaluated_object(&depsgraph, &object);
|
||||
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(object.data);
|
||||
|
||||
bool changed = false;
|
||||
@@ -80,7 +84,7 @@ void GrabOperation::foreach_grabbed_drawing(
|
||||
if (data.point_mask.is_empty()) {
|
||||
return;
|
||||
}
|
||||
const bke::greasepencil::Layer &layer = *grease_pencil.layers()[data.layer_index];
|
||||
const Layer &layer = *grease_pencil.layers()[data.layer_index];
|
||||
/* If a new frame is created, could be impossible find the stroke. */
|
||||
const int drawing_index = layer.drawing_index_at(data.frame_number);
|
||||
if (drawing_index < 0) {
|
||||
@@ -93,15 +97,24 @@ void GrabOperation::foreach_grabbed_drawing(
|
||||
bke::greasepencil::Drawing &drawing =
|
||||
reinterpret_cast<GreasePencilDrawing &>(drawing_base).wrap();
|
||||
|
||||
ed::greasepencil::DrawingPlacement placement(scene, region, view3d, object_eval, layer);
|
||||
if (placement.use_project_to_surface()) {
|
||||
placement.cache_viewport_depths(&depsgraph, ®ion, &view3d);
|
||||
}
|
||||
else if (placement.use_project_to_nearest_stroke()) {
|
||||
placement.cache_viewport_depths(&depsgraph, ®ion, &view3d);
|
||||
placement.set_origin_to_nearest_stroke(this->start_mouse_position);
|
||||
}
|
||||
|
||||
GreasePencilStrokeParams params = GreasePencilStrokeParams::from_context(
|
||||
scene,
|
||||
depsgraph,
|
||||
region,
|
||||
view3d,
|
||||
object,
|
||||
data.layer_index,
|
||||
data.frame_number,
|
||||
data.multi_frame_falloff,
|
||||
std::move(placement),
|
||||
drawing);
|
||||
if (fn(params, data.point_mask, data.weights)) {
|
||||
changed = true;
|
||||
|
||||
Reference in New Issue
Block a user