Cleanup Graphics to parallel Cleanup Tracks & Vias.
This also allows for easier migration to DRAWSEGMENT::S_RECTs by auto-converting 4 rectilinear lines to a rectangle.
This commit is contained in:
parent
a3cab09fb4
commit
a7703d1207
|
@ -108,6 +108,8 @@ KIID RC_TREE_MODEL::ToUUID( wxDataViewItem aItem )
|
|||
|
||||
case RC_TREE_NODE::MAIN_ITEM: return rc_item->GetMainItemID();
|
||||
case RC_TREE_NODE::AUX_ITEM: return rc_item->GetAuxItemID();
|
||||
case RC_TREE_NODE::AUX_ITEM2: return rc_item->GetAuxItem2ID();
|
||||
case RC_TREE_NODE::AUX_ITEM3: return rc_item->GetAuxItem3ID();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -162,16 +164,22 @@ void RC_TREE_MODEL::rebuildModel( RC_ITEMS_PROVIDER* aProvider, int aSeverities
|
|||
|
||||
for( int i = 0; m_rcItemsProvider && i < m_rcItemsProvider->GetCount(); ++i )
|
||||
{
|
||||
RC_ITEM* drcItem = m_rcItemsProvider->GetItem( i );
|
||||
RC_ITEM* rcItem = m_rcItemsProvider->GetItem( i );
|
||||
|
||||
m_tree.push_back( new RC_TREE_NODE( nullptr, drcItem, RC_TREE_NODE::MARKER ) );
|
||||
m_tree.push_back( new RC_TREE_NODE( nullptr, rcItem, RC_TREE_NODE::MARKER ) );
|
||||
RC_TREE_NODE* n = m_tree.back();
|
||||
|
||||
if( drcItem->GetMainItemID() != niluuid )
|
||||
n->m_Children.push_back( new RC_TREE_NODE( n, drcItem, RC_TREE_NODE::MAIN_ITEM ) );
|
||||
if( rcItem->GetMainItemID() != niluuid )
|
||||
n->m_Children.push_back( new RC_TREE_NODE( n, rcItem, RC_TREE_NODE::MAIN_ITEM ) );
|
||||
|
||||
if( drcItem->GetAuxItemID() != niluuid )
|
||||
n->m_Children.push_back( new RC_TREE_NODE( n, drcItem, RC_TREE_NODE::AUX_ITEM ) );
|
||||
if( rcItem->GetAuxItemID() != niluuid )
|
||||
n->m_Children.push_back( new RC_TREE_NODE( n, rcItem, RC_TREE_NODE::AUX_ITEM ) );
|
||||
|
||||
if( rcItem->GetAuxItem2ID() != niluuid )
|
||||
n->m_Children.push_back( new RC_TREE_NODE( n, rcItem, RC_TREE_NODE::AUX_ITEM2 ) );
|
||||
|
||||
if( rcItem->GetAuxItem3ID() != niluuid )
|
||||
n->m_Children.push_back( new RC_TREE_NODE( n, rcItem, RC_TREE_NODE::AUX_ITEM3 ) );
|
||||
}
|
||||
|
||||
// Must be called after a significant change of items to force the
|
||||
|
@ -256,11 +264,16 @@ void RC_TREE_MODEL::GetValue( wxVariant& aVariant,
|
|||
{
|
||||
case RC_TREE_NODE::MARKER:
|
||||
{
|
||||
bool excluded = rcItem->GetParent() && rcItem->GetParent()->IsExcluded();
|
||||
bool error = m_editFrame->GetSeverity( rcItem->GetErrorCode() ) == RPT_SEVERITY_ERROR;
|
||||
wxString prefix = wxString::Format( wxT( "%s%s" ),
|
||||
excluded ? _( "Excluded " ) : wxString( "" ),
|
||||
error ? _( "Error: " ) : _( "Warning: " ) );
|
||||
wxString prefix;
|
||||
|
||||
if( rcItem->GetParent() && rcItem->GetParent()->IsExcluded() )
|
||||
prefix = _( "Excluded " );
|
||||
|
||||
switch( m_editFrame->GetSeverity( rcItem->GetErrorCode() ) )
|
||||
{
|
||||
case RPT_SEVERITY_ERROR: prefix += _( "Error: " ); break;
|
||||
case RPT_SEVERITY_WARNING: prefix += _( "Warning: " ); break;
|
||||
}
|
||||
|
||||
aVariant = prefix + rcItem->GetErrorMessage();
|
||||
}
|
||||
|
@ -269,22 +282,28 @@ void RC_TREE_MODEL::GetValue( wxVariant& aVariant,
|
|||
case RC_TREE_NODE::MAIN_ITEM:
|
||||
{
|
||||
EDA_ITEM* item = m_editFrame->GetItem( rcItem->GetMainItemID() );
|
||||
|
||||
if( item )
|
||||
aVariant = item->GetSelectMenuText( m_editFrame->GetUserUnits() );
|
||||
else
|
||||
aVariant = _( "item not found (Please, rerun ERC)" );
|
||||
}
|
||||
break;
|
||||
|
||||
case RC_TREE_NODE::AUX_ITEM:
|
||||
{
|
||||
EDA_ITEM* item = m_editFrame->GetItem( rcItem->GetAuxItemID() );
|
||||
|
||||
if( item )
|
||||
aVariant = item->GetSelectMenuText( m_editFrame->GetUserUnits() );
|
||||
else
|
||||
aVariant = _( "item not found (Please, rerun ERC)" );
|
||||
}
|
||||
break;
|
||||
|
||||
case RC_TREE_NODE::AUX_ITEM2:
|
||||
{
|
||||
EDA_ITEM* item = m_editFrame->GetItem( rcItem->GetAuxItem2ID() );
|
||||
aVariant = item->GetSelectMenuText( m_editFrame->GetUserUnits() );
|
||||
}
|
||||
break;
|
||||
|
||||
case RC_TREE_NODE::AUX_ITEM3:
|
||||
{
|
||||
EDA_ITEM* item = m_editFrame->GetItem( rcItem->GetAuxItem3ID() );
|
||||
aVariant = item->GetSelectMenuText( m_editFrame->GetUserUnits() );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -82,6 +82,8 @@ protected:
|
|||
MARKER_BASE* m_parent; // The marker this item belongs to, if any
|
||||
KIID m_mainItemUuid;
|
||||
KIID m_auxItemUuid;
|
||||
KIID m_auxItem2Uuid;
|
||||
KIID m_auxItem3Uuid;
|
||||
|
||||
public:
|
||||
|
||||
|
@ -91,6 +93,8 @@ public:
|
|||
m_parent = nullptr;
|
||||
m_mainItemUuid = niluuid;
|
||||
m_auxItemUuid = niluuid;
|
||||
m_auxItem2Uuid = niluuid;
|
||||
m_auxItem3Uuid = niluuid;
|
||||
}
|
||||
|
||||
RC_ITEM( RC_ITEM* aItem )
|
||||
|
@ -100,28 +104,42 @@ public:
|
|||
m_parent = aItem->m_parent;
|
||||
m_mainItemUuid = aItem->m_mainItemUuid;
|
||||
m_auxItemUuid = aItem->m_auxItemUuid;
|
||||
m_auxItem2Uuid = aItem->m_auxItem2Uuid;
|
||||
m_auxItem3Uuid = aItem->m_auxItem3Uuid;
|
||||
}
|
||||
|
||||
virtual ~RC_ITEM() { }
|
||||
|
||||
void SetErrorMessage( const wxString& aMessage ) { m_errorMessage = aMessage; }
|
||||
|
||||
void SetItems( EDA_ITEM* aItem, EDA_ITEM* bItem = nullptr )
|
||||
void SetItems( EDA_ITEM* aItem, EDA_ITEM* bItem = nullptr, EDA_ITEM* cItem = nullptr,
|
||||
EDA_ITEM* dItem = nullptr )
|
||||
{
|
||||
m_mainItemUuid = aItem->m_Uuid;
|
||||
|
||||
if( bItem )
|
||||
m_auxItemUuid = bItem->m_Uuid;
|
||||
|
||||
if( cItem )
|
||||
m_auxItem2Uuid = cItem->m_Uuid;
|
||||
|
||||
if( dItem )
|
||||
m_auxItem3Uuid = dItem->m_Uuid;
|
||||
}
|
||||
|
||||
void SetItems( const KIID& aItem, const KIID& bItem = niluuid )
|
||||
void SetItems( const KIID& aItem, const KIID& bItem = niluuid, const KIID& cItem = niluuid,
|
||||
const KIID& dItem = niluuid )
|
||||
{
|
||||
m_mainItemUuid = aItem;
|
||||
m_auxItemUuid = bItem;
|
||||
m_auxItem2Uuid = cItem;
|
||||
m_auxItem3Uuid = dItem;
|
||||
}
|
||||
|
||||
KIID GetMainItemID() const { return m_mainItemUuid; }
|
||||
KIID GetAuxItemID() const { return m_auxItemUuid; }
|
||||
KIID GetAuxItem2ID() const { return m_auxItem2Uuid; }
|
||||
KIID GetAuxItem3ID() const { return m_auxItem3Uuid; }
|
||||
|
||||
void SetParent( MARKER_BASE* aMarker ) { m_parent = aMarker; }
|
||||
MARKER_BASE* GetParent() const { return m_parent; }
|
||||
|
@ -161,7 +179,7 @@ public:
|
|||
class RC_TREE_NODE
|
||||
{
|
||||
public:
|
||||
enum NODE_TYPE { MARKER, MAIN_ITEM, AUX_ITEM };
|
||||
enum NODE_TYPE { MARKER, MAIN_ITEM, AUX_ITEM, AUX_ITEM2, AUX_ITEM3 };
|
||||
|
||||
RC_TREE_NODE( RC_TREE_NODE* aParent, RC_ITEM* aRcItem, NODE_TYPE aType ) :
|
||||
m_Type( aType ),
|
||||
|
|
|
@ -41,6 +41,44 @@
|
|||
#include <wx/filename.h>
|
||||
#include "erc_item.h"
|
||||
|
||||
|
||||
/**
|
||||
* A singleton item of this class is returned for a weak reference that no longer exists.
|
||||
* Its sole purpose is to flag the item as having been deleted.
|
||||
*/
|
||||
class DELETED_SHEET_ITEM : public SCH_ITEM
|
||||
{
|
||||
public:
|
||||
DELETED_SHEET_ITEM() :
|
||||
SCH_ITEM( nullptr, NOT_USED )
|
||||
{}
|
||||
|
||||
wxString GetSelectMenuText( EDA_UNITS aUnits ) const override
|
||||
{
|
||||
return _( "(Deleted Item)" );
|
||||
}
|
||||
|
||||
wxString GetClass() const override
|
||||
{
|
||||
return wxT( "DELETED_SHEET_ITEM" );
|
||||
}
|
||||
|
||||
// pure virtuals:
|
||||
void SetPosition( const wxPoint& ) override {}
|
||||
void Print( RENDER_SETTINGS* aSettings, const wxPoint& aOffset ) override {}
|
||||
void Move( const wxPoint& aMoveVector ) override {}
|
||||
void MirrorY( int aYaxis_position ) override {}
|
||||
void MirrorX( int aXaxis_position ) override {}
|
||||
void Rotate( wxPoint aPosition ) override {}
|
||||
|
||||
#if defined(DEBUG)
|
||||
void Show( int , std::ostream& ) const override {}
|
||||
#endif
|
||||
};
|
||||
|
||||
DELETED_SHEET_ITEM* g_DeletedItem = nullptr;
|
||||
|
||||
|
||||
namespace std
|
||||
{
|
||||
size_t hash<SCH_SHEET_PATH>::operator()( const SCH_SHEET_PATH& path ) const
|
||||
|
@ -491,7 +529,11 @@ SCH_ITEM* SCH_SHEET_LIST::GetItem( const KIID& aID, SCH_SHEET_PATH* aPathOut )
|
|||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
// Not found; weak reference has been deleted.
|
||||
if( !g_DeletedItem )
|
||||
g_DeletedItem = new DELETED_SHEET_ITEM();
|
||||
|
||||
return g_DeletedItem;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -362,24 +362,18 @@ public:
|
|||
|
||||
virtual void SwitchLayer( wxDC* DC, PCB_LAYER_ID layer );
|
||||
|
||||
/**
|
||||
* Function SetActiveLayer
|
||||
* will change the currently active layer to \a aLayer.
|
||||
*/
|
||||
virtual void SetActiveLayer( PCB_LAYER_ID aLayer )
|
||||
{
|
||||
GetScreen()->m_Active_Layer = aLayer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function GetActiveLayer
|
||||
* returns the active layer
|
||||
*/
|
||||
virtual PCB_LAYER_ID GetActiveLayer() const
|
||||
{
|
||||
return GetScreen()->m_Active_Layer;
|
||||
}
|
||||
|
||||
int GetSeverity( int aErrorCode ) const override;
|
||||
|
||||
void LoadSettings( APP_SETTINGS_BASE* aCfg ) override;
|
||||
void SaveSettings( APP_SETTINGS_BASE* aCfg ) override;
|
||||
|
||||
|
|
|
@ -55,6 +55,8 @@ set( PCBNEW_DIALOGS
|
|||
dialogs/dialog_board_statistics.cpp
|
||||
dialogs/dialog_board_statistics_base.cpp
|
||||
dialogs/dialog_choose_footprint.cpp
|
||||
dialogs/dialog_cleanup_graphics.cpp
|
||||
dialogs/dialog_cleanup_graphics_base.cpp
|
||||
dialogs/dialog_cleanup_tracks_and_vias.cpp
|
||||
dialogs/dialog_cleanup_tracks_and_vias_base.cpp
|
||||
dialogs/dialog_copper_zones.cpp
|
||||
|
@ -262,6 +264,7 @@ set( PCBNEW_CLASS_SRCS
|
|||
array_creator.cpp
|
||||
array_pad_name_provider.cpp
|
||||
build_BOM_from_board.cpp
|
||||
cleanup_item.cpp
|
||||
cross-probing.cpp
|
||||
edit.cpp
|
||||
edit_track_width.cpp
|
||||
|
@ -276,6 +279,7 @@ set( PCBNEW_CLASS_SRCS
|
|||
footprint_viewer_frame.cpp
|
||||
fp_tree_model_adapter.cpp
|
||||
generate_footprint_info.cpp
|
||||
graphics_cleaner.cpp
|
||||
grid_layer_box_helpers.cpp
|
||||
grid_layer_box_helpers.h
|
||||
initpcb.cpp
|
||||
|
|
|
@ -93,15 +93,6 @@ public:
|
|||
bds.m_DRCSeverities[ DRCE_OVERLAPPING_FOOTPRINTS ] = RPT_SEVERITY_IGNORE;
|
||||
}
|
||||
|
||||
bds.m_DRCSeverities[ CLEANUP_SHORT ] = RPT_SEVERITY_ACTION;
|
||||
bds.m_DRCSeverities[ CLEANUP_REDUNDANT_VIA ] = RPT_SEVERITY_ACTION;
|
||||
bds.m_DRCSeverities[ CLEANUP_DUPLICATE_TRACK ] = RPT_SEVERITY_ACTION;
|
||||
bds.m_DRCSeverities[ CLEANUP_MERGE_TRACKS ] = RPT_SEVERITY_ACTION;
|
||||
bds.m_DRCSeverities[ CLEANUP_DANGLING_TRACK ] = RPT_SEVERITY_ACTION;
|
||||
bds.m_DRCSeverities[ CLEANUP_DANGLING_VIA ] = RPT_SEVERITY_ACTION;
|
||||
bds.m_DRCSeverities[ CLEANUP_ZERO_LENGTH_TRACK ] = RPT_SEVERITY_ACTION;
|
||||
bds.m_DRCSeverities[ CLEANUP_TRACK_IN_PAD ] = RPT_SEVERITY_ACTION;
|
||||
|
||||
DRC_ITEM drc( 0 );
|
||||
wxString severity;
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <msgpanel.h>
|
||||
#include <bitmaps.h>
|
||||
#include <base_units.h>
|
||||
#include <pcb_base_frame.h>
|
||||
#include <class_board.h>
|
||||
#include <class_board_item.h>
|
||||
#include <class_marker_pcb.h>
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2020 KiCad Developers, see change_log.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 Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
|
||||
#include <fctsys.h>
|
||||
#include <cleanup_item.h>
|
||||
#include <pcb_base_frame.h>
|
||||
|
||||
|
||||
CLEANUP_ITEM::CLEANUP_ITEM( int aErrorCode )
|
||||
{
|
||||
m_errorCode = aErrorCode;
|
||||
}
|
||||
|
||||
|
||||
wxString CLEANUP_ITEM::GetErrorText( int aCode, bool aTranslate ) const
|
||||
{
|
||||
wxString msg;
|
||||
|
||||
if( aCode < 0 )
|
||||
aCode = m_errorCode;
|
||||
|
||||
switch( aCode )
|
||||
{
|
||||
// For cleanup tracks and vias:
|
||||
case CLEANUP_SHORT: msg = _HKI( "Remove track shorting two nets" ); break;
|
||||
case CLEANUP_REDUNDANT_VIA: msg = _HKI( "Remove redundant via" ); break;
|
||||
case CLEANUP_DUPLICATE_TRACK: msg = _HKI( "Remove duplicate track" ); break;
|
||||
case CLEANUP_MERGE_TRACKS: msg = _HKI( "Merge co-linear tracks" ); break;
|
||||
case CLEANUP_DANGLING_TRACK: msg = _HKI( "Remove dangling track" ); break;
|
||||
case CLEANUP_DANGLING_VIA: msg = _HKI( "Remove dangling via" ); break;
|
||||
case CLEANUP_ZERO_LENGTH_TRACK: msg = _HKI( "Remove zero-length track" ); break;
|
||||
case CLEANUP_TRACK_IN_PAD: msg = _HKI( "Remove track inside pad" ); break;
|
||||
|
||||
// For cleanup graphics:
|
||||
case CLEANUP_NULL_GRAPHIC: msg = _HKI( "Remove zero-size graphic" ); break;
|
||||
case CLEANUP_DUPLICATE_GRAPHIC: msg = _HKI( "Remove duplicated graphic" ); break;
|
||||
case CLEANUP_LINES_TO_RECT: msg = _HKI( "Convert lines to rectangle" ); break;
|
||||
|
||||
default:
|
||||
wxFAIL_MSG( "Missing cleanup item description" );
|
||||
msg = _HKI( "Unknown cleanup action" );
|
||||
break;
|
||||
}
|
||||
|
||||
if( aTranslate )
|
||||
return wxGetTranslation( msg );
|
||||
else
|
||||
return msg;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2020 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 Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef CLEANUP_ITEM_H
|
||||
#define CLEANUP_ITEM_H
|
||||
|
||||
#include <rc_item.h>
|
||||
#include <drc/drc.h>
|
||||
|
||||
class PCB_BASE_FRAME;
|
||||
|
||||
|
||||
enum CLEANUP_RC_CODE {
|
||||
CLEANUP_FIRST = DRCE_LAST + 1,
|
||||
CLEANUP_SHORT = CLEANUP_FIRST,
|
||||
CLEANUP_REDUNDANT_VIA,
|
||||
CLEANUP_DUPLICATE_TRACK,
|
||||
CLEANUP_MERGE_TRACKS,
|
||||
CLEANUP_DANGLING_TRACK,
|
||||
CLEANUP_DANGLING_VIA,
|
||||
CLEANUP_ZERO_LENGTH_TRACK,
|
||||
CLEANUP_TRACK_IN_PAD,
|
||||
CLEANUP_NULL_GRAPHIC,
|
||||
CLEANUP_DUPLICATE_GRAPHIC,
|
||||
CLEANUP_LINES_TO_RECT
|
||||
};
|
||||
|
||||
class CLEANUP_ITEM : public RC_ITEM
|
||||
{
|
||||
public:
|
||||
CLEANUP_ITEM( int aErrorCode );
|
||||
|
||||
/**
|
||||
* Function GetErrorText
|
||||
* returns the string form of a drc error code.
|
||||
*/
|
||||
wxString GetErrorText( int aErrorCode = -1, bool aTranslate = true ) const override;
|
||||
|
||||
/**
|
||||
* Function ShowHtml
|
||||
* translates this object into a fragment of HTML suitable for the wxHtmlListBox class.
|
||||
* @return wxString - the html text.
|
||||
*/
|
||||
wxString ShowHtml( PCB_BASE_FRAME* aFrame ) const;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* VECTOR_CLEANUP_ITEMS_PROVIDER
|
||||
* is an implementation of the interface named RC_ITEMS_PROVIDER which uses a vector
|
||||
* of pointers to CLEANUP_ITEMs to fulfill the interface. No ownership is taken of the
|
||||
* vector.
|
||||
*/
|
||||
class VECTOR_CLEANUP_ITEMS_PROVIDER : public RC_ITEMS_PROVIDER
|
||||
{
|
||||
std::vector<CLEANUP_ITEM*>* m_sourceVector; // owns its CLEANUP_ITEMs
|
||||
|
||||
public:
|
||||
|
||||
VECTOR_CLEANUP_ITEMS_PROVIDER( std::vector<CLEANUP_ITEM*>* aList ) :
|
||||
m_sourceVector( aList )
|
||||
{
|
||||
}
|
||||
|
||||
void SetSeverities( int aSeverities ) override
|
||||
{
|
||||
}
|
||||
|
||||
int GetCount( int aSeverity = -1 ) override
|
||||
{
|
||||
return m_sourceVector->size();
|
||||
}
|
||||
|
||||
CLEANUP_ITEM* GetItem( int aIndex ) override
|
||||
{
|
||||
return m_sourceVector->at( aIndex );
|
||||
}
|
||||
|
||||
void DeleteItem( int aIndex, bool aDeep ) override
|
||||
{
|
||||
if( aDeep )
|
||||
{
|
||||
CLEANUP_ITEM* item = m_sourceVector->at( aIndex );
|
||||
delete item;
|
||||
|
||||
m_sourceVector->erase( m_sourceVector->begin() + aIndex );
|
||||
}
|
||||
}
|
||||
|
||||
void DeleteAllItems() override
|
||||
{
|
||||
if( m_sourceVector )
|
||||
{
|
||||
for( CLEANUP_ITEM* item : *m_sourceVector )
|
||||
delete item;
|
||||
|
||||
m_sourceVector->clear();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // CLEANUP_ITEM_H
|
|
@ -0,0 +1,149 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2020 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 Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <wx/wx.h>
|
||||
#include <dialog_cleanup_graphics.h>
|
||||
#include <tool/tool_manager.h>
|
||||
#include <tools/pcb_actions.h>
|
||||
#include <graphics_cleaner.h>
|
||||
|
||||
|
||||
DIALOG_CLEANUP_GRAPHICS::DIALOG_CLEANUP_GRAPHICS( PCB_BASE_FRAME* aParent, bool isModEdit ) :
|
||||
DIALOG_CLEANUP_GRAPHICS_BASE( aParent ),
|
||||
m_parentFrame( aParent ),
|
||||
m_isModEdit( isModEdit )
|
||||
{
|
||||
m_changesTreeModel = new RC_TREE_MODEL( m_parentFrame, m_changesDataView );
|
||||
m_changesDataView->AssociateModel( m_changesTreeModel );
|
||||
|
||||
m_changesTreeModel->SetSeverities( RPT_SEVERITY_ACTION );
|
||||
|
||||
// We use a sdbSizer to get platform-dependent ordering of the action buttons, but
|
||||
// that requires us to correct the button labels here.
|
||||
m_sdbSizerOK->SetLabel( isModEdit ? _( "Update Footprint" ) : _( "Update PCB" ) );
|
||||
|
||||
m_sdbSizerOK->SetDefault();
|
||||
GetSizer()->SetSizeHints(this);
|
||||
Centre();
|
||||
}
|
||||
|
||||
|
||||
DIALOG_CLEANUP_GRAPHICS::~DIALOG_CLEANUP_GRAPHICS()
|
||||
{
|
||||
for( CLEANUP_ITEM* item : m_items )
|
||||
delete item;
|
||||
|
||||
m_changesTreeModel->DecRef();
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_CLEANUP_GRAPHICS::OnCheckBox( wxCommandEvent& anEvent )
|
||||
{
|
||||
doCleanup( true );
|
||||
}
|
||||
|
||||
|
||||
bool DIALOG_CLEANUP_GRAPHICS::TransferDataToWindow()
|
||||
{
|
||||
doCleanup( true );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool DIALOG_CLEANUP_GRAPHICS::TransferDataFromWindow()
|
||||
{
|
||||
doCleanup( false );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_CLEANUP_GRAPHICS::doCleanup( bool aDryRun )
|
||||
{
|
||||
wxBusyCursor busy;
|
||||
|
||||
BOARD_COMMIT commit( m_parentFrame );
|
||||
BOARD* board = m_parentFrame->GetBoard();
|
||||
MODULE* fp = m_isModEdit ? board->GetFirstModule() : nullptr;
|
||||
GRAPHICS_CLEANER cleaner( fp ? fp->GraphicalItems() : board->Drawings(), fp, commit );
|
||||
|
||||
if( !aDryRun )
|
||||
{
|
||||
// Clear current selection list to avoid selection of deleted items
|
||||
m_parentFrame->GetToolManager()->RunAction( PCB_ACTIONS::selectionClear, true );
|
||||
|
||||
// ... and to keep the treeModel from trying to refresh a deleted item
|
||||
m_changesTreeModel->SetProvider( nullptr );
|
||||
}
|
||||
|
||||
for( CLEANUP_ITEM* item : m_items )
|
||||
delete item;
|
||||
|
||||
m_items.clear();
|
||||
|
||||
// Old model has to be refreshed, GAL normally does not keep updating it
|
||||
m_parentFrame->Compile_Ratsnest( false );
|
||||
|
||||
cleaner.CleanupBoard( aDryRun, &m_items, m_createRectanglesOpt->GetValue(),
|
||||
m_deleteRedundantOpt->GetValue() );
|
||||
|
||||
if( aDryRun )
|
||||
{
|
||||
RC_ITEMS_PROVIDER* provider = new VECTOR_CLEANUP_ITEMS_PROVIDER( &m_items );
|
||||
m_changesTreeModel->SetProvider( provider );
|
||||
}
|
||||
else if( !commit.Empty() )
|
||||
{
|
||||
// Clear undo and redo lists to avoid inconsistencies between lists
|
||||
commit.Push( _( "Graphics cleanup" ) );
|
||||
m_parentFrame->GetCanvas()->Refresh( true );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_CLEANUP_GRAPHICS::OnSelectItem( wxDataViewEvent& aEvent )
|
||||
{
|
||||
const KIID& itemID = RC_TREE_MODEL::ToUUID( aEvent.GetItem() );
|
||||
BOARD_ITEM* item = m_parentFrame->GetBoard()->GetItem( itemID );
|
||||
WINDOW_THAWER thawer( m_parentFrame );
|
||||
|
||||
m_parentFrame->FocusOnItem( item );
|
||||
m_parentFrame->GetCanvas()->Refresh();
|
||||
|
||||
aEvent.Skip();
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_CLEANUP_GRAPHICS::OnLeftDClickItem( wxMouseEvent& event )
|
||||
{
|
||||
event.Skip();
|
||||
|
||||
if( m_changesDataView->GetCurrentItem().IsOk() )
|
||||
{
|
||||
if( !IsModal() )
|
||||
Show( false );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2010-2014 Jean-Pierre Charras, jean-pierre.charras at wanadoo.fr
|
||||
* Copyright (C) 1992-2019 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 Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef DIALOG_CLEANUP_GRAPHICS_H_
|
||||
#define DIALOG_CLEANUP_GRAPHICS_H_
|
||||
|
||||
#include <dialog_cleanup_graphics_base.h>
|
||||
#include <cleanup_item.h>
|
||||
|
||||
|
||||
class PCB_BASE_FRAME;
|
||||
|
||||
|
||||
class DIALOG_CLEANUP_GRAPHICS: public DIALOG_CLEANUP_GRAPHICS_BASE
|
||||
{
|
||||
PCB_BASE_FRAME* m_parentFrame;
|
||||
bool m_isModEdit;
|
||||
std::vector<CLEANUP_ITEM*> m_items;
|
||||
RC_TREE_MODEL* m_changesTreeModel;
|
||||
|
||||
void doCleanup( bool aDryRun );
|
||||
|
||||
void OnCheckBox( wxCommandEvent& anEvent ) override;
|
||||
void OnSelectItem( wxDataViewEvent& event ) override;
|
||||
void OnLeftDClickItem( wxMouseEvent& event ) override;
|
||||
|
||||
bool TransferDataToWindow() override;
|
||||
bool TransferDataFromWindow() override;
|
||||
|
||||
public:
|
||||
DIALOG_CLEANUP_GRAPHICS( PCB_BASE_FRAME* aParent, bool isModEdit );
|
||||
~DIALOG_CLEANUP_GRAPHICS();
|
||||
};
|
||||
|
||||
#endif // DIALOG_CLEANUP_GRAPHICS_H_
|
|
@ -0,0 +1,76 @@
|
|||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version Oct 26 2018)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "dialog_cleanup_graphics_base.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DIALOG_CLEANUP_GRAPHICS_BASE::DIALOG_CLEANUP_GRAPHICS_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
|
||||
{
|
||||
this->SetSizeHints( wxDefaultSize, wxDefaultSize );
|
||||
|
||||
wxBoxSizer* bSizerMain;
|
||||
bSizerMain = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
wxBoxSizer* bSizerUpper;
|
||||
bSizerUpper = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
m_createRectanglesOpt = new wxCheckBox( this, wxID_ANY, _("Merge lines into rectangles"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_createRectanglesOpt->SetToolTip( _("remove track segments connecting nodes belonging to different nets (short circuit)") );
|
||||
|
||||
bSizerUpper->Add( m_createRectanglesOpt, 0, wxALL, 5 );
|
||||
|
||||
m_deleteRedundantOpt = new wxCheckBox( this, wxID_ANY, _("Delete redundant graphics"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
bSizerUpper->Add( m_deleteRedundantOpt, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
|
||||
|
||||
|
||||
bSizerMain->Add( bSizerUpper, 0, wxEXPAND|wxALL, 5 );
|
||||
|
||||
wxBoxSizer* bLowerSizer;
|
||||
bLowerSizer = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
bLowerSizer->SetMinSize( wxSize( 660,250 ) );
|
||||
staticChangesLabel = new wxStaticText( this, wxID_ANY, _("Changes To Be Applied:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
staticChangesLabel->Wrap( -1 );
|
||||
bLowerSizer->Add( staticChangesLabel, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
|
||||
|
||||
m_changesDataView = new wxDataViewCtrl( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxDV_NO_HEADER );
|
||||
bLowerSizer->Add( m_changesDataView, 1, wxALL|wxEXPAND, 5 );
|
||||
|
||||
|
||||
bSizerMain->Add( bLowerSizer, 1, wxEXPAND|wxRIGHT|wxLEFT, 5 );
|
||||
|
||||
m_sdbSizer = new wxStdDialogButtonSizer();
|
||||
m_sdbSizerOK = new wxButton( this, wxID_OK );
|
||||
m_sdbSizer->AddButton( m_sdbSizerOK );
|
||||
m_sdbSizerCancel = new wxButton( this, wxID_CANCEL );
|
||||
m_sdbSizer->AddButton( m_sdbSizerCancel );
|
||||
m_sdbSizer->Realize();
|
||||
|
||||
bSizerMain->Add( m_sdbSizer, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 );
|
||||
|
||||
|
||||
this->SetSizer( bSizerMain );
|
||||
this->Layout();
|
||||
bSizerMain->Fit( this );
|
||||
|
||||
this->Centre( wxBOTH );
|
||||
|
||||
// Connect Events
|
||||
m_createRectanglesOpt->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_CLEANUP_GRAPHICS_BASE::OnCheckBox ), NULL, this );
|
||||
m_changesDataView->Connect( wxEVT_COMMAND_DATAVIEW_SELECTION_CHANGED, wxDataViewEventHandler( DIALOG_CLEANUP_GRAPHICS_BASE::OnSelectItem ), NULL, this );
|
||||
m_changesDataView->Connect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( DIALOG_CLEANUP_GRAPHICS_BASE::OnLeftDClickItem ), NULL, this );
|
||||
}
|
||||
|
||||
DIALOG_CLEANUP_GRAPHICS_BASE::~DIALOG_CLEANUP_GRAPHICS_BASE()
|
||||
{
|
||||
// Disconnect Events
|
||||
m_createRectanglesOpt->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_CLEANUP_GRAPHICS_BASE::OnCheckBox ), NULL, this );
|
||||
m_changesDataView->Disconnect( wxEVT_COMMAND_DATAVIEW_SELECTION_CHANGED, wxDataViewEventHandler( DIALOG_CLEANUP_GRAPHICS_BASE::OnSelectItem ), NULL, this );
|
||||
m_changesDataView->Disconnect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( DIALOG_CLEANUP_GRAPHICS_BASE::OnLeftDClickItem ), NULL, this );
|
||||
|
||||
}
|
|
@ -0,0 +1,323 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
||||
<wxFormBuilder_Project>
|
||||
<FileVersion major="1" minor="15" />
|
||||
<object class="Project" expanded="1">
|
||||
<property name="class_decoration"></property>
|
||||
<property name="code_generation">C++</property>
|
||||
<property name="disconnect_events">1</property>
|
||||
<property name="disconnect_mode">source_name</property>
|
||||
<property name="disconnect_php_events">0</property>
|
||||
<property name="disconnect_python_events">0</property>
|
||||
<property name="embedded_files_path">res</property>
|
||||
<property name="encoding">UTF-8</property>
|
||||
<property name="event_generation">connect</property>
|
||||
<property name="file">dialog_cleanup_graphics_base</property>
|
||||
<property name="first_id">1000</property>
|
||||
<property name="help_provider">none</property>
|
||||
<property name="indent_with_spaces"></property>
|
||||
<property name="internationalize">1</property>
|
||||
<property name="name">dialog_cleanup_graphics</property>
|
||||
<property name="namespace"></property>
|
||||
<property name="path">.</property>
|
||||
<property name="precompiled_header"></property>
|
||||
<property name="relative_path">1</property>
|
||||
<property name="skip_lua_events">1</property>
|
||||
<property name="skip_php_events">1</property>
|
||||
<property name="skip_python_events">1</property>
|
||||
<property name="ui_table">UI</property>
|
||||
<property name="use_enum">0</property>
|
||||
<property name="use_microsoft_bom">0</property>
|
||||
<object class="Dialog" expanded="1">
|
||||
<property name="aui_managed">0</property>
|
||||
<property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
|
||||
<property name="bg"></property>
|
||||
<property name="center">wxBOTH</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="event_handler">impl_virtual</property>
|
||||
<property name="extra_style"></property>
|
||||
<property name="fg"></property>
|
||||
<property name="font"></property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">DIALOG_CLEANUP_GRAPHICS_BASE</property>
|
||||
<property name="pos"></property>
|
||||
<property name="size">-1,-1</property>
|
||||
<property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
|
||||
<property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
|
||||
<property name="title">Cleanup Graphics</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<object class="wxBoxSizer" expanded="1">
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">bSizerMain</property>
|
||||
<property name="orient">wxVERTICAL</property>
|
||||
<property name="permission">none</property>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND|wxALL</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxBoxSizer" expanded="1">
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">bSizerUpper</property>
|
||||
<property name="orient">wxVERTICAL</property>
|
||||
<property name="permission">none</property>
|
||||
<object class="sizeritem" expanded="0">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALL</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxCheckBox" expanded="0">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer"></property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="checked">0</property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="default_pane">0</property>
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
<property name="font"></property>
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">Merge lines into rectangles</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="min_size"></property>
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_createRectanglesOpt</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="pin_button">1</property>
|
||||
<property name="pos"></property>
|
||||
<property name="resize">Resizable</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="style"></property>
|
||||
<property name="subclass"></property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip">remove track segments connecting nodes belonging to different nets (short circuit)</property>
|
||||
<property name="validator_data_type"></property>
|
||||
<property name="validator_style">wxFILTER_NUMERIC</property>
|
||||
<property name="validator_type">wxDefaultValidator</property>
|
||||
<property name="validator_variable"></property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<event name="OnCheckBox">OnCheckBox</event>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxBOTTOM|wxRIGHT|wxLEFT</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxCheckBox" expanded="1">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer"></property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="checked">0</property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="default_pane">0</property>
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
<property name="font"></property>
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">Delete redundant graphics</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="min_size"></property>
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_deleteRedundantOpt</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="pin_button">1</property>
|
||||
<property name="pos"></property>
|
||||
<property name="resize">Resizable</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="style"></property>
|
||||
<property name="subclass">; ; forward_declare</property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="validator_data_type"></property>
|
||||
<property name="validator_style">wxFILTER_NONE</property>
|
||||
<property name="validator_type">wxDefaultValidator</property>
|
||||
<property name="validator_variable"></property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND|wxRIGHT|wxLEFT</property>
|
||||
<property name="proportion">1</property>
|
||||
<object class="wxBoxSizer" expanded="1">
|
||||
<property name="minimum_size">660,250</property>
|
||||
<property name="name">bLowerSizer</property>
|
||||
<property name="orient">wxVERTICAL</property>
|
||||
<property name="permission">none</property>
|
||||
<object class="sizeritem" expanded="0">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxStaticText" expanded="0">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer"></property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="default_pane">0</property>
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
<property name="font"></property>
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">Changes To Be Applied:</property>
|
||||
<property name="markup">0</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="min_size"></property>
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">staticChangesLabel</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="pin_button">1</property>
|
||||
<property name="pos"></property>
|
||||
<property name="resize">Resizable</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="style"></property>
|
||||
<property name="subclass">; forward_declare</property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<property name="wrap">-1</property>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALL|wxEXPAND</property>
|
||||
<property name="proportion">1</property>
|
||||
<object class="wxDataViewCtrl" expanded="1">
|
||||
<property name="bg"></property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="font"></property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">m_changesDataView</property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="pos"></property>
|
||||
<property name="size"></property>
|
||||
<property name="style">wxDV_NO_HEADER</property>
|
||||
<property name="subclass">; ; forward_declare</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<event name="OnDataViewCtrlSelectionChanged">OnSelectItem</event>
|
||||
<event name="OnLeftDClick">OnLeftDClickItem</event>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="0">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxStdDialogButtonSizer" expanded="0">
|
||||
<property name="Apply">0</property>
|
||||
<property name="Cancel">1</property>
|
||||
<property name="ContextHelp">0</property>
|
||||
<property name="Help">0</property>
|
||||
<property name="No">0</property>
|
||||
<property name="OK">1</property>
|
||||
<property name="Save">0</property>
|
||||
<property name="Yes">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">m_sdbSizer</property>
|
||||
<property name="permission">protected</property>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</wxFormBuilder_Project>
|
|
@ -0,0 +1,57 @@
|
|||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version Oct 26 2018)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wx/artprov.h>
|
||||
#include <wx/xrc/xmlres.h>
|
||||
#include <wx/intl.h>
|
||||
#include "dialog_shim.h"
|
||||
#include <wx/string.h>
|
||||
#include <wx/checkbox.h>
|
||||
#include <wx/gdicmn.h>
|
||||
#include <wx/font.h>
|
||||
#include <wx/colour.h>
|
||||
#include <wx/settings.h>
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/stattext.h>
|
||||
#include <wx/dataview.h>
|
||||
#include <wx/button.h>
|
||||
#include <wx/dialog.h>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// Class DIALOG_CLEANUP_GRAPHICS_BASE
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class DIALOG_CLEANUP_GRAPHICS_BASE : public DIALOG_SHIM
|
||||
{
|
||||
private:
|
||||
|
||||
protected:
|
||||
wxCheckBox* m_createRectanglesOpt;
|
||||
wxCheckBox* m_deleteRedundantOpt;
|
||||
wxStaticText* staticChangesLabel;
|
||||
wxDataViewCtrl* m_changesDataView;
|
||||
wxStdDialogButtonSizer* m_sdbSizer;
|
||||
wxButton* m_sdbSizerOK;
|
||||
wxButton* m_sdbSizerCancel;
|
||||
|
||||
// Virtual event handlers, overide them in your derived class
|
||||
virtual void OnCheckBox( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnSelectItem( wxDataViewEvent& event ) { event.Skip(); }
|
||||
virtual void OnLeftDClickItem( wxMouseEvent& event ) { event.Skip(); }
|
||||
|
||||
|
||||
public:
|
||||
|
||||
DIALOG_CLEANUP_GRAPHICS_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Cleanup Graphics"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
|
||||
~DIALOG_CLEANUP_GRAPHICS_BASE();
|
||||
|
||||
};
|
||||
|
|
@ -20,21 +20,18 @@
|
|||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
#include <wx/wx.h>
|
||||
|
||||
#include <board_commit.h>
|
||||
#include <wx/wx.h>
|
||||
#include <dialog_cleanup_tracks_and_vias.h>
|
||||
#include <kiface_i.h>
|
||||
#include <pcb_edit_frame.h>
|
||||
#include <pcbnew_settings.h>
|
||||
#include <reporter.h>
|
||||
#include <tool/tool_manager.h>
|
||||
#include <tools/pcb_actions.h>
|
||||
#include <tracks_cleaner.h>
|
||||
#include <drc/drc_item.h>
|
||||
#include <drc/drc_provider.h>
|
||||
|
||||
DIALOG_CLEANUP_TRACKS_AND_VIAS::DIALOG_CLEANUP_TRACKS_AND_VIAS( PCB_EDIT_FRAME* aParentFrame ):
|
||||
DIALOG_CLEANUP_TRACKS_AND_VIAS::DIALOG_CLEANUP_TRACKS_AND_VIAS( PCB_EDIT_FRAME* aParentFrame ) :
|
||||
DIALOG_CLEANUP_TRACKS_AND_VIAS_BASE( aParentFrame ),
|
||||
m_parentFrame( aParentFrame )
|
||||
{
|
||||
|
@ -71,7 +68,7 @@ DIALOG_CLEANUP_TRACKS_AND_VIAS::~DIALOG_CLEANUP_TRACKS_AND_VIAS()
|
|||
cfg->m_Cleanup.cleanup_short_circuits = m_cleanShortCircuitOpt->GetValue();
|
||||
cfg->m_Cleanup.cleanup_tracks_in_pad = m_deleteTracksInPadsOpt->GetValue();
|
||||
|
||||
for( DRC_ITEM* item : m_items )
|
||||
for( CLEANUP_ITEM* item : m_items )
|
||||
delete item;
|
||||
|
||||
m_changesTreeModel->DecRef();
|
||||
|
@ -104,7 +101,7 @@ void DIALOG_CLEANUP_TRACKS_AND_VIAS::doCleanup( bool aDryRun )
|
|||
{
|
||||
wxBusyCursor busy;
|
||||
BOARD_COMMIT commit( m_parentFrame );
|
||||
TRACKS_CLEANER cleaner( m_parentFrame->GetUserUnits(), m_parentFrame->GetBoard(), commit );
|
||||
TRACKS_CLEANER cleaner( m_parentFrame->GetBoard(), commit );
|
||||
|
||||
if( !aDryRun )
|
||||
{
|
||||
|
@ -115,7 +112,7 @@ void DIALOG_CLEANUP_TRACKS_AND_VIAS::doCleanup( bool aDryRun )
|
|||
m_changesTreeModel->SetProvider( nullptr );
|
||||
}
|
||||
|
||||
for( DRC_ITEM* item : m_items )
|
||||
for( CLEANUP_ITEM* item : m_items )
|
||||
delete item;
|
||||
|
||||
m_items.clear();
|
||||
|
@ -123,8 +120,7 @@ void DIALOG_CLEANUP_TRACKS_AND_VIAS::doCleanup( bool aDryRun )
|
|||
// Old model has to be refreshed, GAL normally does not keep updating it
|
||||
m_parentFrame->Compile_Ratsnest( false );
|
||||
|
||||
bool modified = cleaner.CleanupBoard( aDryRun, &m_items,
|
||||
m_cleanShortCircuitOpt->GetValue(),
|
||||
cleaner.CleanupBoard( aDryRun, &m_items, m_cleanShortCircuitOpt->GetValue(),
|
||||
m_cleanViasOpt->GetValue(),
|
||||
m_mergeSegmOpt->GetValue(),
|
||||
m_deleteUnconnectedOpt->GetValue(),
|
||||
|
@ -132,10 +128,10 @@ void DIALOG_CLEANUP_TRACKS_AND_VIAS::doCleanup( bool aDryRun )
|
|||
|
||||
if( aDryRun )
|
||||
{
|
||||
RC_ITEMS_PROVIDER* provider = new VECTOR_DRC_ITEMS_PROVIDER( m_parentFrame, &m_items );
|
||||
RC_ITEMS_PROVIDER* provider = new VECTOR_CLEANUP_ITEMS_PROVIDER( &m_items );
|
||||
m_changesTreeModel->SetProvider( provider );
|
||||
}
|
||||
else if( modified )
|
||||
else if( !commit.Empty() )
|
||||
{
|
||||
// Clear undo and redo lists to avoid inconsistencies between lists
|
||||
commit.Push( _( "Board cleanup" ) );
|
||||
|
|
|
@ -26,18 +26,16 @@
|
|||
#define DIALOG_CLEANUP_TRACKS_AND_VIAS_H_
|
||||
|
||||
#include <dialog_cleanup_tracks_and_vias_base.h>
|
||||
|
||||
#include <drc/drc.h>
|
||||
#include <cleanup_item.h>
|
||||
|
||||
|
||||
class PCB_EDIT_FRAME;
|
||||
class DRC_TREE_MODEL;
|
||||
|
||||
|
||||
class DIALOG_CLEANUP_TRACKS_AND_VIAS: public DIALOG_CLEANUP_TRACKS_AND_VIAS_BASE
|
||||
{
|
||||
PCB_EDIT_FRAME* m_parentFrame;
|
||||
std::vector<DRC_ITEM*> m_items;
|
||||
std::vector<CLEANUP_ITEM*> m_items;
|
||||
RC_TREE_MODEL* m_changesTreeModel;
|
||||
|
||||
void doCleanup( bool aDryRun );
|
||||
|
|
|
@ -58,11 +58,11 @@
|
|||
<property name="name">bSizerMain</property>
|
||||
<property name="orient">wxVERTICAL</property>
|
||||
<property name="permission">none</property>
|
||||
<object class="sizeritem" expanded="0">
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND|wxALL</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxBoxSizer" expanded="0">
|
||||
<object class="wxBoxSizer" expanded="1">
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">bSizerUpper</property>
|
||||
<property name="orient">wxVERTICAL</property>
|
||||
|
@ -295,7 +295,7 @@
|
|||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">Delete &dangling tracks</property>
|
||||
<property name="label">Delete tracks unconnected at one end</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
|
@ -360,7 +360,7 @@
|
|||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">Delete Tracks in Pads</property>
|
||||
<property name="label">Delete tracks fully inside pads</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
|
|
|
@ -106,17 +106,7 @@ enum PCB_DRC_CODE {
|
|||
|
||||
DRCE_UNRESOLVED_VARIABLE,
|
||||
|
||||
DRCE_LAST = DRCE_UNRESOLVED_VARIABLE,
|
||||
|
||||
// These are actually Cleanup Tracks and Vias actions, not DRCE errors
|
||||
CLEANUP_SHORT,
|
||||
CLEANUP_REDUNDANT_VIA,
|
||||
CLEANUP_DUPLICATE_TRACK,
|
||||
CLEANUP_MERGE_TRACKS,
|
||||
CLEANUP_DANGLING_TRACK,
|
||||
CLEANUP_DANGLING_VIA,
|
||||
CLEANUP_ZERO_LENGTH_TRACK,
|
||||
CLEANUP_TRACK_IN_PAD
|
||||
DRCE_LAST = DRCE_UNRESOLVED_VARIABLE
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -129,16 +129,6 @@ wxString DRC_ITEM::GetErrorText( int aCode, bool aTranslate ) const
|
|||
case DRCE_MISSING_FOOTPRINT: msg = _HKI( "Missing footprint" ); break;
|
||||
case DRCE_EXTRA_FOOTPRINT: msg = _HKI( "Extra footprint" ); break;
|
||||
|
||||
// For cleanup tracks and vias:
|
||||
case CLEANUP_SHORT: msg = _HKI( "Remove track shorting two nets" ); break;
|
||||
case CLEANUP_REDUNDANT_VIA: msg = _HKI( "Remove redundant via" ); break;
|
||||
case CLEANUP_DUPLICATE_TRACK: msg = _HKI( "Remove duplicate track" ); break;
|
||||
case CLEANUP_MERGE_TRACKS: msg = _HKI( "Merge co-linear tracks" ); break;
|
||||
case CLEANUP_DANGLING_TRACK: msg = _HKI( "Remove dangling track" ); break;
|
||||
case CLEANUP_DANGLING_VIA: msg = _HKI( "Remove dangling via" ); break;
|
||||
case CLEANUP_ZERO_LENGTH_TRACK: msg = _HKI( "Remove zero-length track" ); break;
|
||||
case CLEANUP_TRACK_IN_PAD: msg = _HKI( "Remove track inside pad" ); break;
|
||||
|
||||
case DRCE_UNRESOLVED_VARIABLE: msg = _HKI( "Unresolved text variable" ); break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -25,13 +25,9 @@
|
|||
#ifndef DRC_ITEM_H
|
||||
#define DRC_ITEM_H
|
||||
|
||||
#include <macros.h>
|
||||
#include <base_struct.h>
|
||||
#include <rc_item.h>
|
||||
#include <marker_base.h>
|
||||
#include <class_board.h>
|
||||
#include <pcb_base_frame.h>
|
||||
#include "drc.h"
|
||||
|
||||
class PCB_BASE_FRAME;
|
||||
|
||||
class DRC_ITEM : public RC_ITEM
|
||||
{
|
||||
|
|
|
@ -27,7 +27,9 @@
|
|||
|
||||
#include <class_board.h>
|
||||
#include <class_marker_pcb.h>
|
||||
|
||||
#include <pcb_base_frame.h>
|
||||
#include <drc/drc.h>
|
||||
#include <widgets/ui_common.h>
|
||||
#include <functional>
|
||||
|
||||
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
#include <settings/settings_manager.h>
|
||||
#include <wx/config.h>
|
||||
#include <base_units.h>
|
||||
#include <drc/drc.h>
|
||||
#include <widgets/ui_common.h>
|
||||
|
||||
extern const char* traceSettings;
|
||||
|
||||
|
|
|
@ -0,0 +1,347 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2004-2018 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||
* Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
|
||||
* Copyright (C) 1992-2020 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 Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <fctsys.h>
|
||||
#include <reporter.h>
|
||||
#include <board_commit.h>
|
||||
#include <cleanup_item.h>
|
||||
#include <class_drawsegment.h>
|
||||
#include <class_edge_mod.h>
|
||||
#include <graphics_cleaner.h>
|
||||
|
||||
|
||||
GRAPHICS_CLEANER::GRAPHICS_CLEANER( DRAWINGS& aDrawings, MODULE* aParentModule,
|
||||
BOARD_COMMIT& aCommit ) :
|
||||
m_drawings( aDrawings ),
|
||||
m_parentModule( aParentModule ),
|
||||
m_commit( aCommit ),
|
||||
m_dryRun( true ),
|
||||
m_itemsList( nullptr )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void GRAPHICS_CLEANER::CleanupBoard( bool aDryRun, std::vector<CLEANUP_ITEM*>* aItemsList,
|
||||
bool aMergeRects, bool aDeleteRedundant )
|
||||
{
|
||||
m_dryRun = aDryRun;
|
||||
m_itemsList = aItemsList;
|
||||
|
||||
// Clear the flag used to mark some segments as deleted, in dry run:
|
||||
for( BOARD_ITEM* drawing : m_drawings )
|
||||
drawing->ClearFlags( IS_DELETED );
|
||||
|
||||
if( aDeleteRedundant )
|
||||
cleanupSegments();
|
||||
|
||||
if( aMergeRects )
|
||||
mergeRects();
|
||||
|
||||
// Clear the flag used to mark some segments:
|
||||
for( BOARD_ITEM* drawing : m_drawings )
|
||||
drawing->ClearFlags( IS_DELETED );
|
||||
}
|
||||
|
||||
|
||||
bool GRAPHICS_CLEANER::isNullSegment( DRAWSEGMENT* aSegment )
|
||||
{
|
||||
switch( aSegment->GetShape() )
|
||||
{
|
||||
case S_SEGMENT:
|
||||
case S_RECT:
|
||||
return aSegment->GetStart() == aSegment->GetEnd();
|
||||
|
||||
case S_CIRCLE:
|
||||
return aSegment->GetRadius() == 0;
|
||||
|
||||
case S_ARC:
|
||||
return aSegment->GetCenter().x == aSegment->GetArcStart().x
|
||||
&& aSegment->GetCenter().y == aSegment->GetArcStart().y;
|
||||
|
||||
case S_POLYGON:
|
||||
return aSegment->GetPointCount() == 0;
|
||||
|
||||
case S_CURVE:
|
||||
aSegment->RebuildBezierToSegmentsPointsList( aSegment->GetWidth() );
|
||||
return aSegment->GetBezierPoints().empty();
|
||||
|
||||
default:
|
||||
wxFAIL_MSG( wxString::Format( "unknown DRAWSEGMENT shape: %d", aSegment->GetShape() ) );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool GRAPHICS_CLEANER::areEquivalent( DRAWSEGMENT* aSegment1, DRAWSEGMENT* aSegment2 )
|
||||
{
|
||||
if( aSegment1->GetShape() != aSegment2->GetShape()
|
||||
|| aSegment1->GetLayer() != aSegment2->GetLayer()
|
||||
|| aSegment1->GetWidth() != aSegment2->GetWidth() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
switch( aSegment1->GetShape() )
|
||||
{
|
||||
case S_SEGMENT:
|
||||
case S_RECT:
|
||||
case S_CIRCLE:
|
||||
return aSegment1->GetStart() == aSegment2->GetStart()
|
||||
&& aSegment1->GetEnd() == aSegment2->GetEnd();
|
||||
|
||||
case S_ARC:
|
||||
return aSegment1->GetCenter() == aSegment2->GetCenter()
|
||||
&& aSegment1->GetArcStart() == aSegment2->GetArcStart()
|
||||
&& aSegment1->GetAngle() == aSegment2->GetAngle();
|
||||
|
||||
case S_POLYGON:
|
||||
// TODO
|
||||
return false;
|
||||
|
||||
case S_CURVE:
|
||||
return aSegment1->GetBezControl1() == aSegment2->GetBezControl1()
|
||||
&& aSegment1->GetBezControl2() == aSegment2->GetBezControl2()
|
||||
&& aSegment1->GetBezierPoints() == aSegment2->GetBezierPoints();
|
||||
|
||||
default:
|
||||
wxFAIL_MSG( wxString::Format( "unknown DRAWSEGMENT shape: %d", aSegment1->GetShape() ) );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GRAPHICS_CLEANER::cleanupSegments()
|
||||
{
|
||||
std::set<BOARD_ITEM*> toRemove;
|
||||
|
||||
// Remove duplicate segments (2 superimposed identical segments):
|
||||
for( auto it = m_drawings.begin(); it != m_drawings.end(); it++ )
|
||||
{
|
||||
DRAWSEGMENT* segment = dynamic_cast<DRAWSEGMENT*>( *it );
|
||||
|
||||
if( !segment || segment->GetShape() != S_SEGMENT || segment->HasFlag( IS_DELETED ) )
|
||||
continue;
|
||||
|
||||
if( isNullSegment( segment ) )
|
||||
{
|
||||
CLEANUP_ITEM* item = new CLEANUP_ITEM( CLEANUP_NULL_GRAPHIC );
|
||||
item->SetItems( segment );
|
||||
m_itemsList->push_back( item );
|
||||
|
||||
toRemove.insert( segment );
|
||||
continue;
|
||||
}
|
||||
|
||||
for( auto it2 = it + 1; it2 != m_drawings.end(); it2++ )
|
||||
{
|
||||
DRAWSEGMENT* segment2 = dynamic_cast<DRAWSEGMENT*>( *it2 );
|
||||
|
||||
if( !segment2 || segment2->HasFlag( IS_DELETED ) )
|
||||
continue;
|
||||
|
||||
if( areEquivalent( segment, segment2 ) )
|
||||
{
|
||||
CLEANUP_ITEM* item = new CLEANUP_ITEM( CLEANUP_DUPLICATE_GRAPHIC );
|
||||
item->SetItems( segment2 );
|
||||
m_itemsList->push_back( item );
|
||||
|
||||
segment2->SetFlags( IS_DELETED );
|
||||
toRemove.insert( segment2 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( !m_dryRun )
|
||||
removeItems( toRemove );
|
||||
}
|
||||
|
||||
|
||||
void GRAPHICS_CLEANER::mergeRects()
|
||||
{
|
||||
struct SIDE_CANDIDATE
|
||||
{
|
||||
SIDE_CANDIDATE( DRAWSEGMENT* aSeg ) :
|
||||
start( aSeg->GetStart() ),
|
||||
end( aSeg->GetEnd() ),
|
||||
seg( aSeg )
|
||||
{
|
||||
if( start.x > end.x || start.y > end.y )
|
||||
std::swap( start, end );
|
||||
}
|
||||
|
||||
wxPoint start;
|
||||
wxPoint end;
|
||||
DRAWSEGMENT* seg;
|
||||
};
|
||||
|
||||
std::set<BOARD_ITEM*> toRemove;
|
||||
|
||||
auto markForRemoval = [&]( SIDE_CANDIDATE* aSide )
|
||||
{
|
||||
toRemove.insert( aSide->seg );
|
||||
aSide->seg->SetFlags( IS_DELETED );
|
||||
};
|
||||
|
||||
std::vector<SIDE_CANDIDATE*> sides;
|
||||
std::map<wxPoint, std::vector<SIDE_CANDIDATE*>> ptMap;
|
||||
|
||||
// First load all the candidates into the side vector and layer maps
|
||||
for( BOARD_ITEM* item : m_drawings )
|
||||
{
|
||||
DRAWSEGMENT* seg = dynamic_cast<DRAWSEGMENT*>( item );
|
||||
|
||||
if( !seg || seg->GetShape() != S_SEGMENT )
|
||||
continue;
|
||||
|
||||
if( seg->GetStart().x == seg->GetEnd().x || seg->GetStart().y == seg->GetEnd().y )
|
||||
{
|
||||
sides.emplace_back( new SIDE_CANDIDATE( seg ) );
|
||||
ptMap[ sides.back()->start ].push_back( sides.back() );
|
||||
}
|
||||
}
|
||||
|
||||
// Now go through the sides and try and match lines into rectangles
|
||||
for( SIDE_CANDIDATE* side : sides )
|
||||
{
|
||||
if( side->seg->HasFlag( IS_DELETED ) )
|
||||
continue;
|
||||
|
||||
SIDE_CANDIDATE* left = nullptr;
|
||||
SIDE_CANDIDATE* top = nullptr;
|
||||
SIDE_CANDIDATE* right = nullptr;
|
||||
SIDE_CANDIDATE* bottom = nullptr;
|
||||
|
||||
auto viable = [&]( SIDE_CANDIDATE* aCandidate ) -> bool
|
||||
{
|
||||
return aCandidate->seg->GetLayer() == side->seg->GetLayer()
|
||||
&& aCandidate->seg->GetWidth() == side->seg->GetWidth()
|
||||
&& !aCandidate->seg->HasFlag( IS_DELETED );
|
||||
};
|
||||
|
||||
if( side->start.x == side->end.x )
|
||||
{
|
||||
// We've found a possible left; see if we have a top
|
||||
//
|
||||
left = side;
|
||||
|
||||
for( SIDE_CANDIDATE* candidate : ptMap[ left->start ] )
|
||||
{
|
||||
if( candidate != left && viable( candidate ) )
|
||||
{
|
||||
top = candidate;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( side->start.y == side->end.y )
|
||||
{
|
||||
// We've found a possible top; see if we have a left
|
||||
//
|
||||
top = side;
|
||||
|
||||
for( SIDE_CANDIDATE* candidate : ptMap[ top->start ] )
|
||||
{
|
||||
if( candidate != top && viable( candidate ) )
|
||||
{
|
||||
left = candidate;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( top && left )
|
||||
{
|
||||
// See if we can fill in the other two sides
|
||||
//
|
||||
for( SIDE_CANDIDATE* candidate : ptMap[ top->end ] )
|
||||
{
|
||||
if( candidate != top && viable( candidate ) )
|
||||
{
|
||||
right = candidate;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for( SIDE_CANDIDATE* candidate : ptMap[ left->end ] )
|
||||
{
|
||||
if( candidate != left && viable( candidate ) )
|
||||
{
|
||||
bottom = candidate;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( right && bottom )
|
||||
{
|
||||
markForRemoval( left );
|
||||
markForRemoval( top );
|
||||
markForRemoval( right );
|
||||
markForRemoval( bottom );
|
||||
|
||||
CLEANUP_ITEM* item = new CLEANUP_ITEM( CLEANUP_LINES_TO_RECT );
|
||||
item->SetItems( left->seg, top->seg, right->seg, bottom->seg );
|
||||
m_itemsList->push_back( item );
|
||||
|
||||
if( !m_dryRun )
|
||||
{
|
||||
DRAWSEGMENT* rect;
|
||||
|
||||
if( m_parentModule )
|
||||
rect = new EDGE_MODULE( m_parentModule );
|
||||
else
|
||||
rect = new DRAWSEGMENT();
|
||||
|
||||
rect->SetShape( S_RECT );
|
||||
rect->SetStart( top->start );
|
||||
rect->SetEnd( bottom->end );
|
||||
rect->SetLayer( top->seg->GetLayer() );
|
||||
rect->SetWidth( top->seg->GetWidth() );
|
||||
|
||||
m_commit.Add( rect );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( !m_dryRun )
|
||||
removeItems( toRemove );
|
||||
|
||||
for( SIDE_CANDIDATE* side : sides )
|
||||
delete side;
|
||||
}
|
||||
|
||||
|
||||
void GRAPHICS_CLEANER::removeItems( std::set<BOARD_ITEM*>& aItems )
|
||||
{
|
||||
for( BOARD_ITEM* item : aItems )
|
||||
{
|
||||
if( m_parentModule )
|
||||
m_parentModule->Remove( item );
|
||||
else
|
||||
item->GetParent()->Remove( item );
|
||||
|
||||
m_commit.Removed( item );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2019 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 Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef KICAD_GRAPHICS_CLEANER_H
|
||||
#define KICAD_GRAPHICS_CLEANER_H
|
||||
|
||||
#include <class_board.h>
|
||||
|
||||
class MODULE;
|
||||
class BOARD_COMMIT;
|
||||
class CLEANUP_ITEM;
|
||||
|
||||
|
||||
// Helper class used to clean tracks and vias
|
||||
class GRAPHICS_CLEANER
|
||||
{
|
||||
public:
|
||||
GRAPHICS_CLEANER( DRAWINGS& aDrawings, MODULE* aParentModule, BOARD_COMMIT& aCommit );
|
||||
|
||||
/**
|
||||
* the cleanup function.
|
||||
* @param aMergeRects = merge for segments forming a rectangle into a rect
|
||||
* @param aDeleteRedundant = true to delete null graphics and duplicated graphics
|
||||
*/
|
||||
void CleanupBoard( bool aDryRun, std::vector<CLEANUP_ITEM*>* aItemsList, bool aMergeRects,
|
||||
bool aDeleteRedundant );
|
||||
|
||||
private:
|
||||
bool isNullSegment( DRAWSEGMENT* aSegment );
|
||||
bool areEquivalent( DRAWSEGMENT* aSegment1, DRAWSEGMENT* aSegment2 );
|
||||
|
||||
void cleanupSegments();
|
||||
void mergeRects();
|
||||
void removeItems( std::set<BOARD_ITEM*>& aItems );
|
||||
|
||||
private:
|
||||
DRAWINGS& m_drawings;
|
||||
MODULE* m_parentModule; // nullptr if not in ModEdit
|
||||
BOARD_COMMIT& m_commit;
|
||||
bool m_dryRun;
|
||||
std::vector<CLEANUP_ITEM*>* m_itemsList;
|
||||
};
|
||||
|
||||
|
||||
#endif //KICAD_GRAPHICS_CLEANER_H
|
|
@ -137,6 +137,9 @@ void FOOTPRINT_EDIT_FRAME::ReCreateMenuBar()
|
|||
editMenu->AddItem( PCB_ACTIONS::footprintProperties, haveFootprintCondition );
|
||||
editMenu->AddItem( PCB_ACTIONS::defaultPadProperties, SELECTION_CONDITIONS::ShowAlways );
|
||||
|
||||
editMenu->AddSeparator();
|
||||
editMenu->AddItem( PCB_ACTIONS::cleanupGraphics, haveFootprintCondition );
|
||||
|
||||
editMenu->Resolve();
|
||||
|
||||
//-- View menu -------------------------------------------------------
|
||||
|
|
|
@ -251,6 +251,7 @@ void PCB_EDIT_FRAME::ReCreateMenuBar()
|
|||
editMenu->AddItem( ACTIONS::deleteTool, SELECTION_CONDITIONS::ShowAlways );
|
||||
editMenu->AddItem( PCB_ACTIONS::globalDeletions, SELECTION_CONDITIONS::ShowAlways );
|
||||
editMenu->AddItem( PCB_ACTIONS::cleanupTracksAndVias, SELECTION_CONDITIONS::ShowAlways );
|
||||
editMenu->AddItem( PCB_ACTIONS::cleanupGraphics, SELECTION_CONDITIONS::ShowAlways );
|
||||
|
||||
editMenu->Resolve();
|
||||
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
#include <tool/tool_dispatcher.h>
|
||||
#include <tools/pcb_actions.h>
|
||||
#include <tool/grid_menu.h>
|
||||
#include "cleanup_item.h"
|
||||
|
||||
wxDEFINE_EVENT( BOARD_CHANGED, wxCommandEvent );
|
||||
|
||||
|
@ -662,6 +663,17 @@ void PCB_BASE_FRAME::LoadSettings( APP_SETTINGS_BASE* aCfg )
|
|||
}
|
||||
|
||||
|
||||
int PCB_BASE_FRAME::GetSeverity( int aErrorCode ) const
|
||||
{
|
||||
if( aErrorCode >= CLEANUP_FIRST )
|
||||
return RPT_SEVERITY_ACTION;
|
||||
|
||||
BOARD_DESIGN_SETTINGS& bds = GetBoard()->GetDesignSettings();
|
||||
|
||||
return bds.m_DRCSeverities[ aErrorCode ];
|
||||
}
|
||||
|
||||
|
||||
void PCB_BASE_FRAME::SaveSettings( APP_SETTINGS_BASE* aCfg )
|
||||
{
|
||||
EDA_DRAW_FRAME::SaveSettings( aCfg );
|
||||
|
|
|
@ -370,14 +370,6 @@ BOARD_ITEM_CONTAINER* PCB_EDIT_FRAME::GetModel() const
|
|||
}
|
||||
|
||||
|
||||
int PCB_EDIT_FRAME::GetSeverity( int aErrorCode ) const
|
||||
{
|
||||
BOARD_DESIGN_SETTINGS& bds = GetBoard()->GetDesignSettings();
|
||||
|
||||
return bds.m_DRCSeverities[ aErrorCode ];
|
||||
}
|
||||
|
||||
|
||||
void PCB_EDIT_FRAME::SetPageSettings( const PAGE_INFO& aPageSettings )
|
||||
{
|
||||
PCB_BASE_FRAME::SetPageSettings( aPageSettings );
|
||||
|
|
|
@ -672,9 +672,6 @@ public:
|
|||
///> @copydoc PCB_BASE_FRAME::GetModel()
|
||||
BOARD_ITEM_CONTAINER* GetModel() const override;
|
||||
|
||||
///> @copydoc EDA_BASE_FRAME::GetSeverity()
|
||||
int GetSeverity( int aErrorCode ) const override;
|
||||
|
||||
///> @copydoc PCB_BASE_FRAME::SetPageSettings()
|
||||
void SetPageSettings( const PAGE_INFO& aPageSettings ) override;
|
||||
|
||||
|
|
|
@ -27,32 +27,21 @@
|
|||
#include <pad_naming.h>
|
||||
#include "kicad_clipboard.h"
|
||||
#include "selection_tool.h"
|
||||
#include "pcb_actions.h"
|
||||
#include <core/optional.h>
|
||||
#include <tool/tool_manager.h>
|
||||
#include <class_draw_panel_gal.h>
|
||||
#include <tools/pcb_actions.h>
|
||||
#include <view/view_controls.h>
|
||||
#include <view/view_group.h>
|
||||
#include <pcb_painter.h>
|
||||
#include <origin_viewitem.h>
|
||||
#include <status_popup.h>
|
||||
#include <footprint_edit_frame.h>
|
||||
#include <kicad_plugin.h>
|
||||
#include <pcbnew_id.h>
|
||||
#include <collectors.h>
|
||||
#include <confirm.h>
|
||||
#include <bitmaps.h>
|
||||
#include <pcb_edit_frame.h>
|
||||
#include <class_board.h>
|
||||
#include <class_module.h>
|
||||
#include <class_edge_mod.h>
|
||||
#include <board_commit.h>
|
||||
#include <project.h>
|
||||
#include <tools/tool_event_utils.h>
|
||||
#include <fp_lib_table.h>
|
||||
#include <functional>
|
||||
using namespace std::placeholders;
|
||||
#include <wx/defs.h>
|
||||
#include <dialogs/dialog_cleanup_graphics.h>
|
||||
|
||||
|
||||
FOOTPRINT_EDITOR_TOOLS::FOOTPRINT_EDITOR_TOOLS() :
|
||||
|
@ -605,6 +594,17 @@ int FOOTPRINT_EDITOR_TOOLS::CreatePadFromShapes( const TOOL_EVENT& aEvent )
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int FOOTPRINT_EDITOR_TOOLS::CleanupGraphics( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
FOOTPRINT_EDIT_FRAME* editFrame = getEditFrame<FOOTPRINT_EDIT_FRAME>();
|
||||
DIALOG_CLEANUP_GRAPHICS dlg( editFrame, true );
|
||||
|
||||
dlg.ShowModal();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void FOOTPRINT_EDITOR_TOOLS::setTransitions()
|
||||
{
|
||||
Go( &FOOTPRINT_EDITOR_TOOLS::NewFootprint, PCB_ACTIONS::newFootprint.MakeEvent() );
|
||||
|
@ -625,6 +625,8 @@ void FOOTPRINT_EDITOR_TOOLS::setTransitions()
|
|||
Go( &FOOTPRINT_EDITOR_TOOLS::ImportFootprint, PCB_ACTIONS::importFootprint.MakeEvent() );
|
||||
Go( &FOOTPRINT_EDITOR_TOOLS::ExportFootprint, PCB_ACTIONS::exportFootprint.MakeEvent() );
|
||||
|
||||
Go( &FOOTPRINT_EDITOR_TOOLS::CleanupGraphics, PCB_ACTIONS::cleanupGraphics.MakeEvent() );
|
||||
|
||||
Go( &FOOTPRINT_EDITOR_TOOLS::PinLibrary, ACTIONS::pinLibrary.MakeEvent() );
|
||||
Go( &FOOTPRINT_EDITOR_TOOLS::UnpinLibrary, ACTIONS::unpinLibrary.MakeEvent() );
|
||||
Go( &FOOTPRINT_EDITOR_TOOLS::ToggleFootprintTree, PCB_ACTIONS::toggleFootprintTree.MakeEvent() );
|
||||
|
|
|
@ -67,6 +67,8 @@ public:
|
|||
int ToggleFootprintTree( const TOOL_EVENT& aEvent );
|
||||
int Properties( const TOOL_EVENT& aEvent );
|
||||
|
||||
int CleanupGraphics( const TOOL_EVENT& aEvent );
|
||||
|
||||
/**
|
||||
* Edit the properties used for new pad creation.
|
||||
*/
|
||||
|
|
|
@ -21,21 +21,16 @@
|
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <bitmaps.h>
|
||||
#include <class_track.h>
|
||||
#include <class_zone.h>
|
||||
#include <tool/tool_manager.h>
|
||||
#include <tools/pcb_actions.h>
|
||||
#include <tools/selection_tool.h>
|
||||
#include <tools/edit_tool.h>
|
||||
#include <dialogs/dialog_track_via_properties.h>
|
||||
#include <dialogs/dialog_exchange_footprints.h>
|
||||
#include <dialogs/dialog_cleanup_tracks_and_vias.h>
|
||||
#include <dialogs/dialog_swap_layers.h>
|
||||
#include <tools/global_edit_tool.h>
|
||||
#include <board_commit.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <dialogs/dialog_cleanup_graphics.h>
|
||||
|
||||
GLOBAL_EDIT_TOOL::GLOBAL_EDIT_TOOL() :
|
||||
PCB_TOOL_BASE( "pcbnew.GlobalEdit" ),
|
||||
|
@ -175,6 +170,26 @@ int GLOBAL_EDIT_TOOL::SwapLayers( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
|
||||
|
||||
int GLOBAL_EDIT_TOOL::CleanupTracksAndVias( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
PCB_EDIT_FRAME* editFrame = getEditFrame<PCB_EDIT_FRAME>();
|
||||
DIALOG_CLEANUP_TRACKS_AND_VIAS dlg( editFrame );
|
||||
|
||||
dlg.ShowModal();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int GLOBAL_EDIT_TOOL::CleanupGraphics( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
PCB_EDIT_FRAME* editFrame = getEditFrame<PCB_EDIT_FRAME>();
|
||||
DIALOG_CLEANUP_GRAPHICS dlg( editFrame, false );
|
||||
|
||||
dlg.ShowModal();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void GLOBAL_EDIT_TOOL::setTransitions()
|
||||
{
|
||||
Go( &GLOBAL_EDIT_TOOL::ExchangeFootprints, PCB_ACTIONS::updateFootprint.MakeEvent() );
|
||||
|
@ -188,6 +203,7 @@ void GLOBAL_EDIT_TOOL::setTransitions()
|
|||
Go( &GLOBAL_EDIT_TOOL::EditTextAndGraphics, PCB_ACTIONS::editTextAndGraphics.MakeEvent() );
|
||||
Go( &GLOBAL_EDIT_TOOL::GlobalDeletions, PCB_ACTIONS::globalDeletions.MakeEvent() );
|
||||
Go( &GLOBAL_EDIT_TOOL::CleanupTracksAndVias, PCB_ACTIONS::cleanupTracksAndVias.MakeEvent() );
|
||||
Go( &GLOBAL_EDIT_TOOL::CleanupGraphics, PCB_ACTIONS::cleanupGraphics.MakeEvent() );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -60,6 +60,7 @@ public:
|
|||
int EditTextAndGraphics( const TOOL_EVENT& aEvent );
|
||||
int GlobalDeletions( const TOOL_EVENT& aEvent );
|
||||
int CleanupTracksAndVias( const TOOL_EVENT& aEvent );
|
||||
int CleanupGraphics( const TOOL_EVENT& aEvent );
|
||||
|
||||
private:
|
||||
bool swapBoardItem( BOARD_ITEM* aItem, PCB_LAYER_ID* new_layer );
|
||||
|
|
|
@ -405,9 +405,14 @@ TOOL_ACTION PCB_ACTIONS::globalDeletions( "pcbnew.GlobalEdit.globalDeletions",
|
|||
TOOL_ACTION PCB_ACTIONS::cleanupTracksAndVias( "pcbnew.GlobalEdit.cleanupTracksAndVias",
|
||||
AS_GLOBAL, 0, "",
|
||||
_( "Cleanup Tracks & Vias..." ),
|
||||
_( "Clean stubs, vias, delete break points or unconnected tracks" ),
|
||||
_( "Cleanup redundant items, shorting items, etc." ),
|
||||
delete_xpm );
|
||||
|
||||
TOOL_ACTION PCB_ACTIONS::cleanupGraphics( "pcbnew.GlobalEdit.cleanupGraphics",
|
||||
AS_GLOBAL, 0, "",
|
||||
_( "Cleanup Graphics..." ),
|
||||
_( "Cleanup redundant items, etc." ),
|
||||
delete_xpm );
|
||||
|
||||
// MICROWAVE_TOOL
|
||||
//
|
||||
|
|
|
@ -297,6 +297,7 @@ public:
|
|||
static TOOL_ACTION editTextAndGraphics;
|
||||
static TOOL_ACTION globalDeletions;
|
||||
static TOOL_ACTION cleanupTracksAndVias;
|
||||
static TOOL_ACTION cleanupGraphics;
|
||||
static TOOL_ACTION updateFootprint;
|
||||
static TOOL_ACTION updateFootprints;
|
||||
static TOOL_ACTION changeFootprint;
|
||||
|
|
|
@ -24,14 +24,9 @@
|
|||
*/
|
||||
|
||||
#include <fctsys.h>
|
||||
#include <pcb_edit_frame.h>
|
||||
#include <pcbnew.h>
|
||||
#include <class_board.h>
|
||||
#include <class_track.h>
|
||||
#include <dialog_cleanup_tracks_and_vias.h>
|
||||
#include <reporter.h>
|
||||
#include <board_commit.h>
|
||||
#include <drc/drc_item.h>
|
||||
#include <cleanup_item.h>
|
||||
#include <connectivity/connectivity_algo.h>
|
||||
#include <connectivity/connectivity_data.h>
|
||||
#include <tool/tool_manager.h>
|
||||
|
@ -40,20 +35,8 @@
|
|||
#include <tracks_cleaner.h>
|
||||
|
||||
|
||||
/* Install the cleanup dialog frame to know what should be cleaned
|
||||
*/
|
||||
int GLOBAL_EDIT_TOOL::CleanupTracksAndVias( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
PCB_EDIT_FRAME* editFrame = getEditFrame<PCB_EDIT_FRAME>();
|
||||
DIALOG_CLEANUP_TRACKS_AND_VIAS dlg( editFrame );
|
||||
|
||||
dlg.ShowModal();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
TRACKS_CLEANER::TRACKS_CLEANER( EDA_UNITS aUnits, BOARD* aPcb, BOARD_COMMIT& aCommit )
|
||||
: m_brd( aPcb ),
|
||||
TRACKS_CLEANER::TRACKS_CLEANER( BOARD* aPcb, BOARD_COMMIT& aCommit ) :
|
||||
m_brd( aPcb ),
|
||||
m_commit( aCommit ),
|
||||
m_dryRun( true ),
|
||||
m_itemsList( nullptr )
|
||||
|
@ -67,42 +50,39 @@ TRACKS_CLEANER::TRACKS_CLEANER( EDA_UNITS aUnits, BOARD* aPcb, BOARD_COMMIT& aCo
|
|||
* - vias on pad
|
||||
* - null length segments
|
||||
*/
|
||||
bool TRACKS_CLEANER::CleanupBoard( bool aDryRun, std::vector<DRC_ITEM*>* aItemsList,
|
||||
void TRACKS_CLEANER::CleanupBoard( bool aDryRun, std::vector<CLEANUP_ITEM*>* aItemsList,
|
||||
bool aRemoveMisConnected, bool aCleanVias, bool aMergeSegments,
|
||||
bool aDeleteUnconnected, bool aDeleteTracksinPad )
|
||||
{
|
||||
m_dryRun = aDryRun;
|
||||
m_itemsList = aItemsList;
|
||||
bool modified = false;
|
||||
|
||||
// Clear the flag used to mark some segments as deleted, in dry run:
|
||||
for( auto segment : m_brd->Tracks() )
|
||||
for( TRACK* segment : m_brd->Tracks() )
|
||||
segment->ClearFlags( IS_DELETED );
|
||||
|
||||
// delete redundant vias
|
||||
if( aCleanVias )
|
||||
modified |= cleanupVias();
|
||||
cleanupVias();
|
||||
|
||||
// Remove null segments and intermediate points on aligned segments
|
||||
// If not asked, remove null segments only if remove misconnected is asked
|
||||
if( aMergeSegments )
|
||||
modified |= cleanupSegments();
|
||||
cleanupSegments();
|
||||
else if( aRemoveMisConnected )
|
||||
modified |= deleteNullSegments( m_brd->Tracks() );
|
||||
deleteNullSegments( m_brd->Tracks() );
|
||||
|
||||
if( aRemoveMisConnected )
|
||||
modified |= removeBadTrackSegments();
|
||||
removeBadTrackSegments();
|
||||
|
||||
if( aDeleteTracksinPad )
|
||||
modified |= deleteTracksInPads();
|
||||
deleteTracksInPads();
|
||||
|
||||
// Delete dangling tracks
|
||||
if( aDeleteUnconnected )
|
||||
{
|
||||
if( deleteDanglingTracks() )
|
||||
{
|
||||
modified = true;
|
||||
|
||||
// Removed tracks can leave aligned segments
|
||||
// (when a T was formed by tracks and the "vertical" segment is removed)
|
||||
if( aMergeSegments )
|
||||
|
@ -111,20 +91,18 @@ bool TRACKS_CLEANER::CleanupBoard( bool aDryRun, std::vector<DRC_ITEM*>* aItemsL
|
|||
}
|
||||
|
||||
// Clear the flag used to mark some segments:
|
||||
for( auto segment : m_brd->Tracks() )
|
||||
for( TRACK* segment : m_brd->Tracks() )
|
||||
segment->ClearFlags( IS_DELETED );
|
||||
|
||||
return modified;
|
||||
}
|
||||
|
||||
|
||||
bool TRACKS_CLEANER::removeBadTrackSegments()
|
||||
void TRACKS_CLEANER::removeBadTrackSegments()
|
||||
{
|
||||
auto connectivity = m_brd->GetConnectivity();
|
||||
std::shared_ptr<CONNECTIVITY_DATA> connectivity = m_brd->GetConnectivity();
|
||||
|
||||
std::set<BOARD_ITEM *> toRemove;
|
||||
|
||||
for( auto segment : m_brd->Tracks() )
|
||||
for( TRACK* segment : m_brd->Tracks() )
|
||||
{
|
||||
segment->SetState( FLAG0, false );
|
||||
|
||||
|
@ -132,7 +110,7 @@ bool TRACKS_CLEANER::removeBadTrackSegments()
|
|||
{
|
||||
if( segment->GetNetCode() != testedPad->GetNetCode() )
|
||||
{
|
||||
DRC_ITEM* item = new DRC_ITEM( CLEANUP_SHORT );
|
||||
CLEANUP_ITEM* item = new CLEANUP_ITEM( CLEANUP_SHORT );
|
||||
item->SetItems( segment );
|
||||
m_itemsList->push_back( item );
|
||||
|
||||
|
@ -140,11 +118,11 @@ bool TRACKS_CLEANER::removeBadTrackSegments()
|
|||
}
|
||||
}
|
||||
|
||||
for( auto testedTrack : connectivity->GetConnectedTracks( segment ) )
|
||||
for( TRACK* testedTrack : connectivity->GetConnectedTracks( segment ) )
|
||||
{
|
||||
if( segment->GetNetCode() != testedTrack->GetNetCode() && !testedTrack->GetState( FLAG0 ) )
|
||||
{
|
||||
DRC_ITEM* item = new DRC_ITEM( CLEANUP_SHORT );
|
||||
CLEANUP_ITEM* item = new CLEANUP_ITEM( CLEANUP_SHORT );
|
||||
item->SetItems( segment );
|
||||
m_itemsList->push_back( item );
|
||||
|
||||
|
@ -153,16 +131,17 @@ bool TRACKS_CLEANER::removeBadTrackSegments()
|
|||
}
|
||||
}
|
||||
|
||||
return removeItems( toRemove );
|
||||
if( !m_dryRun )
|
||||
removeItems( toRemove );
|
||||
}
|
||||
|
||||
|
||||
bool TRACKS_CLEANER::cleanupVias()
|
||||
void TRACKS_CLEANER::cleanupVias()
|
||||
{
|
||||
std::set<BOARD_ITEM*> toRemove;
|
||||
std::vector<VIA*> vias;
|
||||
|
||||
for( auto track : m_brd->Tracks() )
|
||||
for( TRACK* track : m_brd->Tracks() )
|
||||
{
|
||||
if( auto via = dyn_cast<VIA*>( track ) )
|
||||
vias.push_back( via );
|
||||
|
@ -170,7 +149,7 @@ bool TRACKS_CLEANER::cleanupVias()
|
|||
|
||||
for( auto via1_it = vias.begin(); via1_it != vias.end(); via1_it++ )
|
||||
{
|
||||
auto via1 = *via1_it;
|
||||
VIA* via1 = *via1_it;
|
||||
|
||||
if( via1->IsLocked() )
|
||||
continue;
|
||||
|
@ -182,14 +161,15 @@ bool TRACKS_CLEANER::cleanupVias()
|
|||
// Examine the list of connected pads:
|
||||
// if a through pad is found, the via can be removed
|
||||
|
||||
const auto pads = m_brd->GetConnectivity()->GetConnectedPads( via1 );
|
||||
for( const auto pad : pads )
|
||||
const std::vector<D_PAD*> pads = m_brd->GetConnectivity()->GetConnectedPads( via1 );
|
||||
|
||||
for( D_PAD* pad : pads )
|
||||
{
|
||||
const LSET all_cu = LSET::AllCuMask();
|
||||
|
||||
if( ( pad->GetLayerSet() & all_cu ) == all_cu )
|
||||
{
|
||||
DRC_ITEM* item = new DRC_ITEM( CLEANUP_REDUNDANT_VIA );
|
||||
CLEANUP_ITEM* item = new CLEANUP_ITEM( CLEANUP_REDUNDANT_VIA );
|
||||
item->SetItems( via1, pad );
|
||||
m_itemsList->push_back( item );
|
||||
|
||||
|
@ -201,14 +181,14 @@ bool TRACKS_CLEANER::cleanupVias()
|
|||
|
||||
for( auto via2_it = via1_it + 1; via2_it != vias.end(); via2_it++ )
|
||||
{
|
||||
auto via2 = *via2_it;
|
||||
VIA* via2 = *via2_it;
|
||||
|
||||
if( via1->GetPosition() != via2->GetPosition() || via2->IsLocked() )
|
||||
continue;
|
||||
|
||||
if( via1->GetViaType() == via2->GetViaType() )
|
||||
{
|
||||
DRC_ITEM* item = new DRC_ITEM( CLEANUP_REDUNDANT_VIA );
|
||||
CLEANUP_ITEM* item = new CLEANUP_ITEM( CLEANUP_REDUNDANT_VIA );
|
||||
item->SetItems( via1, via2 );
|
||||
m_itemsList->push_back( item );
|
||||
|
||||
|
@ -218,8 +198,8 @@ bool TRACKS_CLEANER::cleanupVias()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
return removeItems( toRemove );
|
||||
if( !m_dryRun )
|
||||
removeItems( toRemove );
|
||||
}
|
||||
|
||||
|
||||
|
@ -282,7 +262,7 @@ bool TRACKS_CLEANER::deleteDanglingTracks()
|
|||
if( flag_erase )
|
||||
{
|
||||
int errorCode = track->IsTrack() ? CLEANUP_DANGLING_TRACK : CLEANUP_DANGLING_VIA;
|
||||
DRC_ITEM* item = new DRC_ITEM( errorCode );
|
||||
CLEANUP_ITEM* item = new CLEANUP_ITEM( errorCode );
|
||||
item->SetItems( track );
|
||||
m_itemsList->push_back( item );
|
||||
|
||||
|
@ -307,15 +287,15 @@ bool TRACKS_CLEANER::deleteDanglingTracks()
|
|||
|
||||
|
||||
// Delete null length track segments
|
||||
bool TRACKS_CLEANER::deleteNullSegments( TRACKS& aTracks )
|
||||
void TRACKS_CLEANER::deleteNullSegments( TRACKS& aTracks )
|
||||
{
|
||||
std::set<BOARD_ITEM *> toRemove;
|
||||
|
||||
for( auto segment : aTracks )
|
||||
for( TRACK* segment : aTracks )
|
||||
{
|
||||
if( segment->IsNull() && segment->Type() == PCB_TRACE_T && !segment->IsLocked() )
|
||||
{
|
||||
DRC_ITEM* item = new DRC_ITEM( CLEANUP_ZERO_LENGTH_TRACK );
|
||||
CLEANUP_ITEM* item = new CLEANUP_ITEM( CLEANUP_ZERO_LENGTH_TRACK );
|
||||
item->SetItems( segment );
|
||||
m_itemsList->push_back( item );
|
||||
|
||||
|
@ -323,25 +303,26 @@ bool TRACKS_CLEANER::deleteNullSegments( TRACKS& aTracks )
|
|||
}
|
||||
}
|
||||
|
||||
return removeItems( toRemove );
|
||||
if( !m_dryRun )
|
||||
removeItems( toRemove );
|
||||
}
|
||||
|
||||
|
||||
bool TRACKS_CLEANER::deleteTracksInPads()
|
||||
void TRACKS_CLEANER::deleteTracksInPads()
|
||||
{
|
||||
std::set<BOARD_ITEM*> toRemove;
|
||||
|
||||
// Delete tracks that start and end on the same pad
|
||||
auto connectivity = m_brd->GetConnectivity();
|
||||
std::shared_ptr<CONNECTIVITY_DATA> connectivity = m_brd->GetConnectivity();
|
||||
|
||||
for( auto track : m_brd->Tracks() )
|
||||
for( TRACK* track : m_brd->Tracks() )
|
||||
{
|
||||
// Mark track if connected to pads
|
||||
for( auto pad : connectivity->GetConnectedPads( track ) )
|
||||
for( D_PAD* pad : connectivity->GetConnectedPads( track ) )
|
||||
{
|
||||
if( pad->HitTest( track->GetStart() ) && pad->HitTest( track->GetEnd() ) )
|
||||
{
|
||||
DRC_ITEM* item = new DRC_ITEM( CLEANUP_TRACK_IN_PAD );
|
||||
CLEANUP_ITEM* item = new CLEANUP_ITEM( CLEANUP_TRACK_IN_PAD );
|
||||
item->SetItems( track );
|
||||
m_itemsList->push_back( item );
|
||||
|
||||
|
@ -350,31 +331,30 @@ bool TRACKS_CLEANER::deleteTracksInPads()
|
|||
}
|
||||
}
|
||||
|
||||
return removeItems( toRemove );
|
||||
if( !m_dryRun )
|
||||
removeItems( toRemove );
|
||||
}
|
||||
|
||||
|
||||
// Delete null length segments, and intermediate points ..
|
||||
bool TRACKS_CLEANER::cleanupSegments()
|
||||
void TRACKS_CLEANER::cleanupSegments()
|
||||
{
|
||||
bool modified = false;
|
||||
|
||||
// Easy things first
|
||||
modified |= deleteNullSegments( m_brd->Tracks() );
|
||||
deleteNullSegments( m_brd->Tracks() );
|
||||
|
||||
std::set<BOARD_ITEM*> toRemove;
|
||||
|
||||
// Remove duplicate segments (2 superimposed identical segments):
|
||||
for( auto it = m_brd->Tracks().begin(); it != m_brd->Tracks().end(); it++ )
|
||||
{
|
||||
auto track1 = *it;
|
||||
TRACK* track1 = *it;
|
||||
|
||||
if( track1->Type() != PCB_TRACE_T || track1->HasFlag( IS_DELETED ) || track1->IsLocked() )
|
||||
continue;
|
||||
|
||||
for( auto it2 = it + 1; it2 != m_brd->Tracks().end(); it2++ )
|
||||
{
|
||||
auto track2 = *it2;
|
||||
TRACK* track2 = *it2;
|
||||
|
||||
if( track2->HasFlag( IS_DELETED ) )
|
||||
continue;
|
||||
|
@ -384,7 +364,7 @@ bool TRACKS_CLEANER::cleanupSegments()
|
|||
&& track1->GetWidth() == track2->GetWidth()
|
||||
&& track1->GetLayer() == track2->GetLayer() )
|
||||
{
|
||||
DRC_ITEM* item = new DRC_ITEM( CLEANUP_DUPLICATE_TRACK );
|
||||
CLEANUP_ITEM* item = new CLEANUP_ITEM( CLEANUP_DUPLICATE_TRACK );
|
||||
item->SetItems( track2 );
|
||||
m_itemsList->push_back( item );
|
||||
|
||||
|
@ -394,7 +374,8 @@ bool TRACKS_CLEANER::cleanupSegments()
|
|||
}
|
||||
}
|
||||
|
||||
modified |= removeItems( toRemove );
|
||||
if( !m_dryRun )
|
||||
removeItems( toRemove );
|
||||
|
||||
// Keep a duplicate deque to all deleting in the primary
|
||||
std::deque<TRACK*> temp_segments( m_brd->Tracks() );
|
||||
|
@ -412,9 +393,9 @@ bool TRACKS_CLEANER::cleanupSegments()
|
|||
|
||||
auto& entry = connectivity->GetConnectivityAlgo()->ItemEntry( segment );
|
||||
|
||||
for( auto citem : entry.GetItems() )
|
||||
for( CN_ITEM* citem : entry.GetItems() )
|
||||
{
|
||||
for( auto connected : citem->ConnectedItems() )
|
||||
for( CN_ITEM* connected : citem->ConnectedItems() )
|
||||
{
|
||||
if( !connected->Valid() )
|
||||
continue;
|
||||
|
@ -431,20 +412,18 @@ bool TRACKS_CLEANER::cleanupSegments()
|
|||
continue;
|
||||
|
||||
if( segment->ApproxCollinear( *candidateSegment ) )
|
||||
modified |= mergeCollinearSegments( segment, candidateSegment );
|
||||
mergeCollinearSegments( segment, candidateSegment );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return modified;
|
||||
}
|
||||
|
||||
|
||||
bool TRACKS_CLEANER::mergeCollinearSegments( TRACK* aSeg1, TRACK* aSeg2 )
|
||||
void TRACKS_CLEANER::mergeCollinearSegments( TRACK* aSeg1, TRACK* aSeg2 )
|
||||
{
|
||||
if( aSeg1->IsLocked() || aSeg2->IsLocked() )
|
||||
return false;
|
||||
return;
|
||||
|
||||
auto connectivity = m_brd->GetConnectivity();
|
||||
|
||||
|
@ -478,16 +457,16 @@ bool TRACKS_CLEANER::mergeCollinearSegments( TRACK* aSeg1, TRACK* aSeg2 )
|
|||
if( aSeg1->GetStart() != dummy_seg.GetStart() && aSeg1->GetStart() != dummy_seg.GetEnd() )
|
||||
{
|
||||
if( testTrackEndpointIsNode( aSeg1, true ) )
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
if( aSeg1->GetEnd() != dummy_seg.GetStart() && aSeg1->GetEnd() != dummy_seg.GetEnd() )
|
||||
{
|
||||
if( testTrackEndpointIsNode( aSeg1, false ) )
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
DRC_ITEM* item = new DRC_ITEM( CLEANUP_MERGE_TRACKS );
|
||||
CLEANUP_ITEM* item = new CLEANUP_ITEM( CLEANUP_MERGE_TRACKS );
|
||||
item->SetItems( aSeg1, aSeg2 );
|
||||
m_itemsList->push_back( item );
|
||||
|
||||
|
@ -511,21 +490,14 @@ bool TRACKS_CLEANER::mergeCollinearSegments( TRACK* aSeg1, TRACK* aSeg2 )
|
|||
m_brd->Remove( aSeg2 );
|
||||
m_commit.Removed( aSeg2 );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool TRACKS_CLEANER::removeItems( std::set<BOARD_ITEM*>& aItems )
|
||||
void TRACKS_CLEANER::removeItems( std::set<BOARD_ITEM*>& aItems )
|
||||
{
|
||||
if( m_dryRun )
|
||||
return false;
|
||||
|
||||
for( auto item : aItems )
|
||||
{
|
||||
m_brd->Remove( item );
|
||||
m_commit.Removed( item );
|
||||
}
|
||||
|
||||
return !aItems.empty();
|
||||
}
|
||||
|
|
|
@ -25,60 +25,52 @@
|
|||
#define KICAD_TRACKS_CLEANER_H
|
||||
|
||||
#include <class_track.h>
|
||||
#include <class_board.h>
|
||||
|
||||
class BOARD;
|
||||
class BOARD_COMMIT;
|
||||
class CLEANUP_ITEM;
|
||||
|
||||
|
||||
// Helper class used to clean tracks and vias
|
||||
class TRACKS_CLEANER
|
||||
{
|
||||
public:
|
||||
TRACKS_CLEANER( EDA_UNITS aUnits, BOARD* aPcb, BOARD_COMMIT& aCommit );
|
||||
TRACKS_CLEANER( BOARD* aPcb, BOARD_COMMIT& aCommit );
|
||||
|
||||
/**
|
||||
* the cleanup function.
|
||||
* return true if some item was modified
|
||||
* @param aCleanVias = true to remove superimposed vias
|
||||
* @param aRemoveMisConnected = true to remove segments connecting 2 different nets
|
||||
* (short circuits)
|
||||
* @param aMergeSegments = true to merge collinear segmenst and remove 0 len segm
|
||||
* @param aDeleteUnconnected = true to remove dangling tracks
|
||||
* @param aDeleteTracksinPad = true to remove tracks fully inside pads
|
||||
* (short circuits)
|
||||
*/
|
||||
bool CleanupBoard( bool aDryRun, std::vector<DRC_ITEM*>* aItemsList, bool aCleanVias,
|
||||
void CleanupBoard( bool aDryRun, std::vector<CLEANUP_ITEM*>* aItemsList, bool aCleanVias,
|
||||
bool aRemoveMisConnected, bool aMergeSegments, bool aDeleteUnconnected,
|
||||
bool aDeleteTracksinPad );
|
||||
|
||||
private:
|
||||
/* finds and remove all track segments which are connected to more than one net.
|
||||
* (short circuits)
|
||||
/*
|
||||
* Removes track segments which are connected to more than one net (short circuits).
|
||||
*/
|
||||
bool removeBadTrackSegments();
|
||||
void removeBadTrackSegments();
|
||||
|
||||
/**
|
||||
* Removes redundant vias like vias at same location
|
||||
* or on pad through
|
||||
* Removes redundant vias like vias at same location or on pad through.
|
||||
*/
|
||||
bool cleanupVias();
|
||||
void cleanupVias();
|
||||
|
||||
/**
|
||||
* Removes dangling tracks
|
||||
*/
|
||||
bool deleteDanglingTracks();
|
||||
|
||||
/**
|
||||
* Removes tracks that are fully inside pads
|
||||
*/
|
||||
bool deleteTracksInPads();
|
||||
void deleteTracksInPads();
|
||||
|
||||
/// Delete null length track segments
|
||||
bool deleteNullSegments( TRACKS& aTracks );
|
||||
void deleteNullSegments( TRACKS& aTracks );
|
||||
|
||||
/**
|
||||
* Merge collinear segments and remove duplicated and null len segments
|
||||
* Merge collinear segments and remove duplicated and null length segments.
|
||||
*/
|
||||
bool cleanupSegments();
|
||||
void cleanupSegments();
|
||||
|
||||
/**
|
||||
* helper function
|
||||
|
@ -88,23 +80,23 @@ private:
|
|||
* @param aSeg1 is the reference
|
||||
* @param aSeg2 is the candidate, and after merging, the removed segment
|
||||
*/
|
||||
bool mergeCollinearSegments( TRACK* aSeg1, TRACK* aSeg2 );
|
||||
void mergeCollinearSegments( TRACK* aSeg1, TRACK* aSeg2 );
|
||||
|
||||
/**
|
||||
* @return true if a track end position is a node, i.e. a end connected
|
||||
* to more than one item.
|
||||
* @param aTrack is the track to test.
|
||||
* @param aTstStart = true ot test the start point of the track, and false to
|
||||
* test the end point
|
||||
* @param aTstStart = true ot test the start point of the track or false for end point
|
||||
*/
|
||||
bool testTrackEndpointIsNode( TRACK* aTrack, bool aTstStart );
|
||||
|
||||
void removeItems( std::set<BOARD_ITEM*>& aItems );
|
||||
|
||||
private:
|
||||
BOARD* m_brd;
|
||||
BOARD_COMMIT& m_commit;
|
||||
bool m_dryRun;
|
||||
std::vector<DRC_ITEM*>* m_itemsList;
|
||||
|
||||
bool removeItems( std::set<BOARD_ITEM*>& aItems );
|
||||
std::vector<CLEANUP_ITEM*>* m_itemsList;
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue