Multiple fixes:
- ratsnest is updated now when undoing in legacy view - select whole net regression - local ratsnest in the GAL regression - pick correct zone net for stitching vias - mark nets as dirty on net propagation to force ratsnest update Todo: - cleanup board algorithm is still broken
This commit is contained in:
parent
81dbd930ae
commit
a7759efc59
|
@ -558,6 +558,12 @@ void PCB_LAYER_WIDGET::OnRenderEnable( int aId, bool isEnabled )
|
|||
galCanvas->GetGAL()->SetGridVisibility( myframe->IsGridVisible() );
|
||||
galCanvas->GetView()->MarkTargetDirty( KIGFX::TARGET_NONCACHED );
|
||||
}
|
||||
else if ( aId == LAYER_RATSNEST )
|
||||
{
|
||||
// don't touch the layers. ratsnest is enabled on per-item basis.
|
||||
galCanvas->GetView()->MarkTargetDirty( KIGFX::TARGET_NONCACHED );
|
||||
galCanvas->GetView()->SetLayerVisible( aId, true );
|
||||
}
|
||||
else
|
||||
galCanvas->GetView()->SetLayerVisible( aId, isEnabled );
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include <dialog_cleaning_options.h>
|
||||
#include <board_commit.h>
|
||||
#include <connectivity.h>
|
||||
#include <connectivity_algo.h>
|
||||
|
||||
// Helper class used to clean tracks and vias
|
||||
class TRACKS_CLEANER
|
||||
|
@ -158,18 +159,19 @@ void TRACKS_CLEANER::buildTrackConnectionInfo()
|
|||
connectivity->Build(m_brd);
|
||||
|
||||
// clear flags and variables used in cleanup
|
||||
for( TRACK* track = m_brd->m_Track; track != NULL; track = track->Next() )
|
||||
for( auto track : m_brd->Tracks() )
|
||||
{
|
||||
track->start = NULL;
|
||||
track->end = NULL;
|
||||
track->SetState( START_ON_PAD | END_ON_PAD | BUSY, false );
|
||||
}
|
||||
|
||||
for( TRACK* track = m_brd->m_Track; track != NULL; track = track->Next() )
|
||||
for( auto track : m_brd->Tracks() )
|
||||
{
|
||||
// Mark track if connected to pads
|
||||
for( auto pad : connectivity->GetConnectedPads( track ) )
|
||||
{
|
||||
printf("take pad %p\n", pad);
|
||||
if( pad->HitTest( track->GetStart() ) )
|
||||
{
|
||||
track->start = pad;
|
||||
|
@ -313,6 +315,10 @@ bool TRACKS_CLEANER::cleanupVias()
|
|||
for( VIA* via = GetFirstVia( m_brd->m_Track ); via != NULL;
|
||||
via = GetFirstVia( via->Next() ) )
|
||||
{
|
||||
|
||||
if( via->GetFlags() & TRACK_LOCKED )
|
||||
continue;
|
||||
|
||||
// Correct via m_End defects (if any), should never happen
|
||||
if( via->GetStart() != via->GetEnd() )
|
||||
{
|
||||
|
@ -351,66 +357,27 @@ bool TRACKS_CLEANER::cleanupVias()
|
|||
}
|
||||
|
||||
|
||||
/// Utility for checking if a track/via ends on a zone
|
||||
const ZONE_CONTAINER* TRACKS_CLEANER::zoneForTrackEndpoint( const TRACK* aTrack,
|
||||
ENDPOINT_T aEndPoint )
|
||||
{
|
||||
// Vias are special cased, since they get a layer range, not a single one
|
||||
PCB_LAYER_ID top_layer, bottom_layer;
|
||||
const VIA* via = dyn_cast<const VIA*>( aTrack );
|
||||
|
||||
if( via )
|
||||
via->LayerPair( &top_layer, &bottom_layer );
|
||||
else
|
||||
{
|
||||
top_layer = aTrack->GetLayer();
|
||||
bottom_layer = top_layer;
|
||||
}
|
||||
|
||||
return m_brd->HitTestForAnyFilledArea( aTrack->GetEndPoint( aEndPoint ),
|
||||
top_layer, bottom_layer, aTrack->GetNetCode() );
|
||||
}
|
||||
|
||||
|
||||
/** Utility: does the endpoint unconnected processed for one endpoint of one track
|
||||
* Returns true if the track must be deleted, false if not necessarily */
|
||||
bool TRACKS_CLEANER::testTrackEndpointDangling( TRACK* aTrack, ENDPOINT_T aEndPoint )
|
||||
{
|
||||
bool flag_erase = false;
|
||||
auto connectivity = m_brd->GetConnectivity();
|
||||
VECTOR2I endpoint ;
|
||||
|
||||
TRACK* other = aTrack->GetTrack( m_brd->m_Track, NULL, aEndPoint, true, false );
|
||||
if ( aTrack->Type() == PCB_TRACE_T )
|
||||
endpoint = aTrack->GetEndPoint( aEndPoint );
|
||||
else
|
||||
endpoint = aTrack->GetStart( );
|
||||
|
||||
if( !other && !zoneForTrackEndpoint( aTrack, aEndPoint ) )
|
||||
flag_erase = true; // Start endpoint is neither on pad, zone or other track
|
||||
else // segment, via or zone connected to this end
|
||||
auto anchors = connectivity->GetConnectivityAlgo()->ItemEntry( aTrack ).GetItems().front()->Anchors();
|
||||
|
||||
for ( auto anchor : anchors )
|
||||
{
|
||||
// Fill connectivity informations
|
||||
if( aEndPoint == ENDPOINT_START )
|
||||
aTrack->start = other;
|
||||
else
|
||||
aTrack->end = other;
|
||||
|
||||
/* If a via is connected to this end, test if this via has a second item connected.
|
||||
* If not, remove the current segment (the via would then become
|
||||
* unconnected and remove on the following pass) */
|
||||
VIA* via = dyn_cast<VIA*>( other );
|
||||
|
||||
if( via )
|
||||
{
|
||||
// search for another segment following the via
|
||||
aTrack->SetState( BUSY, true );
|
||||
|
||||
other = via->GetTrack( m_brd->m_Track, NULL, aEndPoint, true, false );
|
||||
|
||||
// There is a via on the start but it goes nowhere
|
||||
if( !other && !zoneForTrackEndpoint( via, aEndPoint ) )
|
||||
flag_erase = true;
|
||||
|
||||
aTrack->SetState( BUSY, false );
|
||||
}
|
||||
if ( anchor->Pos() == endpoint && anchor->IsDangling() )
|
||||
return true;
|
||||
}
|
||||
|
||||
return flag_erase;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -36,60 +36,8 @@
|
|||
|
||||
#include <pcbnew.h>
|
||||
#include <class_board.h>
|
||||
/*
|
||||
* Function SortTracksByNetCode used in RebuildTrackChain()
|
||||
* to sort track segments by net code.
|
||||
*/
|
||||
static bool SortTracksByNetCode( const TRACK* const & ref, const TRACK* const & compare )
|
||||
{
|
||||
// For items having the same Net, keep the order in list
|
||||
if( ref->GetNetCode() == compare->GetNetCode())
|
||||
return ref->m_Param < compare->m_Param;
|
||||
|
||||
return ref->GetNetCode() < compare->GetNetCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function RebuildTrackChain
|
||||
* rebuilds the track segment linked list in order to have a chain
|
||||
* sorted by increasing netcodes.
|
||||
* We try to keep order of track segments in list, when possible
|
||||
* @param pcb = board to rebuild
|
||||
*/
|
||||
static void RebuildTrackChain( BOARD* pcb )
|
||||
{
|
||||
if( pcb->m_Track == NULL )
|
||||
return;
|
||||
|
||||
int item_count = pcb->m_Track.GetCount();
|
||||
|
||||
std::vector<TRACK*> trackList;
|
||||
trackList.reserve( item_count );
|
||||
|
||||
// Put track list in a temporary list to sort tracks by netcode
|
||||
// We try to keep the initial order of track segments in list, when possible
|
||||
// so we use m_Param (a member variable used for temporary storage)
|
||||
// to temporary keep trace of the order of segments
|
||||
// The sort function uses this variable to sort items that
|
||||
// have the same net code.
|
||||
// Without this, during sorting, the initial order is sometimes lost
|
||||
// by the sort algorithm
|
||||
for( int ii = 0; ii < item_count; ++ii )
|
||||
{
|
||||
pcb->m_Track->m_Param = ii;
|
||||
trackList.push_back( pcb->m_Track.PopFront() );
|
||||
}
|
||||
|
||||
// the list is empty now
|
||||
wxASSERT( pcb->m_Track == NULL && pcb->m_Track.GetCount()==0 );
|
||||
|
||||
sort( trackList.begin(), trackList.end(), SortTracksByNetCode );
|
||||
|
||||
// add them back to the list
|
||||
for( int i = 0; i < item_count; ++i )
|
||||
pcb->m_Track.PushBack( trackList[i] );
|
||||
}
|
||||
|
||||
void PCB_BASE_FRAME::TestNetConnection( wxDC* aDC, int aNetCode )
|
||||
{
|
||||
Compile_Ratsnest( aDC, false );
|
||||
}
|
||||
|
|
|
@ -354,10 +354,19 @@ const std::list<BOARD_CONNECTED_ITEM*> CONNECTIVITY_DATA::GetConnectedItems(
|
|||
const std::list<BOARD_CONNECTED_ITEM*> CONNECTIVITY_DATA::GetNetItems( int aNetCode,
|
||||
const KICAD_T aTypes[] ) const
|
||||
{
|
||||
std::list<BOARD_CONNECTED_ITEM*> rv;
|
||||
std::set<BOARD_CONNECTED_ITEM *> items;
|
||||
std::list<BOARD_CONNECTED_ITEM *> rv;
|
||||
|
||||
// FIXME!
|
||||
return rv;
|
||||
// fixme: apply aTypes
|
||||
|
||||
m_connAlgo->ForEachItem( [&items, aNetCode] ( CN_ITEM* aItem) {
|
||||
if ( aItem->Net() == aNetCode )
|
||||
items.insert( aItem->Parent() );
|
||||
} );
|
||||
|
||||
std::copy( items.begin(), items.end(), std::front_inserter( rv ) );
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -211,6 +211,11 @@ public:
|
|||
|
||||
void BlockRatsnestItems( const std::vector<BOARD_ITEM*>& aItems );
|
||||
|
||||
std::shared_ptr<CN_CONNECTIVITY_ALGO> GetConnectivityAlgo() const
|
||||
{
|
||||
return m_connAlgo;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void updateRatsnest();
|
||||
|
|
|
@ -738,6 +738,7 @@ void CN_CONNECTIVITY_ALGO::propagateConnections()
|
|||
if( item->CanChangeNet() )
|
||||
{
|
||||
item->Parent()->SetNetCode( cluster->OriginNet() );
|
||||
markNetAsDirty( cluster->OriginNet() );
|
||||
n_changed++;
|
||||
}
|
||||
}
|
||||
|
@ -902,6 +903,18 @@ void CN_CONNECTIVITY_ALGO::Clear()
|
|||
|
||||
}
|
||||
|
||||
void CN_CONNECTIVITY_ALGO::ForEachItem( std::function<void(CN_ITEM*)> aFunc )
|
||||
{
|
||||
for ( auto item : m_padList )
|
||||
aFunc( item );
|
||||
for ( auto item : m_viaList )
|
||||
aFunc( item );
|
||||
for ( auto item : m_trackList )
|
||||
aFunc( item );
|
||||
for ( auto item : m_zoneList )
|
||||
aFunc( item );
|
||||
}
|
||||
|
||||
void CN_CONNECTIVITY_ALGO::ForEachAnchor( std::function<void(CN_ANCHOR_PTR)> aFunc )
|
||||
{
|
||||
for ( auto anchor : m_padList.Anchors() )
|
||||
|
@ -913,3 +926,8 @@ void CN_CONNECTIVITY_ALGO::ForEachAnchor( std::function<void(CN_ANCHOR_PTR)> aF
|
|||
for ( auto anchor : m_zoneList.Anchors() )
|
||||
aFunc( anchor );
|
||||
}
|
||||
|
||||
bool CN_ANCHOR::IsDangling() const
|
||||
{
|
||||
return m_cluster->Size() <= 1;
|
||||
}
|
||||
|
|
|
@ -119,6 +119,8 @@ public:
|
|||
return m_cluster;
|
||||
}
|
||||
|
||||
bool IsDangling() const;
|
||||
|
||||
// Tag used for unconnected items.
|
||||
static const int TAG_UNCONNECTED = -1;
|
||||
|
||||
|
@ -948,6 +950,7 @@ public:
|
|||
CN_PAD_LIST& PadList() { return m_padList; }
|
||||
|
||||
void ForEachAnchor( std::function<void(CN_ANCHOR_PTR)> aFunc );
|
||||
void ForEachItem( std::function<void(CN_ITEM*)> aFunc );
|
||||
};
|
||||
|
||||
bool operator<( const CN_ANCHOR_PTR a, const CN_ANCHOR_PTR b );
|
||||
|
|
|
@ -160,18 +160,18 @@ DRAWING_TOOL::~DRAWING_TOOL()
|
|||
bool DRAWING_TOOL::Init()
|
||||
{
|
||||
auto activeToolFunctor = [ this ] ( const SELECTION& aSel ) {
|
||||
return m_mode != MODE::NONE;
|
||||
};
|
||||
return m_mode != MODE::NONE;
|
||||
};
|
||||
|
||||
// some interactive drawing tools can undo the last point
|
||||
auto canUndoPoint = [ this ] ( const SELECTION& aSel ) {
|
||||
return m_mode == MODE::ARC || m_mode == MODE::ZONE;
|
||||
};
|
||||
return m_mode == MODE::ARC || m_mode == MODE::ZONE;
|
||||
};
|
||||
|
||||
// functor for zone-only actions
|
||||
auto zoneActiveFunctor = [this ] ( const SELECTION& aSel ) {
|
||||
return m_mode == MODE::ZONE;
|
||||
};
|
||||
return m_mode == MODE::ZONE;
|
||||
};
|
||||
|
||||
auto& ctxMenu = m_menu.GetMenu();
|
||||
|
||||
|
@ -214,13 +214,14 @@ int DRAWING_TOOL::DrawLine( const TOOL_EVENT& aEvent )
|
|||
{
|
||||
BOARD_ITEM_CONTAINER* parent = m_frame->GetModel();
|
||||
DRAWSEGMENT* line = m_editModules ? new EDGE_MODULE( (MODULE*) parent ) : new DRAWSEGMENT;
|
||||
|
||||
boost::optional<VECTOR2D> startingPoint;
|
||||
BOARD_COMMIT commit( m_frame );
|
||||
|
||||
SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::LINE );
|
||||
|
||||
m_frame->SetToolID( m_editModules ? ID_MODEDIT_LINE_TOOL : ID_PCB_ADD_LINE_BUTT,
|
||||
wxCURSOR_PENCIL, _( "Add graphic line" ) );
|
||||
wxCURSOR_PENCIL, _( "Add graphic line" ) );
|
||||
m_lineWidth = getSegmentWidth( getDrawingLayer() );
|
||||
|
||||
while( drawSegment( S_SEGMENT, line, startingPoint ) )
|
||||
|
@ -248,8 +249,8 @@ int DRAWING_TOOL::DrawLine( const TOOL_EVENT& aEvent )
|
|||
int DRAWING_TOOL::DrawCircle( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
BOARD_ITEM_CONTAINER* parent = m_frame->GetModel();
|
||||
DRAWSEGMENT* circle = m_editModules ? new EDGE_MODULE( (MODULE*) parent ) : new DRAWSEGMENT;
|
||||
BOARD_COMMIT commit( m_frame );
|
||||
DRAWSEGMENT* circle = m_editModules ? new EDGE_MODULE( (MODULE*) parent ) : new DRAWSEGMENT;
|
||||
BOARD_COMMIT commit( m_frame );
|
||||
|
||||
SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::CIRCLE );
|
||||
|
||||
|
@ -277,8 +278,8 @@ int DRAWING_TOOL::DrawCircle( const TOOL_EVENT& aEvent )
|
|||
int DRAWING_TOOL::DrawArc( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
BOARD_ITEM_CONTAINER* parent = m_frame->GetModel();
|
||||
DRAWSEGMENT* arc = m_editModules ? new EDGE_MODULE( (MODULE*) parent ) : new DRAWSEGMENT;
|
||||
BOARD_COMMIT commit( m_frame );
|
||||
DRAWSEGMENT* arc = m_editModules ? new EDGE_MODULE( (MODULE*) parent ) : new DRAWSEGMENT;
|
||||
BOARD_COMMIT commit( m_frame );
|
||||
|
||||
SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::ARC );
|
||||
|
||||
|
@ -311,6 +312,7 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent )
|
|||
|
||||
// Add a VIEW_GROUP that serves as a preview for the new item
|
||||
SELECTION preview;
|
||||
|
||||
m_view->Add( &preview );
|
||||
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
|
||||
|
@ -322,7 +324,7 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent )
|
|||
|
||||
Activate();
|
||||
m_frame->SetToolID( m_editModules ? ID_MODEDIT_TEXT_TOOL : ID_PCB_ADD_TEXT_BUTT,
|
||||
wxCURSOR_PENCIL, _( "Add text" ) );
|
||||
wxCURSOR_PENCIL, _( "Add text" ) );
|
||||
|
||||
// Main loop: keep receiving events
|
||||
while( OPT_TOOL_EVENT evt = Wait() )
|
||||
|
@ -346,10 +348,9 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent )
|
|||
else
|
||||
break;
|
||||
|
||||
if( evt->IsActivate() ) // now finish unconditionally
|
||||
if( evt->IsActivate() ) // now finish unconditionally
|
||||
break;
|
||||
}
|
||||
|
||||
else if( text && evt->Category() == TC_COMMAND )
|
||||
{
|
||||
if( TOOL_EVT_UTILS::IsRotateToolEvt( *evt ) )
|
||||
|
@ -366,12 +367,10 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent )
|
|||
m_view->Update( &preview );
|
||||
}
|
||||
}
|
||||
|
||||
else if( evt->IsClick( BUT_RIGHT ) )
|
||||
{
|
||||
m_menu.ShowContextMenu();
|
||||
}
|
||||
|
||||
else if( evt->IsClick( BUT_LEFT ) )
|
||||
{
|
||||
if( !text )
|
||||
|
@ -389,7 +388,7 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent )
|
|||
DialogEditModuleText textDialog( m_frame, textMod, NULL );
|
||||
bool placing;
|
||||
|
||||
RunMainStack( [&]() {
|
||||
RunMainStack([&]() {
|
||||
placing = textDialog.ShowModal() && ( textMod->GetText().Length() > 0 );
|
||||
} );
|
||||
|
||||
|
@ -415,7 +414,7 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent )
|
|||
textPcb->SetThickness( dsnSettings.m_PcbTextWidth );
|
||||
textPcb->SetTextPos( wxPoint( cursorPos.x, cursorPos.y ) );
|
||||
|
||||
RunMainStack( [&]() {
|
||||
RunMainStack([&]() {
|
||||
getEditFrame<PCB_EDIT_FRAME>()->InstallTextPCBOptionsFrame( textPcb, NULL );
|
||||
} );
|
||||
|
||||
|
@ -430,14 +429,14 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent )
|
|||
|
||||
m_controls->CaptureCursor( true );
|
||||
m_controls->SetAutoPan( true );
|
||||
//m_controls->ShowCursor( false );
|
||||
// m_controls->ShowCursor( false );
|
||||
|
||||
preview.Add( text );
|
||||
}
|
||||
else
|
||||
{
|
||||
//assert( text->GetText().Length() > 0 );
|
||||
//assert( text->GetTextSize().x > 0 && text->GetTextSize().y > 0 );
|
||||
// assert( text->GetText().Length() > 0 );
|
||||
// assert( text->GetTextSize().x > 0 && text->GetTextSize().y > 0 );
|
||||
|
||||
text->ClearFlags();
|
||||
preview.Remove( text );
|
||||
|
@ -465,7 +464,6 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent )
|
|||
m_frame->SetNoToolSelected();
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -477,6 +475,7 @@ int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent )
|
|||
|
||||
// Add a VIEW_GROUP that serves as a preview for the new item
|
||||
SELECTION preview;
|
||||
|
||||
m_view->Add( &preview );
|
||||
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
|
||||
|
@ -515,17 +514,15 @@ int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent )
|
|||
else
|
||||
break;
|
||||
|
||||
if( evt->IsActivate() ) // now finish unconditionally
|
||||
if( evt->IsActivate() ) // now finish unconditionally
|
||||
break;
|
||||
}
|
||||
|
||||
else if( evt->IsAction( &PCB_ACTIONS::incWidth ) && step != SET_ORIGIN )
|
||||
{
|
||||
m_lineWidth += WIDTH_STEP;
|
||||
dimension->SetWidth( m_lineWidth );
|
||||
m_view->Update( &preview );
|
||||
}
|
||||
|
||||
else if( evt->IsAction( &PCB_ACTIONS::decWidth ) && step != SET_ORIGIN )
|
||||
{
|
||||
if( m_lineWidth > WIDTH_STEP )
|
||||
|
@ -535,46 +532,44 @@ int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent )
|
|||
m_view->Update( &preview );
|
||||
}
|
||||
}
|
||||
|
||||
else if( evt->IsClick( BUT_RIGHT ) )
|
||||
{
|
||||
m_menu.ShowContextMenu();
|
||||
}
|
||||
|
||||
else if( evt->IsClick( BUT_LEFT ) )
|
||||
{
|
||||
switch( step )
|
||||
{
|
||||
case SET_ORIGIN:
|
||||
{
|
||||
PCB_LAYER_ID layer = getDrawingLayer();
|
||||
{
|
||||
PCB_LAYER_ID layer = getDrawingLayer();
|
||||
|
||||
if( layer == Edge_Cuts ) // dimensions are not allowed on EdgeCuts
|
||||
layer = Dwgs_User;
|
||||
if( layer == Edge_Cuts ) // dimensions are not allowed on EdgeCuts
|
||||
layer = Dwgs_User;
|
||||
|
||||
// Init the new item attributes
|
||||
dimension = new DIMENSION( m_board );
|
||||
dimension->SetLayer( layer );
|
||||
dimension->SetOrigin( wxPoint( cursorPos.x, cursorPos.y ) );
|
||||
dimension->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) );
|
||||
dimension->Text().SetTextSize( m_board->GetDesignSettings().m_PcbTextSize );
|
||||
// Init the new item attributes
|
||||
dimension = new DIMENSION( m_board );
|
||||
dimension->SetLayer( layer );
|
||||
dimension->SetOrigin( wxPoint( cursorPos.x, cursorPos.y ) );
|
||||
dimension->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) );
|
||||
dimension->Text().SetTextSize( m_board->GetDesignSettings().m_PcbTextSize );
|
||||
|
||||
int width = m_board->GetDesignSettings().m_PcbTextWidth;
|
||||
maxThickness = Clamp_Text_PenSize( width, dimension->Text().GetTextSize() );
|
||||
int width = m_board->GetDesignSettings().m_PcbTextWidth;
|
||||
maxThickness = Clamp_Text_PenSize( width, dimension->Text().GetTextSize() );
|
||||
|
||||
if( width > maxThickness )
|
||||
width = maxThickness;
|
||||
if( width > maxThickness )
|
||||
width = maxThickness;
|
||||
|
||||
dimension->Text().SetThickness( width );
|
||||
dimension->SetWidth( width );
|
||||
dimension->AdjustDimensionDetails();
|
||||
dimension->Text().SetThickness( width );
|
||||
dimension->SetWidth( width );
|
||||
dimension->AdjustDimensionDetails();
|
||||
|
||||
preview.Add( dimension );
|
||||
preview.Add( dimension );
|
||||
|
||||
m_controls->SetAutoPan( true );
|
||||
m_controls->CaptureCursor( true );
|
||||
}
|
||||
break;
|
||||
m_controls->SetAutoPan( true );
|
||||
m_controls->CaptureCursor( true );
|
||||
}
|
||||
break;
|
||||
|
||||
case SET_END:
|
||||
dimension->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) );
|
||||
|
@ -582,23 +577,23 @@ int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent )
|
|||
// Dimensions that have origin and end in the same spot are not valid
|
||||
if( dimension->GetOrigin() == dimension->GetEnd() )
|
||||
--step;
|
||||
|
||||
break;
|
||||
|
||||
case SET_HEIGHT:
|
||||
{
|
||||
if( wxPoint( cursorPos.x, cursorPos.y ) != dimension->GetPosition() )
|
||||
{
|
||||
if( wxPoint( cursorPos.x, cursorPos.y ) != dimension->GetPosition() )
|
||||
{
|
||||
assert( dimension->GetOrigin() != dimension->GetEnd() );
|
||||
assert( dimension->GetWidth() > 0 );
|
||||
assert( dimension->GetOrigin() != dimension->GetEnd() );
|
||||
assert( dimension->GetWidth() > 0 );
|
||||
|
||||
preview.Remove( dimension );
|
||||
preview.Remove( dimension );
|
||||
|
||||
commit.Add( dimension );
|
||||
commit.Push( _( "Draw a dimension" ) );
|
||||
|
||||
}
|
||||
commit.Add( dimension );
|
||||
commit.Push( _( "Draw a dimension" ) );
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if( ++step == FINISHED )
|
||||
|
@ -608,7 +603,6 @@ int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent )
|
|||
m_controls->CaptureCursor( false );
|
||||
}
|
||||
}
|
||||
|
||||
else if( evt->IsMotion() )
|
||||
{
|
||||
switch( step )
|
||||
|
@ -624,7 +618,7 @@ int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent )
|
|||
|
||||
wxPoint pos( cursorPos.x, cursorPos.y );
|
||||
wxPoint delta( pos - dimension->m_featureLineDO );
|
||||
double height = ( delta.x * cos( angle ) ) + ( delta.y * sin( angle ) );
|
||||
double height = ( delta.x * cos( angle ) ) + ( delta.y * sin( angle ) );
|
||||
dimension->SetHeight( height );
|
||||
}
|
||||
break;
|
||||
|
@ -648,6 +642,7 @@ int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent )
|
|||
int DRAWING_TOOL::DrawZone( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::ZONE );
|
||||
|
||||
m_frame->SetToolID( ID_PCB_ZONES_BUTT, wxCURSOR_PENCIL, _( "Add zones" ) );
|
||||
|
||||
return drawZone( false, ZONE_MODE::ADD );
|
||||
|
@ -657,6 +652,7 @@ int DRAWING_TOOL::DrawZone( const TOOL_EVENT& aEvent )
|
|||
int DRAWING_TOOL::DrawZoneKeepout( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::KEEPOUT );
|
||||
|
||||
m_frame->SetToolID( ID_PCB_KEEPOUT_AREA_BUTT, wxCURSOR_PENCIL, _( "Add keepout" ) );
|
||||
|
||||
return drawZone( true, ZONE_MODE::ADD );
|
||||
|
@ -666,6 +662,7 @@ int DRAWING_TOOL::DrawZoneKeepout( const TOOL_EVENT& aEvent )
|
|||
int DRAWING_TOOL::DrawZoneCutout( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::ZONE );
|
||||
|
||||
m_frame->SetToolID( ID_PCB_ZONES_BUTT, wxCURSOR_PENCIL, _( "Add zone cutout" ) );
|
||||
|
||||
return drawZone( false, ZONE_MODE::CUTOUT );
|
||||
|
@ -675,6 +672,7 @@ int DRAWING_TOOL::DrawZoneCutout( const TOOL_EVENT& aEvent )
|
|||
int DRAWING_TOOL::DrawSimilarZone( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::ZONE );
|
||||
|
||||
m_frame->SetToolID( ID_PCB_ZONES_BUTT, wxCURSOR_PENCIL, _( "Add similar zone" ) );
|
||||
|
||||
return drawZone( false, ZONE_MODE::SIMILAR );
|
||||
|
@ -694,8 +692,8 @@ int DRAWING_TOOL::PlaceDXF( const TOOL_EVENT& aEvent )
|
|||
if( dlgResult != wxID_OK || list.empty() )
|
||||
return 0;
|
||||
|
||||
VECTOR2I cursorPos = m_controls->GetCursorPosition();
|
||||
VECTOR2I delta = cursorPos - list.front()->GetPosition();
|
||||
VECTOR2I cursorPos = m_controls->GetCursorPosition();
|
||||
VECTOR2I delta = cursorPos - list.front()->GetPosition();
|
||||
|
||||
// Add a VIEW_GROUP that serves as a preview for the new item
|
||||
SELECTION preview;
|
||||
|
@ -733,14 +731,13 @@ int DRAWING_TOOL::PlaceDXF( const TOOL_EVENT& aEvent )
|
|||
|
||||
m_view->Update( &preview );
|
||||
}
|
||||
|
||||
else if( evt->Category() == TC_COMMAND )
|
||||
{
|
||||
// TODO it should be handled by EDIT_TOOL, so add items and select?
|
||||
if( TOOL_EVT_UTILS::IsRotateToolEvt( *evt ) )
|
||||
{
|
||||
const auto rotationPoint = wxPoint( cursorPos.x, cursorPos.y );
|
||||
const auto rotationAngle = TOOL_EVT_UTILS::GetEventRotationAngle(
|
||||
const auto rotationPoint = wxPoint( cursorPos.x, cursorPos.y );
|
||||
const auto rotationAngle = TOOL_EVT_UTILS::GetEventRotationAngle(
|
||||
*m_frame, *evt );
|
||||
|
||||
for( auto item : preview )
|
||||
|
@ -763,12 +760,10 @@ int DRAWING_TOOL::PlaceDXF( const TOOL_EVENT& aEvent )
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
else if( evt->IsClick( BUT_RIGHT ) )
|
||||
{
|
||||
m_menu.ShowContextMenu();
|
||||
}
|
||||
|
||||
else if( evt->IsClick( BUT_LEFT ) )
|
||||
{
|
||||
// Place the drawing
|
||||
|
@ -807,7 +802,7 @@ int DRAWING_TOOL::PlaceDXF( const TOOL_EVENT& aEvent )
|
|||
textMod->SetMultilineAllowed( text->IsMultilineAllowed() );
|
||||
#else
|
||||
textMod->EDA_TEXT::SetEffects( *text );
|
||||
textMod->SetLocalCoord(); // using changed SetTexPos() via SetEffects()
|
||||
textMod->SetLocalCoord(); // using changed SetTexPos() via SetEffects()
|
||||
#endif
|
||||
converted = textMod;
|
||||
break;
|
||||
|
@ -815,8 +810,8 @@ int DRAWING_TOOL::PlaceDXF( const TOOL_EVENT& aEvent )
|
|||
|
||||
case PCB_LINE_T:
|
||||
{
|
||||
DRAWSEGMENT* seg = static_cast<DRAWSEGMENT*>( item );
|
||||
EDGE_MODULE* modSeg = new EDGE_MODULE( (MODULE*) parent );
|
||||
DRAWSEGMENT* seg = static_cast<DRAWSEGMENT*>( item );
|
||||
EDGE_MODULE* modSeg = new EDGE_MODULE( (MODULE*) parent );
|
||||
|
||||
// Assignment operator also copies the item PCB_LINE_T type,
|
||||
// so it cannot be added to a module which handles PCB_MODULE_EDGE_T
|
||||
|
@ -870,7 +865,7 @@ int DRAWING_TOOL::SetAnchor( const TOOL_EVENT& aEvent )
|
|||
|
||||
Activate();
|
||||
m_frame->SetToolID( ID_MODEDIT_ANCHOR_TOOL, wxCURSOR_PENCIL,
|
||||
_( "Place the footprint anchor" ) );
|
||||
_( "Place the footprint anchor" ) );
|
||||
|
||||
m_controls->ShowCursor( true );
|
||||
m_controls->SetSnapping( true );
|
||||
|
@ -886,8 +881,8 @@ int DRAWING_TOOL::SetAnchor( const TOOL_EVENT& aEvent )
|
|||
commit.Modify( module );
|
||||
|
||||
// set the new relative internal local coordinates of footprint items
|
||||
VECTOR2I cursorPos = m_controls->GetCursorPosition();
|
||||
wxPoint moveVector = module->GetPosition() - wxPoint( cursorPos.x, cursorPos.y );
|
||||
VECTOR2I cursorPos = m_controls->GetCursorPosition();
|
||||
wxPoint moveVector = module->GetPosition() - wxPoint( cursorPos.x, cursorPos.y );
|
||||
module->MoveAnchorPosition( moveVector );
|
||||
|
||||
commit.Push( _( "Move the footprint reference anchor" ) );
|
||||
|
@ -900,7 +895,7 @@ int DRAWING_TOOL::SetAnchor( const TOOL_EVENT& aEvent )
|
|||
{
|
||||
m_menu.ShowContextMenu();
|
||||
}
|
||||
else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
|
||||
else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -911,7 +906,7 @@ int DRAWING_TOOL::SetAnchor( const TOOL_EVENT& aEvent )
|
|||
|
||||
|
||||
bool DRAWING_TOOL::drawSegment( int aShape, DRAWSEGMENT*& aGraphic,
|
||||
boost::optional<VECTOR2D> aStartingPoint )
|
||||
boost::optional<VECTOR2D> aStartingPoint )
|
||||
{
|
||||
// Only two shapes are currently supported
|
||||
assert( aShape == S_SEGMENT || aShape == S_CIRCLE );
|
||||
|
@ -928,8 +923,8 @@ bool DRAWING_TOOL::drawSegment( int aShape, DRAWSEGMENT*& aGraphic,
|
|||
|
||||
Activate();
|
||||
|
||||
bool direction45 = false; // 45 degrees only mode
|
||||
bool started = false;
|
||||
bool direction45 = false; // 45 degrees only mode
|
||||
bool started = false;
|
||||
VECTOR2I cursorPos = m_controls->GetCursorPosition();
|
||||
|
||||
if( aStartingPoint )
|
||||
|
@ -1016,16 +1011,17 @@ bool DRAWING_TOOL::drawSegment( int aShape, DRAWSEGMENT*& aGraphic,
|
|||
}
|
||||
else
|
||||
{
|
||||
if( aGraphic->GetEnd() == aGraphic->GetStart() ||
|
||||
( evt->IsDblClick( BUT_LEFT ) && aShape == S_SEGMENT ) )
|
||||
// User has clicked twice in the same spot
|
||||
{ // a clear sign that the current drawing is finished
|
||||
if( aGraphic->GetEnd() == aGraphic->GetStart()
|
||||
|| ( evt->IsDblClick( BUT_LEFT ) && aShape == S_SEGMENT ) )
|
||||
// User has clicked twice in the same spot
|
||||
{
|
||||
// a clear sign that the current drawing is finished
|
||||
// Now we have to add the helper line as well
|
||||
if( direction45 )
|
||||
{
|
||||
BOARD_ITEM_CONTAINER* parent = m_frame->GetModel();
|
||||
DRAWSEGMENT* l = m_editModules ? new EDGE_MODULE( (MODULE*) parent )
|
||||
: new DRAWSEGMENT;
|
||||
: new DRAWSEGMENT;
|
||||
|
||||
// Copy coordinates, layer, etc.
|
||||
*static_cast<DRAWSEGMENT*>( l ) = line45;
|
||||
|
@ -1044,7 +1040,6 @@ bool DRAWING_TOOL::drawSegment( int aShape, DRAWSEGMENT*& aGraphic,
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
else if( evt->IsMotion() )
|
||||
{
|
||||
// 45 degree lines
|
||||
|
@ -1055,7 +1050,6 @@ bool DRAWING_TOOL::drawSegment( int aShape, DRAWSEGMENT*& aGraphic,
|
|||
|
||||
m_view->Update( &preview );
|
||||
}
|
||||
|
||||
else if( evt->IsAction( &PCB_ACTIONS::incWidth ) )
|
||||
{
|
||||
m_lineWidth += WIDTH_STEP;
|
||||
|
@ -1063,7 +1057,6 @@ bool DRAWING_TOOL::drawSegment( int aShape, DRAWSEGMENT*& aGraphic,
|
|||
line45.SetWidth( m_lineWidth );
|
||||
m_view->Update( &preview );
|
||||
}
|
||||
|
||||
else if( evt->IsAction( &PCB_ACTIONS::decWidth ) && ( m_lineWidth > WIDTH_STEP ) )
|
||||
{
|
||||
m_lineWidth -= WIDTH_STEP;
|
||||
|
@ -1085,8 +1078,7 @@ bool DRAWING_TOOL::drawSegment( int aShape, DRAWSEGMENT*& aGraphic,
|
|||
* Update an arc DRAWSEGMENT from the current state
|
||||
* of an Arc Geometry Manager
|
||||
*/
|
||||
static void updateArcFromConstructionMgr(
|
||||
const KIGFX::PREVIEW::ARC_GEOM_MANAGER& aMgr,
|
||||
static void updateArcFromConstructionMgr( const KIGFX::PREVIEW::ARC_GEOM_MANAGER& aMgr,
|
||||
DRAWSEGMENT& aArc )
|
||||
{
|
||||
auto vec = aMgr.GetOrigin();
|
||||
|
@ -1148,12 +1140,10 @@ bool DRAWING_TOOL::drawArc( DRAWSEGMENT*& aGraphic )
|
|||
|
||||
arcManager.AddPoint( cursorPos, true );
|
||||
}
|
||||
|
||||
else if( evt->IsAction( &deleteLastPoint ) )
|
||||
{
|
||||
arcManager.RemoveLastPoint();
|
||||
}
|
||||
|
||||
else if( evt->IsMotion() )
|
||||
{
|
||||
// set angle snap
|
||||
|
@ -1162,7 +1152,6 @@ bool DRAWING_TOOL::drawArc( DRAWSEGMENT*& aGraphic )
|
|||
// update, but don't step the manager state
|
||||
arcManager.AddPoint( cursorPos, false );
|
||||
}
|
||||
|
||||
else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
|
||||
{
|
||||
preview.Clear();
|
||||
|
@ -1174,21 +1163,18 @@ bool DRAWING_TOOL::drawArc( DRAWSEGMENT*& aGraphic )
|
|||
{
|
||||
m_menu.ShowContextMenu();
|
||||
}
|
||||
|
||||
else if( evt->IsAction( &PCB_ACTIONS::incWidth ) )
|
||||
{
|
||||
m_lineWidth += WIDTH_STEP;
|
||||
aGraphic->SetWidth( m_lineWidth );
|
||||
m_view->Update( &preview );
|
||||
}
|
||||
|
||||
else if( evt->IsAction( &PCB_ACTIONS::decWidth ) && m_lineWidth > WIDTH_STEP )
|
||||
{
|
||||
m_lineWidth -= WIDTH_STEP;
|
||||
aGraphic->SetWidth( m_lineWidth );
|
||||
m_view->Update( &preview );
|
||||
}
|
||||
|
||||
else if( evt->IsAction( &PCB_ACTIONS::arcPosture ) )
|
||||
{
|
||||
arcManager.ToggleClockwise();
|
||||
|
@ -1246,8 +1232,8 @@ bool DRAWING_TOOL::getSourceZoneForAction( ZONE_MODE aMode, ZONE_CONTAINER*& aZo
|
|||
|
||||
void DRAWING_TOOL::runPolygonEventLoop( POLYGON_GEOM_MANAGER& polyGeomMgr )
|
||||
{
|
||||
auto& controls = *getViewControls();
|
||||
bool started = false;
|
||||
auto& controls = *getViewControls();
|
||||
bool started = false;
|
||||
|
||||
while( OPT_TOOL_EVENT evt = Wait() )
|
||||
{
|
||||
|
@ -1269,21 +1255,19 @@ void DRAWING_TOOL::runPolygonEventLoop( POLYGON_GEOM_MANAGER& polyGeomMgr )
|
|||
controls.SetAutoPan( false );
|
||||
controls.CaptureCursor( false );
|
||||
}
|
||||
|
||||
else if( evt->IsClick( BUT_RIGHT ) )
|
||||
{
|
||||
m_menu.ShowContextMenu();
|
||||
}
|
||||
|
||||
// events that lock in nodes
|
||||
else if( evt->IsClick( BUT_LEFT )
|
||||
|| evt->IsDblClick( BUT_LEFT )
|
||||
|| evt->IsAction( &closeZoneOutline ) )
|
||||
|| evt->IsDblClick( BUT_LEFT )
|
||||
|| evt->IsAction( &closeZoneOutline ) )
|
||||
{
|
||||
// Check if it is double click / closing line (so we have to finish the zone)
|
||||
const bool endPolygon = evt->IsDblClick( BUT_LEFT )
|
||||
|| evt->IsAction( &closeZoneOutline )
|
||||
|| polyGeomMgr.NewPointClosesOutline( cursorPos );
|
||||
|| evt->IsAction( &closeZoneOutline )
|
||||
|| polyGeomMgr.NewPointClosesOutline( cursorPos );
|
||||
|
||||
if( endPolygon )
|
||||
{
|
||||
|
@ -1295,7 +1279,7 @@ void DRAWING_TOOL::runPolygonEventLoop( POLYGON_GEOM_MANAGER& polyGeomMgr )
|
|||
controls.SetAutoPan( false );
|
||||
controls.CaptureCursor( false );
|
||||
}
|
||||
else // adding a corner
|
||||
else // adding a corner
|
||||
{
|
||||
polyGeomMgr.AddPoint( cursorPos );
|
||||
|
||||
|
@ -1307,7 +1291,6 @@ void DRAWING_TOOL::runPolygonEventLoop( POLYGON_GEOM_MANAGER& polyGeomMgr )
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if( evt->IsAction( &deleteLastPoint ) )
|
||||
{
|
||||
polyGeomMgr.DeleteLastCorner();
|
||||
|
@ -1323,16 +1306,15 @@ void DRAWING_TOOL::runPolygonEventLoop( POLYGON_GEOM_MANAGER& polyGeomMgr )
|
|||
controls.CaptureCursor( false );
|
||||
}
|
||||
}
|
||||
|
||||
else if( polyGeomMgr.IsPolygonInProgress()
|
||||
&& ( evt->IsMotion() || evt->IsDrag( BUT_LEFT ) ) )
|
||||
&& ( evt->IsMotion() || evt->IsDrag( BUT_LEFT ) ) )
|
||||
{
|
||||
bool draw45 = evt->Modifier( MD_CTRL );
|
||||
polyGeomMgr.SetLeaderMode( draw45 ? POLYGON_GEOM_MANAGER::LEADER_MODE::DEG45
|
||||
: POLYGON_GEOM_MANAGER::LEADER_MODE::DIRECT );
|
||||
: POLYGON_GEOM_MANAGER::LEADER_MODE::DIRECT );
|
||||
polyGeomMgr.SetCursorPosition( cursorPos );
|
||||
}
|
||||
} // end while
|
||||
} // end while
|
||||
}
|
||||
|
||||
|
||||
|
@ -1358,7 +1340,7 @@ int DRAWING_TOOL::drawZone( bool aKeepout, ZONE_MODE aMode )
|
|||
// hands the calculated points over to the zone creator tool
|
||||
POLYGON_GEOM_MANAGER polyGeomMgr( zoneTool );
|
||||
|
||||
Activate(); // register for events
|
||||
Activate(); // register for events
|
||||
|
||||
auto& controls = *getViewControls();
|
||||
|
||||
|
@ -1377,8 +1359,8 @@ int DRAWING_TOOL::drawZone( bool aKeepout, ZONE_MODE aMode )
|
|||
|
||||
void DRAWING_TOOL::make45DegLine( DRAWSEGMENT* aSegment, DRAWSEGMENT* aHelper ) const
|
||||
{
|
||||
VECTOR2I cursorPos = m_controls->GetCursorPosition();
|
||||
VECTOR2I origin( aSegment->GetStart() );
|
||||
VECTOR2I cursorPos = m_controls->GetCursorPosition();
|
||||
VECTOR2I origin( aSegment->GetStart() );
|
||||
DIRECTION_45 direction( origin - cursorPos );
|
||||
SHAPE_LINE_CHAIN newChain = direction.BuildInitialTrace( origin, cursorPos );
|
||||
|
||||
|
@ -1396,76 +1378,94 @@ void DRAWING_TOOL::make45DegLine( DRAWSEGMENT* aSegment, DRAWSEGMENT* aHelper )
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
int DRAWING_TOOL::DrawVia( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
struct VIA_PLACER : public INTERACTIVE_PLACER_BASE
|
||||
{
|
||||
int findStitchedZoneNet( VIA *aVia )
|
||||
int findStitchedZoneNet( VIA* aVia )
|
||||
{
|
||||
const auto pos = aVia->GetPosition();
|
||||
const auto lset = aVia->GetLayerSet();
|
||||
const auto pos = aVia->GetPosition();
|
||||
const auto lset = aVia->GetLayerSet();
|
||||
|
||||
for ( auto tv : m_board->Tracks() ) // fixme: move to BOARD class?
|
||||
if( tv->HitTest(pos) && (tv->GetLayerSet() &
|
||||
lset ).any() )
|
||||
for( auto tv : m_board->Tracks() ) // fixme: move to BOARD class?
|
||||
if( tv->HitTest( pos ) && (tv->GetLayerSet() &
|
||||
lset ).any() )
|
||||
return -1;
|
||||
|
||||
for ( auto mod : m_board->Modules() )
|
||||
for ( auto pad : mod->Pads() )
|
||||
if( pad->HitTest(pos) && (pad->GetLayerSet() &
|
||||
lset ).any() )
|
||||
return -1;
|
||||
|
||||
std::set<ZONE_CONTAINER* > foundZones;
|
||||
|
||||
for( auto mod : m_board->Modules() )
|
||||
for( auto pad : mod->Pads() )
|
||||
if( pad->HitTest( pos ) && (pad->GetLayerSet() &
|
||||
lset ).any() )
|
||||
return -1;
|
||||
|
||||
|
||||
|
||||
std::vector<ZONE_CONTAINER*> foundZones;
|
||||
|
||||
for( auto zone : m_board->Zones() )
|
||||
{
|
||||
if ( zone->HitTestFilledArea ( pos ) )
|
||||
if( zone->HitTestFilledArea( pos ) )
|
||||
{
|
||||
foundZones.insert ( zone );
|
||||
foundZones.push_back( zone );
|
||||
}
|
||||
}
|
||||
|
||||
printf( "Found zones : %d\n", foundZones.size() );
|
||||
|
||||
std::sort( foundZones.begin(), foundZones.end(),
|
||||
[] ( const ZONE_CONTAINER* a, const ZONE_CONTAINER* b ) {
|
||||
return a->GetLayer() < b->GetLayer();
|
||||
} );
|
||||
|
||||
// first take the net of the active layer
|
||||
for( auto z : foundZones )
|
||||
{
|
||||
if ( m_frame->GetActiveLayer() == z->GetLayer() )
|
||||
if( m_frame->GetActiveLayer() == z->GetLayer() )
|
||||
return z->GetNetCode();
|
||||
}
|
||||
|
||||
// none? take the topmost visible layer
|
||||
for( auto z : foundZones )
|
||||
{
|
||||
if( m_board->IsLayerVisible( z->GetLayer() ) )
|
||||
return z->GetNetCode();
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool PlaceItem( BOARD_ITEM *aItem ) override
|
||||
bool PlaceItem( BOARD_ITEM* aItem ) override
|
||||
{
|
||||
auto via = static_cast<VIA*>(aItem);
|
||||
int newNet = findStitchedZoneNet(via);
|
||||
auto via = static_cast<VIA*>( aItem );
|
||||
int newNet = findStitchedZoneNet( via );
|
||||
|
||||
if(newNet > 0 )
|
||||
if( newNet > 0 )
|
||||
via->SetNetCode( newNet );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
std::unique_ptr<BOARD_ITEM> CreateItem() override
|
||||
{
|
||||
auto& ds = m_board->GetDesignSettings();
|
||||
VIA* via = new VIA ( m_board );
|
||||
auto& ds = m_board->GetDesignSettings();
|
||||
VIA* via = new VIA( m_board );
|
||||
|
||||
via->SetNetCode( 0 );
|
||||
via->SetViaType( ds.m_CurrentViaType );
|
||||
|
||||
// for microvias, the size and hole will be changed later.
|
||||
via->SetWidth( ds.GetCurrentViaSize());
|
||||
via->SetWidth( ds.GetCurrentViaSize() );
|
||||
via->SetDrill( ds.GetCurrentViaDrill() );
|
||||
|
||||
// Usual via is from copper to component.
|
||||
// layer pair is B_Cu and F_Cu.
|
||||
via->SetLayerPair( B_Cu, F_Cu );
|
||||
|
||||
PCB_LAYER_ID first_layer = m_frame->GetActiveLayer();
|
||||
PCB_LAYER_ID last_layer;
|
||||
PCB_LAYER_ID first_layer = m_frame->GetActiveLayer();
|
||||
PCB_LAYER_ID last_layer;
|
||||
|
||||
// prepare switch to new active layer:
|
||||
if( first_layer != m_frame->GetScreen()->m_Route_Layer_TOP )
|
||||
|
@ -1480,39 +1480,41 @@ int DRAWING_TOOL::DrawVia( const TOOL_EVENT& aEvent )
|
|||
via->SetLayerPair( first_layer, last_layer );
|
||||
break;
|
||||
|
||||
case VIA_MICROVIA: // from external to the near neighbor inner layer
|
||||
case VIA_MICROVIA: // from external to the near neighbor inner layer
|
||||
{
|
||||
PCB_LAYER_ID last_inner_layer =
|
||||
ToLAYER_ID( ( m_board->GetCopperLayerCount() - 2 ) );
|
||||
|
||||
if( first_layer == B_Cu )
|
||||
last_layer = last_inner_layer;
|
||||
else if( first_layer == F_Cu )
|
||||
last_layer = In1_Cu;
|
||||
else if( first_layer == last_inner_layer )
|
||||
last_layer = B_Cu;
|
||||
else if( first_layer == In1_Cu )
|
||||
last_layer = F_Cu;
|
||||
|
||||
// else error: will be removed later
|
||||
via->SetLayerPair( first_layer, last_layer );
|
||||
|
||||
// Update diameter and hole size, which where set previously
|
||||
// for normal vias
|
||||
NETINFO_ITEM* net = via->GetNet();
|
||||
|
||||
if( net )
|
||||
{
|
||||
PCB_LAYER_ID last_inner_layer = ToLAYER_ID( ( m_board->GetCopperLayerCount() - 2 ) );
|
||||
|
||||
if( first_layer == B_Cu )
|
||||
last_layer = last_inner_layer;
|
||||
else if( first_layer == F_Cu )
|
||||
last_layer = In1_Cu;
|
||||
else if( first_layer == last_inner_layer )
|
||||
last_layer = B_Cu;
|
||||
else if( first_layer == In1_Cu )
|
||||
last_layer = F_Cu;
|
||||
// else error: will be removed later
|
||||
via->SetLayerPair( first_layer, last_layer );
|
||||
|
||||
// Update diameter and hole size, which where set previously
|
||||
// for normal vias
|
||||
NETINFO_ITEM* net = via->GetNet();
|
||||
if( net )
|
||||
{
|
||||
via->SetWidth( net->GetMicroViaSize() );
|
||||
via->SetDrill( net->GetMicroViaDrillSize() );
|
||||
}
|
||||
via->SetWidth( net->GetMicroViaSize() );
|
||||
via->SetDrill( net->GetMicroViaDrillSize() );
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
return std::unique_ptr<BOARD_ITEM>(via);
|
||||
return std::unique_ptr<BOARD_ITEM>( via );
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1520,27 +1522,30 @@ int DRAWING_TOOL::DrawVia( const TOOL_EVENT& aEvent )
|
|||
|
||||
frame()->SetToolID( ID_PCB_DRAW_VIA_BUTT, wxCURSOR_PENCIL, _( "Add vias" ) );
|
||||
|
||||
doInteractiveItemPlacement( &placer, _( "Place via" ), IPO_REPEAT | IPO_SINGLE_CLICK | IPO_ROTATE | IPO_FLIP | IPO_PROPERTIES );
|
||||
doInteractiveItemPlacement( &placer, _(
|
||||
"Place via" ),
|
||||
IPO_REPEAT | IPO_SINGLE_CLICK | IPO_ROTATE | IPO_FLIP | IPO_PROPERTIES );
|
||||
|
||||
frame()->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void DRAWING_TOOL::SetTransitions()
|
||||
{
|
||||
Go( &DRAWING_TOOL::DrawLine, PCB_ACTIONS::drawLine.MakeEvent() );
|
||||
Go( &DRAWING_TOOL::DrawCircle, PCB_ACTIONS::drawCircle.MakeEvent() );
|
||||
Go( &DRAWING_TOOL::DrawArc, PCB_ACTIONS::drawArc.MakeEvent() );
|
||||
Go( &DRAWING_TOOL::DrawDimension, PCB_ACTIONS::drawDimension.MakeEvent() );
|
||||
Go( &DRAWING_TOOL::DrawZone, PCB_ACTIONS::drawZone.MakeEvent() );
|
||||
Go( &DRAWING_TOOL::DrawZoneKeepout, PCB_ACTIONS::drawZoneKeepout.MakeEvent() );
|
||||
Go( &DRAWING_TOOL::DrawZoneCutout, PCB_ACTIONS::drawZoneCutout.MakeEvent() );
|
||||
Go( &DRAWING_TOOL::DrawSimilarZone, PCB_ACTIONS::drawSimilarZone.MakeEvent() );
|
||||
Go( &DRAWING_TOOL::DrawVia, PCB_ACTIONS::drawVia.MakeEvent() );
|
||||
Go( &DRAWING_TOOL::PlaceText, PCB_ACTIONS::placeText.MakeEvent() );
|
||||
Go( &DRAWING_TOOL::PlaceDXF, PCB_ACTIONS::placeDXF.MakeEvent() );
|
||||
Go( &DRAWING_TOOL::SetAnchor, PCB_ACTIONS::setAnchor.MakeEvent() );
|
||||
Go( &DRAWING_TOOL::DrawLine, PCB_ACTIONS::drawLine.MakeEvent() );
|
||||
Go( &DRAWING_TOOL::DrawCircle, PCB_ACTIONS::drawCircle.MakeEvent() );
|
||||
Go( &DRAWING_TOOL::DrawArc, PCB_ACTIONS::drawArc.MakeEvent() );
|
||||
Go( &DRAWING_TOOL::DrawDimension, PCB_ACTIONS::drawDimension.MakeEvent() );
|
||||
Go( &DRAWING_TOOL::DrawZone, PCB_ACTIONS::drawZone.MakeEvent() );
|
||||
Go( &DRAWING_TOOL::DrawZoneKeepout, PCB_ACTIONS::drawZoneKeepout.MakeEvent() );
|
||||
Go( &DRAWING_TOOL::DrawZoneCutout, PCB_ACTIONS::drawZoneCutout.MakeEvent() );
|
||||
Go( &DRAWING_TOOL::DrawSimilarZone, PCB_ACTIONS::drawSimilarZone.MakeEvent() );
|
||||
Go( &DRAWING_TOOL::DrawVia, PCB_ACTIONS::drawVia.MakeEvent() );
|
||||
Go( &DRAWING_TOOL::PlaceText, PCB_ACTIONS::placeText.MakeEvent() );
|
||||
Go( &DRAWING_TOOL::PlaceDXF, PCB_ACTIONS::placeDXF.MakeEvent() );
|
||||
Go( &DRAWING_TOOL::SetAnchor, PCB_ACTIONS::setAnchor.MakeEvent() );
|
||||
}
|
||||
|
||||
|
||||
|
@ -1576,4 +1581,5 @@ PCB_LAYER_ID DRAWING_TOOL::getDrawingLayer() const
|
|||
return layer;
|
||||
}
|
||||
|
||||
|
||||
const unsigned int DRAWING_TOOL::WIDTH_STEP = 100000;
|
||||
|
|
|
@ -1116,12 +1116,8 @@ static bool showLocalRatsnest( TOOL_MANAGER* aToolMgr, const VECTOR2D& aPosition
|
|||
|
||||
int PCB_EDITOR_CONTROL::ShowLocalRatsnest( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
printf("ShowLocalRTool!\n");
|
||||
|
||||
Activate();
|
||||
|
||||
|
||||
|
||||
auto picker = m_toolMgr->GetTool<PICKER_TOOL>();
|
||||
assert( picker );
|
||||
|
||||
|
|
|
@ -556,17 +556,9 @@ void PCB_BASE_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool
|
|||
wxMessageBox( wxT( "Incomplete undo/redo operation: some items not found" ) );
|
||||
|
||||
// Rebuild pointers and connectivity that can be changed.
|
||||
if( reBuild_ratsnest )
|
||||
if( reBuild_ratsnest || deep_reBuild_ratsnest )
|
||||
{
|
||||
// Compile ratsnest propagates nets from pads to tracks
|
||||
/// @todo LEGACY Compile_Ratsnest() has to be rewritten and moved to RN_DATA
|
||||
if( deep_reBuild_ratsnest )
|
||||
Compile_Ratsnest( NULL, false );
|
||||
|
||||
if( IsGalCanvasActive() )
|
||||
{
|
||||
connectivity->RecalculateRatsnest();
|
||||
}
|
||||
Compile_Ratsnest( NULL, false );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue