From 1f088984cee15a066a450150686cad8c4f8c0601 Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Mon, 16 May 2022 10:24:13 +0200 Subject: [PATCH] gerber_placefile_writer: fix angle rotation for flipped footprints. According to latest Gerber documents (rev 2022.02), the previous angle was missing a +180 rotation Fixes #11621 https://gitlab.com/kicad/code/kicad/issues/11621 --- pcbnew/exporters/gerber_placefile_writer.cpp | 28 +++++++++++++++++--- pcbnew/exporters/gerber_placefile_writer.h | 9 +++++-- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/pcbnew/exporters/gerber_placefile_writer.cpp b/pcbnew/exporters/gerber_placefile_writer.cpp index 78c55ed7c6..1c1b95c62d 100644 --- a/pcbnew/exporters/gerber_placefile_writer.cpp +++ b/pcbnew/exporters/gerber_placefile_writer.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2019 Jean_Pierre Charras - * Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -142,7 +142,8 @@ int PLACEFILE_GERBER_WRITER::CreatePlaceFile( wxString& aFullFilename, PCB_LAYER GBR_CMP_PNP_METADATA pnpAttrib; // Add rotation info (rotation is CCW, in degrees): - pnpAttrib.m_Orientation = mapRotationAngle( footprint->GetOrientationDegrees() ); + pnpAttrib.m_Orientation = mapRotationAngle( footprint->GetOrientationDegrees(), + aLayer == B_Cu ? true : false ); pnpAttrib.m_MountType = GBR_CMP_PNP_METADATA::MOUNT_TYPE_UNSPECIFIED; @@ -315,10 +316,29 @@ int PLACEFILE_GERBER_WRITER::CreatePlaceFile( wxString& aFullFilename, PCB_LAYER } -double PLACEFILE_GERBER_WRITER::mapRotationAngle( double aAngle ) +double PLACEFILE_GERBER_WRITER::mapRotationAngle( double aAngle, bool aIsFlipped ) { // Convert a KiCad footprint orientation to gerber rotation, depending on the layer - // Currently, same notation as KiCad. + // Gerber rotation is: + // rot angle > 0 for rot CW, seen from Top side + // same a Pcbnew for Top side + // (angle + 180) for Bottom layer i.e flipped around Y axis: X axis coordinates mirrored. + // because Pcbnew flip around the X axis : Y coord mirrored, that is similar to mirror + // around Y axis + 180 deg rotation + if( aIsFlipped ) + { + double gbr_angle = 180.0 + aAngle; + + // Normalize between -180 ... + 180 deg + // Not mandatory, but the angle is more easy to read + if( gbr_angle <= -180 ) + gbr_angle += 360.0; + else if( gbr_angle > 180 ) + gbr_angle -= 360.0; + + return gbr_angle; + } + return aAngle; } diff --git a/pcbnew/exporters/gerber_placefile_writer.h b/pcbnew/exporters/gerber_placefile_writer.h index 8b3e1ff34f..c72ef9675b 100644 --- a/pcbnew/exporters/gerber_placefile_writer.h +++ b/pcbnew/exporters/gerber_placefile_writer.h @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2019 Jean_Pierre Charras - * Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -80,8 +80,13 @@ public: private: /** * Convert a KiCad footprint orientation to gerber rotation both are in degrees. + * @param aAngle is the Pcbnew angle in degrees + * @param aIsFlipped = false for footprints on top side, true on bottom side (flipped) + * @return the angle in degrees in Gerber convention: + * same as Pcbnew for top side + * 180 + angle for bottom side */ - double mapRotationAngle( double aAngle ); + double mapRotationAngle( double aAngle, bool aIsFlipped ); /** * Find the pad(s) 1 (or pad "A1") of a footprint.