From f77db7b4b9d982c4a733e2c95dd82c892c873362 Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Tue, 16 May 2017 12:59:22 +0200 Subject: [PATCH] Fixes: lp:1690840 (Pcbnew crashes when creating a drill file) https://bugs.launchpad.net/kicad/+bug/1690840 --- .../exporters/gendrill_file_writer_base.cpp | 16 ++++++++------ pcbnew/exporters/gendrill_gerber_writer.cpp | 21 ++++++++++++++++++- 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/pcbnew/exporters/gendrill_file_writer_base.cpp b/pcbnew/exporters/gendrill_file_writer_base.cpp index b58ad93b7f..005e27652e 100644 --- a/pcbnew/exporters/gendrill_file_writer_base.cpp +++ b/pcbnew/exporters/gendrill_file_writer_base.cpp @@ -50,14 +50,18 @@ static bool CmpHoleSorting( const HOLE_INFO& a, const HOLE_INFO& b ) if( pada && padb ) { - if( pada->GetParent()->GetReference().Cmp( padb->GetParent()->GetReference() ) != 0 ) - return pada->GetParent()->GetReference().Cmp( padb->GetParent()->GetReference() ) < 0; + // cmp == 0 means the pads have the same parent, therfore the same reference + int cmp = pada->GetParent() - padb->GetParent(); + + if( cmp ) + return cmp < 0; + } + else if( pada || padb ) // in this case, other item is a via. Sort via first + { + return padb != nullptr; } - else if( pada || padb ) - return true; - - // At this point, holes are via holes: sort by position + // At this point, sort by position, as last sort criteria if( a.m_Hole_Pos.x != b.m_Hole_Pos.x ) return a.m_Hole_Pos.x < b.m_Hole_Pos.x; diff --git a/pcbnew/exporters/gendrill_gerber_writer.cpp b/pcbnew/exporters/gendrill_gerber_writer.cpp index 3725827844..6d412dbc72 100644 --- a/pcbnew/exporters/gendrill_gerber_writer.cpp +++ b/pcbnew/exporters/gendrill_gerber_writer.cpp @@ -220,6 +220,7 @@ int GERBER_WRITER::createDrillFile( wxString& aFullFilename, bool aIsNpth, holes_count = 0; wxPoint hole_pos; + bool last_item_is_via = true; // a flag to clear object attributes when a via hole is created. for( unsigned ii = 0; ii < m_holeListBuffer.size(); ii++ ) { @@ -233,9 +234,21 @@ int GERBER_WRITER::createDrillFile( wxString& aFullFilename, bool aIsNpth, GBR_METADATA gbr_metadata; if( dyn_cast(hole_descr.m_ItemParent ) ) + { gbr_metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_VIADRILL ); + + if( !last_item_is_via ) + { + // be sure the current object attribute is cleared for vias + plotter.EndBlock( NULL ); + } + + last_item_is_via = true; + } else if( dyn_cast( hole_descr.m_ItemParent ) ) { + last_item_is_via = false; + if( hole_descr.m_Hole_Shape ) gbr_metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_SLOTDRILL ); else @@ -243,7 +256,13 @@ int GERBER_WRITER::createDrillFile( wxString& aFullFilename, bool aIsNpth, // Add object attribute: component reference to pads (mainly usefull for users) const D_PAD* pad = dyn_cast( hole_descr.m_ItemParent ); - gbr_metadata.SetCmpReference( pad->GetParent()->GetReference() ); + wxString ref = pad->GetParent()->GetReference(); + +#if 0 // Set to 1 to force a dummy reference for the parent pad. + if( ref.IsEmpty() ) + ref = ""; +#endif + gbr_metadata.SetCmpReference( ref ); gbr_metadata.SetNetAttribType( GBR_NETLIST_METADATA::GBR_NETINFO_CMP ); }