[Bf-blender-cvs] [aa86a727437] soc-2019-npr: LANPR: Merge error fixes.

YimingWu noreply at git.blender.org
Sun Aug 11 04:18:12 CEST 2019


Commit: aa86a727437ab0843e2a21db78ae54b7bd47990b
Author: YimingWu
Date:   Sun Aug 11 10:17:50 2019 +0800
Branches: soc-2019-npr
https://developer.blender.org/rBaa86a727437ab0843e2a21db78ae54b7bd47990b

LANPR: Merge error fixes.

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

M	source/blender/blenkernel/intern/gpencil.c
M	source/blender/makesrna/intern/rna_material.c

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

diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c
index 44dcf252e3f..509e878191e 100644
--- a/source/blender/blenkernel/intern/gpencil.c
+++ b/source/blender/blenkernel/intern/gpencil.c
@@ -2657,6 +2657,322 @@ bool BKE_gpencil_close_stroke(bGPDstroke *gps)
 
   return true;
 }
+
+
+
+/* Helper function to check materials with same color */
+static int gpencil_check_same_material_color(Object *ob_gp, float color[4], Material *r_mat)
+{
+  Material *ma = NULL;
+  float color_cu[4];
+  linearrgb_to_srgb_v3_v3(color_cu, color);
+  float hsv1[4];
+  rgb_to_hsv_v(color_cu, hsv1);
+  hsv1[3] = color[3];
+
+  for (int i = 1; i <= ob_gp->totcol; i++) {
+    ma = give_current_material(ob_gp, i);
+    MaterialGPencilStyle *gp_style = ma->gp_style;
+    /* Check color with small tolerance (better in HSV). */
+    float hsv2[4];
+    rgb_to_hsv_v(gp_style->fill_rgba, hsv2);
+    hsv2[3] = gp_style->fill_rgba[3];
+    if (compare_v4v4(hsv1, hsv2, 0.01f)) {
+      r_mat = ma;
+      return i - 1;
+    }
+  }
+
+  r_mat = NULL;
+  return -1;
+}
+
+/* Add gpencil material using curve material as base */
+static Material *gpencil_add_from_curve_material(Main *bmain,
+                                                 Object *ob_gp,
+                                                 float cu_color[4],
+                                                 const bool gpencil_lines,
+                                                 const bool fill,
+                                                 int *r_idx)
+{
+  Material *mat_gp = BKE_gpencil_object_material_new(
+      bmain, ob_gp, (fill) ? "Material" : "Unassigned", r_idx);
+  MaterialGPencilStyle *gp_style = mat_gp->gp_style;
+
+  /* Stroke color. */
+  if (gpencil_lines) {
+    ARRAY_SET_ITEMS(gp_style->stroke_rgba, 0.0f, 0.0f, 0.0f, 1.0f);
+  }
+  else {
+    linearrgb_to_srgb_v4(gp_style->stroke_rgba, cu_color);
+  }
+
+  /* Fill color. */
+  linearrgb_to_srgb_v4(gp_style->fill_rgba, cu_color);
+  /* Fill is false if the original curva hasn't material assigned. */
+  if (fill) {
+    gp_style->flag |= GP_STYLE_FILL_SHOW;
+  }
+
+  return mat_gp;
+}
+
+/* Helper function to create new stroke section */
+static void gpencil_add_new_points(bGPDstroke *gps,
+                                   float *coord_array,
+                                   float pressure,
+                                   int init,
+                                   int totpoints,
+                                   float init_co[3],
+                                   bool last)
+{
+  for (int i = 0; i < totpoints; i++) {
+    bGPDspoint *pt = &gps->points[i + init];
+    copy_v3_v3(&pt->x, &coord_array[3 * i]);
+    /* Be sure the last point is not on top of the first point of the curve or
+     * the close of the stroke will produce glitches. */
+    if ((last) && (i > 0) && (i == totpoints - 1)) {
+      float dist = len_v3v3(init_co, &pt->x);
+      if (dist < 0.1f) {
+        /* Interpolate between previous point and current to back slightly. */
+        bGPDspoint *pt_prev = &gps->points[i + init - 1];
+        interp_v3_v3v3(&pt->x, &pt_prev->x, &pt->x, 0.95f);
+      }
+    }
+
+    pt->pressure = pressure;
+    pt->strength = 1.0f;
+  }
+}
+
+/* Helper function to get the first collection that includes the object. */
+static Collection *gpencil_get_parent_collection(Scene *scene, Object *ob)
+{
+  Collection *mycol = NULL;
+  FOREACH_SCENE_COLLECTION_BEGIN (scene, collection) {
+    for (CollectionObject *cob = collection->gobject.first; cob; cob = cob->next) {
+      if ((mycol == NULL) && (cob->ob == ob)) {
+        mycol = collection;
+      }
+    }
+  }
+  FOREACH_SCENE_COLLECTION_END;
+
+  return mycol;
+}
+
+/* Helper function to convert one spline to grease pencil stroke. */
+static void gpencil_convert_spline(Main *bmain,
+                                   Scene *UNUSED(scene),
+                                   Object *ob_gp,
+                                   Object *ob_cu,
+                                   const bool gpencil_lines,
+                                   const bool UNUSED(use_collections),
+                                   bGPDframe *gpf,
+                                   Nurb *nu)
+{
+  Curve *cu = (Curve *)ob_cu->data;
+  bool cyclic = true;
+
+  /* Create Stroke. */
+  bGPDstroke *gps = MEM_callocN(sizeof(bGPDstroke), "bGPDstroke");
+  gps->thickness = 1.0f;
+  gps->gradient_f = 1.0f;
+  ARRAY_SET_ITEMS(gps->gradient_s, 1.0f, 1.0f);
+  ARRAY_SET_ITEMS(gps->caps, GP_STROKE_CAP_ROUND, GP_STROKE_CAP_ROUND);
+  gps->inittime = 0.0f;
+
+  /* Enable recalculation flag by default. */
+  gps->flag |= GP_STROKE_RECALC_GEOMETRY;
+  gps->flag &= ~GP_STROKE_SELECT;
+  gps->flag |= GP_STROKE_3DSPACE;
+
+  gps->mat_nr = 0;
+  /* Count total points
+   * The total of points must consider that last point of each segment is equal to the first
+   * point of next segment.
+   */
+  int totpoints = 0;
+  int segments = 0;
+  int resolu = nu->resolu + 1;
+  segments = nu->pntsu;
+  if (((nu->flagu & CU_NURB_CYCLIC) == 0) || (nu->pntsu == 2)) {
+    segments--;
+    cyclic = false;
+  }
+  totpoints = (resolu * segments) - (segments - 1);
+
+  /* Allocate memory for storage points, but keep empty. */
+  gps->totpoints = totpoints;
+  gps->points = MEM_callocN(sizeof(bGPDspoint) * gps->totpoints, "gp_stroke_points");
+  /* Initialize triangle memory to dummy data. */
+  gps->tot_triangles = 0;
+  gps->triangles = NULL;
+
+  /* Materials
+   * Notice: The color of the material is the color of viewport and not the final shader color.
+   */
+  Material *mat_gp = NULL;
+  bool fill = true;
+  /* Check if grease pencil has a material with same color.*/
+  float color[4];
+  if ((cu->mat) && (*cu->mat)) {
+    Material *mat_cu = *cu->mat;
+    copy_v4_v4(color, &mat_cu->r);
+  }
+  else {
+    /* Pink (unassigned) */
+    zero_v4(color);
+    color[0] = 1.0f;
+    color[2] = 1.0f;
+    color[3] = 1.0f;
+    fill = false;
+  }
+
+  /* Special case: If the color was created by the SVG add-on and the name contains '_stroke' and
+   * there is only one color, the stroke must not be closed, fill to false and use for
+   * stroke the fill color.
+   */
+  bool only_stroke = false;
+  if (ob_cu->totcol == 1) {
+    Material *ma_stroke = give_current_material(ob_cu, 1);
+    if ((ma_stroke) && (strstr(ma_stroke->id.name, "_stroke") != NULL)) {
+      only_stroke = true;
+    }
+  }
+
+  int r_idx = gpencil_check_same_material_color(ob_gp, color, mat_gp);
+  if (r_idx < 0) {
+    Material *ma_stroke = NULL;
+    mat_gp = gpencil_add_from_curve_material(bmain, ob_gp, color, gpencil_lines, fill, &r_idx);
+    /* If object has more than 1 material, use second material for stroke color. */
+    if (ob_cu->totcol > 1) {
+      ma_stroke = give_current_material(ob_cu, 2);
+      linearrgb_to_srgb_v3_v3(mat_gp->gp_style->stroke_rgba, &ma_stroke->r);
+      mat_gp->gp_style->stroke_rgba[3] = ma_stroke->a;
+    }
+    else if (only_stroke) {
+      /* Also use the first color if the fill is none for stroke color. */
+      ma_stroke = give_current_material(ob_cu, 1);
+      linearrgb_to_srgb_v3_v3(mat_gp->gp_style->stroke_rgba, &ma_stroke->r);
+      mat_gp->gp_style->stroke_rgba[3] = ma_stroke->a;
+      /* set fill to off. */
+      mat_gp->gp_style->flag &= ~GP_STYLE_FILL_SHOW;
+    }
+  }
+  /* Assign material index to stroke. */
+  gps->mat_nr = r_idx;
+
+  /* Add stroke to frame.*/
+  BLI_addtail(&gpf->strokes, gps);
+
+  /* Read all segments of the curve. */
+  int init = 0;
+  resolu = nu->resolu + 1;
+  segments = nu->pntsu;
+  if (((nu->flagu & CU_NURB_CYCLIC) == 0) || (nu->pntsu == 2)) {
+    segments--;
+  }
+  /* Get all interpolated curve points of Beziert */
+  float init_co[3];
+  for (int s = 0; s < segments; s++) {
+    int inext = (s + 1) % nu->pntsu;
+    BezTriple *prevbezt = &nu->bezt[s];
+    BezTriple *bezt = &nu->bezt[inext];
+    bool last = (bool)(s == segments - 1);
+
+    float *coord_array = MEM_callocN((size_t)3 * resolu * sizeof(float), __func__);
+
+    for (int j = 0; j < 3; j++) {
+      BKE_curve_forward_diff_bezier(prevbezt->vec[1][j],
+                                    prevbezt->vec[2][j],
+                                    bezt->vec[0][j],
+                                    bezt->vec[1][j],
+                                    coord_array + j,
+                                    resolu - 1,
+                                    3 * sizeof(float));
+    }
+    /* Save first point coordinates. */
+    if (s == 0) {
+      copy_v3_v3(init_co, &coord_array[0]);
+    }
+    /* Add points to the stroke */
+    gpencil_add_new_points(gps, coord_array, bezt->radius, init, resolu, init_co, last);
+    /* Free memory. */
+    MEM_SAFE_FREE(coord_array);
+
+    /* As the last point of segment is the first point of next segment, back one array
+     * element to avoid duplicated points on the same location.
+     */
+    init += resolu - 1;
+  }
+  /* Cyclic curve, close stroke. */
+  if ((cyclic) && (!only_stroke)) {
+    BKE_gpencil_close_stroke(gps);
+  }
+}
+
+/* Convert a curve object to grease pencil stroke.
+ *
+ * \param bmain: Main thread pointer
+ * \param scene: Original scene.
+ * \param ob_gp: Grease pencil object to add strokes.
+ * \param ob_cu: Curve to convert.
+ * \param gpencil_lines: Use lines for strokes.
+ * \param use_collections: Create layers using collection names.
+ */
+void BKE_gpencil_convert_curve(Main *bmain,
+                               Scene *scene,
+                               Object *ob_gp,
+                               Object *ob_cu,
+                               const bool gpencil_lines,
+                               const bool use_collections)
+{
+  if (ELEM(NULL, ob_gp, ob_cu) || (ob_gp->type != OB_GPENCIL) || (ob_gp->data == NULL)) {
+    return;
+  }
+
+  Curve *cu = (Curve *)ob_cu->data;
+  bGPdata *gpd = (bGPdata *)ob_gp->data;
+  bGPDlayer *gpl = NULL;
+
+  /* If the curve is empty, cancel. */
+  if (cu->nurb.first == NULL) {
+    return;
+  }
+
+  /* Check if there is an active layer. */
+  if (use_collections) {
+    Collection *collection = gpencil_get_parent_collection(scene, ob_cu);
+    if (col

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list