[Bf-blender-cvs] [94c416195e1] greasepencil-object: Merge branch 'master' into greasepencil-object

Antonio Vazquez noreply at git.blender.org
Thu Aug 8 15:55:55 CEST 2019


Commit: 94c416195e1b7e2bc761074eac7a74aa4ee55124
Author: Antonio Vazquez
Date:   Thu Aug 8 15:49:36 2019 +0200
Branches: greasepencil-object
https://developer.blender.org/rB94c416195e1b7e2bc761074eac7a74aa4ee55124

Merge branch 'master' into greasepencil-object

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



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

diff --cc source/blender/blenkernel/intern/gpencil.c
index 858f8be6dff,efdb35d4409..c04afb582c5
--- a/source/blender/blenkernel/intern/gpencil.c
+++ b/source/blender/blenkernel/intern/gpencil.c
@@@ -2720,390 -2139,80 +2720,468 @@@ void BKE_gpencil_dissolve_points(bGPDfr
    }
  }
  
 +/* Merge by distance ------------------------------------- */
 +/* Reduce a series of points when the distance is below a threshold.
 + * Special case for first and last points (both are keeped) for other points,
 + * the merge point is interpolated between points.
 + *
 + */
 +void BKE_gpencil_merge_distance_stroke(bGPDframe *gpf,
 +                                       bGPDstroke *gps,
 +                                       const float threshold,
 +                                       const bool use_unselected)
 +{
 +  bGPDspoint *pt = NULL;
 +  bGPDspoint *pt_next = NULL;
 +  float tagged = false;
 +  /* Use square distance to speed up loop */
 +  const float th_square = threshold * threshold;
 +  /* Need to have something to merge. */
 +  if (gps->totpoints < 2) {
 +    return;
 +  }
 +  int i = 0;
 +  int step = 1;
 +  while ((i < gps->totpoints - 1) && (i + step < gps->totpoints)) {
 +    pt = &gps->points[i];
 +    if (pt->flag & GP_SPOINT_TAG) {
 +      i++;
 +      step = 1;
 +      continue;
 +    }
 +    pt_next = &gps->points[i + step];
 +    /* Do not recalc tagged points. */
 +    if (pt_next->flag & GP_SPOINT_TAG) {
 +      step++;
 +      continue;
 +    }
 +    /* Check if contiguous points are selected. */
 +    if (!use_unselected) {
 +      if (((pt->flag & GP_SPOINT_SELECT) == 0) || ((pt_next->flag & GP_SPOINT_SELECT) == 0)) {
 +        i++;
 +        step = 1;
 +        continue;
 +      }
 +    }
 +    float len_square = len_squared_v3v3(&pt->x, &pt_next->x);
 +    if (len_square <= th_square) {
 +      tagged = true;
 +      if (i != gps->totpoints - 1) {
 +        /* Tag second point for delete. */
 +        pt_next->flag |= GP_SPOINT_TAG;
 +      }
 +      else {
 +        pt->flag |= GP_SPOINT_TAG;
 +      }
 +      /* Jump to next pair of points, keeping first point segment equals.*/
 +      step++;
 +    }
 +    else {
 +      /* Analyze next point. */
 +      i++;
 +      step = 1;
 +    }
 +  }
 +
 +  /* Always untag extremes. */
 +  pt = &gps->points[0];
 +  pt->flag &= ~GP_SPOINT_TAG;
 +  pt = &gps->points[gps->totpoints - 1];
 +  pt->flag &= ~GP_SPOINT_TAG;
 +
 +  /* Dissolve tagged points */
 +  if (tagged) {
 +    BKE_gpencil_dissolve_points(gpf, gps, GP_SPOINT_TAG);
 +  }
 +}
 +
 +/* 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 *scene,
 +                                   Object *ob_gp,
 +                                   Object *ob_cu,
 +                                   const bool gpencil_lines,
 +                                   const bool 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 < segment

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list