30350n / pcb2blender

KiCad to Blender 3D model workflow
GNU General Public License v3.0
546 stars 12 forks source link

Plugin crash in KiCad 7.0.0 #11

Closed oliv33bx closed 1 year ago

oliv33bx commented 1 year ago

once installed well, the export plugin doesn't work with the latest version of KiCad 7.0.0

set-soft commented 1 year ago

KiBot can export pcb3d files using code based on this project. It can currently do it for KiCad 7 (dev branch, not yet released because KiCad 7.0.0 has some important bugs in the Python API). While adapting the code I remember I had to:

30350n commented 1 year ago

Fixed in v2.2, thanks a lot! Thanks for the hints @set-soft. Getting the svg bounding boxes right again took some more work actually, not sure how you implemented it in KiBot, but here and here is the relevant code if you want to check it out.

oliv33bx commented 1 year ago

Thanks @30350n for the new version of exporter-importer. However, I tried to install the importer plugin in blender 3.4 but it does not appear in the plugin list.

set-soft commented 1 year ago

Fixed in v2.2, thanks a lot! Thanks for the hints @set-soft. Getting the svg bounding boxes right again took some more work actually, not sure how you implemented it in KiBot, but here and here is the relevant code if you want to check it out.

Your code looks ok to me. KiBot uses its own code to generate the SVG, not the code from PCB2Blender.

The SVG is just another output format. So the code is different. It computes the bounding box using KiCad IUs (internal Units) and then converts it to SVG units.

The conversion support KiCad 5.1, 6.0 and 7.0. All of them uses different SVG units, in 6.0 they are configurable.

The relevant code is:

        # Limit the view box of the SVG
        bbox = GS.get_rect_for(GS.board.ComputeBoundingBox(self.size_detection == 'kicad_edge'))
        # Apply the margin (left right top bottom)
        bbox = (bbox[0]-self.margin[0], bbox[1]-self.margin[2],
                bbox[2]+self.margin[0]+self.margin[1], bbox[3]+self.margin[2]+self.margin[3])
        # Width/height of the used area in cm
        width = ToMM(bbox[2])*0.1
        height = ToMM(bbox[3])*0.1
        # Scale factor to convert KiCad IU to the SVG units
        bbox = GS.iu_to_svg(bbox, self.svg_precision)
        logger.debug('Adjusting SVG viewBox to {} for width {} cm and height {} cm'.format(bbox, width, height))
        for f in self._generated_files.values():
            fname = os.path.join(output_dir, f)
            logger.debugl(2, '- '+f)
            change_svg_viewbox(fname, bbox, width, height)

And the SVG patcher:

SVG_VIEW_BOX_REGEX2 = r'width="(.*)" height="(.*)" viewBox="(\S+) (\S+) (\S+) (\S+)"'
SVG_VIEW_BOX_SUB_PAT = r'width="{}cm" height="{}cm" viewBox="{} {} {} {}"'

def change_svg_viewbox(file, view_box, w, h):
    with open(file, 'rt') as f:
        text = f.read()
    text = re.sub(SVG_VIEW_BOX_REGEX2, SVG_VIEW_BOX_SUB_PAT.format(w, h, view_box[0], view_box[1], view_box[2], view_box[3]),
                  text)
    with open(file, 'wt') as f:
        f.write(text)

I keep the width and height in cm to generate files as similar as possible to the originals.