/* * KiRouter - a push-and-(sometimes-)shove PCB router * * Copyright (C) 2013-2014 CERN * Copyright (C) 2016 KiCad Developers, see AUTHORS.txt for contributors. * Author: Tomasz Wlostowski * * 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 3 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, see . */ #include "pns_index.h" namespace PNS { INDEX::INDEX() { memset( m_subIndices, 0, sizeof( m_subIndices ) ); } INDEX::~INDEX() { Clear(); } INDEX::ITEM_SHAPE_INDEX* INDEX::getSubindex( const ITEM* aItem ) { int idx_n = -1; const LAYER_RANGE& l = aItem->Layers(); switch( aItem->Kind() ) { case ITEM::VIA_T: idx_n = SI_Multilayer; break; case ITEM::SOLID_T: { if( l.IsMultilayer() ) idx_n = SI_Multilayer; else if( l.Start() == B_Cu ) // fixme: use kicad layer codes idx_n = SI_PadsTop; else if( l.Start() == F_Cu ) idx_n = SI_PadsBottom; else idx_n = SI_Traces + 2 * l.Start() + SI_SegStraight; } break; case ITEM::SEGMENT_T: case ITEM::LINE_T: idx_n = SI_Traces + 2 * l.Start() + SI_SegStraight; break; default: break; } if( idx_n < 0 || idx_n >= MaxSubIndices ) { wxASSERT( idx_n >= 0 ); wxASSERT( idx_n < MaxSubIndices ); return nullptr; } if( !m_subIndices[idx_n] ) m_subIndices[idx_n] = new ITEM_SHAPE_INDEX; return m_subIndices[idx_n]; } void INDEX::Add( ITEM* aItem ) { ITEM_SHAPE_INDEX* idx = getSubindex( aItem ); if( !idx ) return; idx->Add( aItem ); m_allItems.insert( aItem ); int net = aItem->Net(); if( net >= 0 ) { m_netMap[net].push_back( aItem ); } } void INDEX::Remove( ITEM* aItem ) { ITEM_SHAPE_INDEX* idx = getSubindex( aItem ); if( !idx ) return; idx->Remove( aItem ); m_allItems.erase( aItem ); int net = aItem->Net(); if( net >= 0 && m_netMap.find( net ) != m_netMap.end() ) m_netMap[net].remove( aItem ); } void INDEX::Replace( ITEM* aOldItem, ITEM* aNewItem ) { Remove( aOldItem ); Add( aNewItem ); } void INDEX::Clear() { for( int i = 0; i < MaxSubIndices; ++i ) { ITEM_SHAPE_INDEX* idx = m_subIndices[i]; if( idx ) delete idx; m_subIndices[i] = NULL; } } INDEX::NET_ITEMS_LIST* INDEX::GetItemsForNet( int aNet ) { if( m_netMap.find( aNet ) == m_netMap.end() ) return NULL; return &m_netMap[aNet]; } };