[Bf-blender-cvs] [a808ade3a26] greasepencil-object: GPencil: Create one stroke for each spline
Antonioya
noreply at git.blender.org
Tue Jul 16 12:13:56 CEST 2019
Commit: a808ade3a26750aa7caf71d944cdddcd3a6fd510
Author: Antonioya
Date: Tue Jul 16 11:00:19 2019 +0200
Branches: greasepencil-object
https://developer.blender.org/rBa808ade3a26750aa7caf71d944cdddcd3a6fd510
GPencil: Create one stroke for each spline
For curves with several splines, must create a stroke for each of them or the shape would be wrong.
===================================================================
M source/blender/blenkernel/intern/gpencil.c
===================================================================
diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c
index 70c66805dc0..2c67f89cc14 100644
--- a/source/blender/blenkernel/intern/gpencil.c
+++ b/source/blender/blenkernel/intern/gpencil.c
@@ -2118,7 +2118,7 @@ static void gpencil_add_new_points(
}
}
-/* Helper function to get the first collection that includes the object */
+/* Helper function to get the first collection that includes the object. */
static Collection *gpencil_get_parent_collection(Scene *scene, Object *ob)
{
Collection *mycol = NULL;
@@ -2134,52 +2134,19 @@ static Collection *gpencil_get_parent_collection(Scene *scene, Object *ob)
return mycol;
}
-/* 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)
+/* 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)
{
- if (ELEM(NULL, ob_gp, ob_cu) || (ob_gp->type != OB_GPENCIL) || (ob_gp->data == NULL)) {
- return;
- }
-
- bGPdata *gpd = (bGPdata *)ob_gp->data;
Curve *cu = (Curve *)ob_cu->data;
- Nurb *nu = NULL;
bool cyclic = true;
- bGPDlayer *gpl = NULL;
- /* Check if there is an active layer. */
- if (use_collections) {
- Collection *collection = gpencil_get_parent_collection(scene, ob_cu);
- if (collection != NULL) {
- gpl = BLI_findstring(&gpd->layers, collection->id.name + 2, offsetof(bGPDlayer, info));
- if (gpl == NULL) {
- gpl = BKE_gpencil_layer_addnew(gpd, collection->id.name + 2, true);
- }
- }
- }
-
- if (gpl == NULL) {
- gpl = BKE_gpencil_layer_getactive(gpd);
- if (gpl == NULL) {
- gpl = BKE_gpencil_layer_addnew(gpd, DATA_("GP_Layer"), true);
- }
- }
-
- /* Check if there is an active frame. */
- bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, CFRA, GP_GETFRAME_ADD_COPY);
/* Create Stroke. */
bGPDstroke *gps = MEM_callocN(sizeof(bGPDstroke), "bGPDstroke");
gps->thickness = 1.0f;
@@ -2200,20 +2167,16 @@ void BKE_gpencil_convert_curve(Main *bmain,
*/
int totpoints = 0;
int segments = 0;
- for (nu = cu->nurb.first; nu; nu = nu->next) {
- int resolu = nu->resolu + 1;
- if (nu->type == CU_BEZIER) {
- segments = nu->pntsu;
- if (((nu->flagu & CU_NURB_CYCLIC) == 0) || (nu->pntsu == 2)) {
- segments--;
- cyclic = false;
- }
- totpoints += resolu * segments;
- }
+ int resolu = nu->resolu + 1;
+ segments = nu->pntsu;
+ if (((nu->flagu & CU_NURB_CYCLIC) == 0) || (nu->pntsu == 2)) {
+ segments--;
+ cyclic = false;
}
- totpoints -= segments - 1;
- gps->totpoints = totpoints;
+ 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;
@@ -2263,11 +2226,11 @@ void BKE_gpencil_convert_curve(Main *bmain,
/* 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);
- /* set fill to off */
+ /* 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.*/
@@ -2275,46 +2238,101 @@ void BKE_gpencil_convert_curve(Main *bmain,
/* Read all segments of the curve. */
int init = 0;
- for (nu = cu->nurb.first; nu; nu = nu->next) {
- int resolu = nu->resolu + 1;
- if (nu->type == CU_BEZIER) {
- segments = nu->pntsu;
- if (((nu->flagu & CU_NURB_CYCLIC) == 0) || (nu->pntsu == 2)) {
- segments--;
- }
- /* Get all interpolated curve points of Beziert */
- for (int s = 0; s < segments; s++) {
- int inext = (s + 1) % nu->pntsu;
- BezTriple *prevbezt = &nu->bezt[s];
- BezTriple *bezt = &nu->bezt[inext];
-
- float *coord_array = MEM_callocN(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));
- }
- /* Add points to the stroke */
- gpencil_add_new_points(gps, coord_array, bezt->radius, init, resolu);
- /* 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;
- }
+ 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 */
+ for (int s = 0; s < segments; s++) {
+ int inext = (s + 1) % nu->pntsu;
+ BezTriple *prevbezt = &nu->bezt[s];
+ BezTriple *bezt = &nu->bezt[inext];
+
+ float *coord_array = MEM_callocN(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));
}
+ /* Add points to the stroke */
+ gpencil_add_new_points(gps, coord_array, bezt->radius, init, resolu);
+ /* 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 (collection != NULL) {
+ gpl = BLI_findstring(&gpd->layers, collection->id.name + 2, offsetof(bGPDlayer, info));
+ if (gpl == NULL) {
+ gpl = BKE_gpencil_layer_addnew(gpd, collection->id.name + 2, true);
+ }
+ }
+ }
+
+ if (gpl == NULL) {
+ gpl = BKE_gpencil_layer_getactive(gpd);
+ if (gpl == NULL) {
+ gpl = BKE_gpencil_layer_addnew(gpd, DATA_("GP_Layer"), true);
+ }
+ }
+
+ /* Check if there is an active frame and add if needed. */
+ bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, CFRA, GP_GETFRAME_ADD_COPY);
+
+ /* Read all splines of the curve and create a stroke for each. */
+ for (Nurb *nu = cu->nurb.first; nu; nu = nu->next) {
+ if (nu->type == CU_BEZIER) {
+ gpencil_convert_spline(bmain, scene, ob_gp, ob_cu, gpencil_lines, use_collections, gpf, nu);
+ }
+ }
+ /* Tag for recalculation */
DEG_id_tag_update(&gpd->id, ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE);
}
More information about the Bf-blender-cvs
mailing list