[Bf-blender-cvs] [4272fbae722] greasepencil-object: GPencil: Add multiframe support to reproject surface operator

Antonioya noreply at git.blender.org
Mon May 20 16:53:23 CEST 2019


Commit: 4272fbae72286cbd0a5f90433756bbd92af390a0
Author: Antonioya
Date:   Mon May 20 16:51:26 2019 +0200
Branches: greasepencil-object
https://developer.blender.org/rB4272fbae72286cbd0a5f90433756bbd92af390a0

GPencil: Add multiframe support to reproject surface operator

This change solves T64814

===================================================================

M	source/blender/editors/gpencil/gpencil_edit.c

===================================================================

diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c
index c973a7564dd..fdddda1d379 100644
--- a/source/blender/editors/gpencil/gpencil_edit.c
+++ b/source/blender/editors/gpencil/gpencil_edit.c
@@ -3371,6 +3371,8 @@ static int gp_strokes_reproject_exec(bContext *C, wmOperator *op)
   ARegion *ar = CTX_wm_region(C);
   RegionView3D *rv3d = ar->regiondata;
   SnapObjectContext *sctx = NULL;
+  int oldframe = (int)DEG_get_ctime(depsgraph);
+  const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
 
   GP_SpaceConversion gsc = {NULL};
   eGP_ReprojectModes mode = RNA_enum_get(op->ptr, "type");
@@ -3380,132 +3382,167 @@ static int gp_strokes_reproject_exec(bContext *C, wmOperator *op)
   /* init space conversion stuff */
   gp_point_conversion_init(C, &gsc);
 
+  int cfra_prv = INT_MIN;
   /* init snap context for geometry projection */
-  if (mode == GP_REPROJECT_SURFACE) {
-    sctx = ED_transform_snap_object_context_create_view3d(
-        bmain, scene, depsgraph, 0, ar, CTX_wm_view3d(C));
-  }
-
-  // TODO: For deforming geometry workflow, create new frames?
+  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) {
-      bGPDspoint *pt;
-      int i;
-      float inverse_diff_mat[4][4];
-
-      /* Compute inverse matrix for unapplying parenting once instead of doing per-point */
-      /* TODO: add this bit to the iteration macro? */
-      invert_m4_m4(inverse_diff_mat, gpstroke_iter.diff_mat);
-
-      /* Adjust each point */
-      for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
-        float xy[2];
-
-        /* 3D to Screenspace */
-        /* Note: We can't use gp_point_to_xy() here because that uses ints for the screenspace
-         *       coordinates, resulting in lost precision, which in turn causes stairstepping
-         *       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]);
-
-        /* Project stroke in one axis */
-        if (ELEM(mode,
-                 GP_REPROJECT_FRONT,
-                 GP_REPROJECT_SIDE,
-                 GP_REPROJECT_TOP,
-                 GP_REPROJECT_CURSOR)) {
-          if (mode != GP_REPROJECT_CURSOR) {
-            ED_gp_get_drawing_reference(scene, ob, gpl, ts->gpencil_v3d_align, origin);
+  CTX_DATA_BEGIN (C, bGPDlayer *, gpl, editable_gpencil_layers) {
+    bGPDframe *init_gpf = gpl->actframe;
+    if (is_multiedit) {
+      init_gpf = gpl->frames.first;
+    }
+    float diff_mat[4][4];
+    float inverse_diff_mat[4][4];
+    /* calculate difference matrix object */
+    ED_gpencil_parent_location(depsgraph, ob, gpd, gpl, diff_mat);
+    /* Compute inverse matrix for unapplying parenting once instead of doing per-point */
+    invert_m4_m4(inverse_diff_mat, diff_mat);
+
+    for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) {
+      if ((gpf == gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) {
+        if (gpf == NULL) {
+          continue;
+        }
+
+        for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) {
+          /* skip strokes that are invalid for current view */
+          if (ED_gpencil_stroke_can_use(C, gps) == false) {
+            continue;
           }
-          else {
-            copy_v3_v3(origin, scene->cursor.location);
+          if ((gps->flag & GP_STROKE_SELECT) == 0) {
+            continue;
           }
 
-          int axis = 0;
-          switch (mode) {
-            case GP_REPROJECT_FRONT: {
-              axis = 1;
-              break;
-            }
-            case GP_REPROJECT_SIDE: {
-              axis = 0;
-              break;
-            }
-            case GP_REPROJECT_TOP: {
-              axis = 2;
-              break;
-            }
-            case GP_REPROJECT_CURSOR: {
-              axis = 3;
-              break;
-            }
-            default: {
-              axis = 1;
-              break;
-            }
+          /* 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);
           }
 
-          ED_gp_project_point_to_plane(scene, ob, rv3d, origin, axis, &pt2);
+          bGPDspoint *pt;
+          int i;
+          /* Adjust each point */
+          for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
+            float xy[2];
+
+            /* 3D to Screenspace */
+            /* Note: We can't use gp_point_to_xy() here because that uses ints for the
+             * screenspace coordinates, resulting in lost precision, which in turn causes
+             * stairstepping artifacts in the final points.
+             */
+            bGPDspoint pt2;
+            gp_point_to_parent_space(pt, diff_mat, &pt2);
+            gp_point_to_xy_fl(&gsc, gps, &pt2, &xy[0], &xy[1]);
+
+            /* Project stroke in one axis */
+            if (ELEM(mode,
+                     GP_REPROJECT_FRONT,
+                     GP_REPROJECT_SIDE,
+                     GP_REPROJECT_TOP,
+                     GP_REPROJECT_CURSOR)) {
+              if (mode != GP_REPROJECT_CURSOR) {
+                ED_gp_get_drawing_reference(scene, ob, gpl, ts->gpencil_v3d_align, origin);
+              }
+              else {
+                copy_v3_v3(origin, scene->cursor.location);
+              }
+
+              int axis = 0;
+              switch (mode) {
+                case GP_REPROJECT_FRONT: {
+                  axis = 1;
+                  break;
+                }
+                case GP_REPROJECT_SIDE: {
+                  axis = 0;
+                  break;
+                }
+                case GP_REPROJECT_TOP: {
+                  axis = 2;
+                  break;
+                }
+                case GP_REPROJECT_CURSOR: {
+                  axis = 3;
+                  break;
+                }
+                default: {
+                  axis = 1;
+                  break;
+                }
+              }
+
+              ED_gp_project_point_to_plane(scene, ob, rv3d, origin, axis, &pt2);
 
-          copy_v3_v3(&pt->x, &pt2.x);
+              copy_v3_v3(&pt->x, &pt2.x);
 
-          /* apply parent again */
-          gp_apply_parent_point(depsgraph, ob, gpd, gpl, pt);
-        }
-        /* Project screenspace back to 3D space (from current perspective)
-         * so that all points have been treated the same way
-         */
-        else if (mode == GP_REPROJECT_VIEW) {
-          /* Planar - All on same plane parallel to the viewplane */
-          gp_point_xy_to_3d(&gsc, scene, xy, &pt->x);
-        }
-        else {
-          /* Geometry - Snap to surfaces of visible geometry */
-          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 */
-            gp_point_xy_to_3d(&gsc, scene, xy, &pt->x);
+              /* apply parent again */
+              gp_apply_parent_point(depsgraph, ob, gpd, gpl, pt);
+            }
+            /* Project screenspace back to 3D space (from current perspective)
+             * so that all points have been treated the same way
+             */
+            else if (mode == GP_REPROJECT_VIEW) {
+              /* Planar - All on same plane parallel to the viewplane */
+              gp_point_xy_to_3d(&gsc, scene, xy, &pt->x);
+            }
+            else {
+              /* Geometry - Snap to surfaces of visible geometry */
+              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 */
+                gp_point_xy_to_3d(&gsc, scene, xy, &pt->x);
+        

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list