diff options
-rw-r--r-- | source/blender/editors/gpencil/gpencil_edit.c | 65 |
1 files changed, 47 insertions, 18 deletions
diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index d03c53bf9cb..9fd1d031bb1 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -58,6 +58,7 @@ #include "BKE_paint.h" #include "BKE_report.h" #include "BKE_workspace.h" +#include "BKE_scene.h" #include "UI_interface.h" #include "UI_resources.h" @@ -76,6 +77,7 @@ #include "ED_gpencil.h" #include "ED_object.h" #include "ED_screen.h" +#include "ED_transform_snap_object_context.h" #include "ED_view3d.h" #include "ED_select_utils.h" #include "ED_space_api.h" @@ -3354,11 +3356,14 @@ static int gp_strokes_reproject_exec(bContext *C, wmOperator *op) { bGPdata *gpd = ED_gpencil_data_get_active(C); Scene *scene = CTX_data_scene(C); + Main *bmain = CTX_data_main(C); ToolSettings *ts = CTX_data_tool_settings(C); Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); Object *ob = CTX_data_active_object(C); ARegion *ar = CTX_wm_region(C); RegionView3D *rv3d = ar->regiondata; + SnapObjectContext *sctx = NULL; + int oldframe = (int)DEG_get_ctime(depsgraph); GP_SpaceConversion gsc = {NULL}; eGP_ReprojectModes mode = RNA_enum_get(op->ptr, "type"); @@ -3368,17 +3373,22 @@ static int gp_strokes_reproject_exec(bContext *C, wmOperator *op) /* init space conversion stuff */ gp_point_conversion_init(C, &gsc); - /* init autodist for geometry projection */ - if (mode == GP_REPROJECT_SURFACE) { - view3d_region_operator_needs_opengl(CTX_wm_window(C), gsc.ar); - ED_view3d_autodist_init(depsgraph, gsc.ar, CTX_wm_view3d(C), 0); - } - - // TODO: For deforming geometry workflow, create new frames? + int cfra_prv = INT_MIN; + /* init snap context for geometry projection */ + sctx = ED_transform_snap_object_context_create_view3d( + bmain, scene, depsgraph, 0, ar, CTX_wm_view3d(C)); /* Go through each editable + selected stroke, adjusting each of its points one by one... */ GP_EDITABLE_STROKES_BEGIN (gpstroke_iter, C, gpl, gps) { if (gps->flag & GP_STROKE_SELECT) { + + /* update frame to get the new location of objects */ + if ((mode == GP_REPROJECT_SURFACE) && (cfra_prv != gpf_->framenum)) { + cfra_prv = gpf_->framenum; + CFRA = gpf_->framenum; + BKE_scene_graph_update_for_newframe(depsgraph, bmain); + } + bGPDspoint *pt; int i; /* Adjust each point */ @@ -3389,6 +3399,7 @@ static int gp_strokes_reproject_exec(bContext *C, wmOperator *op) /* Note: We can't use gp_point_to_xy() here because that uses ints for the screen-space * coordinates, resulting in lost precision, which in turn causes stair-stepping * artifacts in the final points. */ + bGPDspoint pt2; gp_point_to_parent_space(pt, gpstroke_iter.diff_mat, &pt2); gp_point_to_xy_fl(&gsc, gps, &pt2, &xy[0], &xy[1]); @@ -3445,17 +3456,26 @@ static int gp_strokes_reproject_exec(bContext *C, wmOperator *op) } else { /* Geometry - Snap to surfaces of visible geometry */ - /* XXX: There will be precision loss (possible stair-step artifacts) - * from this conversion to satisfy the API's */ - const int screen_co[2] = {(int)xy[0], (int)xy[1]}; - - int depth_margin = 0; // XXX: 4 for strokes, 0 for normal - float depth; - - /* XXX: The proper procedure computes the depths into an array, - * to have smooth transitions when all else fails... */ - if (ED_view3d_autodist_depth(gsc.ar, screen_co, depth_margin, &depth)) { - ED_view3d_autodist_simple(gsc.ar, screen_co, &pt->x, 0, &depth); + float ray_start[3]; + float ray_normal[3]; + /* magic value for initial depth copied from the default + * value of Python's Scene.ray_cast function + */ + float depth = 1.70141e+38f; + float location[3] = {0.0f, 0.0f, 0.0f}; + float normal[3] = {0.0f, 0.0f, 0.0f}; + + ED_view3d_win_to_ray(ar, xy, &ray_start[0], &ray_normal[0]); + if (ED_transform_snap_object_project_ray(sctx, + &(const struct SnapObjectParams){ + .snap_select = SNAP_ALL, + }, + &ray_start[0], + &ray_normal[0], + &depth, + &location[0], + &normal[0])) { + copy_v3_v3(&pt->x, location); } else { /* Default to planar */ @@ -3472,6 +3492,15 @@ static int gp_strokes_reproject_exec(bContext *C, wmOperator *op) } GP_EDITABLE_STROKES_END(gpstroke_iter); + /* return frame state and DB to original state */ + CFRA = oldframe; + BKE_scene_graph_update_for_newframe(depsgraph, bmain); + + if (sctx != NULL) { + ED_transform_snap_object_context_destroy(sctx); + } + + /* update changed data */ DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY); WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); return OPERATOR_FINISHED; |