diff options
Diffstat (limited to 'source/blender/io/gpencil')
15 files changed, 146 insertions, 80 deletions
diff --git a/source/blender/io/gpencil/CMakeLists.txt b/source/blender/io/gpencil/CMakeLists.txt index 11c9affbe5a..fec95be6aa8 100644 --- a/source/blender/io/gpencil/CMakeLists.txt +++ b/source/blender/io/gpencil/CMakeLists.txt @@ -39,22 +39,19 @@ set(INC_SYS ) set(SRC - intern/gpencil_io_capi.cc + intern/gpencil_io_base.cc + intern/gpencil_io_capi.cc + intern/gpencil_io_import_base.cc + intern/gpencil_io_import_svg.cc - # This line must be removed if NanoSVG is moved to extern - nanosvg/nanosvg.h + # This line must be removed if NanoSVG is moved to extern + nanosvg/nanosvg.h - gpencil_io.h - - intern/gpencil_io_base.h - intern/gpencil_io_base.cc - - intern/gpencil_io_import_base.h - intern/gpencil_io_import_svg.h - intern/gpencil_io_import_base.cc - intern/gpencil_io_import_svg.cc - - intern/gpencil_io_export_base.h + gpencil_io.h + intern/gpencil_io_base.hh + intern/gpencil_io_export_base.hh + intern/gpencil_io_import_base.hh + intern/gpencil_io_import_svg.hh ) set(LIB @@ -65,8 +62,9 @@ set(LIB if(WITH_PUGIXML) list(APPEND SRC - intern/gpencil_io_export_svg.h intern/gpencil_io_export_svg.cc + + intern/gpencil_io_export_svg.hh ) list(APPEND INC_SYS ${PUGIXML_INCLUDE_DIR} @@ -79,8 +77,9 @@ endif() if(WITH_HARU) list(APPEND SRC - intern/gpencil_io_export_pdf.h intern/gpencil_io_export_pdf.cc + + intern/gpencil_io_export_pdf.hh ) list(APPEND INC_SYS ${HARU_INCLUDE_DIRS} diff --git a/source/blender/io/gpencil/gpencil_io.h b/source/blender/io/gpencil/gpencil_io.h index f4b2e59f8c5..24b13479359 100644 --- a/source/blender/io/gpencil/gpencil_io.h +++ b/source/blender/io/gpencil/gpencil_io.h @@ -78,7 +78,7 @@ typedef enum eGpencilExportSelect { GP_EXPORT_VISIBLE = 2, } eGpencilExportSelect; -/* Framerange to be exported. */ +/** Frame-range to be exported. */ typedef enum eGpencilExportFrame { GP_EXPORT_FRAME_ACTIVE = 0, GP_EXPORT_FRAME_SELECTED = 1, diff --git a/source/blender/io/gpencil/intern/gpencil_io_base.cc b/source/blender/io/gpencil/intern/gpencil_io_base.cc index 855252e648c..a2c1b8f5af6 100644 --- a/source/blender/io/gpencil/intern/gpencil_io_base.cc +++ b/source/blender/io/gpencil/intern/gpencil_io_base.cc @@ -41,6 +41,7 @@ #include "BKE_gpencil_geom.h" #include "BKE_main.h" #include "BKE_material.h" +#include "BKE_scene.h" #include "UI_view2d.h" @@ -49,7 +50,7 @@ #include "DEG_depsgraph.h" #include "DEG_depsgraph_query.h" -#include "gpencil_io_base.h" +#include "gpencil_io_base.hh" using blender::Span; @@ -69,7 +70,21 @@ GpencilIO::GpencilIO(const GpencilIOParams *iparams) cfra_ = iparams->frame_cur; /* Calculate camera matrix. */ - Object *cam_ob = params_.v3d->camera; + prepare_camera_params(scene_, iparams); +} + +void GpencilIO::prepare_camera_params(Scene *scene, const GpencilIOParams *iparams) +{ + params_ = *iparams; + const bool is_pdf = params_.mode == GP_EXPORT_TO_PDF; + const bool any_camera = (params_.v3d->camera != nullptr); + const bool force_camera_view = is_pdf && any_camera; + + /* Ensure camera switch is applied. */ + BKE_scene_camera_switch_update(scene); + + /* Calculate camera matrix. */ + Object *cam_ob = scene->camera; if (cam_ob != nullptr) { /* Set up parameters. */ CameraParams params; @@ -85,16 +100,18 @@ GpencilIO::GpencilIO(const GpencilIOParams *iparams) invert_m4_m4(viewmat, cam_ob->obmat); mul_m4_m4m4(persmat_, params.winmat, viewmat); + is_ortho_ = params.is_ortho; } else { unit_m4(persmat_); + is_ortho_ = false; } winx_ = params_.region->winx; winy_ = params_.region->winy; /* Camera rectangle. */ - if (rv3d_->persp == RV3D_CAMOB) { + if ((rv3d_->persp == RV3D_CAMOB) || (force_camera_view)) { render_x_ = (scene_->r.xsch * scene_->r.size) / 100; render_y_ = (scene_->r.ysch * scene_->r.size) / 100; @@ -112,11 +129,14 @@ GpencilIO::GpencilIO(const GpencilIOParams *iparams) } else { is_camera_ = false; + is_ortho_ = false; /* Calc selected object boundbox. Need set initial value to some variables. */ camera_ratio_ = 1.0f; offset_.x = 0.0f; offset_.y = 0.0f; + create_object_list(); + selected_objects_boundbox_calc(); rctf boundbox; selected_objects_boundbox_get(&boundbox); @@ -228,13 +248,15 @@ bool GpencilIO::gpencil_3D_point_to_screen_space(const float3 co, float2 &r_co) } /** Convert to render space. */ -float2 GpencilIO::gpencil_3D_point_to_render_space(const float3 co) +float2 GpencilIO::gpencil_3D_point_to_render_space(const float3 co, const bool is_ortho) { float3 parent_co = diff_mat_ * co; mul_m4_v3(persmat_, parent_co); - parent_co.x = parent_co.x / max_ff(FLT_MIN, parent_co[2]); - parent_co.y = parent_co.y / max_ff(FLT_MIN, parent_co[2]); + if (!is_ortho) { + parent_co.x = parent_co.x / max_ff(FLT_MIN, parent_co.z); + parent_co.y = parent_co.y / max_ff(FLT_MIN, parent_co.z); + } float2 r_co; r_co.x = (parent_co.x + 1.0f) / 2.0f * (float)render_x_; @@ -257,7 +279,7 @@ float2 GpencilIO::gpencil_3D_point_to_2D(const float3 co) { const bool is_camera = (bool)(rv3d_->persp == RV3D_CAMOB); if (is_camera) { - return gpencil_3D_point_to_render_space(co); + return gpencil_3D_point_to_render_space(co, is_orthographic()); } float2 result; gpencil_3D_point_to_screen_space(co, result); @@ -296,7 +318,7 @@ void GpencilIO::prepare_stroke_export_colors(Object *ob, bGPDstroke *gps) /* Stroke color. */ copy_v4_v4(stroke_color_, gp_style->stroke_rgba); - avg_opacity_ = 0; + avg_opacity_ = 0.0f; /* Get average vertex color and apply. */ float avg_color[4] = {0.0f, 0.0f, 0.0f, 0.0f}; for (const bGPDspoint &pt : Span(gps->points, gps->totpoints)) { @@ -324,6 +346,11 @@ bool GpencilIO::is_camera_mode() return is_camera_; } +bool GpencilIO::is_orthographic() +{ + return is_ortho_; +} + /* Calculate selected strokes boundbox. */ void GpencilIO::selected_objects_boundbox_calc() { diff --git a/source/blender/io/gpencil/intern/gpencil_io_base.h b/source/blender/io/gpencil/intern/gpencil_io_base.hh index 986221618b7..c3c6f1156bb 100644 --- a/source/blender/io/gpencil/intern/gpencil_io_base.h +++ b/source/blender/io/gpencil/intern/gpencil_io_base.hh @@ -50,6 +50,7 @@ class GpencilIO { GpencilIO(const GpencilIOParams *iparams); void frame_number_set(const int value); + void prepare_camera_params(Scene *scene, const GpencilIOParams *iparams); protected: GpencilIOParams params_; @@ -87,13 +88,14 @@ class GpencilIO { /* Geometry functions. */ bool gpencil_3D_point_to_screen_space(const float3 co, float2 &r_co); - float2 gpencil_3D_point_to_render_space(const float3 co); + float2 gpencil_3D_point_to_render_space(const float3 co, const bool is_ortho); float2 gpencil_3D_point_to_2D(const float3 co); float stroke_point_radius_get(struct bGPDlayer *gpl, struct bGPDstroke *gps); void create_object_list(); bool is_camera_mode(); + bool is_orthographic(); float stroke_average_opacity_get(); @@ -107,6 +109,7 @@ class GpencilIO { private: float avg_opacity_; bool is_camera_; + bool is_ortho_; rctf select_boundbox_; /* Camera matrix. */ diff --git a/source/blender/io/gpencil/intern/gpencil_io_capi.cc b/source/blender/io/gpencil/intern/gpencil_io_capi.cc index 231d23948ef..544c51e0b4f 100644 --- a/source/blender/io/gpencil/intern/gpencil_io_capi.cc +++ b/source/blender/io/gpencil/intern/gpencil_io_capi.cc @@ -21,7 +21,7 @@ * \ingroup bgpencil */ -#include <stdio.h> +#include <cstdio> #include "BLI_listbase.h" @@ -40,14 +40,14 @@ #include "../gpencil_io.h" #ifdef WITH_HARU -# include "gpencil_io_export_pdf.h" +# include "gpencil_io_export_pdf.hh" #endif #ifdef WITH_PUGIXML -# include "gpencil_io_export_svg.h" +# include "gpencil_io_export_svg.hh" #endif -#include "gpencil_io_import_svg.h" +#include "gpencil_io_import_svg.hh" #ifdef WITH_HARU using blender::io::gpencil::GpencilExporterPDF; @@ -121,6 +121,7 @@ static bool gpencil_io_export_pdf(Depsgraph *depsgraph, CFRA = i; BKE_scene_graph_update_for_newframe(depsgraph); + exporter->prepare_camera_params(scene, iparams); exporter->frame_number_set(i); exporter->add_newpage(); exporter->add_body(); @@ -129,9 +130,11 @@ static bool gpencil_io_export_pdf(Depsgraph *depsgraph, /* Back to original frame. */ exporter->frame_number_set(iparams->frame_cur); CFRA = iparams->frame_cur; + BKE_scene_camera_switch_update(scene); BKE_scene_graph_update_for_newframe(depsgraph); } else { + exporter->prepare_camera_params(scene, iparams); exporter->add_newpage(); exporter->add_body(); result = exporter->write(); @@ -144,6 +147,7 @@ static bool gpencil_io_export_pdf(Depsgraph *depsgraph, /* Export current frame in SVG. */ #ifdef WITH_PUGIXML static bool gpencil_io_export_frame_svg(GpencilExporterSVG *exporter, + Scene *scene, const GpencilIOParams *iparams, const bool newpage, const bool body, @@ -151,6 +155,8 @@ static bool gpencil_io_export_frame_svg(GpencilExporterSVG *exporter, { bool result = false; exporter->frame_number_set(iparams->frame_cur); + exporter->prepare_camera_params(scene, iparams); + if (newpage) { result |= exporter->add_newpage(); } @@ -185,7 +191,7 @@ bool gpencil_io_export(const char *filename, GpencilIOParams *iparams) #ifdef WITH_PUGIXML case GP_EXPORT_TO_SVG: { GpencilExporterSVG exporter = GpencilExporterSVG(filename, iparams); - return gpencil_io_export_frame_svg(&exporter, iparams, true, true, true); + return gpencil_io_export_frame_svg(&exporter, scene_, iparams, true, true, true); break; } #endif diff --git a/source/blender/io/gpencil/intern/gpencil_io_export_base.h b/source/blender/io/gpencil/intern/gpencil_io_export_base.hh index 19a24a75fd2..ffb1c6ce262 100644 --- a/source/blender/io/gpencil/intern/gpencil_io_export_base.h +++ b/source/blender/io/gpencil/intern/gpencil_io_export_base.hh @@ -21,7 +21,7 @@ /** \file * \ingroup bgpencil */ -#include "gpencil_io_base.h" +#include "gpencil_io_base.hh" namespace blender::io::gpencil { diff --git a/source/blender/io/gpencil/intern/gpencil_io_export_pdf.cc b/source/blender/io/gpencil/intern/gpencil_io_export_pdf.cc index ba16d635c2d..0f90855dcb8 100644 --- a/source/blender/io/gpencil/intern/gpencil_io_export_pdf.cc +++ b/source/blender/io/gpencil/intern/gpencil_io_export_pdf.cc @@ -49,7 +49,7 @@ #include "UI_view2d.h" #include "gpencil_io.h" -#include "gpencil_io_export_pdf.h" +#include "gpencil_io_export_pdf.hh" namespace blender ::io ::gpencil { @@ -69,7 +69,6 @@ GpencilExporterPDF::GpencilExporterPDF(const char *filename, const GpencilIOPara pdf_ = nullptr; page_ = nullptr; - gstate_ = nullptr; } bool GpencilExporterPDF::new_document() @@ -169,16 +168,29 @@ void GpencilExporterPDF::export_gpencil_layers() if (!ED_gpencil_stroke_material_visible(ob, gps)) { continue; } - /* Duplicate the stroke to apply any layer thickness change. */ - bGPDstroke *gps_duplicate = BKE_gpencil_stroke_duplicate(gps, true, false); - MaterialGPencilStyle *gp_style = BKE_gpencil_material_settings(ob, - gps_duplicate->mat_nr + 1); + /* Skip invisible lines. */ + prepare_stroke_export_colors(ob, gps); + const float fill_opacity = fill_color_[3] * gpl->opacity; + const float stroke_opacity = stroke_color_[3] * stroke_average_opacity_get() * + gpl->opacity; + if ((fill_opacity < GPENCIL_ALPHA_OPACITY_THRESH) && + (stroke_opacity < GPENCIL_ALPHA_OPACITY_THRESH)) { + continue; + } + MaterialGPencilStyle *gp_style = BKE_gpencil_material_settings(ob, gps->mat_nr + 1); const bool is_stroke = ((gp_style->flag & GP_MATERIAL_STROKE_SHOW) && - (gp_style->stroke_rgba[3] > GPENCIL_ALPHA_OPACITY_THRESH)); + (gp_style->stroke_rgba[3] > GPENCIL_ALPHA_OPACITY_THRESH) && + (stroke_opacity > GPENCIL_ALPHA_OPACITY_THRESH)); const bool is_fill = ((gp_style->flag & GP_MATERIAL_FILL_SHOW) && (gp_style->fill_rgba[3] > GPENCIL_ALPHA_OPACITY_THRESH)); - prepare_stroke_export_colors(ob, gps_duplicate); + + if ((!is_stroke) && (!is_fill)) { + continue; + } + + /* Duplicate the stroke to apply any layer thickness change. */ + bGPDstroke *gps_duplicate = BKE_gpencil_stroke_duplicate(gps, true, false); /* Apply layer thickness change. */ gps_duplicate->thickness += gpl->line_change; @@ -283,29 +295,35 @@ void GpencilExporterPDF::color_set(bGPDlayer *gpl, const bool do_fill) { const float fill_opacity = fill_color_[3] * gpl->opacity; const float stroke_opacity = stroke_color_[3] * stroke_average_opacity_get() * gpl->opacity; + const bool need_state = (do_fill && fill_opacity < 1.0f) || (stroke_opacity < 1.0f); HPDF_Page_GSave(page_); - gstate_ = HPDF_CreateExtGState(pdf_); + HPDF_ExtGState gstate = (need_state) ? HPDF_CreateExtGState(pdf_) : nullptr; float col[3]; if (do_fill) { interp_v3_v3v3(col, fill_color_, gpl->tintcolor, gpl->tintcolor[3]); linearrgb_to_srgb_v3_v3(col, col); CLAMP3(col, 0.0f, 1.0f); - - HPDF_ExtGState_SetAlphaFill(gstate_, clamp_f(fill_opacity, 0.0f, 1.0f)); HPDF_Page_SetRGBFill(page_, col[0], col[1], col[2]); + if (gstate) { + HPDF_ExtGState_SetAlphaFill(gstate, clamp_f(fill_opacity, 0.0f, 1.0f)); + } } else { interp_v3_v3v3(col, stroke_color_, gpl->tintcolor, gpl->tintcolor[3]); linearrgb_to_srgb_v3_v3(col, col); CLAMP3(col, 0.0f, 1.0f); - HPDF_ExtGState_SetAlphaFill(gstate_, clamp_f(stroke_opacity, 0.0f, 1.0f)); - HPDF_ExtGState_SetAlphaStroke(gstate_, clamp_f(stroke_opacity, 0.0f, 1.0f)); HPDF_Page_SetRGBFill(page_, col[0], col[1], col[2]); HPDF_Page_SetRGBStroke(page_, col[0], col[1], col[2]); + if (gstate) { + HPDF_ExtGState_SetAlphaFill(gstate, clamp_f(stroke_opacity, 0.0f, 1.0f)); + HPDF_ExtGState_SetAlphaStroke(gstate, clamp_f(stroke_opacity, 0.0f, 1.0f)); + } + } + if (gstate) { + HPDF_Page_SetExtGState(page_, gstate); } - HPDF_Page_SetExtGState(page_, gstate_); } } // namespace blender::io::gpencil diff --git a/source/blender/io/gpencil/intern/gpencil_io_export_pdf.h b/source/blender/io/gpencil/intern/gpencil_io_export_pdf.hh index 009c05a8b49..89d97f79783 100644 --- a/source/blender/io/gpencil/intern/gpencil_io_export_pdf.h +++ b/source/blender/io/gpencil/intern/gpencil_io_export_pdf.hh @@ -22,7 +22,7 @@ * \ingroup bgpencil */ -#include "gpencil_io_export_base.h" +#include "gpencil_io_export_base.hh" #include "hpdf.h" struct GpencilIOParams; @@ -49,8 +49,6 @@ class GpencilExporterPDF : public GpencilExporter { HPDF_Doc pdf_; /* PDF page. */ HPDF_Page page_; - /* State. */ - HPDF_ExtGState gstate_; bool create_document(); bool add_page(); diff --git a/source/blender/io/gpencil/intern/gpencil_io_export_svg.cc b/source/blender/io/gpencil/intern/gpencil_io_export_svg.cc index 89584cd242f..c62764cca06 100644 --- a/source/blender/io/gpencil/intern/gpencil_io_export_svg.cc +++ b/source/blender/io/gpencil/intern/gpencil_io_export_svg.cc @@ -49,7 +49,7 @@ #include "UI_view2d.h" #include "gpencil_io.h" -#include "gpencil_io_export_svg.h" +#include "gpencil_io_export_svg.hh" #include "pugixml.hpp" @@ -119,6 +119,7 @@ void GpencilExporterSVG::create_document_header() main_node_.append_attribute("version").set_value("1.0"); main_node_.append_attribute("x").set_value("0px"); main_node_.append_attribute("y").set_value("0px"); + main_node_.append_attribute("xmlns").set_value("http://www.w3.org/2000/svg"); std::string width; std::string height; @@ -396,7 +397,7 @@ void GpencilExporterSVG::color_string_set(bGPDlayer *gpl, * \param node: Parent node * \param x: X location * \param y: Y location - * \param width: width of the recntagle + * \param width: width of the rectangle * \param height: Height of the rectangle * \param thickness: Thickness of the line * \param hexcolor: Color of the line @@ -427,7 +428,7 @@ void GpencilExporterSVG::add_rect(pugi::xml_node node, * \param x: X location * \param y: Y location * \param text: Text to include - * \param size: Size of th etext + * \param size: Size of the text * \param hexcolor: Color of the text */ void GpencilExporterSVG::add_text(pugi::xml_node node, @@ -448,7 +449,7 @@ void GpencilExporterSVG::add_text(pugi::xml_node node, } /** Convert a color to Hex value (#FFFFFF). */ -std::string GpencilExporterSVG::rgb_to_hexstr(float color[3]) +std::string GpencilExporterSVG::rgb_to_hexstr(const float color[3]) { uint8_t r = color[0] * 255.0f; uint8_t g = color[1] * 255.0f; diff --git a/source/blender/io/gpencil/intern/gpencil_io_export_svg.h b/source/blender/io/gpencil/intern/gpencil_io_export_svg.hh index f564736c16e..3bff31f20bf 100644 --- a/source/blender/io/gpencil/intern/gpencil_io_export_svg.h +++ b/source/blender/io/gpencil/intern/gpencil_io_export_svg.hh @@ -23,7 +23,7 @@ */ #include "BLI_path_util.h" -#include "gpencil_io_export_base.h" +#include "gpencil_io_export_base.hh" #include "pugixml.hpp" struct GpencilIOParams; @@ -70,20 +70,20 @@ class GpencilExporterSVG : public GpencilExporter { void export_stroke_to_path(struct bGPDlayer *gpl, struct bGPDstroke *gps, pugi::xml_node node_gpl, - const bool is_fill); + const bool do_fill); void export_stroke_to_polyline(struct bGPDlayer *gpl, struct bGPDstroke *gps, pugi::xml_node node_gpl, const bool is_stroke, - const bool is_fill); + const bool do_fill); void color_string_set(struct bGPDlayer *gpl, struct bGPDstroke *gps, pugi::xml_node node_gps, - const bool is_fill); + const bool do_fill); - std::string rgb_to_hexstr(float color[3]); + std::string rgb_to_hexstr(const float color[3]); }; } // namespace blender::io::gpencil diff --git a/source/blender/io/gpencil/intern/gpencil_io_import_base.cc b/source/blender/io/gpencil/intern/gpencil_io_import_base.cc index 2e7cfdeb5cd..d0b6e20bda2 100644 --- a/source/blender/io/gpencil/intern/gpencil_io_import_base.cc +++ b/source/blender/io/gpencil/intern/gpencil_io_import_base.cc @@ -33,7 +33,7 @@ #include "ED_gpencil.h" -#include "gpencil_io_import_base.h" +#include "gpencil_io_import_base.hh" namespace blender::io::gpencil { diff --git a/source/blender/io/gpencil/intern/gpencil_io_import_base.h b/source/blender/io/gpencil/intern/gpencil_io_import_base.hh index efe6264e4e9..7d6fad2340b 100644 --- a/source/blender/io/gpencil/intern/gpencil_io_import_base.h +++ b/source/blender/io/gpencil/intern/gpencil_io_import_base.hh @@ -21,7 +21,7 @@ /** \file * \ingroup bgpencil */ -#include "gpencil_io_base.h" +#include "gpencil_io_base.hh" namespace blender::io::gpencil { diff --git a/source/blender/io/gpencil/intern/gpencil_io_import_svg.cc b/source/blender/io/gpencil/intern/gpencil_io_import_svg.cc index 7f450477ac2..52fcc017ffb 100644 --- a/source/blender/io/gpencil/intern/gpencil_io_import_svg.cc +++ b/source/blender/io/gpencil/intern/gpencil_io_import_svg.cc @@ -36,7 +36,7 @@ #include "ED_gpencil.h" #include "gpencil_io.h" -#include "gpencil_io_import_svg.h" +#include "gpencil_io_import_svg.hh" /* Custom flags for NanoSVG. */ #define NANOSVG_ALL_COLOR_KEYWORDS @@ -69,9 +69,7 @@ bool GpencilImporterSVG::read() params_.ob = create_object(); if (params_.ob == nullptr) { std::cout << "Unable to create new object.\n"; - if (svg_data) { - nsvgDelete(svg_data); - } + nsvgDelete(svg_data); return false; } @@ -102,7 +100,7 @@ bool GpencilImporterSVG::read() bGPDlayer *gpl = (bGPDlayer *)BLI_findstring( &gpd_->layers, layer_id, offsetof(bGPDlayer, info)); if (gpl == nullptr) { - gpl = BKE_gpencil_layer_addnew(gpd_, layer_id, true); + gpl = BKE_gpencil_layer_addnew(gpd_, layer_id, true, false); /* Disable lights. */ gpl->flag &= ~GP_LAYER_USE_LIGHTS; } @@ -118,15 +116,17 @@ bool GpencilImporterSVG::read() } /* Create_shape materials. */ - const char *const mat_names[] = {"Stroke", "Fill"}; + const char *const mat_names[] = {"Stroke", "Fill", "Both"}; int index = 0; - if ((is_stroke) && (is_fill)) { + if ((is_stroke) && (!is_fill)) { index = 0; - is_fill = false; } else if ((!is_stroke) && (is_fill)) { index = 1; } + else if ((is_stroke) && (is_fill)) { + index = 2; + } int32_t mat_index = create_material(mat_names[index], is_stroke, is_fill); /* Loop all paths to create the stroke data. */ @@ -196,10 +196,10 @@ void GpencilImporterSVG::create_stroke(bGPdata *gpd, pt->strength = shape->opacity; pt->pressure = 1.0f; pt->z = 0.0f; - /* TODO: (antoniov) Can be improved loading curve data instead of loading strokes. */ + /* TODO(antoniov): Can be improved loading curve data instead of loading strokes. */ interp_v2_v2v2v2v2_cubic(&pt->x, &p[0], &p[2], &p[4], &p[6], a); - /* Scale from milimeters. */ + /* Scale from millimeters. */ mul_v3_fl(&pt->x, 0.001f); mul_m4_v3(matrix, &pt->x); diff --git a/source/blender/io/gpencil/intern/gpencil_io_import_svg.h b/source/blender/io/gpencil/intern/gpencil_io_import_svg.hh index 6a34ec8423b..0e9271dd2c6 100644 --- a/source/blender/io/gpencil/intern/gpencil_io_import_svg.h +++ b/source/blender/io/gpencil/intern/gpencil_io_import_svg.hh @@ -21,7 +21,7 @@ /** \file * \ingroup bgpencil */ -#include "gpencil_io_import_base.h" +#include "gpencil_io_import_base.hh" struct GpencilIOParams; struct NSVGshape; diff --git a/source/blender/io/gpencil/nanosvg/nanosvg.h b/source/blender/io/gpencil/nanosvg/nanosvg.h index 1009d684f7c..94dad37861a 100644 --- a/source/blender/io/gpencil/nanosvg/nanosvg.h +++ b/source/blender/io/gpencil/nanosvg/nanosvg.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-14 Mikko Mononen memon@inside.org + * Copyright (c) 2013-14 `Mikko Mononen <memon@inside.org>` * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -459,9 +459,9 @@ typedef struct NSVGparser { float dpi; char pathFlag; char defsFlag; - /** Blender breadscrum for layers. */ + /** Blender breadcrumb for layers. */ char breadcrumb[NSVG_MAX_BREADCRUMB][64]; - /** Blender number of elements in breadscrum. */ + /** Blender number of elements in breadcrumb. */ int breadcrumb_len; } NSVGparser; @@ -1289,7 +1289,7 @@ static const char *nsvg__parseNumber(const char *s, char *it, const int size) return s; } -static const char *nsvg__getNextPathItem(const char *s, char *it) +static const char *nsvg__getNextPathItem(const char *s, char *it, char cmd, int nargs) { it[0] = '\0'; // Skip white spaces and commas @@ -1297,6 +1297,15 @@ static const char *nsvg__getNextPathItem(const char *s, char *it) s++; if (!*s) return s; + + /* Blender: Special case for arc command's 4th and 5th arguments. */ + if (ELEM(cmd, 'a', 'A') && ELEM(nargs, 3, 4)) { + it[0] = s[0]; + it[1] = '\0'; + s++; + return s; + } + if (*s == '-' || *s == '+' || *s == '.' || nsvg__isdigit(*s)) { s = nsvg__parseNumber(s, it, 64); } @@ -1576,8 +1585,8 @@ static int nsvg__isCoordinate(const char *s) // optional sign if (*s == '-' || *s == '+') s++; - // must have at least one digit - return nsvg__isdigit(*s); + // must have at least one digit, or start by a dot + return (nsvg__isdigit(*s) || *s == '.'); } static NSVGcoordinate nsvg__parseCoordinateRaw(const char *str) @@ -2353,7 +2362,12 @@ static void nsvg__pathArcTo(NSVGparser *p, float *cpx, float *cpy, float *args, // The loop assumes an iteration per end point (including start and end), this +1. ndivs = (int)(fabsf(da) / (NSVG_PI * 0.5f) + 1.0f); hda = (da / (float)ndivs) / 2.0f; - kappa = fabsf(4.0f / 3.0f * (1.0f - cosf(hda)) / sinf(hda)); + // Fix for ticket #179: division by 0: avoid cotangens around 0 (infinite) + if ((hda < 1e-3f) && (hda > -1e-3f)) + hda *= 0.5f; + else + hda = (1.0f - cosf(hda)) / sinf(hda); + kappa = fabsf(4.0f / 3.0f * hda); if (da < 0.0f) kappa = -kappa; @@ -2413,7 +2427,7 @@ static void nsvg__parsePath(NSVGparser *p, const char **attr) nargs = 0; while (*s) { - s = nsvg__getNextPathItem(s, item); + s = nsvg__getNextPathItem(s, item, cmd, nargs); if (!*item) break; if (cmd != '\0' && nsvg__isCoordinate(item)) { @@ -2740,7 +2754,7 @@ static void nsvg__parsePoly(NSVGparser *p, const char **attr, int closeFlag) s = attr[i + 1]; nargs = 0; while (*s) { - s = nsvg__getNextPathItem(s, item); + s = nsvg__getNextPathItem(s, item, '\0', nargs); args[nargs++] = (float)nsvg__atof(item); if (nargs >= 2) { if (npts == 0) |