Specctra export: Fix incorrect export of holes from mirrored footprints.

If a footprint is containing a closed shape on Edges.Cuts it is exported as Hole
(keepout zone). For flipped footprints the hole was incorrect.
Fixes #8753
https://gitlab.com/kicad/code/kicad/issues/8753
This commit is contained in:
jean-pierre charras 2021-07-07 16:40:19 +02:00
parent 1e76b7808f
commit 7a1e8520ae
2 changed files with 27 additions and 12 deletions

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2007-2013 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2007-2015 KiCad Developers, see change_log.txt for contributors.
* Copyright (C) 2007-2021 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
@ -35,6 +35,7 @@
#include <specctra_import_export/specctra_lexer.h>
#include <memory>
#include <geometry/shape_poly_set.h>
// all outside the DSN namespace:
class BOARD;
@ -3634,6 +3635,7 @@ class SPECCTRA_DB : public SPECCTRA_LEXER
static const KEYWORD keywords[];
PCB* m_pcb;
SHAPE_POLY_SET m_brd_outlines; // the board outlines for DSN export
SESSION* m_session;
wxString m_filename;
std::string m_quote_char;
@ -3981,6 +3983,14 @@ public:
*/
void ExportSESSION( const wxString& aFilename );
/**
* Build the board outlines and store it in m_brd_outlines.
* Because it calls GetBoardPolygonOutlines() it *must be* called
* before flipping footprints
* @return false if the board outlines cannot be built (not closed outlines)
*/
bool BuiltBoardOutlines( BOARD* aBoard );
/**
* Function FlipFOOTPRINTs
* flips the footprints which are on the back side of the board to the front.

View File

@ -96,6 +96,12 @@ bool PCB_EDIT_FRAME::ExportSpecctraFile( const wxString& aFullFilename )
LOCALE_IO toggle; // Switch the locale to standard C
// Build the board oulines *before* flipping footprints
if( !db.BuiltBoardOutlines( GetBoard() ) )
{
wxLogWarning( _( "Board outline is malformed. Run DRC for a full analysis." ) );
}
// DSN Images (=KiCad FOOTPRINTs and PADs) must be presented from the top view. So we
// temporarily flip any footprints which are on the back side of the board to the front,
// and record this in the FOOTPRINT's flag field.
@ -229,6 +235,12 @@ static PATH* makePath( const POINT& aStart, const POINT& aEnd, const std::string
}
bool SPECCTRA_DB::BuiltBoardOutlines( BOARD* aBoard )
{
return aBoard->GetBoardPolygonOutlines( m_brd_outlines );
}
PADSTACK* SPECCTRA_DB::makePADSTACK( BOARD* aBoard, PAD* aPad )
{
char name[256]; // padstack name builder
@ -949,20 +961,13 @@ PADSTACK* SPECCTRA_DB::makeVia( const PCB_VIA* aVia )
void SPECCTRA_DB::fillBOUNDARY( BOARD* aBoard, BOUNDARY* boundary )
{
SHAPE_POLY_SET outlines;
if( !aBoard->GetBoardPolygonOutlines( outlines ) )
{
wxLogWarning( _( "Board outline is malformed. Run DRC for a full analysis." ) );
}
for( int cnt = 0; cnt < outlines.OutlineCount(); cnt++ ) // Should be one outline
for( int cnt = 0; cnt < m_brd_outlines.OutlineCount(); cnt++ ) // Should be one outline
{
PATH* path = new PATH( boundary );
boundary->paths.push_back( path );
path->layer_id = "pcb";
SHAPE_LINE_CHAIN& outline = outlines.Outline( cnt );
SHAPE_LINE_CHAIN& outline = m_brd_outlines.Outline( cnt );
for( int ii = 0; ii < outline.PointCount(); ii++ )
{
@ -975,7 +980,7 @@ void SPECCTRA_DB::fillBOUNDARY( BOARD* aBoard, BOUNDARY* boundary )
path->AppendPoint( mapPt( pos0 ) );
// Generate holes as keepout:
for( int ii = 0; ii < outlines.HoleCount( cnt ); ii++ )
for( int ii = 0; ii < m_brd_outlines.HoleCount( cnt ); ii++ )
{
// emit a signal layers keepout for every interior polygon left...
KEEPOUT* keepout = new KEEPOUT( NULL, T_keepout );
@ -985,7 +990,7 @@ void SPECCTRA_DB::fillBOUNDARY( BOARD* aBoard, BOUNDARY* boundary )
poly_ko->SetLayerId( "signal" );
m_pcb->structure->keepouts.push_back( keepout );
SHAPE_LINE_CHAIN& hole = outlines.Hole( cnt, ii );
SHAPE_LINE_CHAIN& hole = m_brd_outlines.Hole( cnt, ii );
for( int jj = 0; jj < hole.PointCount(); jj++ )
{