GPencil: Recode all material management when convert SVG
This commit is contained in:
parent
504c257dae
commit
145445c6b4
|
@ -50,60 +50,107 @@
|
|||
#include "DEG_depsgraph_query.h"
|
||||
|
||||
/* Helper: Check materials with same color. */
|
||||
static int gpencil_check_same_material_color(Object *ob_gp, const float color[4], Material **r_mat)
|
||||
static int gpencil_check_same_material_color(Object *ob_gp,
|
||||
const float color_stroke[4],
|
||||
const float color_fill[4],
|
||||
const bool do_fill,
|
||||
const bool do_stroke,
|
||||
Material **r_mat)
|
||||
{
|
||||
int index = -1;
|
||||
Material *ma = NULL;
|
||||
*r_mat = NULL;
|
||||
float color_cu[4];
|
||||
copy_v4_v4(color_cu, color);
|
||||
float hsv_stroke[4], hsv_fill[4];
|
||||
|
||||
float hsv1[4];
|
||||
rgb_to_hsv_v(color_cu, hsv1);
|
||||
hsv1[3] = color[3];
|
||||
copy_v4_v4(color_cu, color_stroke);
|
||||
rgb_to_hsv_v(color_cu, hsv_stroke);
|
||||
hsv_stroke[3] = color_stroke[3];
|
||||
|
||||
copy_v4_v4(color_cu, color_fill);
|
||||
rgb_to_hsv_v(color_cu, hsv_fill);
|
||||
hsv_fill[3] = color_fill[3];
|
||||
|
||||
bool match_stroke = false;
|
||||
bool match_fill = false;
|
||||
|
||||
for (int i = 1; i <= ob_gp->totcol; i++) {
|
||||
ma = BKE_object_material_get(ob_gp, i);
|
||||
MaterialGPencilStyle *gp_style = ma->gp_style;
|
||||
/* Check color with small tolerance (better in HSV). */
|
||||
const bool fill = (gp_style->fill_style == GP_MATERIAL_FILL_STYLE_SOLID);
|
||||
const bool stroke = (gp_style->fill_style == GP_MATERIAL_STROKE_STYLE_SOLID);
|
||||
|
||||
if (do_fill && !fill) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (do_stroke && !stroke) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check color with small tolerance (better result in HSV). */
|
||||
float hsv2[4];
|
||||
rgb_to_hsv_v(gp_style->fill_rgba, hsv2);
|
||||
hsv2[3] = gp_style->fill_rgba[3];
|
||||
if ((gp_style->fill_style == GP_MATERIAL_FILL_STYLE_SOLID) &&
|
||||
(compare_v4v4(hsv1, hsv2, 0.01f))) {
|
||||
*r_mat = ma;
|
||||
return i - 1;
|
||||
if (do_fill) {
|
||||
rgb_to_hsv_v(gp_style->fill_rgba, hsv2);
|
||||
hsv2[3] = gp_style->fill_rgba[3];
|
||||
if (compare_v4v4(hsv_fill, hsv2, 0.01f)) {
|
||||
*r_mat = ma;
|
||||
index = i - 1;
|
||||
match_fill = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
match_fill = true;
|
||||
}
|
||||
|
||||
if (do_stroke) {
|
||||
rgb_to_hsv_v(gp_style->stroke_rgba, hsv2);
|
||||
hsv2[3] = gp_style->stroke_rgba[3];
|
||||
if (compare_v4v4(hsv_stroke, hsv2, 0.01f)) {
|
||||
*r_mat = ma;
|
||||
index = i - 1;
|
||||
match_stroke = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
match_stroke = true;
|
||||
}
|
||||
|
||||
/* If match, don't look for more. */
|
||||
if (match_stroke || match_fill) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*r_mat = NULL;
|
||||
return -1;
|
||||
if (!match_stroke || !match_fill) {
|
||||
*r_mat = NULL;
|
||||
index = -1;
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
/* Helper: Add gpencil material using curve material as base. */
|
||||
static Material *gpencil_add_from_curve_material(Main *bmain,
|
||||
Object *ob_gp,
|
||||
const float cu_color[4],
|
||||
const bool gpencil_lines,
|
||||
const float stroke_color[4],
|
||||
const float fill_color[4],
|
||||
const bool stroke,
|
||||
const bool fill,
|
||||
int *r_idx)
|
||||
{
|
||||
Material *mat_gp = BKE_gpencil_object_material_new(
|
||||
bmain, ob_gp, (fill) ? "Material" : "Unassigned", r_idx);
|
||||
Material *mat_gp = BKE_gpencil_object_material_new(bmain, ob_gp, "Material", 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);
|
||||
if (stroke) {
|
||||
copy_v4_v4(mat_gp->gp_style->stroke_rgba, stroke_color);
|
||||
gp_style->flag |= GP_MATERIAL_STROKE_SHOW;
|
||||
}
|
||||
else {
|
||||
copy_v4_v4(mat_gp->gp_style->stroke_rgba, cu_color);
|
||||
gp_style->flag &= ~GP_MATERIAL_STROKE_SHOW;
|
||||
}
|
||||
|
||||
/* Fill color. */
|
||||
copy_v4_v4(mat_gp->gp_style->fill_rgba, cu_color);
|
||||
/* Fill is false if the original curve hasn't material assigned, so enable it. */
|
||||
if (fill) {
|
||||
copy_v4_v4(mat_gp->gp_style->fill_rgba, fill_color);
|
||||
gp_style->flag |= GP_MATERIAL_FILL_SHOW;
|
||||
}
|
||||
|
||||
|
@ -165,6 +212,92 @@ static Collection *gpencil_get_parent_collection(Scene *scene, Object *ob)
|
|||
|
||||
return mycol;
|
||||
}
|
||||
static int gpencil_get_stroke_material_fromcurve(Main *bmain,
|
||||
Object *ob_gp,
|
||||
Object *ob_cu,
|
||||
const bool only_stroke,
|
||||
bool *do_stroke,
|
||||
bool *do_fill)
|
||||
{
|
||||
Curve *cu = (Curve *)ob_cu->data;
|
||||
|
||||
Material *mat_gp = NULL;
|
||||
Material *mat_curve_stroke = NULL;
|
||||
Material *mat_curve_fill = NULL;
|
||||
|
||||
float color_stroke[4] = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||
float color_fill[4] = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||
|
||||
/* 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 {
|
||||
/* Gray (unassigned from SVG add-on) */
|
||||
zero_v4(color);
|
||||
add_v3_fl(color, 0.6f);
|
||||
color[3] = 1.0f;
|
||||
do_fill = false;
|
||||
}
|
||||
|
||||
/* If the curve has 2 materials, the first is considered as Fill and the second as Stroke.
|
||||
* If the has only one material, if the name contains _stroke, the is used
|
||||
* as stroke, else as fill.*/
|
||||
if (ob_cu->totcol >= 2) {
|
||||
*do_stroke = true;
|
||||
*do_fill = true;
|
||||
mat_curve_fill = BKE_object_material_get(ob_cu, 1);
|
||||
mat_curve_stroke = BKE_object_material_get(ob_cu, 2);
|
||||
}
|
||||
else if (ob_cu->totcol == 1) {
|
||||
mat_curve_stroke = BKE_object_material_get(ob_cu, 1);
|
||||
if ((mat_curve_stroke) && (strstr(mat_curve_stroke->id.name, "_stroke") != NULL)) {
|
||||
*do_stroke = true;
|
||||
*do_fill = false;
|
||||
mat_curve_fill = NULL;
|
||||
}
|
||||
else {
|
||||
*do_stroke = false;
|
||||
*do_fill = true;
|
||||
/* Invert materials. */
|
||||
mat_curve_fill = mat_curve_stroke;
|
||||
mat_curve_stroke = NULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* No materials in the curve. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (mat_curve_stroke) {
|
||||
copy_v4_v4(color_stroke, &mat_curve_stroke->r);
|
||||
}
|
||||
if (mat_curve_fill) {
|
||||
copy_v4_v4(color_fill, &mat_curve_fill->r);
|
||||
}
|
||||
|
||||
int r_idx = gpencil_check_same_material_color(
|
||||
ob_gp, color_stroke, color_fill, *do_stroke, *do_fill, &mat_gp);
|
||||
|
||||
if ((ob_gp->totcol < r_idx) || (r_idx < 0)) {
|
||||
mat_gp = gpencil_add_from_curve_material(
|
||||
bmain, ob_gp, color_stroke, color_fill, *do_stroke, *do_fill, &r_idx);
|
||||
}
|
||||
|
||||
/* Set fill and stroke depending of curve type (3D or 2D). */
|
||||
if ((cu->flag & CU_3D) || ((cu->flag & (CU_FRONT | CU_BACK)) == 0)) {
|
||||
mat_gp->gp_style->flag |= GP_MATERIAL_STROKE_SHOW;
|
||||
mat_gp->gp_style->flag &= ~GP_MATERIAL_FILL_SHOW;
|
||||
}
|
||||
else {
|
||||
mat_gp->gp_style->flag &= ~GP_MATERIAL_STROKE_SHOW;
|
||||
mat_gp->gp_style->flag |= GP_MATERIAL_FILL_SHOW;
|
||||
}
|
||||
|
||||
return r_idx;
|
||||
}
|
||||
|
||||
/* Helper: Convert one spline to grease pencil stroke. */
|
||||
static void gpencil_convert_spline(Main *bmain,
|
||||
|
@ -177,7 +310,6 @@ static void gpencil_convert_spline(Main *bmain,
|
|||
bGPDframe *gpf,
|
||||
Nurb *nu)
|
||||
{
|
||||
Curve *cu = (Curve *)ob_cu->data;
|
||||
bool cyclic = true;
|
||||
|
||||
/* Create Stroke. */
|
||||
|
@ -212,75 +344,9 @@ static void gpencil_convert_spline(Main *bmain,
|
|||
/* 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 {
|
||||
/* Gray (unassigned from SVG add-on) */
|
||||
zero_v4(color);
|
||||
add_v3_fl(color, 0.6f);
|
||||
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 do_stroke = false;
|
||||
if (ob_cu->totcol == 1) {
|
||||
Material *ma_stroke = BKE_object_material_get(ob_cu, 1);
|
||||
if ((ma_stroke) && (strstr(ma_stroke->id.name, "_stroke") != NULL)) {
|
||||
do_stroke = true;
|
||||
}
|
||||
}
|
||||
|
||||
int r_idx = gpencil_check_same_material_color(ob_gp, color, &mat_gp);
|
||||
if ((ob_cu->totcol > 0) && (r_idx < 0)) {
|
||||
Material *mat_curve = BKE_object_material_get(ob_cu, 1);
|
||||
mat_gp = gpencil_add_from_curve_material(bmain, ob_gp, color, gpencil_lines, fill, &r_idx);
|
||||
|
||||
if ((mat_curve) && (mat_curve->gp_style != NULL)) {
|
||||
MaterialGPencilStyle *gp_style_cur = mat_curve->gp_style;
|
||||
MaterialGPencilStyle *gp_style_gp = mat_gp->gp_style;
|
||||
|
||||
copy_v4_v4(gp_style_gp->mix_rgba, gp_style_cur->mix_rgba);
|
||||
gp_style_gp->fill_style = gp_style_cur->fill_style;
|
||||
gp_style_gp->mix_factor = gp_style_cur->mix_factor;
|
||||
}
|
||||
|
||||
/* If object has more than 1 material, use second material for stroke color. */
|
||||
if ((!only_stroke) && (ob_cu->totcol > 1) && (BKE_object_material_get(ob_cu, 2))) {
|
||||
mat_curve = BKE_object_material_get(ob_cu, 2);
|
||||
if (mat_curve) {
|
||||
copy_v4_v4(mat_gp->gp_style->stroke_rgba, &mat_curve->r);
|
||||
}
|
||||
}
|
||||
else if ((only_stroke) || (do_stroke)) {
|
||||
/* Also use the first color if the fill is none for stroke color. */
|
||||
if (ob_cu->totcol > 0) {
|
||||
mat_curve = BKE_object_material_get(ob_cu, 1);
|
||||
if (mat_curve) {
|
||||
copy_v3_v3(mat_gp->gp_style->stroke_rgba, &mat_curve->r);
|
||||
mat_gp->gp_style->stroke_rgba[3] = mat_curve->a;
|
||||
/* Set fill and stroke depending of curve type (3D or 2D). */
|
||||
if ((cu->flag & CU_3D) || ((cu->flag & (CU_FRONT | CU_BACK)) == 0)) {
|
||||
mat_gp->gp_style->flag |= GP_MATERIAL_STROKE_SHOW;
|
||||
mat_gp->gp_style->flag &= ~GP_MATERIAL_FILL_SHOW;
|
||||
}
|
||||
else {
|
||||
mat_gp->gp_style->flag &= ~GP_MATERIAL_STROKE_SHOW;
|
||||
mat_gp->gp_style->flag |= GP_MATERIAL_FILL_SHOW;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
bool do_stroke, do_fill;
|
||||
int r_idx = gpencil_get_stroke_material_fromcurve(
|
||||
bmain, ob_gp, ob_cu, only_stroke, &do_stroke, &do_fill);
|
||||
CLAMP_MIN(r_idx, 0);
|
||||
|
||||
/* Assign material index to stroke. */
|
||||
|
@ -390,9 +456,11 @@ static void gpencil_convert_spline(Main *bmain,
|
|||
}
|
||||
}
|
||||
/* Cyclic curve, close stroke. */
|
||||
if ((cyclic) && (!do_stroke)) {
|
||||
// if ((cyclic) && (!do_stroke)) {
|
||||
if (cyclic) {
|
||||
BKE_gpencil_stroke_close(gps);
|
||||
}
|
||||
|
||||
if (sample > 0.0f) {
|
||||
BKE_gpencil_stroke_sample(gps, sample, false);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue