From 417dbadcd2e0a7a6bf3c9a4b936532f85530ad77 Mon Sep 17 00:00:00 2001 From: "Salvador E. Tropea" Date: Fri, 21 Oct 2022 13:42:29 -0300 Subject: [PATCH] [PcbDraw][PCB_Print][Fixed] SVG issues for browsers - Same fix used for SVG output --- CHANGELOG.md | 6 ++- README.md | 6 +++ docs/samples/generic_plot.kibot.yaml | 8 ++++ kibot/PcbDraw/README.md | 60 ++++++++++++++++++++++++++++ kibot/PcbDraw/plot.py | 23 +++++++++++ kibot/out_pcb_print.py | 14 +++++++ kibot/out_pcbdraw.py | 5 +++ 7 files changed, 121 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 29a9b349..f09db56e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,8 +17,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Resistor remap and flip - A `remap_components` option with better type checks - Better support for variants + - Option to control the *SVG precision* (units scale) - SVG: - Option to control the *SVG precision* (units scale) +- PCB_Print: + - Option to control the *SVG precision* (units scale) ### Changed - Diff: @@ -27,7 +30,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - QR lib update: Problems when moving the footprint to the bottom for KiCad 5. -- SVG: Problems to display the outputs using Chrome and Firefox. +- SVG, PCB_Print, PcbDraw: Problems to display the outputs using Chrome and + Firefox. ## [1.4.0] - 2022-10-12 diff --git a/README.md b/README.md index d012ffad..95512406 100644 --- a/README.md +++ b/README.md @@ -2500,6 +2500,9 @@ Notes: In order to get a good looking select a color with transparency, i.e. '#14332440'. PcbDraw must be installed in order to use this option. - `sheet_reference_layout`: [string=''] Worksheet file (.kicad_wks) to use. Leave empty to use the one specified in the project. + - `svg_precision`: [number=4] [0,6] Scale factor used to represent 1 mm in the SVG (KiCad 6). + The value is how much zeros has the multiplier (1 mm = 10 power `svg_precision` units). + Note that for an A4 paper Firefox 91 and Chrome 105 can't handle more than 5. - `title`: [string=''] Text used to replace the sheet title. %VALUE expansions are allowed. If it starts with `+` the text is concatenated. - `variant`: [string=''] Board variant to apply. @@ -2628,6 +2631,9 @@ Notes: The `kicad_all` method uses the whole size reported by KiCad. Usually includes extra space. The `svg_paths` uses all visible drawings in the image. To use this method you must install the `numpy` Python module (may not be available in docker images). + - `svg_precision`: [number=4] [0,6] Scale factor used to represent 1 mm in the SVG (KiCad 6). + The value is how much zeros has the multiplier (1 mm = 10 power `svg_precision` units). + Note that for an A4 paper Firefox 91 and Chrome 105 can't handle more than 5. - `variant`: [string=''] Board variant to apply. - `vcuts`: [boolean=false] Render V-CUTS on the `vcuts_layer` layer. - `vcuts_layer`: [string='Cmts.User'] Layer to render the V-CUTS, only used when `vcuts` is enabled. diff --git a/docs/samples/generic_plot.kibot.yaml b/docs/samples/generic_plot.kibot.yaml index 4ff66c92..4734ccfe 100644 --- a/docs/samples/generic_plot.kibot.yaml +++ b/docs/samples/generic_plot.kibot.yaml @@ -1308,6 +1308,10 @@ outputs: scaling: 1.0 # [string=''] Worksheet file (.kicad_wks) to use. Leave empty to use the one specified in the project sheet_reference_layout: '' + # [number=4] [0,6] Scale factor used to represent 1 mm in the SVG (KiCad 6). + # The value is how much zeros has the multiplier (1 mm = 10 power `svg_precision` units). + # Note that for an A4 paper Firefox 91 and Chrome 105 can't handle more than 5 + svg_precision: 4 # [string=''] Text used to replace the sheet title. %VALUE expansions are allowed. # If it starts with `+` the text is concatenated title: '' @@ -1453,6 +1457,10 @@ outputs: silk: '#d5dce4' # [string='#bf2600'] Color for the V-CUTS vcut: '#bf2600' + # [number=4] [0,6] Scale factor used to represent 1 mm in the SVG (KiCad 6). + # The value is how much zeros has the multiplier (1 mm = 10 power `svg_precision` units). + # Note that for an A4 paper Firefox 91 and Chrome 105 can't handle more than 5 + svg_precision: 4 # [string=''] Board variant to apply variant: '' # [boolean=false] Render V-CUTS on the `vcuts_layer` layer diff --git a/kibot/PcbDraw/README.md b/kibot/PcbDraw/README.md index b6ff90bd..46aadb15 100644 --- a/kibot/PcbDraw/README.md +++ b/kibot/PcbDraw/README.md @@ -246,3 +246,63 @@ index f8990722..17f90185 100644 - So we don't load it again - Changed the margin to be a tuple, so the user can control the margins individually + +- Added KiCad 6 SVG precision. + - Fixes issues with Browsers + - A plotter member controls the precision + - We adjust the ki2svg and svg2ki converters before plotting + +```diff +diff --git a/kibot/PcbDraw/plot.py b/kibot/PcbDraw/plot.py +index 01e7f523..9685d032 100644 +--- a/kibot/PcbDraw/plot.py ++++ b/kibot/PcbDraw/plot.py +@@ -1066,6 +1066,7 @@ class PcbPlotter(): + self.margin: tuple = (0, 0, 0, 0) # Margin of the resulting document + self.compute_bbox: bool = False # Adjust the bbox using the SVG drawings + self.kicad_bb_only_edge: bool = False # Use the PCB edge when asking the BBox to KiCad ++ self.svg_precision: int = 4 # KiCad 6 SVG scale (1 mm == 10 ** svg_precision) + + self.yield_warning: Callable[[str, str], None] = lambda tag, msg: None # Handle warnings + +@@ -1074,6 +1075,7 @@ class PcbPlotter(): + Plot the board based on the arguments stored in this class. Returns + SVG tree that you can either save or post-process as you wish. + """ ++ self._set_unit_conversion() + self._build_libs_path() + self._setup_document(self.render_back, self.mirror) + for plotter in self.plot_plan: +@@ -1219,6 +1221,8 @@ class PcbPlotter(): + with tempfile.TemporaryDirectory() as tmp: + pctl = pcbnew.PLOT_CONTROLLER(self.board) + popt = pctl.GetPlotOptions() ++ if isV6(KICAD_VERSION): ++ popt.SetSvgPrecision(self.svg_precision, False) + popt.SetOutputDirectory(tmp) + popt.SetScale(1) + popt.SetMirror(False) +@@ -1280,3 +1284,22 @@ class PcbPlotter(): + self._board_cont.attrib["id"] = "boardContainer" + self._comp_cont.attrib["id"] = "componentContainer" + self._high_cont.attrib["id"] = "highlightContainer" ++ ++ def _set_unit_conversion(self): ++ """ Setup the KiCad to SVG and SVG to KiCad conversions. ++ Only needed for KiCad 6 where we can select the `SVG precision` """ ++ if not isV6(KICAD_VERSION): ++ # KiCad 5 has a fixed precision ++ return ++ global ki2svg ++ global svg2ki ++ if self.svg_precision == 6: ++ # This is the default for KiCad 6, lamentably this isn't supported by ++ # Chrome and Firefox (october 2022) ++ ki2svg = (lambda x: int(x)) ++ svg2ki = (lambda x: int(x)) ++ return ++ # Not the default precision, must be 0 to 5 ++ divider = 10.0 ** (6 - self.svg_precision) ++ ki2svg = (lambda x: x / divider) ++ svg2ki = (lambda x: int(x * divider)) +``` diff --git a/kibot/PcbDraw/plot.py b/kibot/PcbDraw/plot.py index 01e7f523..9685d032 100644 --- a/kibot/PcbDraw/plot.py +++ b/kibot/PcbDraw/plot.py @@ -1066,6 +1066,7 @@ class PcbPlotter(): self.margin: tuple = (0, 0, 0, 0) # Margin of the resulting document self.compute_bbox: bool = False # Adjust the bbox using the SVG drawings self.kicad_bb_only_edge: bool = False # Use the PCB edge when asking the BBox to KiCad + self.svg_precision: int = 4 # KiCad 6 SVG scale (1 mm == 10 ** svg_precision) self.yield_warning: Callable[[str, str], None] = lambda tag, msg: None # Handle warnings @@ -1074,6 +1075,7 @@ class PcbPlotter(): Plot the board based on the arguments stored in this class. Returns SVG tree that you can either save or post-process as you wish. """ + self._set_unit_conversion() self._build_libs_path() self._setup_document(self.render_back, self.mirror) for plotter in self.plot_plan: @@ -1219,6 +1221,8 @@ class PcbPlotter(): with tempfile.TemporaryDirectory() as tmp: pctl = pcbnew.PLOT_CONTROLLER(self.board) popt = pctl.GetPlotOptions() + if isV6(KICAD_VERSION): + popt.SetSvgPrecision(self.svg_precision, False) popt.SetOutputDirectory(tmp) popt.SetScale(1) popt.SetMirror(False) @@ -1280,3 +1284,22 @@ class PcbPlotter(): self._board_cont.attrib["id"] = "boardContainer" self._comp_cont.attrib["id"] = "componentContainer" self._high_cont.attrib["id"] = "highlightContainer" + + def _set_unit_conversion(self): + """ Setup the KiCad to SVG and SVG to KiCad conversions. + Only needed for KiCad 6 where we can select the `SVG precision` """ + if not isV6(KICAD_VERSION): + # KiCad 5 has a fixed precision + return + global ki2svg + global svg2ki + if self.svg_precision == 6: + # This is the default for KiCad 6, lamentably this isn't supported by + # Chrome and Firefox (october 2022) + ki2svg = (lambda x: int(x)) + svg2ki = (lambda x: int(x)) + return + # Not the default precision, must be 0 to 5 + divider = 10.0 ** (6 - self.svg_precision) + ki2svg = (lambda x: x / divider) + svg2ki = (lambda x: int(x * divider)) diff --git a/kibot/out_pcb_print.py b/kibot/out_pcb_print.py index dcbc2402..0703433c 100644 --- a/kibot/out_pcb_print.py +++ b/kibot/out_pcb_print.py @@ -292,6 +292,10 @@ class PCB_PrintOptions(VariantOptions): """ Color for the background when `add_background` is enabled """ self.background_image = '' """ Background image, must be an SVG, only when `add_background` is enabled """ + self.svg_precision = 4 + """ [0,6] Scale factor used to represent 1 mm in the SVG (KiCad 6). + The value is how much zeros has the multiplier (1 mm = 10 power `svg_precision` units). + Note that for an A4 paper Firefox 91 and Chrome 105 can't handle more than 5 """ add_drill_marks(self) super().__init__() self._expand_id = 'assembly' @@ -773,6 +777,7 @@ class PCB_PrintOptions(VariantOptions): plotter.yield_warning = pcbdraw_warnings plotter.render_back = back plotter.plot_plan = [PlotSubstrate(only_mask=True)] + plotter.svg_precision = self.svg_precision image = plotter.plot() except (RuntimeError, SyntaxError, IOError) as e: logger.error('PcbDraw error: '+str(e)) @@ -812,6 +817,13 @@ class PCB_PrintOptions(VariantOptions): # KiCad 5 uses a different precision, we must adjust board_center.x = round(board_center.x*KICAD5_SVG_SCALE) board_center.y = round(board_center.y*KICAD5_SVG_SCALE) + elif self.svg_precision != 6: + # KiCad 6 can adjust the precision + # The default is 6 and makes 1 KiCad unit == 1 SVG unit + # But this isn't supported by browsers (Chrome and Firefox) + divider = 10.0 ** (6 - self.svg_precision) + board_center.x = round(board_center.x/divider) + board_center.y = round(board_center.y/divider) offset_x = round((board_center.x*scale-(paper_size_x/2.0))/scale) offset_y = round((board_center.y*scale-(paper_size_y/2.0))/scale) if mirror: @@ -973,6 +985,8 @@ class PCB_PrintOptions(VariantOptions): po.SetExcludeEdgeLayer(True) # We plot it separately po.SetUseAuxOrigin(False) po.SetAutoScale(False) + if GS.ki6: + po.SetSvgPrecision(self.svg_precision, False) # Helpers for force_edge_cuts if self.force_edge_cuts: edge_layer = LayerOptions.create_layer('Edge.Cuts') diff --git a/kibot/out_pcbdraw.py b/kibot/out_pcbdraw.py index bee7bacb..2514f986 100644 --- a/kibot/out_pcbdraw.py +++ b/kibot/out_pcbdraw.py @@ -261,6 +261,10 @@ class PcbDrawOptions(VariantOptions): The `kicad_all` method uses the whole size reported by KiCad. Usually includes extra space. The `svg_paths` uses all visible drawings in the image. To use this method you must install the `numpy` Python module (may not be available in docker images) """ + self.svg_precision = 4 + """ [0,6] Scale factor used to represent 1 mm in the SVG (KiCad 6). + The value is how much zeros has the multiplier (1 mm = 10 power `svg_precision` units). + Note that for an A4 paper Firefox 91 and Chrome 105 can't handle more than 5 """ super().__init__() def config(self, parent): @@ -421,6 +425,7 @@ class PcbDrawOptions(VariantOptions): plotter.render_back = self.bottom plotter.mirror = self.mirror plotter.margin = self.margin + plotter.svg_precision = self.svg_precision if self.style: if isinstance(self.style, str): plotter.resolve_style(self.style)