Gerbview: fix some issues related to comments and primitives in macros:

- comments on more than one line were not fully skipped, creating read errors
- in macros, some primitives (not all) were incorrectly rotated: they must be
rotated around the aperture macro origin, not the primitive origin.
- a new test file with rotated primitives in macros is added.
Fixes #16049
https://gitlab.com/kicad/code/kicad/-/issues/16049
This commit is contained in:
jean-pierre charras 2023-11-08 10:45:13 +01:00
parent 7abe2e3ea0
commit 72ce955066
6 changed files with 162 additions and 30 deletions

View File

@ -92,6 +92,7 @@ void AM_PRIMITIVE::ConvertBasicShapeToPolygon( APERTURE_MACRO* aApertMacro,
SHAPE_POLY_SET& aShapeBuffer )
{
// Draw the primitive shape for flashed items.
// Note: rotation of primitives inside a macro must be always done around the macro origin.
// Create a static buffer to avoid a lot of memory reallocation.
static std::vector<VECTOR2I> polybuffer;
polybuffer.clear();
@ -218,15 +219,17 @@ void AM_PRIMITIVE::ConvertBasicShapeToPolygon( APERTURE_MACRO* aApertMacro,
for( int ii = 0; ii < 4; ii++ )
{
polybuffer = subshape_poly;
EDA_ANGLE sub_rotation = rotation + ANGLE_90 * ii;
EDA_ANGLE sub_rotation = ANGLE_90 * ii;
for( unsigned jj = 0; jj < polybuffer.size(); jj++ )
RotatePoint( polybuffer[jj], -sub_rotation );
// Move to center position given by the tool:
// Move to center position given by the tool, and rotate the full shape around
// the center position (origin of the macro):
for( unsigned jj = 0; jj < polybuffer.size(); jj++ )
{
polybuffer[jj] += center;
RotatePoint( polybuffer[jj], -rotation );
}
aShapeBuffer.NewOutline();
@ -264,6 +267,8 @@ void AM_PRIMITIVE::ConvertBasicShapeToPolygon( APERTURE_MACRO* aApertMacro,
VECTOR2I center( mapPt( m_Params[0].GetValueFromMacro( aApertMacro ),
m_Params[1].GetValueFromMacro( aApertMacro ), m_GerbMetric ) );
EDA_ANGLE rotation( m_Params[8].GetValueFromMacro( aApertMacro ), DEGREES_T );
// adjust outerDiam by this on each nested circle
int diamAdjust = ( gap + penThickness ) * 2;
@ -272,17 +277,21 @@ void AM_PRIMITIVE::ConvertBasicShapeToPolygon( APERTURE_MACRO* aApertMacro,
if( outerDiam <= 0 )
break;
// calculate the rotated position of the center:
VECTOR2I circle_center = center;
RotatePoint( circle_center, -rotation );
// Note: outerDiam is the outer diameter of the ring.
// the ring graphic diameter is (outerDiam - penThickness)
if( outerDiam <= penThickness )
{ // No room to draw a ring (no room for the hole):
// draw a circle instead (with no hole), with the right diameter
TransformCircleToPolygon( aShapeBuffer, center, outerDiam / 2, arc_to_seg_error,
TransformCircleToPolygon( aShapeBuffer, circle_center, outerDiam / 2, arc_to_seg_error,
ERROR_INSIDE );
}
else
{
TransformRingToPolygon( aShapeBuffer, center, ( outerDiam - penThickness ) / 2,
TransformRingToPolygon( aShapeBuffer, circle_center, ( outerDiam - penThickness ) / 2,
penThickness, arc_to_seg_error, ERROR_INSIDE );
}
}
@ -290,13 +299,11 @@ void AM_PRIMITIVE::ConvertBasicShapeToPolygon( APERTURE_MACRO* aApertMacro,
// Draw the cross:
ConvertShapeToPolygon( aApertMacro, polybuffer );
EDA_ANGLE rotation( m_Params[8].GetValueFromMacro( aApertMacro ), DEGREES_T );
for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
{
// move crossair shape to center and rotate shape:
RotatePoint( polybuffer[ii], -rotation );
polybuffer[ii] += center;
RotatePoint( polybuffer[ii], -rotation );
}
break;
@ -375,13 +382,13 @@ void AM_PRIMITIVE::ConvertBasicShapeToPolygon( APERTURE_MACRO* aApertMacro,
// Creates the shape:
ConvertShapeToPolygon( aApertMacro, polybuffer );
// rotate polygon
// move and rotate polygonal shape
EDA_ANGLE rotation( m_Params[5].GetValueFromMacro( aApertMacro ), DEGREES_T );
for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
{
RotatePoint( polybuffer[ii], -rotation );
polybuffer[ii] += curPos;
RotatePoint( polybuffer[ii], -rotation );
}
break;

View File

@ -99,6 +99,10 @@ public:
// and the actual coordinates calculation must handle this
};
// size of a single line of text from a gerber file.
// warning: some files can have *very long* lines, so the buffer must be large.
#define GERBER_BUFZ 1000000
/**
* Hold the image data and parameters for one gerber file and layer parameters.
*
@ -469,6 +473,9 @@ public:
VECTOR2I m_DisplayOffset;
EDA_ANGLE m_DisplayRotation;
// A large buffer to store one line
static char m_LineBuffer[GERBER_BUFZ+1];
private:
wxArrayString m_messagesList; // A list of messages created when reading a file

View File

@ -0,0 +1,125 @@
G04 ================================================================================================
Copyright (C) 2023 Tony Luken <tonyluken62+gerberfileparser.gmail.com>
This file is part of GerberFileParser.
GerberFileParser is free software: you can redistribute it and/or modify it under the terms of
the GNU General Public License as published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
GerberFileParser is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with GerberFileParser. If
not, see <http://www.gnu.org/licenses/>.
===================================================================================================*
G04 Demonstrate rotation of all macro primitives*
G04 Set coordinate format and units*
%FSLAX26Y26*%
%MOMM*%
G04 Demo Circle Primitive*
%AMSomeCircles*
0 1, Exposure, Diameter, Center X, Center Y[, Rotation]*
1,1,4,8,-5,0*
1,1,4,8,-5,120*
1,1,4,8,-5,240*
%
G04 Demo Polygon Primitive*
%AMSomePolygons*
0 5, Exposure, # vertices, Center X, Center Y, Diameter, Rotation*
5,1,5,7,8,7.5,0*
5,1,5,7,8,7.5,120*
5,1,5,7,8,7.5,240*
%
G04 Demo Thermal Primitive*
%AMSomeThermals*
0 7, Center X, Center Y, Outer diameter, Inner diameter, Gap, Rotation*
7,-15,-5,3,2,0.5,0*
7,-15,-5,3,2,0.5,120*
7,-15,-5,3,2,0.5,-120*
%
G04 Demo Outline Primitive*
%AMSomeOutlines*
0 4, Exposure, # vertices, Start X, Start Y, Subsequent points..., Rotation*
4,1,3,15,2,15,5,19,2,15,2,0*
4,1,3,15,2,15,5,19,2,15,2,120*
4,1,3,15,2,15,5,19,2,15,2,240*
%
G04 Demo deprecated Lower Left Line Primitive*
%AMSomeLowerLeftLines*
0 22, Exposure, Width, Height, Lower Left X, Lower Left Y, Rotation*
22,1,20,3,-10,-25,0*
22,1,20,3,-10,-25,120*
22,1,20,3,-10,-25,240*
%
G04 Demo Center Line Primitive*
%AMSomeCenterLines*
0 21, Exposure, width, height, center X, center Y, rotation*
21,1,13,1.5,2,20,0*
21,1,13,1.5,2,20,120*
21,1,13,1.5,2,20,-120*
%
G04 Demo Vector Line Primitive including deprecated version (2)*
%AMSomeVectorLines*
0 20 (or 2), Exposure , Width, Start X, Start Y, End X, End Y, Rotation*
20,1,1.5,-2,2,-6,7,0*
20,1,1.5,-2,2,-6,7,120*
2,1,1.5,-2,2,-6,7,240*
%
G04 Demo deprecated Moire Primitive*
%AMSomeMoires*
0 6, Center X, Center Y, Outer Diameter, Ring Thickness, Ring Gap, Max #Rings,
Crosshair Thickness, Crosshair Length, Rotation*
6,3,-17,5,0.5,0.5,2,0.1,6,0*
6,3,-17,5,0.5,0.5,2,0.1,6,120*
6,3,-17,5,0.5,0.5,2,0.1,6,-120*
%
%ADD10SomeCircles*%
%ADD11SomePolygons*%
%ADD12SomeThermals*%
%ADD13SomeOutlines*%
%ADD14SomeLowerLeftLines*%
%ADD15SomeCenterLines*%
%ADD16SomeVectorLines*%
%ADD17SomeMoires*%
G01*
%LPD*%
D10*
X0Y0D03*
D11*
X0Y0D03*
D12*
X0Y0D03*
D13*
X0Y0D03*
D14*
X0Y0D03*
D15*
X0Y0D03*
D16*
X0Y0D03*
D17*
X0Y0D03*
M02*

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2007-2016 Jean-Pierre Charras jp.charras at wanadoo.fr
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2023 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
@ -224,11 +224,9 @@ bool GERBER_FILE_IMAGE::TestFileIsRS274( const wxString& aFullFileName )
return false;
}
// size of a single line of text from a gerber file.
// warning: some files can have *very long* lines, so the buffer must be large.
#define GERBER_BUFZ 1000000
// A large buffer to store one line
static char lineBuffer[GERBER_BUFZ+1];
char GERBER_FILE_IMAGE::m_LineBuffer[GERBER_BUFZ+1];
bool GERBER_FILE_IMAGE::LoadGerberFile( const wxString& aFullFileName )
{
@ -253,11 +251,11 @@ bool GERBER_FILE_IMAGE::LoadGerberFile( const wxString& aFullFileName )
while( true )
{
if( fgets( lineBuffer, GERBER_BUFZ, m_Current_File ) == nullptr )
if( fgets( m_LineBuffer, GERBER_BUFZ, m_Current_File ) == nullptr )
break;
m_LineNum++;
text = StrPurge( lineBuffer );
text = StrPurge( m_LineBuffer );
while( text && *text )
{
@ -314,7 +312,7 @@ bool GERBER_FILE_IMAGE::LoadGerberFile( const wxString& aFullFileName )
if( m_CommandState != ENTER_RS274X_CMD )
{
m_CommandState = ENTER_RS274X_CMD;
ReadRS274XCommand( lineBuffer, GERBER_BUFZ, text );
ReadRS274XCommand( m_LineBuffer, GERBER_BUFZ, text );
}
else //Error
{

View File

@ -1,8 +1,3 @@
/**
* @file rs274d.cpp
* @brief functions to read the rs274d commands from a rs274d/rs274x file
*/
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
@ -26,6 +21,11 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @brief functions to read the rs274d commands from a rs274d/rs274x file
*/
#include <gerbview.h>
#include <gerbview_frame.h>
#include <trigo.h>
@ -464,8 +464,7 @@ bool GERBER_FILE_IMAGE::Execute_G_Command( char*& text, int G_command )
ExecuteRS274XCommand( code_command, nullptr, 0, cptr );
}
while( *text && (*text != '*') )
text++;
GetEndOfBlock( m_LineBuffer, GERBER_BUFZ, text, m_Current_File );
break;

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2007-2018 Jean-Pierre Charras jp.charras at wanadoo.fr
* Copyright (C) 1992-2018 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2023 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
@ -22,9 +22,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file rs274x.cpp
*/
#include <base_units.h>
#include <math/util.h> // for KiROUND
@ -1049,8 +1046,7 @@ bool GERBER_FILE_IMAGE::ReadApertureMacro( char *aBuff, unsigned int aBuffSize,
is_comment = true;
// Skip comment
while( *aText && ( *aText != '*' ) )
aText++;
GetEndOfBlock( m_LineBuffer, GERBER_BUFZ, aText, m_Current_File );
break;