Merge selection tool branch.

This commit is contained in:
Maciej Suminski 2014-03-11 20:45:01 -04:00 committed by Wayne Stambaugh
commit f0251ebdb6
144 changed files with 3519 additions and 2517 deletions

View File

@ -149,6 +149,13 @@ if( CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility-inlines-hidden" ) set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility-inlines-hidden" )
endif() endif()
find_package( OpenMP QUIET )
if( OPENMP_FOUND )
set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}" )
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}" )
add_definitions( -DUSE_OPENMP )
endif()
if( MINGW ) if( MINGW )
set( CMAKE_EXE_LINKER_FLAGS_RELEASE "-s" ) set( CMAKE_EXE_LINKER_FLAGS_RELEASE "-s" )

View File

@ -219,6 +219,8 @@ set( PCB_COMMON_SRCS
../pcbnew/class_zone.cpp ../pcbnew/class_zone.cpp
../pcbnew/class_zone_settings.cpp ../pcbnew/class_zone_settings.cpp
../pcbnew/classpcb.cpp ../pcbnew/classpcb.cpp
../pcbnew/ratsnest_data.cpp
../pcbnew/ratsnest_viewitem.cpp
../pcbnew/collectors.cpp ../pcbnew/collectors.cpp
../pcbnew/netlist_reader.cpp ../pcbnew/netlist_reader.cpp
../pcbnew/legacy_netlist_reader.cpp ../pcbnew/legacy_netlist_reader.cpp

View File

@ -50,7 +50,7 @@ PICKED_ITEMS_LIST::~PICKED_ITEMS_LIST()
} }
void PICKED_ITEMS_LIST::PushItem( ITEM_PICKER& aItem ) void PICKED_ITEMS_LIST::PushItem( const ITEM_PICKER& aItem )
{ {
m_ItemsList.push_back( aItem ); m_ItemsList.push_back( aItem );
} }
@ -70,7 +70,7 @@ ITEM_PICKER PICKED_ITEMS_LIST::PopItem()
} }
bool PICKED_ITEMS_LIST::ContainsItem( EDA_ITEM* aItem ) const bool PICKED_ITEMS_LIST::ContainsItem( const EDA_ITEM* aItem ) const
{ {
for( size_t i = 0; i < m_ItemsList.size(); i++ ) for( size_t i = 0; i < m_ItemsList.size(); i++ )
{ {
@ -82,6 +82,18 @@ bool PICKED_ITEMS_LIST::ContainsItem( EDA_ITEM* aItem ) const
} }
int PICKED_ITEMS_LIST::FindItem( const EDA_ITEM* aItem ) const
{
for( size_t i = 0; i < m_ItemsList.size(); i++ )
{
if( m_ItemsList[i].GetItem() == aItem )
return i;
}
return -1;
}
void PICKED_ITEMS_LIST::ClearItemsList() void PICKED_ITEMS_LIST::ClearItemsList()
{ {
m_ItemsList.clear(); m_ItemsList.clear();
@ -157,7 +169,7 @@ void PICKED_ITEMS_LIST::ClearListAndDeleteItems()
} }
ITEM_PICKER PICKED_ITEMS_LIST::GetItemWrapper( unsigned int aIdx ) ITEM_PICKER PICKED_ITEMS_LIST::GetItemWrapper( unsigned int aIdx ) const
{ {
ITEM_PICKER picker; ITEM_PICKER picker;
@ -168,7 +180,7 @@ ITEM_PICKER PICKED_ITEMS_LIST::GetItemWrapper( unsigned int aIdx )
} }
EDA_ITEM* PICKED_ITEMS_LIST::GetPickedItem( unsigned int aIdx ) EDA_ITEM* PICKED_ITEMS_LIST::GetPickedItem( unsigned int aIdx ) const
{ {
if( aIdx < m_ItemsList.size() ) if( aIdx < m_ItemsList.size() )
return m_ItemsList[aIdx].GetItem(); return m_ItemsList[aIdx].GetItem();
@ -177,7 +189,7 @@ EDA_ITEM* PICKED_ITEMS_LIST::GetPickedItem( unsigned int aIdx )
} }
EDA_ITEM* PICKED_ITEMS_LIST::GetPickedItemLink( unsigned int aIdx ) EDA_ITEM* PICKED_ITEMS_LIST::GetPickedItemLink( unsigned int aIdx ) const
{ {
if( aIdx < m_ItemsList.size() ) if( aIdx < m_ItemsList.size() )
return m_ItemsList[aIdx].GetLink(); return m_ItemsList[aIdx].GetLink();
@ -186,7 +198,7 @@ EDA_ITEM* PICKED_ITEMS_LIST::GetPickedItemLink( unsigned int aIdx )
} }
UNDO_REDO_T PICKED_ITEMS_LIST::GetPickedItemStatus( unsigned int aIdx ) UNDO_REDO_T PICKED_ITEMS_LIST::GetPickedItemStatus( unsigned int aIdx ) const
{ {
if( aIdx < m_ItemsList.size() ) if( aIdx < m_ItemsList.size() )
return m_ItemsList[aIdx].GetStatus(); return m_ItemsList[aIdx].GetStatus();
@ -195,7 +207,7 @@ UNDO_REDO_T PICKED_ITEMS_LIST::GetPickedItemStatus( unsigned int aIdx )
} }
STATUS_FLAGS PICKED_ITEMS_LIST::GetPickerFlags( unsigned aIdx ) STATUS_FLAGS PICKED_ITEMS_LIST::GetPickerFlags( unsigned aIdx ) const
{ {
if( aIdx < m_ItemsList.size() ) if( aIdx < m_ItemsList.size() )
return m_ItemsList[aIdx].GetFlags(); return m_ItemsList[aIdx].GetFlags();

View File

@ -81,10 +81,13 @@ EDA_DRAW_PANEL_GAL::EDA_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWin
Connect( wxEVT_MOTION, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); Connect( wxEVT_MOTION, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
Connect( wxEVT_LEFT_UP, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); Connect( wxEVT_LEFT_UP, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
Connect( wxEVT_LEFT_DOWN, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); Connect( wxEVT_LEFT_DOWN, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
Connect( wxEVT_LEFT_DCLICK, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
Connect( wxEVT_RIGHT_UP, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); Connect( wxEVT_RIGHT_UP, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
Connect( wxEVT_RIGHT_DOWN, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); Connect( wxEVT_RIGHT_DOWN, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
Connect( wxEVT_RIGHT_DCLICK, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
Connect( wxEVT_MIDDLE_UP, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); Connect( wxEVT_MIDDLE_UP, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
Connect( wxEVT_MIDDLE_DOWN, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); Connect( wxEVT_MIDDLE_DOWN, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
Connect( wxEVT_MIDDLE_DCLICK, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
Connect( wxEVT_MOUSEWHEEL, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); Connect( wxEVT_MOUSEWHEEL, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
Connect( wxEVT_CHAR_HOOK, wxEventHandler( EDA_DRAW_PANEL_GAL::skipEvent ) ); Connect( wxEVT_CHAR_HOOK, wxEventHandler( EDA_DRAW_PANEL_GAL::skipEvent ) );
Connect( wxEVT_KEY_UP, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); Connect( wxEVT_KEY_UP, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );

View File

@ -60,10 +60,13 @@ CAIRO_GAL::CAIRO_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener,
Connect( wxEVT_MOTION, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) ); Connect( wxEVT_MOTION, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) ); Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
Connect( wxEVT_LEFT_UP, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) ); Connect( wxEVT_LEFT_UP, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
Connect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
Connect( wxEVT_MIDDLE_DOWN, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) ); Connect( wxEVT_MIDDLE_DOWN, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
Connect( wxEVT_MIDDLE_UP, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) ); Connect( wxEVT_MIDDLE_UP, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
Connect( wxEVT_MIDDLE_DCLICK, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) ); Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
Connect( wxEVT_RIGHT_UP, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) ); Connect( wxEVT_RIGHT_UP, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
Connect( wxEVT_RIGHT_DCLICK, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
#if defined _WIN32 || defined _WIN64 #if defined _WIN32 || defined _WIN64
Connect( wxEVT_ENTER_WINDOW, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) ); Connect( wxEVT_ENTER_WINDOW, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
#endif #endif

View File

@ -34,11 +34,11 @@
#include <typeinfo> #include <typeinfo>
#include <wx/msgdlg.h> #include <wx/msgdlg.h>
#include <confirm.h> #include <confirm.h>
#ifdef __WXDEBUG__ #ifdef PROFILE
#include <profile.h> #include <profile.h>
#include <wx/debug.h> #include <wx/debug.h>
#include <wx/log.h> #include <wx/log.h>
#endif #endif /* PROFILE */
using namespace KIGFX; using namespace KIGFX;
@ -187,10 +187,10 @@ void GPU_CACHED_MANAGER::EndDrawing()
void GPU_CACHED_MANAGER::uploadToGpu() void GPU_CACHED_MANAGER::uploadToGpu()
{ {
#ifdef __WXDEBUG__ #ifdef PROFILE
prof_counter totalTime; prof_counter totalTime;
prof_start( &totalTime ); prof_start( &totalTime );
#endif /* __WXDEBUG__ */ #endif /* PROFILE */
if( !m_buffersInitialized ) if( !m_buffersInitialized )
Initialize(); Initialize();
@ -207,15 +207,13 @@ void GPU_CACHED_MANAGER::uploadToGpu()
m_indices.reset( new GLuint[bufferSize] ); m_indices.reset( new GLuint[bufferSize] );
if( glGetError() != GL_NO_ERROR ) if( glGetError() != GL_NO_ERROR )
{
DisplayError( NULL, wxT( "Error during data upload to the GPU memory" ) ); DisplayError( NULL, wxT( "Error during data upload to the GPU memory" ) );
}
#ifdef __WXDEBUG__ #ifdef PROFILE
prof_end( &totalTime ); prof_end( &totalTime );
wxLogDebug( wxT( "Uploading %d vertices to GPU / %.1f ms" ), bufferSize, totalTime.msecs() ); wxLogDebug( wxT( "Uploading %d vertices to GPU / %.1f ms" ), bufferSize, totalTime.msecs() );
#endif /* __WXDEBUG__ */ #endif /* PROFILE */
} }

View File

@ -73,10 +73,13 @@ OPENGL_GAL::OPENGL_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener,
Connect( wxEVT_MOTION, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) ); Connect( wxEVT_MOTION, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) );
Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) ); Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) );
Connect( wxEVT_LEFT_UP, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) ); Connect( wxEVT_LEFT_UP, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) );
Connect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) );
Connect( wxEVT_MIDDLE_DOWN, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) ); Connect( wxEVT_MIDDLE_DOWN, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) );
Connect( wxEVT_MIDDLE_UP, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) ); Connect( wxEVT_MIDDLE_UP, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) );
Connect( wxEVT_MIDDLE_DCLICK, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) );
Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) ); Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) );
Connect( wxEVT_RIGHT_UP, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) ); Connect( wxEVT_RIGHT_UP, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) );
Connect( wxEVT_RIGHT_DCLICK, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) );
#if defined _WIN32 || defined _WIN64 #if defined _WIN32 || defined _WIN64
Connect( wxEVT_ENTER_WINDOW, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) ); Connect( wxEVT_ENTER_WINDOW, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) );
#endif #endif

View File

@ -45,14 +45,14 @@
#include <algorithm> #include <algorithm>
#include <fstream> #include <fstream>
#include <limits> #include <limits>
#include <boost/foreach.hpp>
#include <boost/make_shared.hpp>
using namespace hed; using namespace hed;
using namespace std; using namespace std;
Triangulation* TTLtraits::triang_ = NULL;
#ifdef TTL_USE_NODE_ID #ifdef TTL_USE_NODE_ID
int Node::id_count = 0; int Node::id_count = 0;
#endif #endif
@ -117,28 +117,27 @@ EdgePtr Triangulation::initTwoEnclosingTriangles(NodesContainer::iterator first,
double dx = (xmax-xmin)/fac; double dx = (xmax-xmin)/fac;
double dy = (ymax-ymin)/fac; double dy = (ymax-ymin)/fac;
NodePtr n1(new Node(xmin-dx,ymin-dy)); NodePtr n1 = boost::make_shared<Node>(xmin-dx, ymin-dy);
NodePtr n2(new Node(xmax+dx,ymin-dy)); NodePtr n2 = boost::make_shared<Node>(xmax+dx, ymin-dy);
NodePtr n3(new Node(xmax+dx,ymax+dy)); NodePtr n3 = boost::make_shared<Node>(xmax+dx, ymax+dy);
NodePtr n4(new Node(xmin-dx,ymax+dy)); NodePtr n4 = boost::make_shared<Node>(xmin-dx, ymax+dy);
// diagonal // diagonal
EdgePtr e1d(new Edge); // lower EdgePtr e1d = boost::make_shared<Edge>();
EdgePtr e2d(new Edge); // upper, the twin edge EdgePtr e2d = boost::make_shared<Edge>();
// lower triangle // lower triangle
EdgePtr e11(new Edge); EdgePtr e11 = boost::make_shared<Edge>();
EdgePtr e12(new Edge); EdgePtr e12 = boost::make_shared<Edge>();
// upper triangle // upper triangle
EdgePtr e21(new Edge); // upper upper EdgePtr e21 = boost::make_shared<Edge>();
EdgePtr e22(new Edge); EdgePtr e22 = boost::make_shared<Edge>();
// lower triangle // lower triangle
e1d->setSourceNode(n3); e1d->setSourceNode(n3);
e1d->setNextEdgeInFace(e11); e1d->setNextEdgeInFace(e11);
e1d->setTwinEdge(e2d); e1d->setTwinEdge(e2d);
e1d->setAsLeadingEdge();
addLeadingEdge(e1d); addLeadingEdge(e1d);
e11->setSourceNode(n1); e11->setSourceNode(n1);
@ -151,7 +150,6 @@ EdgePtr Triangulation::initTwoEnclosingTriangles(NodesContainer::iterator first,
e2d->setSourceNode(n1); e2d->setSourceNode(n1);
e2d->setNextEdgeInFace(e21); e2d->setNextEdgeInFace(e21);
e2d->setTwinEdge(e1d); e2d->setTwinEdge(e1d);
e2d->setAsLeadingEdge();
addLeadingEdge(e2d); addLeadingEdge(e2d);
e21->setSourceNode(n3); e21->setSourceNode(n3);
@ -164,11 +162,30 @@ EdgePtr Triangulation::initTwoEnclosingTriangles(NodesContainer::iterator first,
} }
//--------------------------------------------------------------------------------------------------
Triangulation::Triangulation() {
helper = new ttl::TriangulationHelper( *this );
}
//--------------------------------------------------------------------------------------------------
Triangulation::Triangulation(const Triangulation& tr) {
std::cout << "Triangulation: Copy constructor not present - EXIT.";
exit(-1);
}
//--------------------------------------------------------------------------------------------------
Triangulation::~Triangulation() {
cleanAll();
delete helper;
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void Triangulation::createDelaunay(NodesContainer::iterator first, void Triangulation::createDelaunay(NodesContainer::iterator first,
NodesContainer::iterator last) { NodesContainer::iterator last) {
TTLtraits::triang_ = this;
cleanAll(); cleanAll();
EdgePtr bedge = initTwoEnclosingTriangles(first, last); EdgePtr bedge = initTwoEnclosingTriangles(first, last);
@ -178,7 +195,7 @@ void Triangulation::createDelaunay(NodesContainer::iterator first,
NodesContainer::iterator it; NodesContainer::iterator it;
for (it = first; it != last; ++it) { for (it = first; it != last; ++it) {
ttl::insertNode<TTLtraits>(d_iter, *it); helper->insertNode<TTLtraits>(d_iter, *it);
} }
// In general (e.g. for the triangle based data structure), the initial dart // In general (e.g. for the triangle based data structure), the initial dart
@ -189,7 +206,7 @@ void Triangulation::createDelaunay(NodesContainer::iterator first,
// triangle "outside" the triangulation.) // triangle "outside" the triangulation.)
// Assumes rectangular domain // Assumes rectangular domain
ttl::removeRectangularBoundary<TTLtraits>(dc); helper->removeRectangularBoundary<TTLtraits>(dc);
} }
@ -206,15 +223,12 @@ void Triangulation::removeTriangle(EdgePtr& edge) {
removeLeadingEdgeFromList(e1); removeLeadingEdgeFromList(e1);
// cout << "No leading edges = " << leadingEdges_.size() << endl; // cout << "No leading edges = " << leadingEdges_.size() << endl;
// Remove the triangle // Remove the triangle
EdgePtr e2 = e1->getNextEdgeInFace(); EdgePtr e2(e1->getNextEdgeInFace());
EdgePtr e3 = e2->getNextEdgeInFace(); EdgePtr e3(e2->getNextEdgeInFace());
if (e1->getTwinEdge()) e1->clear();
e1->getTwinEdge()->setTwinEdge(EdgePtr()); e2->clear();
if (e2->getTwinEdge()) e3->clear();
e2->getTwinEdge()->setTwinEdge(EdgePtr());
if (e3->getTwinEdge())
e3->getTwinEdge()->setTwinEdge(EdgePtr());
} }
@ -223,15 +237,15 @@ void Triangulation::reverse_splitTriangle(EdgePtr& edge) {
// Reverse operation of splitTriangle // Reverse operation of splitTriangle
EdgePtr e1 = edge->getNextEdgeInFace(); EdgePtr e1(edge->getNextEdgeInFace());
EdgePtr le = getLeadingEdgeInTriangle(e1); EdgePtr le(getLeadingEdgeInTriangle(e1));
#ifdef DEBUG_HE #ifdef DEBUG_HE
if (!le) if (!le)
errorAndExit("Triangulation::removeTriangle: could not find leading edge"); errorAndExit("Triangulation::removeTriangle: could not find leading edge");
#endif #endif
removeLeadingEdgeFromList(le); removeLeadingEdgeFromList(le);
EdgePtr e2 = e1->getNextEdgeInFace()->getTwinEdge()->getNextEdgeInFace(); EdgePtr e2(e1->getNextEdgeInFace()->getTwinEdge()->getNextEdgeInFace());
le = getLeadingEdgeInTriangle(e2); le = getLeadingEdgeInTriangle(e2);
#ifdef DEBUG_HE #ifdef DEBUG_HE
if (!le) if (!le)
@ -239,7 +253,7 @@ void Triangulation::reverse_splitTriangle(EdgePtr& edge) {
#endif #endif
removeLeadingEdgeFromList(le); removeLeadingEdgeFromList(le);
EdgePtr e3 = edge->getTwinEdge()->getNextEdgeInFace()->getNextEdgeInFace(); EdgePtr e3(edge->getTwinEdge()->getNextEdgeInFace()->getNextEdgeInFace());
le = getLeadingEdgeInTriangle(e3); le = getLeadingEdgeInTriangle(e3);
#ifdef DEBUG_HE #ifdef DEBUG_HE
if (!le) if (!le)
@ -251,6 +265,19 @@ void Triangulation::reverse_splitTriangle(EdgePtr& edge) {
// from the triangulation, but the arcs have not been deleted. // from the triangulation, but the arcs have not been deleted.
// Next delete the 6 half edges radiating from the node // Next delete the 6 half edges radiating from the node
// The node is maintained by handle and need not be deleted explicitly // The node is maintained by handle and need not be deleted explicitly
EdgePtr estar = edge;
EdgePtr enext = estar->getTwinEdge()->getNextEdgeInFace();
estar->getTwinEdge()->clear();
estar->clear();
estar = enext;
enext = estar->getTwinEdge()->getNextEdgeInFace();
estar->getTwinEdge()->clear();
estar->clear();
enext->getTwinEdge()->clear();
enext->clear();
// Create the new triangle // Create the new triangle
e1->setNextEdgeInFace(e2); e1->setNextEdgeInFace(e2);
@ -260,25 +287,6 @@ void Triangulation::reverse_splitTriangle(EdgePtr& edge) {
} }
//--------------------------------------------------------------------------------------------------
// This is a "template" for iterating the boundary
/*
static void iterateBoundary(const Dart& dart) {
cout << "Iterate boundary 2" << endl;
// input is a dart at the boundary
Dart dart_iter = dart;
do {
if (ttl::isBoundaryEdge(dart_iter))
dart_iter.alpha0().alpha1();
else
dart_iter.alpha2().alpha1();
} while(dart_iter != dart);
}
*/
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
Dart Triangulation::createDart() { Dart Triangulation::createDart() {
@ -305,20 +313,43 @@ bool Triangulation::removeLeadingEdgeFromList(EdgePtr& leadingEdge) {
edge->setAsLeadingEdge(false); edge->setAsLeadingEdge(false);
it = leadingEdges_.erase(it); it = leadingEdges_.erase(it);
break;
}
}
if (it == leadingEdges_.end())
return false;
return true; return true;
} }
}
return false;
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void Triangulation::cleanAll() { void Triangulation::cleanAll() {
leadingEdges_.clear(); BOOST_FOREACH(EdgePtr& edge, leadingEdges_)
edge->setNextEdgeInFace(EdgePtr());
}
//--------------------------------------------------------------------------------------------------
void Triangulation::swapEdge(Dart& dart) {
swapEdge(dart.getEdge());
}
//--------------------------------------------------------------------------------------------------
void Triangulation::splitTriangle(Dart& dart, const NodePtr& point) {
EdgePtr edge = splitTriangle(dart.getEdge(), point);
dart.init(edge);
}
//--------------------------------------------------------------------------------------------------
void Triangulation::reverse_splitTriangle(Dart& dart) {
reverse_splitTriangle(dart.getEdge());
}
//--------------------------------------------------------------------------------------------------
void Triangulation::removeBoundaryTriangle(Dart& d) {
removeTriangle(d.getEdge());
} }
@ -390,7 +421,7 @@ list<EdgePtr>* Triangulation::getEdges(bool skip_boundary_edges) const {
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
EdgePtr Triangulation::splitTriangle(EdgePtr& edge, NodePtr& point) { EdgePtr Triangulation::splitTriangle(EdgePtr& edge, const NodePtr& point) {
// Add a node by just splitting a triangle into three triangles // Add a node by just splitting a triangle into three triangles
// Assumes the half edge is located in the triangle // Assumes the half edge is located in the triangle
@ -409,21 +440,21 @@ EdgePtr Triangulation::splitTriangle(EdgePtr& edge, NodePtr& point) {
// Add the node to the structure // Add the node to the structure
//NodePtr new_node(new Node(x,y,z)); //NodePtr new_node(new Node(x,y,z));
NodePtr n1 = edge->getSourceNode(); NodePtr n1(edge->getSourceNode());
EdgePtr e1 = edge; EdgePtr e1(edge);
EdgePtr e2 = edge->getNextEdgeInFace(); EdgePtr e2(edge->getNextEdgeInFace());
NodePtr n2 = e2->getSourceNode(); NodePtr n2(e2->getSourceNode());
EdgePtr e3 = e2->getNextEdgeInFace(); EdgePtr e3(e2->getNextEdgeInFace());
NodePtr n3 = e3->getSourceNode(); NodePtr n3(e3->getSourceNode());
EdgePtr e1_n(new Edge); EdgePtr e1_n = boost::make_shared<Edge>();
EdgePtr e11_n(new Edge); EdgePtr e11_n = boost::make_shared<Edge>();
EdgePtr e2_n(new Edge); EdgePtr e2_n = boost::make_shared<Edge>();
EdgePtr e22_n(new Edge); EdgePtr e22_n = boost::make_shared<Edge>();
EdgePtr e3_n(new Edge); EdgePtr e3_n = boost::make_shared<Edge>();
EdgePtr e33_n(new Edge); EdgePtr e33_n = boost::make_shared<Edge>();
e1_n->setSourceNode(n1); e1_n->setSourceNode(n1);
e11_n->setSourceNode(point); e11_n->setSourceNode(point);
@ -447,7 +478,6 @@ EdgePtr Triangulation::splitTriangle(EdgePtr& edge, NodePtr& point) {
e22_n->setNextEdgeInFace(e2); e22_n->setNextEdgeInFace(e2);
e33_n->setNextEdgeInFace(e3); e33_n->setNextEdgeInFace(e3);
// and update old's next edge // and update old's next edge
e1->setNextEdgeInFace(e2_n); e1->setNextEdgeInFace(e2_n);
e2->setNextEdgeInFace(e3_n); e2->setNextEdgeInFace(e3_n);
@ -458,18 +488,14 @@ EdgePtr Triangulation::splitTriangle(EdgePtr& edge, NodePtr& point) {
// Use the field telling if an edge is a leading edge // Use the field telling if an edge is a leading edge
// NOTE: Must search in the list!!! // NOTE: Must search in the list!!!
EdgePtr leadingEdge;
if (e1->isLeadingEdge()) if (e1->isLeadingEdge())
leadingEdge = e1; removeLeadingEdgeFromList(e1);
else if (e2->isLeadingEdge()) else if (e2->isLeadingEdge())
leadingEdge = e2; removeLeadingEdgeFromList(e2);
else if(e3->isLeadingEdge()) else if(e3->isLeadingEdge())
leadingEdge = e3; removeLeadingEdgeFromList(e3);
else else
return EdgePtr(); assert( false ); // one of the edges should be leading
removeLeadingEdgeFromList(leadingEdge);
addLeadingEdge(e1_n); addLeadingEdge(e1_n);
addLeadingEdge(e2_n); addLeadingEdge(e2_n);
@ -486,20 +512,20 @@ void Triangulation::swapEdge(EdgePtr& diagonal) {
// Note that diagonal is both input and output and it is always // Note that diagonal is both input and output and it is always
// kept in counterclockwise direction (this is not required by all // kept in counterclockwise direction (this is not required by all
// finctions in ttl:: now) // functions in TriangulationHelper now)
// Swap by rotating counterclockwise // Swap by rotating counterclockwise
// Use the same objects - no deletion or new objects // Use the same objects - no deletion or new objects
EdgePtr eL = diagonal; EdgePtr eL(diagonal);
EdgePtr eR = eL->getTwinEdge(); EdgePtr eR(eL->getTwinEdge());
EdgePtr eL_1 = eL->getNextEdgeInFace(); EdgePtr eL_1(eL->getNextEdgeInFace());
EdgePtr eL_2 = eL_1->getNextEdgeInFace(); EdgePtr eL_2(eL_1->getNextEdgeInFace());
EdgePtr eR_1 = eR->getNextEdgeInFace(); EdgePtr eR_1(eR->getNextEdgeInFace());
EdgePtr eR_2 = eR_1->getNextEdgeInFace(); EdgePtr eR_2(eR_1->getNextEdgeInFace());
// avoid node to be dereferenced to zero and deleted // avoid node to be dereferenced to zero and deleted
NodePtr nR = eR_2->getSourceNode(); NodePtr nR(eR_2->getSourceNode());
NodePtr nL = eL_2->getSourceNode(); NodePtr nL(eL_2->getSourceNode());
eL->setSourceNode(nR); eL->setSourceNode(nR);
eR->setSourceNode(nL); eR->setSourceNode(nL);
@ -513,24 +539,20 @@ void Triangulation::swapEdge(EdgePtr& diagonal) {
eR_2->setNextEdgeInFace(eL_1); eR_2->setNextEdgeInFace(eL_1);
eL_1->setNextEdgeInFace(eR); eL_1->setNextEdgeInFace(eR);
EdgePtr leL;
if (eL->isLeadingEdge()) if (eL->isLeadingEdge())
leL = eL; removeLeadingEdgeFromList(eL);
else if (eL_1->isLeadingEdge()) else if (eL_1->isLeadingEdge())
leL = eL_1; removeLeadingEdgeFromList(eL_1);
else if (eL_2->isLeadingEdge()) else if (eL_2->isLeadingEdge())
leL = eL_2; removeLeadingEdgeFromList(eL_2);
EdgePtr leR;
if (eR->isLeadingEdge()) if (eR->isLeadingEdge())
leR = eR; removeLeadingEdgeFromList(eR);
else if (eR_1->isLeadingEdge()) else if (eR_1->isLeadingEdge())
leR = eR_1; removeLeadingEdgeFromList(eR_1);
else if (eR_2->isLeadingEdge()) else if (eR_2->isLeadingEdge())
leR = eR_2; removeLeadingEdgeFromList(eR_2);
removeLeadingEdgeFromList(leL);
removeLeadingEdgeFromList(leR);
addLeadingEdge(eL); addLeadingEdge(eL);
addLeadingEdge(eR); addLeadingEdge(eR);
} }
@ -567,7 +589,7 @@ bool Triangulation::checkDelaunay() const {
// only one of the half-edges // only one of the half-edges
if (!twinedge || (size_t)edge.get() > (size_t)twinedge.get()) { if (!twinedge || (size_t)edge.get() > (size_t)twinedge.get()) {
Dart dart(edge); Dart dart(edge);
if (ttl::swapTestDelaunay<TTLtraits>(dart)) { if (helper->swapTestDelaunay<TTLtraits>(dart)) {
noNotDelaunay++; noNotDelaunay++;
//printEdge(dart,os); os << "\n"; //printEdge(dart,os); os << "\n";
@ -610,7 +632,7 @@ void Triangulation::optimizeDelaunay() {
Dart dart(edge); Dart dart(edge);
// Constrained edges should not be swapped // Constrained edges should not be swapped
if (!edge->isConstrained() && ttl::swapTestDelaunay<TTLtraits>(dart, cycling_check)) { if (helper->swapTestDelaunay<TTLtraits>(dart, cycling_check)) {
optimal = false; optimal = false;
swapEdge(edge); swapEdge(edge);
} }
@ -632,7 +654,7 @@ EdgePtr Triangulation::getInteriorNode() const {
for (int i = 0; i < 3; ++i) { for (int i = 0; i < 3; ++i) {
if (edge->getTwinEdge()) { if (edge->getTwinEdge()) {
if (!ttl::isBoundaryNode(Dart(edge))) if (!helper->isBoundaryNode(Dart(edge)))
return edge; return edge;
} }
edge = edge->getNextEdgeInFace(); edge = edge->getNextEdgeInFace();
@ -643,18 +665,18 @@ EdgePtr Triangulation::getInteriorNode() const {
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
static EdgePtr getBoundaryEdgeInTriangle(const EdgePtr& e) { EdgePtr Triangulation::getBoundaryEdgeInTriangle(const EdgePtr& e) const {
EdgePtr edge = e; EdgePtr edge = e;
if (ttl::isBoundaryEdge(Dart(edge))) if (helper->isBoundaryEdge(Dart(edge)))
return edge; return edge;
edge = edge->getNextEdgeInFace(); edge = edge->getNextEdgeInFace();
if (ttl::isBoundaryEdge(Dart(edge))) if (helper->isBoundaryEdge(Dart(edge)))
return edge; return edge;
edge = edge->getNextEdgeInFace(); edge = edge->getNextEdgeInFace();
if (ttl::isBoundaryEdge(Dart(edge))) if (helper->isBoundaryEdge(Dart(edge)))
return edge; return edge;
return EdgePtr(); return EdgePtr();

View File

@ -34,9 +34,18 @@ ACTION_MANAGER::ACTION_MANAGER( TOOL_MANAGER* aToolManager ) :
} }
ACTION_MANAGER::~ACTION_MANAGER()
{
while( !m_actionIdIndex.empty() )
UnregisterAction( m_actionIdIndex.begin()->second );
}
void ACTION_MANAGER::RegisterAction( TOOL_ACTION* aAction ) void ACTION_MANAGER::RegisterAction( TOOL_ACTION* aAction )
{ {
assert( aAction->GetId() == -1 ); // Check if the TOOL_ACTION was not registered before assert( aAction->GetId() == -1 ); // Check if the TOOL_ACTION was not registered before
assert( m_actionNameIndex.find( aAction->m_name ) == m_actionNameIndex.end() );
assert( m_actionIdIndex.find( aAction->m_id ) == m_actionIdIndex.end() );
aAction->setId( MakeActionId( aAction->m_name ) ); aAction->setId( MakeActionId( aAction->m_name ) );
@ -44,7 +53,13 @@ void ACTION_MANAGER::RegisterAction( TOOL_ACTION* aAction )
m_actionIdIndex[aAction->m_id] = aAction; m_actionIdIndex[aAction->m_id] = aAction;
if( aAction->HasHotKey() ) if( aAction->HasHotKey() )
{
// Duplication of hot keys leads to unexpected behaviour
// The right way to change a hotkey is to use ACTION_MANAGER::ClearHotKey() first
assert( m_actionHotKeys.find( aAction->m_currentHotKey ) == m_actionHotKeys.end() );
m_actionHotKeys[aAction->m_currentHotKey] = aAction; m_actionHotKeys[aAction->m_currentHotKey] = aAction;
}
aAction->setActionMgr( this ); aAction->setActionMgr( this );
} }
@ -52,13 +67,13 @@ void ACTION_MANAGER::RegisterAction( TOOL_ACTION* aAction )
void ACTION_MANAGER::UnregisterAction( TOOL_ACTION* aAction ) void ACTION_MANAGER::UnregisterAction( TOOL_ACTION* aAction )
{ {
m_actionNameIndex.erase( aAction->m_name );
m_actionIdIndex.erase( aAction->m_id );
// Indicate that the ACTION_MANAGER no longer care about the object // Indicate that the ACTION_MANAGER no longer care about the object
aAction->setActionMgr( NULL ); aAction->setActionMgr( NULL );
aAction->setId( -1 ); aAction->setId( -1 );
m_actionNameIndex.erase( aAction->m_name );
m_actionIdIndex.erase( aAction->m_id );
if( aAction->HasHotKey() ) if( aAction->HasHotKey() )
m_actionHotKeys.erase( aAction->m_currentHotKey ); m_actionHotKeys.erase( aAction->m_currentHotKey );
} }
@ -98,6 +113,12 @@ bool ACTION_MANAGER::RunHotKey( int aHotKey ) const
} }
void ACTION_MANAGER::ClearHotKey( int aHotKey )
{
m_actionHotKeys.erase( aHotKey );
}
void ACTION_MANAGER::runAction( const TOOL_ACTION* aAction ) const void ACTION_MANAGER::runAction( const TOOL_ACTION* aAction ) const
{ {
TOOL_EVENT event = aAction->MakeEvent(); TOOL_EVENT event = aAction->MakeEvent();

View File

@ -29,7 +29,7 @@
#include <cassert> #include <cassert>
CONTEXT_MENU::CONTEXT_MENU() : CONTEXT_MENU::CONTEXT_MENU() :
m_titleSet( false ), m_handler( this ), m_tool( NULL ) m_titleSet( false ), m_selected( -1 ), m_handler( this ), m_tool( NULL )
{ {
m_menu.Connect( wxEVT_MENU_HIGHLIGHT, wxEventHandler( CMEventHandler::onEvent ), m_menu.Connect( wxEVT_MENU_HIGHLIGHT, wxEventHandler( CMEventHandler::onEvent ),
NULL, &m_handler ); NULL, &m_handler );
@ -43,7 +43,7 @@ CONTEXT_MENU::CONTEXT_MENU() :
CONTEXT_MENU::CONTEXT_MENU( const CONTEXT_MENU& aMenu ) : CONTEXT_MENU::CONTEXT_MENU( const CONTEXT_MENU& aMenu ) :
m_titleSet( aMenu.m_titleSet ), m_handler( this ), m_tool( aMenu.m_tool ) m_titleSet( aMenu.m_titleSet ), m_selected( -1 ), m_handler( this ), m_tool( aMenu.m_tool )
{ {
m_menu.Connect( wxEVT_MENU_HIGHLIGHT, wxEventHandler( CMEventHandler::onEvent ), m_menu.Connect( wxEVT_MENU_HIGHLIGHT, wxEventHandler( CMEventHandler::onEvent ),
NULL, &m_handler ); NULL, &m_handler );
@ -164,6 +164,9 @@ void CONTEXT_MENU::CMEventHandler::onEvent( wxEvent& aEvent )
// One of menu entries was selected.. // One of menu entries was selected..
else if( type == wxEVT_COMMAND_MENU_SELECTED ) else if( type == wxEVT_COMMAND_MENU_SELECTED )
{ {
// Store the selected position
m_menu->m_selected = aEvent.GetId();
// Check if there is a TOOL_ACTION for the given ID // Check if there is a TOOL_ACTION for the given ID
if( m_menu->m_toolActions.count( aEvent.GetId() ) == 1 ) if( m_menu->m_toolActions.count( aEvent.GetId() ) == 1 )
{ {

View File

@ -43,10 +43,11 @@ using boost::optional;
struct TOOL_DISPATCHER::BUTTON_STATE struct TOOL_DISPATCHER::BUTTON_STATE
{ {
BUTTON_STATE( TOOL_MOUSE_BUTTONS aButton, const wxEventType& aDownEvent, BUTTON_STATE( TOOL_MOUSE_BUTTONS aButton, const wxEventType& aDownEvent,
const wxEventType& aUpEvent ) : const wxEventType& aUpEvent, const wxEventType& aDblClickEvent ) :
button( aButton ), button( aButton ),
downEvent( aDownEvent ), downEvent( aDownEvent ),
upEvent( aUpEvent ) upEvent( aUpEvent ),
dblClickEvent( aDblClickEvent )
{}; {};
///> Flag indicating that dragging is active for the given button. ///> Flag indicating that dragging is active for the given button.
@ -74,6 +75,9 @@ struct TOOL_DISPATCHER::BUTTON_STATE
///> The type of wxEvent that determines mouse button release. ///> The type of wxEvent that determines mouse button release.
wxEventType upEvent; wxEventType upEvent;
///> The type of wxEvent that determines mouse button double click.
wxEventType dblClickEvent;
///> Time stamp for the last mouse button press event. ///> Time stamp for the last mouse button press event.
wxLongLong downTimestamp; wxLongLong downTimestamp;
@ -89,9 +93,12 @@ struct TOOL_DISPATCHER::BUTTON_STATE
TOOL_DISPATCHER::TOOL_DISPATCHER( TOOL_MANAGER* aToolMgr, PCB_BASE_FRAME* aEditFrame ) : TOOL_DISPATCHER::TOOL_DISPATCHER( TOOL_MANAGER* aToolMgr, PCB_BASE_FRAME* aEditFrame ) :
m_toolMgr( aToolMgr ), m_editFrame( aEditFrame ) m_toolMgr( aToolMgr ), m_editFrame( aEditFrame )
{ {
m_buttons.push_back( new BUTTON_STATE( BUT_LEFT, wxEVT_LEFT_DOWN, wxEVT_LEFT_UP ) ); m_buttons.push_back( new BUTTON_STATE( BUT_LEFT, wxEVT_LEFT_DOWN,
m_buttons.push_back( new BUTTON_STATE( BUT_RIGHT, wxEVT_RIGHT_DOWN, wxEVT_RIGHT_UP ) ); wxEVT_LEFT_UP, wxEVT_LEFT_DCLICK ) );
m_buttons.push_back( new BUTTON_STATE( BUT_MIDDLE, wxEVT_MIDDLE_DOWN, wxEVT_MIDDLE_UP ) ); m_buttons.push_back( new BUTTON_STATE( BUT_RIGHT, wxEVT_RIGHT_DOWN,
wxEVT_RIGHT_UP, wxEVT_RIGHT_DCLICK ) );
m_buttons.push_back( new BUTTON_STATE( BUT_MIDDLE, wxEVT_MIDDLE_DOWN,
wxEVT_MIDDLE_UP, wxEVT_MIDDLE_DCLICK ) );
ResetState(); ResetState();
} }
@ -126,6 +133,7 @@ bool TOOL_DISPATCHER::handleMouseButton( wxEvent& aEvent, int aIndex, bool aMoti
bool up = type == st->upEvent; bool up = type == st->upEvent;
bool down = type == st->downEvent; bool down = type == st->downEvent;
bool dblClick = type == st->dblClickEvent;
int mods = decodeModifiers<wxMouseEvent>( static_cast<wxMouseEvent*>( &aEvent ) ); int mods = decodeModifiers<wxMouseEvent>( static_cast<wxMouseEvent*>( &aEvent ) );
int args = st->button | mods; int args = st->button | mods;
@ -162,6 +170,10 @@ bool TOOL_DISPATCHER::handleMouseButton( wxEvent& aEvent, int aIndex, bool aMoti
st->dragging = false; st->dragging = false;
} }
else if( dblClick )
{
evt = TOOL_EVENT( TC_MOUSE, TA_MOUSE_DBLCLICK, args );
}
if( st->pressed && aMotion ) if( st->pressed && aMotion )
{ {
@ -204,14 +216,15 @@ void TOOL_DISPATCHER::DispatchWxEvent( wxEvent& aEvent )
type == wxEVT_LEFT_DOWN || type == wxEVT_LEFT_UP || type == wxEVT_LEFT_DOWN || type == wxEVT_LEFT_UP ||
type == wxEVT_MIDDLE_DOWN || type == wxEVT_MIDDLE_UP || type == wxEVT_MIDDLE_DOWN || type == wxEVT_MIDDLE_UP ||
type == wxEVT_RIGHT_DOWN || type == wxEVT_RIGHT_UP || type == wxEVT_RIGHT_DOWN || type == wxEVT_RIGHT_UP ||
type == wxEVT_LEFT_DCLICK || type == wxEVT_MIDDLE_DCLICK || type == wxEVT_RIGHT_DCLICK ||
// Event issued whem mouse retains position in screen coordinates, // Event issued whem mouse retains position in screen coordinates,
// but changes in world coordinates (eg. autopanning) // but changes in world coordinates (e.g. autopanning)
type == KIGFX::WX_VIEW_CONTROLS::EVT_REFRESH_MOUSE ) type == KIGFX::WX_VIEW_CONTROLS::EVT_REFRESH_MOUSE )
{ {
VECTOR2D screenPos = m_toolMgr->GetViewControls()->GetCursorPosition(); VECTOR2D screenPos = m_toolMgr->GetViewControls()->GetMousePosition();
VECTOR2D pos = getView()->ToWorld( screenPos ); VECTOR2D pos = getView()->ToWorld( screenPos );
if( pos != m_lastMousePos || type == KIGFX::WX_VIEW_CONTROLS::EVT_REFRESH_MOUSE ) if( pos != m_lastMousePos )
{ {
motion = true; motion = true;
m_lastMousePos = pos; m_lastMousePos = pos;
@ -267,11 +280,6 @@ void TOOL_DISPATCHER::DispatchWxCommand( const wxCommandEvent& aEvent )
toolName = "pcbnew.InteractiveRouter"; toolName = "pcbnew.InteractiveRouter";
activateTool = true; activateTool = true;
break; break;
case ID_SELECTION_TOOL:
toolName = "pcbnew.InteractiveSelection";
activateTool = true;
break;
} }
// do nothing if the legacy view is active // do nothing if the legacy view is active

View File

@ -75,6 +75,7 @@ const std::string TOOL_EVENT::Format() const
const FlagString actions[] = const FlagString actions[] =
{ {
{ TA_MOUSE_CLICK, "click" }, { TA_MOUSE_CLICK, "click" },
{ TA_MOUSE_DBLCLICK, "double click" },
{ TA_MOUSE_UP, "button-up" }, { TA_MOUSE_UP, "button-up" },
{ TA_MOUSE_DOWN, "button-down" }, { TA_MOUSE_DOWN, "button-down" },
{ TA_MOUSE_DRAG, "drag" }, { TA_MOUSE_DRAG, "drag" },
@ -90,6 +91,7 @@ const std::string TOOL_EVENT::Format() const
{ TA_CANCEL_TOOL, "cancel-tool" }, { TA_CANCEL_TOOL, "cancel-tool" },
{ TA_CONTEXT_MENU_UPDATE, "context-menu-update" }, { TA_CONTEXT_MENU_UPDATE, "context-menu-update" },
{ TA_CONTEXT_MENU_CHOICE, "context-menu-choice" }, { TA_CONTEXT_MENU_CHOICE, "context-menu-choice" },
{ TA_UNDO_REDO, "undo-redo" },
{ TA_ACTION, "action" }, { TA_ACTION, "action" },
{ 0, "" } { 0, "" }
}; };

View File

@ -96,7 +96,7 @@ struct TOOL_MANAGER::TOOL_STATE
TOOL_MANAGER::TOOL_MANAGER() : TOOL_MANAGER::TOOL_MANAGER() :
m_model( NULL ), m_view( NULL ) m_model( NULL ), m_view( NULL ), m_viewControls( NULL ), m_editFrame( NULL )
{ {
m_actionMgr = new ACTION_MANAGER( this ); m_actionMgr = new ACTION_MANAGER( this );
} }
@ -119,10 +119,14 @@ TOOL_MANAGER::~TOOL_MANAGER()
void TOOL_MANAGER::RegisterTool( TOOL_BASE* aTool ) void TOOL_MANAGER::RegisterTool( TOOL_BASE* aTool )
{ {
wxASSERT_MSG( m_toolNameIndex.find( aTool->GetName() ) == m_toolNameIndex.end(),
wxT( "Adding two tools with the same name may result in unexpected behaviour.") );
wxASSERT_MSG( m_toolIdIndex.find( aTool->GetId() ) == m_toolIdIndex.end(),
wxT( "Adding two tools with the same ID may result in unexpected behaviour.") );
TOOL_STATE* st = new TOOL_STATE; TOOL_STATE* st = new TOOL_STATE;
st->theTool = aTool; st->theTool = aTool;
st->idle = true;
st->pendingWait = false; st->pendingWait = false;
st->pendingContextMenu = false; st->pendingContextMenu = false;
st->cofunc = NULL; st->cofunc = NULL;
@ -134,11 +138,10 @@ void TOOL_MANAGER::RegisterTool( TOOL_BASE* aTool )
aTool->m_toolMgr = this; aTool->m_toolMgr = this;
if( aTool->GetType() == INTERACTIVE ) if( !aTool->Init() )
{ {
if( !static_cast<TOOL_INTERACTIVE*>( aTool )->Init() ) std::string msg = StrPrintf( "Initialization of the %s tool failed",
{ aTool->GetName().c_str() );
std::string msg = StrPrintf( "Initialization of the %s tool failed", aTool->GetName().c_str() );
DisplayError( NULL, wxString::FromUTF8( msg.c_str() ) ); DisplayError( NULL, wxString::FromUTF8( msg.c_str() ) );
@ -151,7 +154,6 @@ void TOOL_MANAGER::RegisterTool( TOOL_BASE* aTool )
delete aTool; delete aTool;
} }
} }
}
bool TOOL_MANAGER::InvokeTool( TOOL_ID aToolId ) bool TOOL_MANAGER::InvokeTool( TOOL_ID aToolId )
@ -188,6 +190,12 @@ void TOOL_MANAGER::UnregisterAction( TOOL_ACTION* aAction )
} }
bool TOOL_MANAGER::RunAction( const std::string& aActionName )
{
return m_actionMgr->RunAction( aActionName );
}
bool TOOL_MANAGER::invokeTool( TOOL_BASE* aTool ) bool TOOL_MANAGER::invokeTool( TOOL_BASE* aTool )
{ {
wxASSERT( aTool != NULL ); wxASSERT( aTool != NULL );
@ -226,17 +234,16 @@ bool TOOL_MANAGER::runTool( TOOL_BASE* aTool )
wxASSERT( aTool != NULL ); wxASSERT( aTool != NULL );
if( !isRegistered( aTool ) ) if( !isRegistered( aTool ) )
{
wxASSERT_MSG( false, wxT( "You cannot run unregistered tools" ) );
return false; return false;
}
TOOL_STATE* state = m_toolState[aTool];
// If the tool is already active, do not invoke it again // If the tool is already active, do not invoke it again
if( state->idle == false ) if( isActive( aTool ) )
return false; return false;
state->idle = false; aTool->Reset( TOOL_INTERACTIVE::RUN );
static_cast<TOOL_INTERACTIVE*>( aTool )->Reset();
// Add the tool on the front of the processing queue (it gets events first) // Add the tool on the front of the processing queue (it gets events first)
m_activeTools.push_front( aTool->GetId() ); m_activeTools.push_front( aTool->GetId() );
@ -267,6 +274,13 @@ TOOL_BASE* TOOL_MANAGER::FindTool( const std::string& aName ) const
} }
void TOOL_MANAGER::ResetTools( TOOL_BASE::RESET_REASON aReason )
{
BOOST_FOREACH( TOOL_BASE* tool, m_toolState | boost::adaptors::map_keys )
tool->Reset( aReason );
}
void TOOL_MANAGER::ScheduleNextState( TOOL_BASE* aTool, TOOL_STATE_FUNC& aHandler, void TOOL_MANAGER::ScheduleNextState( TOOL_BASE* aTool, TOOL_STATE_FUNC& aHandler,
const TOOL_EVENT_LIST& aConditions ) const TOOL_EVENT_LIST& aConditions )
{ {
@ -333,10 +347,11 @@ void TOOL_MANAGER::dispatchInternal( TOOL_EVENT& aEvent )
// Go() method that match the event. // Go() method that match the event.
if( st->transitions.size() ) if( st->transitions.size() )
{ {
BOOST_FOREACH( TRANSITION tr, st->transitions ) BOOST_FOREACH( TRANSITION& tr, st->transitions )
{ {
if( tr.first.Matches( aEvent ) ) if( tr.first.Matches( aEvent ) )
{ {
// as the state changes, the transition table has to be set up again
st->transitions.clear(); st->transitions.clear();
// no tool context allocated yet? Create one. // no tool context allocated yet? Create one.
@ -350,6 +365,9 @@ void TOOL_MANAGER::dispatchInternal( TOOL_EVENT& aEvent )
if( !st->cofunc->Running() ) if( !st->cofunc->Running() )
finishTool( st ); // The couroutine has finished immediately? finishTool( st ); // The couroutine has finished immediately?
// there is no point in further checking, as transitions got cleared
break;
} }
} }
} }
@ -394,21 +412,18 @@ bool TOOL_MANAGER::dispatchActivation( TOOL_EVENT& aEvent )
void TOOL_MANAGER::finishTool( TOOL_STATE* aState ) void TOOL_MANAGER::finishTool( TOOL_STATE* aState )
{ {
// Find the tool to be deactivated std::deque<TOOL_ID>::iterator it, itEnd;
std::deque<TOOL_ID>::iterator it, it_end;
for( it = m_activeTools.begin(), it_end = m_activeTools.end(); it != it_end; ++it ) // Find the tool and deactivate it
for( it = m_activeTools.begin(), itEnd = m_activeTools.end(); it != itEnd; ++it )
{ {
if( aState == m_toolIdIndex[*it] ) if( aState == m_toolIdIndex[*it] )
{
m_activeTools.erase( it );
break; break;
} }
}
if( it != m_activeTools.end() )
m_activeTools.erase( it );
else
wxLogWarning( wxT( "Tried to finish inactive tool" ) );
aState->idle = true;
delete aState->cofunc; delete aState->cofunc;
aState->cofunc = NULL; aState->cofunc = NULL;
} }
@ -445,9 +460,12 @@ bool TOOL_MANAGER::ProcessEvent( TOOL_EVENT& aEvent )
boost::scoped_ptr<CONTEXT_MENU> menu( new CONTEXT_MENU( *st->contextMenu ) ); boost::scoped_ptr<CONTEXT_MENU> menu( new CONTEXT_MENU( *st->contextMenu ) );
GetEditFrame()->PopupMenu( menu->GetMenu() ); GetEditFrame()->PopupMenu( menu->GetMenu() );
// // If nothing was chosen from the context menu, we must notify the tool as well
if( menu->GetSelected() < 0 )
{
TOOL_EVENT evt( TC_COMMAND, TA_CONTEXT_MENU_CHOICE ); TOOL_EVENT evt( TC_COMMAND, TA_CONTEXT_MENU_CHOICE );
dispatchInternal( evt ); dispatchInternal( evt );
}
break; break;
} }
@ -456,6 +474,7 @@ bool TOOL_MANAGER::ProcessEvent( TOOL_EVENT& aEvent )
if( m_view->IsDirty() ) if( m_view->IsDirty() )
{ {
PCB_EDIT_FRAME* f = static_cast<PCB_EDIT_FRAME*>( GetEditFrame() ); PCB_EDIT_FRAME* f = static_cast<PCB_EDIT_FRAME*>( GetEditFrame() );
if( f->IsGalCanvasActive() )
f->GetGalCanvas()->Refresh(); // fixme: ugly hack, provide a method in TOOL_DISPATCHER. f->GetGalCanvas()->Refresh(); // fixme: ugly hack, provide a method in TOOL_DISPATCHER.
} }
@ -492,15 +511,6 @@ void TOOL_MANAGER::SetEnvironment( EDA_ITEM* aModel, KIGFX::VIEW* aView,
m_view = aView; m_view = aView;
m_viewControls = aViewControls; m_viewControls = aViewControls;
m_editFrame = aFrame; m_editFrame = aFrame;
// Reset state of the registered tools
BOOST_FOREACH( TOOL_ID toolId, m_activeTools )
{
TOOL_BASE* tool = m_toolIdIndex[toolId]->theTool;
if( tool->GetType() == INTERACTIVE )
static_cast<TOOL_INTERACTIVE*>( tool )->Reset();
}
} }
@ -509,5 +519,6 @@ bool TOOL_MANAGER::isActive( TOOL_BASE* aTool )
if( !isRegistered( aTool ) ) if( !isRegistered( aTool ) )
return false; return false;
return !m_toolState[aTool]->idle; // Just check if the tool is on the active tools stack
return std::find( m_activeTools.begin(), m_activeTools.end(), aTool->GetId() ) != m_activeTools.end();
} }

View File

@ -34,9 +34,9 @@
#include <gal/graphics_abstraction_layer.h> #include <gal/graphics_abstraction_layer.h>
#include <painter.h> #include <painter.h>
#ifdef __WXDEBUG__ #ifdef PROFILE
#include <profile.h> #include <profile.h>
#endif /* __WXDEBUG__ */ #endif /* PROFILE */
using namespace KIGFX; using namespace KIGFX;
@ -122,6 +122,12 @@ void VIEW::Remove( VIEW_ITEM* aItem )
{ {
VIEW_LAYER& l = m_layers[layers[i]]; VIEW_LAYER& l = m_layers[layers[i]];
l.items->Remove( aItem ); l.items->Remove( aItem );
MarkTargetDirty( l.target );
// Clear the GAL cache
int prevGroup = aItem->getGroup( layers[i] );
if( prevGroup >= 0 )
m_gal->DeleteGroup( prevGroup );
} }
} }
@ -833,7 +839,7 @@ void VIEW::clearGroupCache()
} }
void VIEW::invalidateItem( VIEW_ITEM* aItem, int aUpdateFlags ) void VIEW::InvalidateItem( VIEW_ITEM* aItem, int aUpdateFlags )
{ {
// updateLayers updates geometry too, so we do not have to update both of them at the same time // updateLayers updates geometry too, so we do not have to update both of them at the same time
if( aUpdateFlags & VIEW_ITEM::LAYERS ) if( aUpdateFlags & VIEW_ITEM::LAYERS )
@ -944,6 +950,12 @@ void VIEW::updateLayers( VIEW_ITEM* aItem )
VIEW_LAYER& l = m_layers[layers[i]]; VIEW_LAYER& l = m_layers[layers[i]];
l.items->Remove( aItem ); l.items->Remove( aItem );
MarkTargetDirty( l.target ); MarkTargetDirty( l.target );
// Redraw the item from scratch
int prevGroup = aItem->getGroup( layers[i] );
if( prevGroup >= 0 )
m_gal->DeleteGroup( prevGroup );
} }
// Add the item to new layer set // Add the item to new layer set
@ -983,10 +995,10 @@ void VIEW::RecacheAllItems( bool aImmediately )
r.SetMaximum(); r.SetMaximum();
#ifdef __WXDEBUG__ #ifdef PROFILE
prof_counter totalRealTime; prof_counter totalRealTime;
prof_start( &totalRealTime ); prof_start( &totalRealTime );
#endif /* __WXDEBUG__ */ #endif /* PROFILE */
for( LAYER_MAP_ITER i = m_layers.begin(); i != m_layers.end(); ++i ) for( LAYER_MAP_ITER i = m_layers.begin(); i != m_layers.end(); ++i )
{ {
@ -1002,12 +1014,12 @@ void VIEW::RecacheAllItems( bool aImmediately )
} }
} }
#ifdef __WXDEBUG__ #ifdef PROFILE
prof_end( &totalRealTime ); prof_end( &totalRealTime );
wxLogDebug( wxT( "RecacheAllItems::immediately: %u %.1f ms" ), wxLogDebug( wxT( "RecacheAllItems::immediately: %u %.1f ms" ),
aImmediately, totalRealTime.msecs() ); aImmediately, totalRealTime.msecs() );
#endif /* __WXDEBUG__ */ #endif /* PROFILE */
} }

View File

@ -34,18 +34,14 @@ void VIEW_ITEM::ViewSetVisible( bool aIsVisible )
bool update = false; bool update = false;
if( m_visible != aIsVisible ) if( m_visible != aIsVisible )
{
update = true; update = true;
}
m_visible = aIsVisible; m_visible = aIsVisible;
// update only if the visibility has really changed // update only if the visibility has really changed
if( update ) if( update )
{
ViewUpdate( APPEARANCE ); ViewUpdate( APPEARANCE );
} }
}
void VIEW_ITEM::ViewUpdate( int aUpdateFlags ) void VIEW_ITEM::ViewUpdate( int aUpdateFlags )
@ -53,17 +49,15 @@ void VIEW_ITEM::ViewUpdate( int aUpdateFlags )
if( !m_view ) if( !m_view )
return; return;
m_view->invalidateItem( this, aUpdateFlags ); m_view->InvalidateItem( this, aUpdateFlags );
} }
void VIEW_ITEM::ViewRelease() void VIEW_ITEM::ViewRelease()
{ {
if( m_view && m_view->IsDynamic() ) if( m_view && m_view->IsDynamic() )
{
m_view->Remove( this ); m_view->Remove( this );
} }
}
void VIEW_ITEM::getLayers( int* aLayers, int& aCount ) const void VIEW_ITEM::getLayers( int* aLayers, int& aCount ) const

View File

@ -73,19 +73,12 @@ void WX_VIEW_CONTROLS::onMotion( wxMouseEvent& aEvent )
m_mousePosition.x = aEvent.GetX(); m_mousePosition.x = aEvent.GetX();
m_mousePosition.y = aEvent.GetY(); m_mousePosition.y = aEvent.GetY();
if( m_forceCursorPosition ) updateCursor();
m_cursorPosition = m_view->ToScreen( m_forcedPosition );
else if( m_snappingEnabled )
m_cursorPosition = m_view->GetGAL()->GetGridPoint( m_mousePosition );
else
m_cursorPosition = m_mousePosition;
bool isAutoPanning = false; bool isAutoPanning = false;
if( m_autoPanEnabled ) if( m_autoPanEnabled )
{
isAutoPanning = handleAutoPanning( aEvent ); isAutoPanning = handleAutoPanning( aEvent );
}
if( !isAutoPanning && aEvent.Dragging() ) if( !isAutoPanning && aEvent.Dragging() )
{ {
@ -168,17 +161,13 @@ void WX_VIEW_CONTROLS::onButton( wxMouseEvent& aEvent )
} }
if( aEvent.LeftUp() ) if( aEvent.LeftUp() )
{
m_state = IDLE; // Stop autopanning when user release left mouse button m_state = IDLE; // Stop autopanning when user release left mouse button
}
break; break;
case DRAG_PANNING: case DRAG_PANNING:
if( aEvent.MiddleUp() ) if( aEvent.MiddleUp() )
{
m_state = IDLE; m_state = IDLE;
}
break; break;
} }
@ -210,8 +199,23 @@ void WX_VIEW_CONTROLS::onTimer( wxTimerEvent& aEvent )
dir = m_view->ToWorld( dir, false ); dir = m_view->ToWorld( dir, false );
m_view->SetCenter( m_view->GetCenter() + dir * m_autoPanSpeed ); m_view->SetCenter( m_view->GetCenter() + dir * m_autoPanSpeed );
updateCursor();
// Notify tools that the cursor position has changed in the world coordinates // Notify tools that the cursor position has changed in the world coordinates
wxCommandEvent moveEvent( EVT_REFRESH_MOUSE ); wxMouseEvent moveEvent( EVT_REFRESH_MOUSE );
// Set the modifiers state
#if wxCHECK_VERSION( 3, 0, 0 )
moveEvent.SetControlDown( wxGetKeyState( WXK_CONTROL ) );
moveEvent.SetShiftDown( wxGetKeyState( WXK_SHIFT ) );
moveEvent.SetAltDown( wxGetKeyState( WXK_ALT) );
#else
// wx <3.0 do not have accessors, but the fields are exposed
moveEvent.m_controlDown = wxGetKeyState( WXK_CONTROL );
moveEvent.m_shiftDown = wxGetKeyState( WXK_SHIFT );
moveEvent.m_altDown = wxGetKeyState( WXK_ALT );
#endif
wxPostEvent( m_parentPanel, moveEvent ); wxPostEvent( m_parentPanel, moveEvent );
} }
break; break;
@ -225,7 +229,7 @@ void WX_VIEW_CONTROLS::onTimer( wxTimerEvent& aEvent )
void WX_VIEW_CONTROLS::SetGrabMouse( bool aEnabled ) void WX_VIEW_CONTROLS::SetGrabMouse( bool aEnabled )
{ {
m_grabMouse = aEnabled; VIEW_CONTROLS::SetGrabMouse( aEnabled );
if( aEnabled ) if( aEnabled )
m_parentPanel->CaptureMouse(); m_parentPanel->CaptureMouse();
@ -243,15 +247,6 @@ const VECTOR2D WX_VIEW_CONTROLS::GetMousePosition() const
} }
const VECTOR2D WX_VIEW_CONTROLS::GetCursorPosition() const
{
if( m_snappingEnabled )
return m_view->GetGAL()->GetGridPoint( GetMousePosition() );
else
return GetMousePosition();
}
bool WX_VIEW_CONTROLS::handleAutoPanning( const wxMouseEvent& aEvent ) bool WX_VIEW_CONTROLS::handleAutoPanning( const wxMouseEvent& aEvent )
{ {
VECTOR2D p( aEvent.GetX(), aEvent.GetY() ); VECTOR2D p( aEvent.GetX(), aEvent.GetY() );
@ -309,3 +304,14 @@ bool WX_VIEW_CONTROLS::handleAutoPanning( const wxMouseEvent& aEvent )
wxASSERT_MSG( false, wxT( "This line should never be reached" ) ); wxASSERT_MSG( false, wxT( "This line should never be reached" ) );
return false; // Should not be reached, just avoid the compiler warnings.. return false; // Should not be reached, just avoid the compiler warnings..
} }
void WX_VIEW_CONTROLS::updateCursor()
{
if( m_forceCursorPosition )
m_cursorPosition = m_view->ToScreen( m_forcedPosition );
else if( m_snappingEnabled )
m_cursorPosition = m_view->GetGAL()->GetGridPoint( m_mousePosition );
else
m_cursorPosition = m_mousePosition;
}

View File

@ -36,10 +36,8 @@
using namespace KIGFX; using namespace KIGFX;
WORKSHEET_VIEWITEM::WORKSHEET_VIEWITEM( const std::string& aFileName, const std::string& aSheetName, WORKSHEET_VIEWITEM::WORKSHEET_VIEWITEM( const PAGE_INFO* aPageInfo, const TITLE_BLOCK* aTitleBlock ) :
const PAGE_INFO* aPageInfo, const TITLE_BLOCK* aTitleBlock ) :
EDA_ITEM( NOT_USED ), // this item is never added to a BOARD so it needs no type EDA_ITEM( NOT_USED ), // this item is never added to a BOARD so it needs no type
m_fileName( aFileName ), m_sheetName( aSheetName ),
m_titleBlock( aTitleBlock ), m_pageInfo( aPageInfo ), m_sheetNumber( 1 ), m_sheetCount( 1 ) {} m_titleBlock( aTitleBlock ), m_pageInfo( aPageInfo ), m_sheetNumber( 1 ), m_sheetCount( 1 ) {}

View File

@ -124,7 +124,7 @@ public:
* @param aTransformPoint = the reference point of the transformation, * @param aTransformPoint = the reference point of the transformation,
* for commands like move * for commands like move
*/ */
virtual void SaveCopyInUndoList( PICKED_ITEMS_LIST& aItemsList, virtual void SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList,
UNDO_REDO_T aTypeCommand, UNDO_REDO_T aTypeCommand,
const wxPoint& aTransformPoint = wxPoint( 0, 0 ) ) const wxPoint& aTransformPoint = wxPoint( 0, 0 ) )
{ {

View File

@ -160,7 +160,7 @@ void SCH_EDIT_FRAME::SaveCopyInUndoList( SCH_ITEM* aItem,
} }
void SCH_EDIT_FRAME::SaveCopyInUndoList( PICKED_ITEMS_LIST& aItemsList, void SCH_EDIT_FRAME::SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList,
UNDO_REDO_T aTypeCommand, UNDO_REDO_T aTypeCommand,
const wxPoint& aTransformPoint ) const wxPoint& aTransformPoint )
{ {

View File

@ -676,7 +676,7 @@ public:
* @param aTransformPoint = the reference point of the transformation, * @param aTransformPoint = the reference point of the transformation,
* for commands like move * for commands like move
*/ */
void SaveCopyInUndoList( PICKED_ITEMS_LIST& aItemsList, void SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList,
UNDO_REDO_T aTypeCommand, UNDO_REDO_T aTypeCommand,
const wxPoint& aTransformPoint = wxPoint( 0, 0 ) ) const wxPoint& aTransformPoint = wxPoint( 0, 0 ) )
{ {

View File

@ -83,8 +83,7 @@ protected:
public: public:
BOARD_ITEM( BOARD_ITEM* aParent, KICAD_T idtype ) : BOARD_ITEM( BOARD_ITEM* aParent, KICAD_T idtype ) :
EDA_ITEM( aParent, idtype ) EDA_ITEM( aParent, idtype ), m_Layer( FIRST_LAYER )
, m_Layer( FIRST_LAYER )
{ {
} }
@ -94,6 +93,16 @@ public:
virtual void SetPosition( const wxPoint& aPos ) = 0; virtual void SetPosition( const wxPoint& aPos ) = 0;
/**
* Function IsConnected()
* Returns information if the object is derived from BOARD_CONNECTED_ITEM.
* @return True if the object is of BOARD_CONNECTED_ITEM type, false otherwise.
*/
virtual bool IsConnected() const
{
return false;
}
/** /**
* A value of wxPoint(0,0) which can be passed to the Draw() functions. * A value of wxPoint(0,0) which can be passed to the Draw() functions.
*/ */

View File

@ -111,7 +111,7 @@ public:
void SetStatus( UNDO_REDO_T aStatus ) { m_undoRedoStatus = aStatus; } void SetStatus( UNDO_REDO_T aStatus ) { m_undoRedoStatus = aStatus; }
UNDO_REDO_T GetStatus() { return m_undoRedoStatus; } UNDO_REDO_T GetStatus() const { return m_undoRedoStatus; }
void SetFlags( STATUS_FLAGS aFlags ) { m_pickerFlags = aFlags; } void SetFlags( STATUS_FLAGS aFlags ) { m_pickerFlags = aFlags; }
@ -148,7 +148,7 @@ public:
* pushes \a aItem to the top of the list * pushes \a aItem to the top of the list
* @param aItem Picker to push on to the list. * @param aItem Picker to push on to the list.
*/ */
void PushItem( ITEM_PICKER& aItem ); void PushItem( const ITEM_PICKER& aItem );
/** /**
* Function PopItem * Function PopItem
@ -160,7 +160,14 @@ public:
* Function IsItemInList * Function IsItemInList
* @return True if \a aItem is found in the pick list. * @return True if \a aItem is found in the pick list.
*/ */
bool ContainsItem( EDA_ITEM* aItem ) const; bool ContainsItem( const EDA_ITEM* aItem ) const;
/**
* Function FindItem
* @return Index of the searched item. If the item is not stored in the list, negative value
* is returned.
*/
int FindItem( const EDA_ITEM* aItem ) const;
/** /**
* Function ClearItemsList * Function ClearItemsList
@ -201,21 +208,21 @@ public:
* if this picker does not exist, a picker is returned, * if this picker does not exist, a picker is returned,
* with its members set to 0 or NULL * with its members set to 0 or NULL
*/ */
ITEM_PICKER GetItemWrapper( unsigned int aIdx ); ITEM_PICKER GetItemWrapper( unsigned int aIdx ) const;
/** /**
* Function GetPickedItem * Function GetPickedItem
* @return A pointer to the picked item * @return A pointer to the picked item
* @param aIdx Index of the picked item in the picked list * @param aIdx Index of the picked item in the picked list
*/ */
EDA_ITEM* GetPickedItem( unsigned int aIdx ); EDA_ITEM* GetPickedItem( unsigned int aIdx ) const;
/** /**
* Function GetPickedItemLink * Function GetPickedItemLink
* @return link of the picked item, or null if does not exist * @return link of the picked item, or null if does not exist
* @param aIdx Index of the picked item in the picked list * @param aIdx Index of the picked item in the picked list
*/ */
EDA_ITEM* GetPickedItemLink( unsigned int aIdx ); EDA_ITEM* GetPickedItemLink( unsigned int aIdx ) const;
/** /**
* Function GetPickedItemStatus * Function GetPickedItemStatus
@ -223,7 +230,7 @@ public:
* or UR_UNSPECIFIED if does not exist * or UR_UNSPECIFIED if does not exist
* @param aIdx Index of the picked item in the picked list * @param aIdx Index of the picked item in the picked list
*/ */
UNDO_REDO_T GetPickedItemStatus( unsigned int aIdx ); UNDO_REDO_T GetPickedItemStatus( unsigned int aIdx ) const;
/** /**
* Function GetPickerFlags * Function GetPickerFlags
@ -231,7 +238,7 @@ public:
* @param aIdx Index of the picker in the picked list * @param aIdx Index of the picker in the picked list
* @return The value stored in the picker, if the picker exists, or 0 if does not exist * @return The value stored in the picker, if the picker exists, or 0 if does not exist
*/ */
STATUS_FLAGS GetPickerFlags( unsigned aIdx ); STATUS_FLAGS GetPickerFlags( unsigned aIdx ) const;
/** /**
* Function SetPickedItem * Function SetPickedItem

View File

@ -136,7 +136,7 @@ public:
* Function Brightened * Function Brightened
* Returns a color that is brighter by a given factor, without modifying object. * Returns a color that is brighter by a given factor, without modifying object.
* @param aFactor Specifies how bright the color should become (valid values: 0.0 .. 1.0). * @param aFactor Specifies how bright the color should become (valid values: 0.0 .. 1.0).
* @return COLOR4D Highlightedd color. * @return COLOR4D Highlighted color.
*/ */
COLOR4D Brightened( double aFactor ) const COLOR4D Brightened( double aFactor ) const
{ {

View File

@ -98,6 +98,24 @@ struct fnv_1a
}; };
/// Hash function for wxString, counterpart of std::string hash
struct WXSTRING_HASH : std::unary_function<wxString, std::size_t>
{
std::size_t operator()( const wxString& aString ) const
{
std::size_t hash = 2166136261u;
for( wxString::const_iterator it = aString.begin(); it != aString.end(); ++it )
{
hash ^= (unsigned char) *it;
hash *= 16777619;
}
return hash;
}
};
/** /**
* Type KEYWORD_MAP * Type KEYWORD_MAP
* is a hashtable made of a const char* and an int. Note that use of this * is a hashtable made of a const char* and an int. Note that use of this

View File

@ -31,6 +31,7 @@
#include <climits> #include <climits>
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
#include <cmath>
#include <math/math_util.h> #include <math/math_util.h>

View File

@ -47,6 +47,12 @@ public:
*/ */
ACTION_MANAGER( TOOL_MANAGER* aToolManager ); ACTION_MANAGER( TOOL_MANAGER* aToolManager );
/**
* Destructor.
* Unregisters every registered action.
*/
~ACTION_MANAGER();
/** /**
* Function RegisterAction() * Function RegisterAction()
* Adds a tool action to the manager and sets it up. After that is is possible to invoke * Adds a tool action to the manager and sets it up. After that is is possible to invoke
@ -75,18 +81,21 @@ public:
*/ */
bool RunAction( const std::string& aActionName ) const; bool RunAction( const std::string& aActionName ) const;
// TODO to be considered
// bool RunAction( int aActionId ) const;
// bool RunAction( TOOL_ACTION* aAction ) const;
/** /**
* Function RunHotKey() * Function RunHotKey()
* Runs an action associated with a hotkey (if there is one available). * Runs an action associated with a hotkey (if there is one available).
* @param aHotKey is the hotkey to be served. * @param aHotKey is the hotkey to be handled.
* @return True if there was an action associated with the hotkey, false otherwise. * @return True if there was an action associated with the hotkey, false otherwise.
*/ */
bool RunHotKey( int aHotKey ) const; bool RunHotKey( int aHotKey ) const;
/**
* Function ClearHotKey()
* Removes an action associated with a hotkey.
* @param aHotKey is the hotkey to be cleared.
*/
void ClearHotKey( int aHotKey );
private: private:
///> Tool manager needed to run actions ///> Tool manager needed to run actions
TOOL_MANAGER* m_toolMgr; TOOL_MANAGER* m_toolMgr;

View File

@ -78,6 +78,17 @@ public:
*/ */
void Clear(); void Clear();
/**
* Function GetSelected()
* Returns the position of selected item. If the returned value is negative, that means that
* menu was dismissed.
* @return The position of selected item in the context menu.
*/
int GetSelected() const
{
return m_selected;
}
/** /**
* Function GetMenu() * Function GetMenu()
* Returns the instance of wxMenu object used to display the menu. * Returns the instance of wxMenu object used to display the menu.
@ -131,6 +142,9 @@ private:
///> Instance of wxMenu used for display of the context menu. ///> Instance of wxMenu used for display of the context menu.
wxMenu m_menu; wxMenu m_menu;
///> Stores the id number of selected item.
int m_selected;
///> Instance of menu event handler. ///> Instance of menu event handler.
CMEventHandler m_handler; CMEventHandler m_handler;

View File

@ -70,6 +70,33 @@ public:
virtual ~TOOL_BASE() {}; virtual ~TOOL_BASE() {};
///> Determines the reason of reset for a tool
enum RESET_REASON
{
RUN, ///< Tool is invoked after being inactive
MODEL_RELOAD, ///< Model changes
GAL_SWITCH ///< Rendering engine changes
};
/**
* Function Init()
* Init() is called once upon a registration of the tool.
*
* @return True if the initialization went fine, false - otherwise.
*/
virtual bool Init()
{
return true;
}
/**
* Function Reset()
* Brings the tool to a known, initial state. If the tool claimed anything from
* the model or the view, it must release it when its reset.
* @param aReason contains information about the reason of tool reset.
*/
virtual void Reset( RESET_REASON aReason ) = 0;
/** /**
* Function GetType() * Function GetType()
* Returns the type of the tool. * Returns the type of the tool.

View File

@ -56,37 +56,44 @@ enum TOOL_ACTIONS
// UI input events // UI input events
TA_NONE = 0x0000, TA_NONE = 0x0000,
TA_MOUSE_CLICK = 0x0001, TA_MOUSE_CLICK = 0x0001,
TA_MOUSE_UP = 0x0002, TA_MOUSE_DBLCLICK = 0x0002,
TA_MOUSE_DOWN = 0x0004, TA_MOUSE_UP = 0x0004,
TA_MOUSE_DRAG = 0x0008, TA_MOUSE_DOWN = 0x0008,
TA_MOUSE_MOTION = 0x0010, TA_MOUSE_DRAG = 0x0010,
TA_MOUSE_WHEEL = 0x0020, TA_MOUSE_MOTION = 0x0020,
TA_MOUSE = 0x003f, TA_MOUSE_WHEEL = 0x0040,
TA_KEY_UP = 0x0040, TA_MOUSE = 0x007f,
TA_KEY_DOWN = 0x0080,
TA_KEY_UP = 0x0080,
TA_KEY_DOWN = 0x0100,
TA_KEYBOARD = TA_KEY_UP | TA_KEY_DOWN, TA_KEYBOARD = TA_KEY_UP | TA_KEY_DOWN,
// View related events // View related events
TA_VIEW_REFRESH = 0x0100, TA_VIEW_REFRESH = 0x0200,
TA_VIEW_ZOOM = 0x0200, TA_VIEW_ZOOM = 0x0400,
TA_VIEW_PAN = 0x0400, TA_VIEW_PAN = 0x0800,
TA_VIEW_DIRTY = 0x0800, TA_VIEW_DIRTY = 0x1000,
TA_CHANGE_LAYER = 0x1000, TA_VIEW = 0x1e00,
TA_CHANGE_LAYER = 0x2000,
// Tool cancel event. Issued automagically when the user hits escape or selects End Tool from // Tool cancel event. Issued automagically when the user hits escape or selects End Tool from
// the context menu. // the context menu.
TA_CANCEL_TOOL = 0x2000, TA_CANCEL_TOOL = 0x4000,
// Context menu update. Issued whenever context menu is open and the user hovers the mouse // Context menu update. Issued whenever context menu is open and the user hovers the mouse
// over one of choices. Used in dynamic highligting in disambiguation menu // over one of choices. Used in dynamic highligting in disambiguation menu
TA_CONTEXT_MENU_UPDATE = 0x4000, TA_CONTEXT_MENU_UPDATE = 0x8000,
// Context menu choice. Sent if the user picked something from the context menu or // Context menu choice. Sent if the user picked something from the context menu or
// closed it without selecting anything. // closed it without selecting anything.
TA_CONTEXT_MENU_CHOICE = 0x8000, TA_CONTEXT_MENU_CHOICE = 0x10000,
// This event is sent *before* undo/redo command is performed.
TA_UNDO_REDO = 0x20000,
// Tool action (allows to control tools) // Tool action (allows to control tools)
TA_ACTION = 0x10000, TA_ACTION = 0x40000,
TA_ANY = 0xffffffff TA_ANY = 0xffffffff
}; };
@ -233,6 +240,12 @@ public:
&& ( ( m_mouseButtons & aButtonMask ) == aButtonMask ); && ( ( m_mouseButtons & aButtonMask ) == aButtonMask );
} }
bool IsDblClick( int aButtonMask = BUT_ANY ) const
{
return ( m_actions == TA_MOUSE_DBLCLICK )
&& ( ( m_mouseButtons & aButtonMask ) == aButtonMask );
}
bool IsDrag( int aButtonMask = BUT_ANY ) const bool IsDrag( int aButtonMask = BUT_ANY ) const
{ {
return ( m_actions == TA_MOUSE_DRAG ) && ( ( m_mouseButtons & aButtonMask ) == aButtonMask ); return ( m_actions == TA_MOUSE_DRAG ) && ( ( m_mouseButtons & aButtonMask ) == aButtonMask );
@ -311,6 +324,9 @@ public:
if( m_commandId && aEvent.m_commandId ) if( m_commandId && aEvent.m_commandId )
return *m_commandId == *aEvent.m_commandId; return *m_commandId == *aEvent.m_commandId;
// Command-type event has to contain either id or string
assert( false );
} }
return true; return true;

View File

@ -48,24 +48,6 @@ public:
TOOL_INTERACTIVE( const std::string& aName ); TOOL_INTERACTIVE( const std::string& aName );
virtual ~TOOL_INTERACTIVE(); virtual ~TOOL_INTERACTIVE();
/**
* Function Reset()
* Brings the tool to a known, initial state. If the tool claimed anything from
* the model or the view, it must release it when its reset.
*/
virtual void Reset() = 0;
/**
* Function Init()
* Init() is called once upon a registration of the tool.
*
* @return True if the initialization went fine, false - otherwise.
*/
virtual bool Init()
{
return true;
}
/** /**
* Function SetContextMenu() * Function SetContextMenu()
* *

View File

@ -99,6 +99,15 @@ public:
*/ */
void UnregisterAction( TOOL_ACTION* aAction ); void UnregisterAction( TOOL_ACTION* aAction );
/**
* Function RunAction()
* Runs the specified action. The common format is "application.ToolName.Action".
*
* @param aActionName is the name of action to be invoked.
* @return True if the action finished successfully, false otherwise.
*/
bool RunAction( const std::string& aActionName );
/** /**
* Function FindTool() * Function FindTool()
* Searches for a tool with given ID. * Searches for a tool with given ID.
@ -118,10 +127,10 @@ public:
TOOL_BASE* FindTool( const std::string& aName ) const; TOOL_BASE* FindTool( const std::string& aName ) const;
/** /**
* Resets the state of a given tool by clearing its wait and * Function ResetTools()
* transition lists and calling tool's internal Reset() method. * Resets all tools (i.e. calls their Reset() method).
*/ */
void ResetTool( TOOL_BASE* aTool ); void ResetTools( TOOL_BASE::RESET_REASON aReason );
/** /**
* Takes an event from the TOOL_DISPATCHER and propagates it to * Takes an event from the TOOL_DISPATCHER and propagates it to

View File

@ -69,9 +69,6 @@ namespace hed {
struct TTLtraits { struct TTLtraits {
// The actual triangulation object
static Triangulation* triang_;
/** The floating point type used in calculations /** The floating point type used in calculations
* involving scalar products and cross products. * involving scalar products and cross products.
*/ */
@ -172,127 +169,6 @@ namespace hed {
} }
//@} // End of Geometric Predicates Group //@} // End of Geometric Predicates Group
// A rationale for directing these functions to traits is:
// e.g., constraints
//----------------------------------------------------------------------------------------------
/* Checks if the edge associated with \e dart should be swapped
* according to the Delaunay criterion.<br>
*
* \note
* This function is also present in the TTL as ttl::swapTestDelaunay.<br>
* Thus, the function can be implemented simply as:
* \code
* { return ttl::swapTestDelaunay<TTLtraits>(dart); }
* \endcode
*/
//static bool swapTestDelaunay(const Dart& dart) {
// return ttl::swapTestDelaunay<TTLtraits>(dart);
//}
//----------------------------------------------------------------------------------------------
/* Checks if the edge associated with \e dart can be swapped, i.e.,
* if the edge is a diagonal in a (strictly) convex quadrilateral.
* This function is also present as ttl::swappableEdge.
*/
//static bool swappableEdge(const Dart& dart) {
// return ttl::swappableEdge<TTLtraits>(dart);
//}
//----------------------------------------------------------------------------------------------
/* Checks if the edge associated with \e dart should be \e fixed, meaning
* that it should never be swapped. ??? Use when constraints.
*/
//static bool fixedEdge(const Dart& dart) {
// return dart.getEdge()->isConstrained();
//}
//----------------------------------------------------------------------------------------------
// ----------------------- Functions for Delaunay Triangulation Group -------------------------
//----------------------------------------------------------------------------------------------
/** @name Functions for Delaunay Triangulation */
//@{
//----------------------------------------------------------------------------------------------
/** Swaps the edge associated with \e dart in the actual data structure.
*
* <center>
* \image html swapEdge.gif
* </center>
*
* \param dart
* Some of the functions require a dart as output.
* If this is required by the actual function, the dart should be delivered
* back in a position as seen if it was glued to the edge when swapping (rotating)
* the edge CCW; see the figure.
*
* \note
* - If the edge is \e constrained, or if it should not be swapped for
* some other reason, this function need not do the actual swap of the edge.
* - Some functions in TTL require that \c swapEdge is implemented such that
* darts outside the quadrilateral are not affected by the swap.
*/
static void swapEdge(Dart& dart) {
if (!dart.getEdge()->isConstrained()) triang_->swapEdge(dart.getEdge());
}
//----------------------------------------------------------------------------------------------
/** Splits the triangle associated with \e dart in the actual data structure into
* three new triangles joining at \e point.
*
* <center>
* \image html splitTriangle.gif
* </center>
*
* \param dart
* Output: A CCW dart incident with the new node; see the figure.
*/
static void splitTriangle(Dart& dart, NodePtr point) {
EdgePtr edge = triang_->splitTriangle(dart.getEdge(), point);
dart.init(edge);
}
//@} // End of Functions for Delaunay Triangulation group
//----------------------------------------------------------------------------------------------
// --------------------------- Functions for removing nodes Group -----------------------------
//----------------------------------------------------------------------------------------------
/** @name Functions for removing nodes */
//@{
//----------------------------------------------------------------------------------------------
/** The reverse operation of TTLtraits::splitTriangle.
* This function is only required for functions that involve
* removal of interior nodes; see for example ttl::removeInteriorNode.
*
* <center>
* \image html reverse_splitTriangle.gif
* </center>
*/
static void reverse_splitTriangle(Dart& dart) {
triang_->reverse_splitTriangle(dart.getEdge());
}
//----------------------------------------------------------------------------------------------
/** Removes a triangle with an edge at the boundary of the triangulation
* in the actual data structure
*/
static void removeBoundaryTriangle(Dart& d) {
triang_->removeTriangle(d.getEdge());
}
//@} // End of Functions for removing nodes Group
}; };
}; // End of hed namespace }; // End of hed namespace

View File

@ -51,9 +51,13 @@
#include <vector> #include <vector>
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
#include <ttl/ttl.h>
#include <ttl/ttl_util.h> #include <ttl/ttl_util.h>
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
namespace ttl {
class TriangulationHelper;
};
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
// The half-edge data structure // The half-edge data structure
@ -65,6 +69,7 @@ namespace hed {
class Edge; class Edge;
typedef boost::shared_ptr<Node> NodePtr; typedef boost::shared_ptr<Node> NodePtr;
typedef boost::shared_ptr<Edge> EdgePtr; typedef boost::shared_ptr<Edge> EdgePtr;
typedef boost::weak_ptr<Edge> EdgeWeakPtr;
typedef std::vector<NodePtr> NodesContainer; typedef std::vector<NodePtr> NodesContainer;
//------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------
@ -151,8 +156,7 @@ public:
class Edge { class Edge {
public: public:
/// Constructor /// Constructor
Edge() : weight_(0) Edge() : weight_(0), isLeadingEdge_(false) {}
{ flags_.isLeadingEdge_ = false; flags_.isConstrained_ = false; }
/// Destructor /// Destructor
virtual ~Edge() {} virtual ~Edge() {}
@ -167,49 +171,52 @@ public:
void setTwinEdge(const EdgePtr& edge) { twinEdge_ = edge; } void setTwinEdge(const EdgePtr& edge) { twinEdge_ = edge; }
/// Sets the edge as a leading edge /// Sets the edge as a leading edge
void setAsLeadingEdge(bool val=true) { flags_.isLeadingEdge_ = val; } void setAsLeadingEdge(bool val=true) { isLeadingEdge_ = val; }
/// Checks if an edge is a leading edge /// Checks if an edge is a leading edge
bool isLeadingEdge() const { return flags_.isLeadingEdge_; } bool isLeadingEdge() const { return isLeadingEdge_; }
/// Sets the edge as a constrained edge
void setConstrained(bool val=true) { flags_.isConstrained_ = val;
if (twinEdge_) twinEdge_->flags_.isConstrained_ = val; }
/// Checks if an edge is constrained
bool isConstrained() const { return flags_.isConstrained_; }
/// Returns the twin edge /// Returns the twin edge
const EdgePtr& getTwinEdge() const { return twinEdge_; }; EdgePtr getTwinEdge() const { return twinEdge_.lock(); };
void clearTwinEdge() { twinEdge_.reset(); }
/// Returns the next edge in face /// Returns the next edge in face
const EdgePtr& getNextEdgeInFace() const { return nextEdgeInFace_; } const EdgePtr& getNextEdgeInFace() const { return nextEdgeInFace_; }
/// Retuns the source node /// Retuns the source node
virtual const NodePtr& getSourceNode() const { return sourceNode_; } const NodePtr& getSourceNode() const { return sourceNode_; }
/// Returns the target node /// Returns the target node
virtual const NodePtr& getTargetNode() const { return getNextEdgeInFace()->getSourceNode(); } virtual const NodePtr& getTargetNode() const { return nextEdgeInFace_->getSourceNode(); }
void setWeight( unsigned int weight ) { weight_ = weight; } void setWeight( unsigned int weight ) { weight_ = weight; }
unsigned int getWeight() const { return weight_; } unsigned int getWeight() const { return weight_; }
void clear()
{
sourceNode_.reset();
nextEdgeInFace_.reset();
if( !twinEdge_.expired() )
{
twinEdge_.lock()->clearTwinEdge();
twinEdge_.reset();
}
}
protected: protected:
NodePtr sourceNode_; NodePtr sourceNode_;
EdgePtr twinEdge_; EdgeWeakPtr twinEdge_;
EdgePtr nextEdgeInFace_; EdgePtr nextEdgeInFace_;
unsigned int weight_; unsigned int weight_;
struct {
bool isLeadingEdge_; bool isLeadingEdge_;
bool isConstrained_;
} flags_;
}; // End of class Edge }; // End of class Edge
/** \class EdgeMST /** \class EdgeMST
* \brief \b %Specialization of Edge class to be used for Minimum Spanning Tree algorithm. * \brief \b Specialization of %Edge class to be used for Minimum Spanning Tree algorithm.
*/ */
class EdgeMST : public Edge class EdgeMST : public Edge
{ {
@ -221,10 +228,17 @@ public:
target_(target) target_(target)
{ sourceNode_ = source; weight_ = weight; } { sourceNode_ = source; weight_ = weight; }
EdgeMST( const Edge& edge )
{
sourceNode_ = edge.getSourceNode();
target_ = edge.getTargetNode();
weight_ = edge.getWeight();
}
~EdgeMST() {}; ~EdgeMST() {};
/// @copydoc Edge::setSourceNode() /// @copydoc Edge::setSourceNode()
const NodePtr& getTargetNode() const { return target_; } virtual const NodePtr& getTargetNode() const { return target_; }
}; };
@ -242,26 +256,75 @@ public:
class Triangulation { class Triangulation {
protected: protected:
list<EdgePtr> leadingEdges_; // one half-edge for each arc std::list<EdgePtr> leadingEdges_; // one half-edge for each arc
ttl::TriangulationHelper* helper;
void addLeadingEdge(EdgePtr& edge) { void addLeadingEdge(EdgePtr& edge) {
edge->setAsLeadingEdge(); edge->setAsLeadingEdge();
leadingEdges_.push_front( edge ); leadingEdges_.push_front( edge );
} }
bool removeLeadingEdgeFromList(EdgePtr& leadingEdge); bool removeLeadingEdgeFromList(EdgePtr& leadingEdge);
void cleanAll(); void cleanAll();
/** Swaps the edge associated with \e dart in the actual data structure.
*
* <center>
* \image html swapEdge.gif
* </center>
*
* \param dart
* Some of the functions require a dart as output.
* If this is required by the actual function, the dart should be delivered
* back in a position as seen if it was glued to the edge when swapping (rotating)
* the edge CCW; see the figure.
*
* \note
* - If the edge is \e constrained, or if it should not be swapped for
* some other reason, this function need not do the actual swap of the edge.
* - Some functions in TTL require that \c swapEdge is implemented such that
* darts outside the quadrilateral are not affected by the swap.
*/
void swapEdge(Dart& dart);
/** Splits the triangle associated with \e dart in the actual data structure into
* three new triangles joining at \e point.
*
* <center>
* \image html splitTriangle.gif
* </center>
*
* \param dart
* Output: A CCW dart incident with the new node; see the figure.
*/
void splitTriangle(Dart& dart, const NodePtr& point);
/** The reverse operation of TTLtraits::splitTriangle.
* This function is only required for functions that involve
* removal of interior nodes; see for example TrinagulationHelper::removeInteriorNode.
*
* <center>
* \image html reverse_splitTriangle.gif
* </center>
*/
void reverse_splitTriangle(Dart& dart);
/** Removes a triangle with an edge at the boundary of the triangulation
* in the actual data structure
*/
void removeBoundaryTriangle(Dart& d);
public: public:
/// Default constructor /// Default constructor
Triangulation() {} Triangulation();
/// Copy constructor /// Copy constructor
Triangulation(const Triangulation& tr) { Triangulation(const Triangulation& tr);
std::cout << "Triangulation: Copy constructor not present - EXIT.";
exit(-1);
}
/// Destructor /// Destructor
~Triangulation() { cleanAll(); } ~Triangulation();
/// Creates a Delaunay triangulation from a set of points /// Creates a Delaunay triangulation from a set of points
void createDelaunay(NodesContainer::iterator first, void createDelaunay(NodesContainer::iterator first,
@ -280,7 +343,7 @@ public:
void swapEdge(EdgePtr& diagonal); void swapEdge(EdgePtr& diagonal);
/// Splits the triangle associated with edge into three new triangles joining at point /// Splits the triangle associated with edge into three new triangles joining at point
EdgePtr splitTriangle(EdgePtr& edge, NodePtr& point); EdgePtr splitTriangle(EdgePtr& edge, const NodePtr& point);
// Functions required by TTL for removing nodes in a Delaunay triangulation // Functions required by TTL for removing nodes in a Delaunay triangulation
@ -295,20 +358,20 @@ public:
Dart createDart(); Dart createDart();
/// Returns a list of "triangles" (one leading half-edge for each triangle) /// Returns a list of "triangles" (one leading half-edge for each triangle)
const list<EdgePtr>& getLeadingEdges() const { return leadingEdges_; } const std::list<EdgePtr>& getLeadingEdges() const { return leadingEdges_; }
/// Returns the number of triangles /// Returns the number of triangles
int noTriangles() const { return (int)leadingEdges_.size(); } int noTriangles() const { return (int)leadingEdges_.size(); }
/// Returns a list of half-edges (one half-edge for each arc) /// Returns a list of half-edges (one half-edge for each arc)
list<EdgePtr>* getEdges(bool skip_boundary_edges = false) const; std::list<EdgePtr>* getEdges(bool skip_boundary_edges = false) const;
#ifdef TTL_USE_NODE_FLAG #ifdef TTL_USE_NODE_FLAG
/// Sets flag in all the nodes /// Sets flag in all the nodes
void flagNodes(bool flag) const; void flagNodes(bool flag) const;
/// Returns a list of nodes. This function requires TTL_USE_NODE_FLAG to be defined. \see Node. /// Returns a list of nodes. This function requires TTL_USE_NODE_FLAG to be defined. \see Node.
list<NodePtr>* getNodes() const; std::list<NodePtr>* getNodes() const;
#endif #endif
/// Swaps edges until the triangulation is Delaunay (constrained edges are not swapped) /// Swaps edges until the triangulation is Delaunay (constrained edges are not swapped)
@ -320,12 +383,16 @@ public:
/// Returns an arbitrary interior node (as the source node of the returned edge) /// Returns an arbitrary interior node (as the source node of the returned edge)
EdgePtr getInteriorNode() const; EdgePtr getInteriorNode() const;
EdgePtr getBoundaryEdgeInTriangle(const EdgePtr& e) const;
/// Returns an arbitrary boundary edge /// Returns an arbitrary boundary edge
EdgePtr getBoundaryEdge() const; EdgePtr getBoundaryEdge() const;
/// Print edges for plotting with, e.g., gnuplot /// Print edges for plotting with, e.g., gnuplot
void printEdges(std::ofstream& os) const; void printEdges(std::ofstream& os) const;
friend class ttl::TriangulationHelper;
}; // End of class Triangulation }; // End of class Triangulation

View File

@ -52,8 +52,6 @@
} }
#endif #endif
using std::list;
// Next on TOPOLOGY: // Next on TOPOLOGY:
// - get triangle strips // - get triangle strips
@ -102,7 +100,7 @@
* - \e CW - clockwise * - \e CW - clockwise
* - \e 0_orbit, \e 1_orbit and \e 2_orbit: A sequence of darts around * - \e 0_orbit, \e 1_orbit and \e 2_orbit: A sequence of darts around
* a node, around an edge and in a triangle respectively; * a node, around an edge and in a triangle respectively;
* see ttl::get_0_orbit_interior and ttl::get_0_orbit_boundary * see get_0_orbit_interior and get_0_orbit_boundary
* - \e arc - In a triangulation an arc is equivalent with an edge * - \e arc - In a triangulation an arc is equivalent with an edge
* *
* \see * \see
@ -115,14 +113,14 @@
namespace ttl { namespace ttl {
class TriangulationHelper
{
#ifndef DOXYGEN_SHOULD_SKIP_THIS #ifndef DOXYGEN_SHOULD_SKIP_THIS
//------------------------------------------------------------------------------------------------
// ----------------------------------- Forward declarations -------------------------------------
//------------------------------------------------------------------------------------------------
#if ((_MSC_VER > 0) && (_MSC_VER < 1300)) public:
#else TriangulationHelper(hed::Triangulation& triang) : triangulation(triang)
{
}
// Delaunay Triangulation // Delaunay Triangulation
// ---------------------- // ----------------------
@ -145,55 +143,55 @@ namespace ttl {
// Topological and Geometric Queries // Topological and Geometric Queries
// --------------------------------- // ---------------------------------
template<class TraitsType, class PointType, class DartType> template<class TraitsType, class PointType, class DartType>
bool locateFaceSimplest(const PointType& point, DartType& dart); static bool locateFaceSimplest(const PointType& point, DartType& dart);
template<class TraitsType, class PointType, class DartType> template<class TraitsType, class PointType, class DartType>
bool locateTriangle(const PointType& point, DartType& dart); static bool locateTriangle(const PointType& point, DartType& dart);
template<class TraitsType, class PointType, class DartType> template<class TraitsType, class PointType, class DartType>
bool inTriangleSimplest(const PointType& point, const DartType& dart); static bool inTriangleSimplest(const PointType& point, const DartType& dart);
template<class TraitsType, class PointType, class DartType> template<class TraitsType, class PointType, class DartType>
bool inTriangle(const PointType& point, const DartType& dart); static bool inTriangle(const PointType& point, const DartType& dart);
template<class DartType, class DartListType> template<class DartType, class DartListType>
void getBoundary(const DartType& dart, DartListType& boundary); static void getBoundary(const DartType& dart, DartListType& boundary);
template<class DartType> template<class DartType>
bool isBoundaryEdge(const DartType& dart); static bool isBoundaryEdge(const DartType& dart);
template<class DartType> template<class DartType>
bool isBoundaryFace(const DartType& dart); static bool isBoundaryFace(const DartType& dart);
template<class DartType> template<class DartType>
bool isBoundaryNode(const DartType& dart); static bool isBoundaryNode(const DartType& dart);
template<class DartType> template<class DartType>
int getDegreeOfNode(const DartType& dart); static int getDegreeOfNode(const DartType& dart);
template<class DartType, class DartListType> template<class DartType, class DartListType>
void get_0_orbit_interior(const DartType& dart, DartListType& orbit); static void get_0_orbit_interior(const DartType& dart, DartListType& orbit);
template<class DartType, class DartListType> template<class DartType, class DartListType>
void get_0_orbit_boundary(const DartType& dart, DartListType& orbit); static void get_0_orbit_boundary(const DartType& dart, DartListType& orbit);
template<class DartType> template<class DartType>
bool same_0_orbit(const DartType& d1, const DartType& d2); static bool same_0_orbit(const DartType& d1, const DartType& d2);
template<class DartType> template<class DartType>
bool same_1_orbit(const DartType& d1, const DartType& d2); static bool same_1_orbit(const DartType& d1, const DartType& d2);
template<class DartType> template<class DartType>
bool same_2_orbit(const DartType& d1, const DartType& d2); static bool same_2_orbit(const DartType& d1, const DartType& d2);
template <class TraitsType, class DartType> template <class TraitsType, class DartType>
bool swappableEdge(const DartType& dart, bool allowDegeneracy = false); static bool swappableEdge(const DartType& dart, bool allowDegeneracy = false);
template<class DartType> template<class DartType>
void positionAtNextBoundaryEdge(DartType& dart); static void positionAtNextBoundaryEdge(DartType& dart);
template<class TraitsType, class DartType> template<class TraitsType, class DartType>
bool convexBoundary(const DartType& dart); static bool convexBoundary(const DartType& dart);
// Utilities for Delaunay Triangulation // Utilities for Delaunay Triangulation
@ -205,7 +203,7 @@ namespace ttl {
void optimizeDelaunay(DartListType& elist, const typename DartListType::iterator end); void optimizeDelaunay(DartListType& elist, const typename DartListType::iterator end);
template<class TraitsType, class DartType> template<class TraitsType, class DartType>
bool swapTestDelaunay(const DartType& dart, bool cycling_check = false); bool swapTestDelaunay(const DartType& dart, bool cycling_check = false) const;
template<class TraitsType, class DartType> template<class TraitsType, class DartType>
void recSwapDelaunay(DartType& diagonal); void recSwapDelaunay(DartType& diagonal);
@ -223,9 +221,29 @@ namespace ttl {
// Constrained Triangulation // Constrained Triangulation
// ------------------------- // -------------------------
template<class TraitsType, class DartType> template<class TraitsType, class DartType>
DartType insertConstraint(DartType& dstart, DartType& dend, bool optimize_delaunay); static DartType insertConstraint(DartType& dstart, DartType& dend, bool optimize_delaunay);
#endif private:
hed::Triangulation& triangulation;
template <class TraitsType, class ForwardIterator, class DartType>
void insertNodes(ForwardIterator first, ForwardIterator last, DartType& dart);
template <class TopologyElementType, class DartType>
static bool isMemberOfFace(const TopologyElementType& topologyElement, const DartType& dart);
template <class TraitsType, class NodeType, class DartType>
static bool locateFaceWithNode(const NodeType& node, DartType& dart_iter);
template <class DartType>
static void getAdjacentTriangles(const DartType& dart, DartType& t1, DartType& t2, DartType& t3);
template <class DartType>
static void getNeighborNodes(const DartType& dart, std::list<DartType>& node_list, bool& boundary);
template <class TraitsType, class DartType>
static bool degenerateTriangle(const DartType& dart);
};
#endif // DOXYGEN_SHOULD_SKIP_THIS #endif // DOXYGEN_SHOULD_SKIP_THIS
@ -245,7 +263,7 @@ namespace ttl {
* can be created as two triangles forming a rectangle that contains * can be created as two triangles forming a rectangle that contains
* all the points. * all the points.
* After \c insertNode has been called repeatedly with all the points, * After \c insertNode has been called repeatedly with all the points,
* ttl::removeRectangularBoundary can be called to remove triangles * removeRectangularBoundary can be called to remove triangles
* at the boundary of the triangulation so that the boundary * at the boundary of the triangulation so that the boundary
* form the convex hull of the points. * form the convex hull of the points.
* *
@ -268,19 +286,19 @@ namespace ttl {
* - \ref hed::TTLtraits::splitTriangle "TraitsType::splitTriangle" (DartType&, const PointType&) * - \ref hed::TTLtraits::splitTriangle "TraitsType::splitTriangle" (DartType&, const PointType&)
* *
* \using * \using
* - ttl::locateTriangle * - locateTriangle
* - ttl::recSwapDelaunay * - recSwapDelaunay
* *
* \note * \note
* - For efficiency reasons \e dart should be close to the insertion \e point. * - For efficiency reasons \e dart should be close to the insertion \e point.
* *
* \see * \see
* ttl::removeRectangularBoundary * removeRectangularBoundary
*/ */
template <class TraitsType, class DartType, class PointType> template <class TraitsType, class DartType, class PointType>
bool insertNode(DartType& dart, PointType& point) { bool TriangulationHelper::insertNode(DartType& dart, PointType& point) {
bool found = ttl::locateTriangle<TraitsType>(point, dart); bool found = locateTriangle<TraitsType>(point, dart);
if (!found) { if (!found) {
#ifdef DEBUG_TTL #ifdef DEBUG_TTL
cout << "ERROR: Triangulation::insertNode: NO triangle found. /n"; cout << "ERROR: Triangulation::insertNode: NO triangle found. /n";
@ -289,7 +307,7 @@ namespace ttl {
} }
// ??? can we hide the dart? this is not possible if one triangle only // ??? can we hide the dart? this is not possible if one triangle only
TraitsType::splitTriangle(dart, point); triangulation.splitTriangle(dart, point);
DartType d1 = dart; DartType d1 = dart;
d1.alpha2().alpha1().alpha2().alpha0().alpha1(); d1.alpha2().alpha1().alpha2().alpha0().alpha1();
@ -304,14 +322,14 @@ namespace ttl {
//DartType dsav = d3; //DartType dsav = d3;
d3.alpha0().alpha1(); d3.alpha0().alpha1();
//if (!TraitsType::fixedEdge(d1) && !ttl::isBoundaryEdge(d1)) { //if (!TraitsType::fixedEdge(d1) && !isBoundaryEdge(d1)) {
if (!ttl::isBoundaryEdge(d1)) { if (!isBoundaryEdge(d1)) {
d1.alpha2(); d1.alpha2();
recSwapDelaunay<TraitsType>(d1); recSwapDelaunay<TraitsType>(d1);
} }
//if (!TraitsType::fixedEdge(d2) && !ttl::isBoundaryEdge(d2)) { //if (!TraitsType::fixedEdge(d2) && !isBoundaryEdge(d2)) {
if (!ttl::isBoundaryEdge(d2)) { if (!isBoundaryEdge(d2)) {
d2.alpha2(); d2.alpha2();
recSwapDelaunay<TraitsType>(d2); recSwapDelaunay<TraitsType>(d2);
} }
@ -319,8 +337,8 @@ namespace ttl {
// Preserve the incoming dart as output incident to the node and CCW // Preserve the incoming dart as output incident to the node and CCW
//d = dsav.alpha2(); //d = dsav.alpha2();
dart.alpha2(); dart.alpha2();
//if (!TraitsType::fixedEdge(d3) && !ttl::isBoundaryEdge(d3)) { //if (!TraitsType::fixedEdge(d3) && !isBoundaryEdge(d3)) {
if (!ttl::isBoundaryEdge(d3)) { if (!isBoundaryEdge(d3)) {
d3.alpha2(); d3.alpha2();
recSwapDelaunay<TraitsType>(d3); recSwapDelaunay<TraitsType>(d3);
} }
@ -332,7 +350,7 @@ namespace ttl {
//------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------
// Private/Hidden function (might change later) // Private/Hidden function (might change later)
template <class TraitsType, class ForwardIterator, class DartType> template <class TraitsType, class ForwardIterator, class DartType>
void insertNodes(ForwardIterator first, ForwardIterator last, DartType& dart) { void TriangulationHelper::insertNodes(ForwardIterator first, ForwardIterator last, DartType& dart) {
// Assumes that the dereferenced point objects are pointers. // Assumes that the dereferenced point objects are pointers.
// References to the point objects are then passed to TTL. // References to the point objects are then passed to TTL.
@ -355,14 +373,14 @@ namespace ttl {
* Output: A CCW dart at the new boundary * Output: A CCW dart at the new boundary
* *
* \using * \using
* - ttl::removeBoundaryNode * - removeBoundaryNode
* *
* \note * \note
* - This function requires that the boundary of the triangulation is * - This function requires that the boundary of the triangulation is
* a rectangle with four nodes (one in each corner). * a rectangle with four nodes (one in each corner).
*/ */
template <class TraitsType, class DartType> template <class TraitsType, class DartType>
void removeRectangularBoundary(DartType& dart) { void TriangulationHelper::removeRectangularBoundary(DartType& dart) {
DartType d_next = dart; DartType d_next = dart;
DartType d_iter; DartType d_iter;
@ -370,8 +388,8 @@ namespace ttl {
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
d_iter = d_next; d_iter = d_next;
d_next.alpha0(); d_next.alpha0();
ttl::positionAtNextBoundaryEdge(d_next); positionAtNextBoundaryEdge(d_next);
ttl::removeBoundaryNode<TraitsType>(d_iter); removeBoundaryNode<TraitsType>(d_iter);
} }
dart = d_next; // Return a dart at the new boundary dart = d_next; // Return a dart at the new boundary
@ -383,20 +401,20 @@ namespace ttl {
* updates the triangulation to be Delaunay. * updates the triangulation to be Delaunay.
* *
* \using * \using
* - ttl::removeBoundaryNode if \e dart represents a node at the boundary * - removeBoundaryNode if \e dart represents a node at the boundary
* - ttl::removeInteriorNode if \e dart represents an interior node * - removeInteriorNode if \e dart represents an interior node
* *
* \note * \note
* - The node cannot belong to a fixed (constrained) edge that is not * - The node cannot belong to a fixed (constrained) edge that is not
* swappable. (An endless loop is likely to occur in this case). * swappable. (An endless loop is likely to occur in this case).
*/ */
template <class TraitsType, class DartType> template <class TraitsType, class DartType>
void removeNode(DartType& dart) { void TriangulationHelper::removeNode(DartType& dart) {
if (ttl::isBoundaryNode(dart)) if (isBoundaryNode(dart))
ttl::removeBoundaryNode<TraitsType>(dart); removeBoundaryNode<TraitsType>(dart);
else else
ttl::removeInteriorNode<TraitsType>(dart); removeInteriorNode<TraitsType>(dart);
} }
@ -405,14 +423,14 @@ namespace ttl {
* updates the triangulation to be Delaunay. * updates the triangulation to be Delaunay.
* *
* \using * \using
* - ttl::swapEdgesAwayFromBoundaryNode * - swapEdgesAwayFromBoundaryNode
* - ttl::optimizeDelaunay * - optimizeDelaunay
* *
* \require * \require
* - \ref hed::TTLtraits::removeBoundaryTriangle "TraitsType::removeBoundaryTriangle" (Dart&) * - \ref hed::TTLtraits::removeBoundaryTriangle "TraitsType::removeBoundaryTriangle" (Dart&)
*/ */
template <class TraitsType, class DartType> template <class TraitsType, class DartType>
void removeBoundaryNode(DartType& dart) { void TriangulationHelper::removeBoundaryNode(DartType& dart) {
// ... and update Delaunay // ... and update Delaunay
// - CCW dart must be given (for remove) // - CCW dart must be given (for remove)
@ -420,13 +438,13 @@ namespace ttl {
// we assume that there is not only one triangle left in the triangulation. // we assume that there is not only one triangle left in the triangulation.
// Position at boundary edge and CCW // Position at boundary edge and CCW
if (!ttl::isBoundaryEdge(dart)) { if (!isBoundaryEdge(dart)) {
dart.alpha1(); // ensures that next function delivers back a CCW dart (if the given dart is CCW) dart.alpha1(); // ensures that next function delivers back a CCW dart (if the given dart is CCW)
ttl::positionAtNextBoundaryEdge(dart); positionAtNextBoundaryEdge(dart);
} }
list<DartType> swapped_edges; std::list<DartType> swapped_edges;
ttl::swapEdgesAwayFromBoundaryNode<TraitsType>(dart, swapped_edges); swapEdgesAwayFromBoundaryNode<TraitsType>(dart, swapped_edges);
// Remove boundary triangles and remove the new boundary from the list // Remove boundary triangles and remove the new boundary from the list
// of swapped edges, see below. // of swapped edges, see below.
@ -435,7 +453,7 @@ namespace ttl {
bool bend = false; bool bend = false;
while (bend == false) { while (bend == false) {
dnext.alpha1().alpha2(); dnext.alpha1().alpha2();
if (ttl::isBoundaryEdge(dnext)) if (isBoundaryEdge(dnext))
bend = true; // Stop when boundary bend = true; // Stop when boundary
// Generic: Also remove the new boundary from the list of swapped edges // Generic: Also remove the new boundary from the list of swapped edges
@ -443,20 +461,20 @@ namespace ttl {
n_bedge.alpha1().alpha0().alpha1().alpha2(); // new boundary edge n_bedge.alpha1().alpha0().alpha1().alpha2(); // new boundary edge
// ??? can we avoid find if we do this in swap away? // ??? can we avoid find if we do this in swap away?
typename list<DartType>::iterator it; typename std::list<DartType>::iterator it;
it = find(swapped_edges.begin(), swapped_edges.end(), n_bedge); it = find(swapped_edges.begin(), swapped_edges.end(), n_bedge);
if (it != swapped_edges.end()) if (it != swapped_edges.end())
swapped_edges.erase(it); swapped_edges.erase(it);
// Remove the boundary triangle // Remove the boundary triangle
TraitsType::removeBoundaryTriangle(d_iter); triangulation.removeBoundaryTriangle(d_iter);
d_iter = dnext; d_iter = dnext;
} }
// Optimize Delaunay // Optimize Delaunay
typedef list<DartType> DartListType; typedef std::list<DartType> DartListType;
ttl::optimizeDelaunay<TraitsType, DartType, DartListType>(swapped_edges); optimizeDelaunay<TraitsType, DartType, DartListType>(swapped_edges);
} }
@ -465,8 +483,8 @@ namespace ttl {
* updates the triangulation to be Delaunay. * updates the triangulation to be Delaunay.
* *
* \using * \using
* - ttl::swapEdgesAwayFromInteriorNode * - swapEdgesAwayFromInteriorNode
* - ttl::optimizeDelaunay * - optimizeDelaunay
* *
* \require * \require
* - \ref hed::TTLtraits::reverse_splitTriangle "TraitsType::reverse_splitTriangle" (Dart&) * - \ref hed::TTLtraits::reverse_splitTriangle "TraitsType::reverse_splitTriangle" (Dart&)
@ -476,7 +494,7 @@ namespace ttl {
* swappable. (An endless loop is likely to occur in this case). * swappable. (An endless loop is likely to occur in this case).
*/ */
template <class TraitsType, class DartType> template <class TraitsType, class DartType>
void removeInteriorNode(DartType& dart) { void TriangulationHelper::removeInteriorNode(DartType& dart) {
// ... and update to Delaunay. // ... and update to Delaunay.
// Must allow degeneracy temporarily, see comments in swap edges away // Must allow degeneracy temporarily, see comments in swap edges away
@ -492,13 +510,13 @@ namespace ttl {
// Assumes dart is counterclockwise // Assumes dart is counterclockwise
list<DartType> swapped_edges; std::list<DartType> swapped_edges;
ttl::swapEdgesAwayFromInteriorNode<TraitsType>(dart, swapped_edges); swapEdgesAwayFromInteriorNode<TraitsType>(dart, swapped_edges);
// The reverse operation of split triangle: // The reverse operation of split triangle:
// Make one triangle of the three triangles at the node associated with dart // Make one triangle of the three triangles at the node associated with dart
// TraitsType:: // TraitsType::
TraitsType::reverse_splitTriangle(dart); triangulation.reverse_splitTriangle(dart);
// ???? Not generic yet if we are very strict: // ???? Not generic yet if we are very strict:
// When calling unsplit triangle, darts at the three opposite sides may // When calling unsplit triangle, darts at the three opposite sides may
@ -511,7 +529,7 @@ namespace ttl {
// Note the theoretical result: if there are no edges in the list, // Note the theoretical result: if there are no edges in the list,
// the triangulation is Delaunay already // the triangulation is Delaunay already
ttl::optimizeDelaunay<TraitsType, DartType>(swapped_edges); optimizeDelaunay<TraitsType, DartType>(swapped_edges);
} }
//@} // End of Delaunay Triangulation Group //@} // End of Delaunay Triangulation Group
@ -527,7 +545,7 @@ namespace ttl {
//------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------
// Private/Hidden function (might change later) // Private/Hidden function (might change later)
template <class TopologyElementType, class DartType> template <class TopologyElementType, class DartType>
bool isMemberOfFace(const TopologyElementType& topologyElement, const DartType& dart) { bool TriangulationHelper::isMemberOfFace(const TopologyElementType& topologyElement, const DartType& dart) {
// Check if the given topology element (node, edge or face) is a member of the face // Check if the given topology element (node, edge or face) is a member of the face
// Assumes: // Assumes:
@ -547,7 +565,7 @@ namespace ttl {
//------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------
// Private/Hidden function (might change later) // Private/Hidden function (might change later)
template <class TraitsType, class NodeType, class DartType> template <class TraitsType, class NodeType, class DartType>
bool locateFaceWithNode(const NodeType& node, DartType& dart_iter) { bool TriangulationHelper::locateFaceWithNode(const NodeType& node, DartType& dart_iter) {
// Locate a face in the topology structure with the given node as a member // Locate a face in the topology structure with the given node as a member
// Assumes: // Assumes:
// - TraitsType::orient2d(DartType, DartType, NodeType) // - TraitsType::orient2d(DartType, DartType, NodeType)
@ -594,10 +612,10 @@ namespace ttl {
* \e regular as explained above. * \e regular as explained above.
* *
* \see * \see
* ttl::locateTriangle * locateTriangle
*/ */
template <class TraitsType, class PointType, class DartType> template <class TraitsType, class PointType, class DartType>
bool locateFaceSimplest(const PointType& point, DartType& dart) { bool TriangulationHelper::locateFaceSimplest(const PointType& point, DartType& dart) {
// Not degenerate triangles if point is on the extension of the edges // Not degenerate triangles if point is on the extension of the edges
// But inTriangle may be called in case of true (may update to inFace2) // But inTriangle may be called in case of true (may update to inFace2)
// Convex boundary // Convex boundary
@ -660,11 +678,11 @@ namespace ttl {
* then the edge associated with \e dart will be at the boundary of the triangulation. * then the edge associated with \e dart will be at the boundary of the triangulation.
* *
* \using * \using
* - ttl::locateFaceSimplest * - locateFaceSimplest
* - ttl::inTriangle * - inTriangle
*/ */
template <class TraitsType, class PointType, class DartType> template <class TraitsType, class PointType, class DartType>
bool locateTriangle(const PointType& point, DartType& dart) { bool TriangulationHelper::locateTriangle(const PointType& point, DartType& dart) {
// The purpose is to have a fast and stable procedure that // The purpose is to have a fast and stable procedure that
// i) avoids concluding that a point is inside a triangle if it is not inside // i) avoids concluding that a point is inside a triangle if it is not inside
// ii) avoids infinite loops // ii) avoids infinite loops
@ -713,10 +731,10 @@ namespace ttl {
* - \ref hed::TTLtraits::orient2d "TraitsType::orient2d" (DartType&, DartType&, PointType&) * - \ref hed::TTLtraits::orient2d "TraitsType::orient2d" (DartType&, DartType&, PointType&)
* *
* \see * \see
* ttl::inTriangle for a more robust function * inTriangle for a more robust function
*/ */
template <class TraitsType, class PointType, class DartType> template <class TraitsType, class PointType, class DartType>
bool inTriangleSimplest(const PointType& point, const DartType& dart) { bool TriangulationHelper::inTriangleSimplest(const PointType& point, const DartType& dart) {
// Fast and simple: Do not deal with degenerate faces, i.e., if there is // Fast and simple: Do not deal with degenerate faces, i.e., if there is
// degeneracy, true will be returned if the point is on the extension of the // degeneracy, true will be returned if the point is on the extension of the
@ -757,10 +775,10 @@ namespace ttl {
* - \ref hed::TTLtraits::scalarProduct2d "TraitsType::scalarProduct2d" (DartType&, PointType&) * - \ref hed::TTLtraits::scalarProduct2d "TraitsType::scalarProduct2d" (DartType&, PointType&)
* *
* \see * \see
* ttl::inTriangleSimplest * inTriangleSimplest
*/ */
template <class TraitsType, class PointType, class DartType> template <class TraitsType, class PointType, class DartType>
bool inTriangle(const PointType& point, const DartType& dart) { bool TriangulationHelper::inTriangle(const PointType& point, const DartType& dart) {
// SHOULD WE INCLUDE A STRATEGY WITH EDGE X e_1 ETC? TO GUARANTEE THAT // SHOULD WE INCLUDE A STRATEGY WITH EDGE X e_1 ETC? TO GUARANTEE THAT
// ONLY ON ONE EDGE? BUT THIS DOES NOT SOLVE PROBLEMS WITH // ONLY ON ONE EDGE? BUT THIS DOES NOT SOLVE PROBLEMS WITH
@ -841,7 +859,7 @@ namespace ttl {
//------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------
// Private/Hidden function (might change later) // Private/Hidden function (might change later)
template <class DartType> template <class DartType>
void getAdjacentTriangles(const DartType& dart, DartType& t1, DartType& t2, DartType& t3) { void TriangulationHelper::getAdjacentTriangles(const DartType& dart, DartType& t1, DartType& t2, DartType& t3) {
DartType dart_iter = dart; DartType dart_iter = dart;
@ -886,7 +904,7 @@ namespace ttl {
* - DartListType::push_back (DartType&) * - DartListType::push_back (DartType&)
*/ */
template <class DartType, class DartListType> template <class DartType, class DartListType>
void getBoundary(const DartType& dart, DartListType& boundary) { void TriangulationHelper::getBoundary(const DartType& dart, DartListType& boundary) {
// assumes the given dart is at the boundary (by edge) // assumes the given dart is at the boundary (by edge)
DartType dart_iter(dart); DartType dart_iter(dart);
@ -932,7 +950,7 @@ namespace ttl {
* \endcode * \endcode
*/ */
template <class DartType> template <class DartType>
bool isBoundaryEdge(const DartType& dart) { bool TriangulationHelper::isBoundaryEdge(const DartType& dart) {
DartType dart_iter = dart; DartType dart_iter = dart;
if (dart_iter.alpha2() == dart) if (dart_iter.alpha2() == dart)
@ -947,7 +965,7 @@ namespace ttl {
* the boundary of the triangulation. * the boundary of the triangulation.
*/ */
template <class DartType> template <class DartType>
bool isBoundaryFace(const DartType& dart) { bool TriangulationHelper::isBoundaryFace(const DartType& dart) {
// Strategy: boundary if alpha2(d)=d // Strategy: boundary if alpha2(d)=d
@ -976,7 +994,7 @@ namespace ttl {
* the boundary of the triangulation. * the boundary of the triangulation.
*/ */
template <class DartType> template <class DartType>
bool isBoundaryNode(const DartType& dart) { bool TriangulationHelper::isBoundaryNode(const DartType& dart) {
// Strategy: boundary if alpha2(d)=d // Strategy: boundary if alpha2(d)=d
@ -1009,7 +1027,7 @@ namespace ttl {
* the number of edges joining \e V with another node in the triangulation. * the number of edges joining \e V with another node in the triangulation.
*/ */
template <class DartType> template <class DartType>
int getDegreeOfNode(const DartType& dart) { int TriangulationHelper::getDegreeOfNode(const DartType& dart) {
DartType dart_iter(dart); DartType dart_iter(dart);
DartType dart_prev; DartType dart_prev;
@ -1069,7 +1087,8 @@ namespace ttl {
// Private/Hidden function // Private/Hidden function
template <class DartType> template <class DartType>
void getNeighborNodes(const DartType& dart, std::list<DartType>& node_list, bool& boundary) { void TriangulationHelper::getNeighborNodes(const DartType& dart,
std::list<DartType>& node_list, bool& boundary) {
DartType dart_iter(dart); DartType dart_iter(dart);
@ -1131,10 +1150,10 @@ namespace ttl {
* - DartListType::push_back (DartType&) * - DartListType::push_back (DartType&)
* *
* \see * \see
* ttl::get_0_orbit_boundary * get_0_orbit_boundary
*/ */
template <class DartType, class DartListType> template <class DartType, class DartListType>
void get_0_orbit_interior(const DartType& dart, DartListType& orbit) { void TriangulationHelper::get_0_orbit_interior(const DartType& dart, DartListType& orbit) {
DartType d_iter = dart; DartType d_iter = dart;
orbit.push_back(d_iter); orbit.push_back(d_iter);
@ -1165,10 +1184,10 @@ namespace ttl {
* - The last dart in the sequence have opposite orientation compared to the others! * - The last dart in the sequence have opposite orientation compared to the others!
* *
* \see * \see
* ttl::get_0_orbit_interior * get_0_orbit_interior
*/ */
template <class DartType, class DartListType> template <class DartType, class DartListType>
void get_0_orbit_boundary(const DartType& dart, DartListType& orbit) { void TriangulationHelper::get_0_orbit_boundary(const DartType& dart, DartListType& orbit) {
DartType dart_prev; DartType dart_prev;
DartType d_iter = dart; DartType d_iter = dart;
@ -1195,17 +1214,17 @@ namespace ttl {
* own version.) * own version.)
*/ */
template <class DartType> template <class DartType>
bool same_0_orbit(const DartType& d1, const DartType& d2) { bool TriangulationHelper::same_0_orbit(const DartType& d1, const DartType& d2) {
// Two copies of the same dart // Two copies of the same dart
DartType d_iter = d2; DartType d_iter = d2;
DartType d_end = d2; DartType d_end = d2;
if (ttl::isBoundaryNode(d_iter)) { if (isBoundaryNode(d_iter)) {
// position at both boundary edges // position at both boundary edges
ttl::positionAtNextBoundaryEdge(d_iter); positionAtNextBoundaryEdge(d_iter);
d_end.alpha1(); d_end.alpha1();
ttl::positionAtNextBoundaryEdge(d_end); positionAtNextBoundaryEdge(d_end);
} }
for (;;) { for (;;) {
@ -1229,7 +1248,7 @@ namespace ttl {
* \e d1 and/or \e d2 can be CCW or CW. * \e d1 and/or \e d2 can be CCW or CW.
*/ */
template <class DartType> template <class DartType>
bool same_1_orbit(const DartType& d1, const DartType& d2) { bool TriangulationHelper::same_1_orbit(const DartType& d1, const DartType& d2) {
DartType d_iter = d2; DartType d_iter = d2;
// (Also works at the boundary) // (Also works at the boundary)
@ -1245,7 +1264,7 @@ namespace ttl {
* \e d1 and/or \e d2 can be CCW or CW * \e d1 and/or \e d2 can be CCW or CW
*/ */
template <class DartType> template <class DartType>
bool same_2_orbit(const DartType& d1, const DartType& d2) { bool TriangulationHelper::same_2_orbit(const DartType& d1, const DartType& d2) {
DartType d_iter = d2; DartType d_iter = d2;
if (d_iter == d1 || d_iter.alpha0() == d1 || if (d_iter == d1 || d_iter.alpha0() == d1 ||
@ -1259,7 +1278,7 @@ namespace ttl {
//------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------
// Private/Hidden function // Private/Hidden function
template <class TraitsType, class DartType> template <class TraitsType, class DartType>
bool degenerateTriangle(const DartType& dart) { bool TriangulationHelper::degenerateTriangle(const DartType& dart) {
// Check if triangle is degenerate // Check if triangle is degenerate
// Assumes CCW dart // Assumes CCW dart
@ -1287,7 +1306,7 @@ namespace ttl {
* - \ref hed::TTLtraits::crossProduct2d "TraitsType::crossProduct2d" (Dart&, Dart&) * - \ref hed::TTLtraits::crossProduct2d "TraitsType::crossProduct2d" (Dart&, Dart&)
*/ */
template <class TraitsType, class DartType> template <class TraitsType, class DartType>
bool swappableEdge(const DartType& dart, bool allowDegeneracy) { bool TriangulationHelper::swappableEdge(const DartType& dart, bool allowDegeneracy) {
// How "safe" is it? // How "safe" is it?
@ -1340,7 +1359,7 @@ namespace ttl {
* infinit loop occurs. * infinit loop occurs.
*/ */
template <class DartType> template <class DartType>
void positionAtNextBoundaryEdge(DartType& dart) { void TriangulationHelper::positionAtNextBoundaryEdge(DartType& dart) {
DartType dart_prev; DartType dart_prev;
@ -1365,14 +1384,14 @@ namespace ttl {
* - \ref hed::TTLtraits::crossProduct2d "TraitsType::crossProduct2d" (const Dart&, const Dart&) * - \ref hed::TTLtraits::crossProduct2d "TraitsType::crossProduct2d" (const Dart&, const Dart&)
*/ */
template <class TraitsType, class DartType> template <class TraitsType, class DartType>
bool convexBoundary(const DartType& dart) { bool TriangulationHelper::convexBoundary(const DartType& dart) {
list<DartType> blist; std::list<DartType> blist;
ttl::getBoundary(dart, blist); getBoundary(dart, blist);
int no; int no;
no = (int)blist.size(); no = (int)blist.size();
typename list<DartType>::const_iterator bit = blist.begin(); typename std::list<DartType>::const_iterator bit = blist.begin();
DartType d1 = *bit; DartType d1 = *bit;
++bit; ++bit;
DartType d2; DartType d2;
@ -1428,17 +1447,17 @@ namespace ttl {
* seen if it was glued to the edge when swapping (rotating) the edge CCW * seen if it was glued to the edge when swapping (rotating) the edge CCW
* *
* \using * \using
* - ttl::swapTestDelaunay * - swapTestDelaunay
*/ */
template <class TraitsType, class DartType, class DartListType> template <class TraitsType, class DartType, class DartListType>
void optimizeDelaunay(DartListType& elist) { void TriangulationHelper::optimizeDelaunay(DartListType& elist) {
optimizeDelaunay<TraitsType, DartType, DartListType>(elist, elist.end()); optimizeDelaunay<TraitsType, DartType, DartListType>(elist, elist.end());
} }
//------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------
template <class TraitsType, class DartType, class DartListType> template <class TraitsType, class DartType, class DartListType>
void optimizeDelaunay(DartListType& elist, const typename DartListType::iterator end) { void TriangulationHelper::optimizeDelaunay(DartListType& elist, const typename DartListType::iterator end) {
// CCW darts // CCW darts
// Optimize here means Delaunay, but could be any criterion by // Optimize here means Delaunay, but could be any criterion by
@ -1481,14 +1500,14 @@ namespace ttl {
while(!optimal) { while(!optimal) {
optimal = true; optimal = true;
for (it = elist.begin(); it != end_opt; ++it) { for (it = elist.begin(); it != end_opt; ++it) {
if (ttl::swapTestDelaunay<TraitsType>(*it, cycling_check)) { if (swapTestDelaunay<TraitsType>(*it, cycling_check)) {
// Preserve darts. Potential darts in the list are: // Preserve darts. Potential darts in the list are:
// - The current dart // - The current dart
// - the four CCW darts on the boundary of the quadrilateral // - the four CCW darts on the boundary of the quadrilateral
// (the current arc has only one dart) // (the current arc has only one dart)
ttl::swapEdgeInList<TraitsType, DartType>(it, elist); swapEdgeInList<TraitsType, DartType>(it, elist);
optimal = false; optimal = false;
} // end if should swap } // end if should swap
@ -1513,9 +1532,9 @@ namespace ttl {
*/ */
template <class TraitsType, class DartType> template <class TraitsType, class DartType>
#if ((_MSC_VER > 0) && (_MSC_VER < 1300))//#ifdef _MSC_VER #if ((_MSC_VER > 0) && (_MSC_VER < 1300))//#ifdef _MSC_VER
bool swapTestDelaunay(const DartType& dart, bool cycling_check = false) { bool TriangulationHelper::swapTestDelaunay(const DartType& dart, bool cycling_check = false) const {
#else #else
bool swapTestDelaunay(const DartType& dart, bool cycling_check) { bool TriangulationHelper::swapTestDelaunay(const DartType& dart, bool cycling_check) const {
#endif #endif
// The general strategy is taken from Cline & Renka. They claim that // The general strategy is taken from Cline & Renka. They claim that
@ -1627,17 +1646,17 @@ namespace ttl {
* - Calls itself recursively * - Calls itself recursively
*/ */
template <class TraitsType, class DartType> template <class TraitsType, class DartType>
void recSwapDelaunay(DartType& diagonal) { void TriangulationHelper::recSwapDelaunay(DartType& diagonal) {
if (!ttl::swapTestDelaunay<TraitsType>(diagonal)) if (!swapTestDelaunay<TraitsType>(diagonal))
// ??? ttl::swapTestDelaunay also checks if boundary, so this can be optimized // ??? swapTestDelaunay also checks if boundary, so this can be optimized
return; return;
// Get the other "edges" of the current triangle; see illustration above. // Get the other "edges" of the current triangle; see illustration above.
DartType oppEdge1 = diagonal; DartType oppEdge1 = diagonal;
oppEdge1.alpha1(); oppEdge1.alpha1();
bool b1; bool b1;
if (ttl::isBoundaryEdge(oppEdge1)) if (isBoundaryEdge(oppEdge1))
b1 = true; b1 = true;
else { else {
b1 = false; b1 = false;
@ -1648,7 +1667,7 @@ namespace ttl {
DartType oppEdge2 = diagonal; DartType oppEdge2 = diagonal;
oppEdge2.alpha0().alpha1().alpha0(); oppEdge2.alpha0().alpha1().alpha0();
bool b2; bool b2;
if (ttl::isBoundaryEdge(oppEdge2)) if (isBoundaryEdge(oppEdge2))
b2 = true; b2 = true;
else { else {
b2 = false; b2 = false;
@ -1656,7 +1675,7 @@ namespace ttl {
} }
// Swap the given diagonal // Swap the given diagonal
TraitsType::swapEdge(diagonal); triangulation.swapEdge(diagonal);
if (!b1) if (!b1)
recSwapDelaunay<TraitsType>(oppEdge1); recSwapDelaunay<TraitsType>(oppEdge1);
@ -1669,7 +1688,7 @@ namespace ttl {
/** Swaps edges away from the (interior) node associated with /** Swaps edges away from the (interior) node associated with
* \e dart such that that exactly three edges remain incident * \e dart such that that exactly three edges remain incident
* with the node. * with the node.
* This function is used as a first step in ttl::removeInteriorNode * This function is used as a first step in removeInteriorNode
* *
* \retval dart * \retval dart
* A CCW dart incident with the node * A CCW dart incident with the node
@ -1689,10 +1708,10 @@ namespace ttl {
* at the node that is given as input. * at the node that is given as input.
* *
* \see * \see
* ttl::swapEdgesAwayFromBoundaryNode * swapEdgesAwayFromBoundaryNode
*/ */
template <class TraitsType, class DartType, class ListType> template <class TraitsType, class DartType, class ListType>
void swapEdgesAwayFromInteriorNode(DartType& dart, ListType& swapped_edges) { void TriangulationHelper::swapEdgesAwayFromInteriorNode(DartType& dart, ListType& swapped_edges) {
// Same iteration as in fixEdgesAtCorner, but not boundary // Same iteration as in fixEdgesAtCorner, but not boundary
DartType dnext = dart; DartType dnext = dart;
@ -1706,14 +1725,14 @@ namespace ttl {
// infinite loop with degree > 3. // infinite loop with degree > 3.
bool allowDegeneracy = true; bool allowDegeneracy = true;
int degree = ttl::getDegreeOfNode(dart); int degree = getDegreeOfNode(dart);
DartType d_iter; DartType d_iter;
while (degree > 3) { while (degree > 3) {
d_iter = dnext; d_iter = dnext;
dnext.alpha1().alpha2(); dnext.alpha1().alpha2();
if (ttl::swappableEdge<TraitsType>(d_iter, allowDegeneracy)) { if (swappableEdge<TraitsType>(d_iter, allowDegeneracy)) {
TraitsType::swapEdge(d_iter); // swap the edge away triangulation.swapEdge(d_iter); // swap the edge away
// Collect swapped edges in the list // Collect swapped edges in the list
// "Hide" the dart on the other side of the edge to avoid it being changed for // "Hide" the dart on the other side of the edge to avoid it being changed for
// other swaps // other swaps
@ -1733,7 +1752,7 @@ namespace ttl {
/** Swaps edges away from the (boundary) node associated with /** Swaps edges away from the (boundary) node associated with
* \e dart in such a way that when removing the edges that remain incident * \e dart in such a way that when removing the edges that remain incident
* with the node, the boundary of the triangulation will be convex. * with the node, the boundary of the triangulation will be convex.
* This function is used as a first step in ttl::removeBoundaryNode * This function is used as a first step in removeBoundaryNode
* *
* \retval dart * \retval dart
* A CCW dart incident with the node * A CCW dart incident with the node
@ -1747,10 +1766,10 @@ namespace ttl {
* - The node associated with \e dart is at the boundary of the triangulation. * - The node associated with \e dart is at the boundary of the triangulation.
* *
* \see * \see
* ttl::swapEdgesAwayFromInteriorNode * swapEdgesAwayFromInteriorNode
*/ */
template <class TraitsType, class DartType, class ListType> template <class TraitsType, class DartType, class ListType>
void swapEdgesAwayFromBoundaryNode(DartType& dart, ListType& swapped_edges) { void TriangulationHelper::swapEdgesAwayFromBoundaryNode(DartType& dart, ListType& swapped_edges) {
// All darts that are swappable. // All darts that are swappable.
// To treat collinear nodes at an existing boundary, we must allow degeneracy // To treat collinear nodes at an existing boundary, we must allow degeneracy
@ -1762,7 +1781,7 @@ namespace ttl {
// - A dart on the swapped edge is delivered back in a position as // - A dart on the swapped edge is delivered back in a position as
// seen if it was glued to the edge when swapping (rotating) the edge CCW // seen if it was glued to the edge when swapping (rotating) the edge CCW
//int degree = ttl::getDegreeOfNode(dart); //int degree = getDegreeOfNode(dart);
passes: passes:
@ -1780,7 +1799,7 @@ passes:
while (!bend) { while (!bend) {
d_next.alpha1().alpha2(); d_next.alpha1().alpha2();
if (ttl::isBoundaryEdge(d_next)) if (isBoundaryEdge(d_next))
bend = true; // then it is CW since alpha2 bend = true; // then it is CW since alpha2
// To allow removing among collinear nodes at the boundary, // To allow removing among collinear nodes at the boundary,
@ -1789,13 +1808,13 @@ passes:
tmp1 = d_iter; tmp1.alpha1(); tmp1 = d_iter; tmp1.alpha1();
tmp2 = d_iter; tmp2.alpha2().alpha1(); // don't bother with boundary (checked later) tmp2 = d_iter; tmp2.alpha2().alpha1(); // don't bother with boundary (checked later)
if (ttl::isBoundaryEdge(tmp1) && ttl::isBoundaryEdge(tmp2)) if (isBoundaryEdge(tmp1) && isBoundaryEdge(tmp2))
allowDegeneracy = true; allowDegeneracy = true;
else else
allowDegeneracy = false; allowDegeneracy = false;
if (ttl::swappableEdge<TraitsType>(d_iter, allowDegeneracy)) { if (swappableEdge<TraitsType>(d_iter, allowDegeneracy)) {
TraitsType::swapEdge(d_iter); triangulation.swapEdge(d_iter);
// Collect swapped edges in the list // Collect swapped edges in the list
// "Hide" the dart on the other side of the edge to avoid it being changed for // "Hide" the dart on the other side of the edge to avoid it being changed for
@ -1821,7 +1840,7 @@ passes:
else { else {
d_iter.alpha1(); // CW and see below d_iter.alpha1(); // CW and see below
} }
ttl::positionAtNextBoundaryEdge(d_iter); // CCW positionAtNextBoundaryEdge(d_iter); // CCW
dart = d_iter; // for next pass or output dart = d_iter; // for next pass or output
@ -1839,7 +1858,7 @@ passes:
* keep them in \e elist. * keep them in \e elist.
*/ */
template <class TraitsType, class DartType, class DartListType> template <class TraitsType, class DartType, class DartListType>
void swapEdgeInList(const typename DartListType::iterator& it, DartListType& elist) { void TriangulationHelper::swapEdgeInList(const typename DartListType::iterator& it, DartListType& elist) {
typename DartListType::iterator it1, it2, it3, it4; typename DartListType::iterator it1, it2, it3, it4;
DartType dart(*it); DartType dart(*it);
@ -1867,7 +1886,7 @@ passes:
it3 = find(elist.begin(), elist.end(), d3); it3 = find(elist.begin(), elist.end(), d3);
it4 = find(elist.begin(), elist.end(), d4); it4 = find(elist.begin(), elist.end(), d4);
TraitsType::swapEdge(dart); triangulation.swapEdge(dart);
// Update the current dart which may have changed // Update the current dart which may have changed
*it = dart; *it = dart;

View File

@ -51,9 +51,6 @@
static ofstream ofile_constr("qweCons.dat"); static ofstream ofile_constr("qweCons.dat");
#endif #endif
//using namespace std;
/** \brief Constrained Delaunay triangulation /** \brief Constrained Delaunay triangulation
* *
* Basic generic algorithms in TTL for inserting a constrained edge between two existing nodes.\n * Basic generic algorithms in TTL for inserting a constrained edge between two existing nodes.\n
@ -61,7 +58,7 @@
* See documentation for the namespace ttl for general requirements and assumptions. * See documentation for the namespace ttl for general requirements and assumptions.
* *
* \author * \author
* Øyvind Hjelle, oyvindhj@ifi.uio.no * <EFBFBD>yvind Hjelle, oyvindhj@ifi.uio.no
*/ */
namespace ttl_constr { namespace ttl_constr {
@ -73,6 +70,9 @@ namespace ttl_constr {
#endif #endif
class ConstrainedTriangulation
{
public:
//------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------
/* Checks if \e dart has start and end points in \e dstart and \e dend. /* Checks if \e dart has start and end points in \e dstart and \e dend.
* *
@ -89,14 +89,14 @@ namespace ttl_constr {
* A bool confirming that it's the constraint or not * A bool confirming that it's the constraint or not
* *
* \using * \using
* ttl::same_0_orbit * same_0_orbit
*/ */
template <class DartType> template <class DartType>
bool isTheConstraint(const DartType& dart, const DartType& dstart, const DartType& dend) { static bool isTheConstraint(const DartType& dart, const DartType& dstart, const DartType& dend) {
DartType d0 = dart; DartType d0 = dart;
d0.alpha0(); // CW d0.alpha0(); // CW
if ((ttl::same_0_orbit(dstart, dart) && ttl::same_0_orbit(dend, d0)) || if ((ttl::TriangulationHelper::same_0_orbit(dstart, dart) && ttl::TriangulationHelper::same_0_orbit(dend, d0)) ||
(ttl::same_0_orbit(dstart, d0) && ttl::same_0_orbit(dend, dart))) { (ttl::TriangulationHelper::same_0_orbit(dstart, d0) && ttl::TriangulationHelper::same_0_orbit(dend, dart))) {
return true; return true;
} }
return false; return false;
@ -123,7 +123,7 @@ namespace ttl_constr {
* TraitsType::orient2d * TraitsType::orient2d
*/ */
template <class TraitsType, class DartType> template <class TraitsType, class DartType>
bool crossesConstraint(DartType& dstart, DartType& dend, DartType& d1, DartType& d2) { static bool crossesConstraint(DartType& dstart, DartType& dend, DartType& d1, DartType& d2) {
typename TraitsType::real_type orient_1 = TraitsType::orient2d(dstart,d1,dend); typename TraitsType::real_type orient_1 = TraitsType::orient2d(dstart,d1,dend);
typename TraitsType::real_type orient_2 = TraitsType::orient2d(dstart,d2,dend); typename TraitsType::real_type orient_2 = TraitsType::orient2d(dstart,d2,dend);
@ -156,12 +156,12 @@ namespace ttl_constr {
* The dart \e d making the smallest positive (or == 0) angle * The dart \e d making the smallest positive (or == 0) angle
* *
* \using * \using
* ttl::isBoundaryNode * isBoundaryNode
* ttl::positionAtNextBoundaryEdge * positionAtNextBoundaryEdge
* TraitsType::orient2d * TraitsType::orient2d
*/ */
template <class TraitsType, class DartType> template <class TraitsType, class DartType>
DartType getAtSmallestAngle(const DartType& dstart, const DartType& dend) { static DartType getAtSmallestAngle(const DartType& dstart, const DartType& dend) {
// - Must boundary be convex??? // - Must boundary be convex???
// - Handle the case where the constraint is already present??? // - Handle the case where the constraint is already present???
@ -169,9 +169,9 @@ namespace ttl_constr {
// (dstart and dend may define a boundary edge) // (dstart and dend may define a boundary edge)
DartType d_iter = dstart; DartType d_iter = dstart;
if (ttl::isBoundaryNode(d_iter)) { if (ttl::TriangulationHelper::isBoundaryNode(d_iter)) {
d_iter.alpha1(); // CW d_iter.alpha1(); // CW
ttl::positionAtNextBoundaryEdge(d_iter); // CCW (was rotated CW to the boundary) ttl::TriangulationHelper::positionAtNextBoundaryEdge(d_iter); // CCW (was rotated CW to the boundary)
} }
// assume convex boundary; see comments // assume convex boundary; see comments
@ -273,7 +273,7 @@ namespace ttl_constr {
* Returns the next "collinear" starting node such that dend is returned when done. * Returns the next "collinear" starting node such that dend is returned when done.
*/ */
template <class TraitsType, class DartType, class ListType> template <class TraitsType, class DartType, class ListType>
DartType findCrossingEdges(const DartType& dstart, const DartType& dend, ListType& elist) { static DartType findCrossingEdges(const DartType& dstart, const DartType& dend, ListType& elist) {
const DartType my_start = getAtSmallestAngle<TraitsType>(dstart, dend); const DartType my_start = getAtSmallestAngle<TraitsType>(dstart, dend);
DartType my_end = getAtSmallestAngle<TraitsType>(dend, dstart); DartType my_end = getAtSmallestAngle<TraitsType>(dend, dstart);
@ -387,15 +387,16 @@ namespace ttl_constr {
* A list containing all the edges crossing the spesified constraint * A list containing all the edges crossing the spesified constraint
* *
* \using * \using
* ttl::swappableEdge * swappableEdge
* ttl::swapEdgeInList * swapEdgeInList
* ttl::crossesConstraint * crossesConstraint
* ttl::isTheConstraint * isTheConstraint
*/ */
template <class TraitsType, class DartType> template <class TraitsType, class DartType>
void transformToConstraint(DartType& dstart, DartType& dend, std::list<DartType>& elist) { void transformToConstraint(ttl::TriangulationHelper helper, DartType& dstart, DartType& dend,
std::list<DartType>& elist) const {
typename list<DartType>::iterator it, used; typename std::list<DartType>::iterator it, used;
// We may enter in a situation where dstart and dend are altered because of a swap. // We may enter in a situation where dstart and dend are altered because of a swap.
// (The general rule is that darts inside the actual quadrilateral can be changed, // (The general rule is that darts inside the actual quadrilateral can be changed,
@ -423,7 +424,7 @@ namespace ttl_constr {
if (counter > dartsInList) if (counter > dartsInList)
break; break;
if (ttl::swappableEdge<TraitsType, DartType>(*it, true)) { if (ttl::TriangulationHelper::swappableEdge<TraitsType, DartType>(*it, true)) {
// Dyn & Goren & Rippa 's notation: // Dyn & Goren & Rippa 's notation:
// The node assosiated with dart *it is denoted u_m. u_m has edges crossing the constraint // The node assosiated with dart *it is denoted u_m. u_m has edges crossing the constraint
// named w_1, ... , w_r . The other node to the edge assosiated with dart *it is w_s. // named w_1, ... , w_r . The other node to the edge assosiated with dart *it is w_s.
@ -456,7 +457,7 @@ namespace ttl_constr {
end = true; end = true;
// This is the only place swapping is called when inserting a constraint // This is the only place swapping is called when inserting a constraint
ttl::swapEdgeInList<TraitsType, DartType>(it,elist); helper.swapEdgeInList<TraitsType, DartType>(it,elist);
// If we, during look-ahead, found that dstart and/or dend were in the quadrilateral, // If we, during look-ahead, found that dstart and/or dend were in the quadrilateral,
// we update them. // we update them.
@ -512,6 +513,8 @@ namespace ttl_constr {
} }
}; // End of ConstrainedTriangulation class
}; // End of ttl_constr namespace scope }; // End of ttl_constr namespace scope
@ -546,14 +549,14 @@ namespace ttl { // (extension)
* - \ref hed::TTLtraits::swapEdge "TraitsType::swapEdge" (DartType&) * - \ref hed::TTLtraits::swapEdge "TraitsType::swapEdge" (DartType&)
* *
* \using * \using
* - ttl::optimizeDelaunay if \e optimize_delaunay is set to \c true * - optimizeDelaunay if \e optimize_delaunay is set to \c true
* *
* \par Assumes: * \par Assumes:
* - The constrained edge must be inside the existing triangulation (and it cannot * - The constrained edge must be inside the existing triangulation (and it cannot
* cross the boundary of the triangulation). * cross the boundary of the triangulation).
*/ */
template <class TraitsType, class DartType> template <class TraitsType, class DartType>
DartType insertConstraint(DartType& dstart, DartType& dend, bool optimize_delaunay) { DartType TriangulationHelper::insertConstraint(DartType& dstart, DartType& dend, bool optimize_delaunay) {
// Assumes: // Assumes:
// - It is the users responsibility to avoid crossing constraints // - It is the users responsibility to avoid crossing constraints
@ -567,8 +570,8 @@ namespace ttl { // (extension)
// calls itself recursively. // calls itself recursively.
// RECURSION // RECURSION
list<DartType> elist; std::list<DartType> elist;
DartType next_start = ttl_constr::findCrossingEdges<TraitsType>(dstart, dend, elist); DartType next_start = ttl_constr::ConstrainedTriangulation::findCrossingEdges<TraitsType>(dstart, dend, elist);
// If there are no crossing edges (elist is empty), we assume that the constraint // If there are no crossing edges (elist is empty), we assume that the constraint
// is an existing edge. // is an existing edge.
@ -583,7 +586,7 @@ namespace ttl { // (extension)
// findCrossingEdges stops if it finds a node lying on the constraint. // findCrossingEdges stops if it finds a node lying on the constraint.
// A dart with this node as start node is returned // A dart with this node as start node is returned
// We call insertConstraint recursivly until the received dart is dend // We call insertConstraint recursivly until the received dart is dend
if (!ttl::same_0_orbit(next_start, dend)) { if (!same_0_orbit(next_start, dend)) {
#ifdef DEBUG_TTL_CONSTR_PLOT #ifdef DEBUG_TTL_CONSTR_PLOT
cout << "RECURSION due to collinearity along constraint" << endl; cout << "RECURSION due to collinearity along constraint" << endl;
@ -594,7 +597,7 @@ namespace ttl { // (extension)
// Swap edges such that the constraint edge is present in the transformed triangulation. // Swap edges such that the constraint edge is present in the transformed triangulation.
if (elist.size() > 0) // by Thomas Sevaldrud if (elist.size() > 0) // by Thomas Sevaldrud
ttl_constr::transformToConstraint<TraitsType>(dstart, next_start, elist); ttl_constr::ConstrainedTriangulation::transformToConstraint<TraitsType>(dstart, next_start, elist);
#ifdef DEBUG_TTL_CONSTR_PLOT #ifdef DEBUG_TTL_CONSTR_PLOT
cout << "size of elist = " << elist.size() << endl; cout << "size of elist = " << elist.size() << endl;
@ -607,13 +610,13 @@ namespace ttl { // (extension)
#endif #endif
// Optimize to constrained Delaunay triangulation if required. // Optimize to constrained Delaunay triangulation if required.
typename list<DartType>::iterator end_opt = elist.end(); typename std::list<DartType>::iterator end_opt = elist.end();
if (optimize_delaunay) { if (optimize_delaunay) {
// Indicate that the constrained edge, which is the last element in the list, // Indicate that the constrained edge, which is the last element in the list,
// should not be swapped // should not be swapped
--end_opt; --end_opt;
ttl::optimizeDelaunay<TraitsType, DartType>(elist, end_opt); optimizeDelaunay<TraitsType, DartType>(elist, end_opt);
} }
if(elist.size() == 0) // by Thomas Sevaldrud if(elist.size() == 0) // by Thomas Sevaldrud

View File

@ -493,6 +493,14 @@ public:
m_scaleLimits = VECTOR2D( aMaximum, aMinimum ); m_scaleLimits = VECTOR2D( aMaximum, aMinimum );
} }
/**
* Function InvalidateItem()
* Manages dirty flags & redraw queueing when updating an item.
* @param aItem is the item to be updated.
* @param aUpdateFlags determines the way an item is refreshed.
*/
void InvalidateItem( VIEW_ITEM* aItem, int aUpdateFlags );
static const int VIEW_MAX_LAYERS = 128; ///* maximum number of layers that may be shown static const int VIEW_MAX_LAYERS = 128; ///* maximum number of layers that may be shown
private: private:
@ -563,11 +571,6 @@ private:
*/ */
void draw( VIEW_GROUP* aGroup, bool aImmediate = false ) const; void draw( VIEW_GROUP* aGroup, bool aImmediate = false ) const;
///* Manages dirty flags & redraw queueing when updating an item. Called internally
/// via VIEW_ITEM::ViewUpdate()
void invalidateItem( VIEW_ITEM* aItem, int aUpdateFlags );
///* Sorts m_orderedLayers when layer rendering order has changed ///* Sorts m_orderedLayers when layer rendering order has changed
void sortLayers(); void sortLayers();

View File

@ -60,7 +60,7 @@ public:
* *
* @param aEnabled says whether the opion should be enabled or disabled. * @param aEnabled says whether the opion should be enabled or disabled.
*/ */
void SetSnapping( bool aEnabled ) virtual void SetSnapping( bool aEnabled )
{ {
m_snappingEnabled = aEnabled; m_snappingEnabled = aEnabled;
} }

View File

@ -58,6 +58,13 @@ public:
void onEnter( wxMouseEvent& WXUNUSED( aEvent ) ); void onEnter( wxMouseEvent& WXUNUSED( aEvent ) );
void onTimer( wxTimerEvent& WXUNUSED( aEvent ) ); void onTimer( wxTimerEvent& WXUNUSED( aEvent ) );
///> @copydoc VIEW_CONTROLS::SetSnapping()
void SetSnapping( bool aEnabled )
{
VIEW_CONTROLS::SetSnapping( aEnabled );
updateCursor();
}
/** /**
* Function SetGrabMouse() * Function SetGrabMouse()
* Enables/disables mouse cursor grabbing (limits the movement field only to the panel area). * Enables/disables mouse cursor grabbing (limits the movement field only to the panel area).
@ -84,7 +91,10 @@ public:
const VECTOR2D GetMousePosition() const; const VECTOR2D GetMousePosition() const;
/// @copydoc VIEW_CONTROLS::GetCursorPosition() /// @copydoc VIEW_CONTROLS::GetCursorPosition()
const VECTOR2D GetCursorPosition() const; const VECTOR2D GetCursorPosition() const
{
return m_cursorPosition;
}
/// Event that forces mouse move event in the dispatcher (eg. used in autopanning, when mouse /// Event that forces mouse move event in the dispatcher (eg. used in autopanning, when mouse
/// cursor does not move in screen coordinates, but does in world coordinates) /// cursor does not move in screen coordinates, but does in world coordinates)
@ -109,6 +119,12 @@ private:
*/ */
bool handleAutoPanning( const wxMouseEvent& aEvent ); bool handleAutoPanning( const wxMouseEvent& aEvent );
/**
* Function updateCursor()
* Recomputes the cursor coordinates basing on the current snapping settings and mouse position.
*/
void updateCursor();
/// Current state of VIEW_CONTROLS /// Current state of VIEW_CONTROLS
STATE m_state; STATE m_state;

View File

@ -47,8 +47,7 @@ class GAL;
class WORKSHEET_VIEWITEM : public EDA_ITEM class WORKSHEET_VIEWITEM : public EDA_ITEM
{ {
public: public:
WORKSHEET_VIEWITEM( const std::string& aFileName, const std::string& aSheetName, WORKSHEET_VIEWITEM( const PAGE_INFO* aPageInfo, const TITLE_BLOCK* aTitleBlock );
const PAGE_INFO* aPageInfo, const TITLE_BLOCK* aTitleBlock );
/** /**
* Function SetFileName() * Function SetFileName()

View File

@ -622,7 +622,7 @@ public:
* @param aTransformPoint = the reference point of the transformation, * @param aTransformPoint = the reference point of the transformation,
* for commands like move * for commands like move
*/ */
virtual void SaveCopyInUndoList( PICKED_ITEMS_LIST& aItemsList, virtual void SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList,
UNDO_REDO_T aTypeCommand, UNDO_REDO_T aTypeCommand,
const wxPoint& aTransformPoint = wxPoint( 0, 0 ) ) = 0; const wxPoint& aTransformPoint = wxPoint( 0, 0 ) ) = 0;

View File

@ -1094,7 +1094,7 @@ public:
* @param aTransformPoint = the reference point of the transformation, * @param aTransformPoint = the reference point of the transformation,
* for commands like move * for commands like move
*/ */
void SaveCopyInUndoList( PICKED_ITEMS_LIST& aItemsList, void SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList,
UNDO_REDO_T aTypeCommand, UNDO_REDO_T aTypeCommand,
const wxPoint& aTransformPoint = wxPoint( 0, 0 ) ); const wxPoint& aTransformPoint = wxPoint( 0, 0 ) );

View File

@ -680,7 +680,7 @@ public:
* @param aTransformPoint = the reference point of the transformation, for * @param aTransformPoint = the reference point of the transformation, for
* commands like move * commands like move
*/ */
virtual void SaveCopyInUndoList( PICKED_ITEMS_LIST& aItemsList, virtual void SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList,
UNDO_REDO_T aTypeCommand, UNDO_REDO_T aTypeCommand,
const wxPoint& aTransformPoint = wxPoint( 0, 0 ) ); const wxPoint& aTransformPoint = wxPoint( 0, 0 ) );
@ -705,7 +705,7 @@ public:
* - Get an old version of the board from Redo list * - Get an old version of the board from Redo list
* @return none * @return none
*/ */
void GetBoardFromRedoList( wxCommandEvent& event ); void GetBoardFromRedoList( wxCommandEvent& aEvent );
/** /**
* Function GetBoardFromUndoList * Function GetBoardFromUndoList
@ -714,7 +714,7 @@ public:
* - Get an old version of the board from Undo list * - Get an old version of the board from Undo list
* @return none * @return none
*/ */
void GetBoardFromUndoList( wxCommandEvent& event ); void GetBoardFromUndoList( wxCommandEvent& aEvent );
/* Block operations: */ /* Block operations: */

View File

@ -226,7 +226,6 @@ set( PCBNEW_CLASS_SRCS
print_board_functions.cpp print_board_functions.cpp
printout_controler.cpp printout_controler.cpp
ratsnest.cpp ratsnest.cpp
ratsnest_data.cpp
ratsnest_viewitem.cpp ratsnest_viewitem.cpp
# specctra.cpp #moved in pcbcommon lib # specctra.cpp #moved in pcbcommon lib
# specctra_export.cpp # specctra_export.cpp
@ -256,7 +255,7 @@ set( PCBNEW_CLASS_SRCS
tools/selection_tool.cpp tools/selection_tool.cpp
tools/selection_area.cpp tools/selection_area.cpp
tools/bright_box.cpp tools/bright_box.cpp
tools/move_tool.cpp tools/edit_tool.cpp
tools/pcb_tools.cpp tools/pcb_tools.cpp
tools/common_actions.cpp tools/common_actions.cpp
) )

View File

@ -103,7 +103,7 @@ void PCB_EDIT_FRAME::Attribut_net( wxDC* DC, int net_code, bool Flag_On )
{ {
for( ; Track != NULL; Track = Track->Next() ) for( ; Track != NULL; Track = Track->Next() )
{ {
if( net_code == Track->GetNet() ) if( net_code == Track->GetNetCode() )
break; break;
} }
} }
@ -112,7 +112,7 @@ void PCB_EDIT_FRAME::Attribut_net( wxDC* DC, int net_code, bool Flag_On )
while( Track ) /* Flag change */ while( Track ) /* Flag change */
{ {
if( (net_code >= 0 ) && (net_code != Track->GetNet()) ) if( ( net_code >= 0 ) && ( net_code != Track->GetNetCode() ) )
break; break;
OnModify(); OnModify();

View File

@ -499,7 +499,7 @@ int genPlacementRoutingMatrix( BOARD* aBrd, EDA_MSG_PANEL* messagePanel )
TRACK TmpSegm( NULL ); TRACK TmpSegm( NULL );
TmpSegm.SetLayer( UNDEFINED_LAYER ); TmpSegm.SetLayer( UNDEFINED_LAYER );
TmpSegm.SetNet( -1 ); TmpSegm.SetNetCode( -1 );
TmpSegm.SetWidth( RoutingMatrix.m_GridRouting / 2 ); TmpSegm.SetWidth( RoutingMatrix.m_GridRouting / 2 );
EDA_ITEM* PtStruct = aBrd->m_Drawings; EDA_ITEM* PtStruct = aBrd->m_Drawings;

View File

@ -78,7 +78,7 @@ void PCB_EDIT_FRAME::Autoroute( wxDC* DC, int mode )
{ {
case PCB_PAD_T: case PCB_PAD_T:
Pad = (D_PAD*) GetScreen()->GetCurItem(); Pad = (D_PAD*) GetScreen()->GetCurItem();
autoroute_net_code = Pad->GetNet(); autoroute_net_code = Pad->GetNetCode();
break; break;
default: default:

View File

@ -215,7 +215,7 @@ void PlaceCells( BOARD* aPcb, int net_code, int flag )
{ {
D_PAD* pad = aPcb->GetPad( i ); D_PAD* pad = aPcb->GetPad( i );
if( net_code != pad->GetNet() || (flag & FORCE_PADS) ) if( net_code != pad->GetNetCode() || (flag & FORCE_PADS) )
{ {
::PlacePad( pad, HOLE, marge, WRITE_CELL ); ::PlacePad( pad, HOLE, marge, WRITE_CELL );
} }
@ -247,7 +247,7 @@ void PlaceCells( BOARD* aPcb, int net_code, int flag )
tmpSegm.SetShape( edge->GetShape() ); tmpSegm.SetShape( edge->GetShape() );
tmpSegm.SetWidth( edge->GetWidth() ); tmpSegm.SetWidth( edge->GetWidth() );
tmpSegm.m_Param = edge->GetAngle(); tmpSegm.m_Param = edge->GetAngle();
tmpSegm.SetNet( -1 ); tmpSegm.SetNetCode( -1 );
TraceSegmentPcb( &tmpSegm, HOLE, marge, WRITE_CELL ); TraceSegmentPcb( &tmpSegm, HOLE, marge, WRITE_CELL );
TraceSegmentPcb( &tmpSegm, VIA_IMPOSSIBLE, via_marge, WRITE_OR_CELL ); TraceSegmentPcb( &tmpSegm, VIA_IMPOSSIBLE, via_marge, WRITE_OR_CELL );
@ -284,7 +284,7 @@ void PlaceCells( BOARD* aPcb, int net_code, int flag )
tmpSegm.SetShape( DrawSegm->GetShape() ); tmpSegm.SetShape( DrawSegm->GetShape() );
tmpSegm.SetWidth( DrawSegm->GetWidth() ); tmpSegm.SetWidth( DrawSegm->GetWidth() );
tmpSegm.m_Param = DrawSegm->GetAngle(); tmpSegm.m_Param = DrawSegm->GetAngle();
tmpSegm.SetNet( -1 ); tmpSegm.SetNetCode( -1 );
TraceSegmentPcb( &tmpSegm, type_cell, marge, WRITE_CELL ); TraceSegmentPcb( &tmpSegm, type_cell, marge, WRITE_CELL );
} }
@ -335,7 +335,7 @@ void PlaceCells( BOARD* aPcb, int net_code, int flag )
/* Put tracks and vias on matrix */ /* Put tracks and vias on matrix */
for( TRACK* track = aPcb->m_Track; track; track = track->Next() ) for( TRACK* track = aPcb->m_Track; track; track = track->Next() )
{ {
if( net_code == track->GetNet() ) if( net_code == track->GetNetCode() )
continue; continue;
TraceSegmentPcb( track, HOLE, marge, WRITE_CELL ); TraceSegmentPcb( track, HOLE, marge, WRITE_CELL );
@ -374,7 +374,7 @@ int Build_Work( BOARD* Pcb )
pt_pad = pt_rats->m_PadStart; pt_pad = pt_rats->m_PadStart;
current_net_code = pt_pad->GetNet(); current_net_code = pt_pad->GetNetCode();
pt_ch = pt_rats; pt_ch = pt_rats;
r1 = ( pt_pad->GetPosition().y - RoutingMatrix.m_BrdBox.GetY() + demi_pas ) r1 = ( pt_pad->GetPosition().y - RoutingMatrix.m_BrdBox.GetY() + demi_pas )

View File

@ -1180,7 +1180,7 @@ static void OrCell_Trace( BOARD* pcb, int col, int row,
g_CurrentTrackSegment->SetWidth( pcb->GetCurrentViaSize() ); g_CurrentTrackSegment->SetWidth( pcb->GetCurrentViaSize() );
g_CurrentTrackSegment->SetShape( pcb->GetDesignSettings().m_CurrentViaType ); g_CurrentTrackSegment->SetShape( pcb->GetDesignSettings().m_CurrentViaType );
g_CurrentTrackSegment->SetNet( current_net_code ); g_CurrentTrackSegment->SetNetCode( current_net_code );
} }
else // placement of a standard segment else // placement of a standard segment
{ {
@ -1198,7 +1198,7 @@ static void OrCell_Trace( BOARD* pcb, int col, int row,
( RoutingMatrix.m_GridRouting * row ), ( RoutingMatrix.m_GridRouting * row ),
pcb->GetBoundingBox().GetY() + pcb->GetBoundingBox().GetY() +
( RoutingMatrix.m_GridRouting * col ))); ( RoutingMatrix.m_GridRouting * col )));
g_CurrentTrackSegment->SetNet( current_net_code ); g_CurrentTrackSegment->SetNetCode( current_net_code );
if( g_CurrentTrackSegment->Back() == NULL ) /* Start trace. */ if( g_CurrentTrackSegment->Back() == NULL ) /* Start trace. */
{ {
@ -1319,7 +1319,7 @@ static void AddNewTrace( PCB_EDIT_FRAME* pcbframe, wxDC* DC )
} }
// Insert new segments in real board // Insert new segments in real board
int netcode = g_FirstTrackSegment->GetNet(); int netcode = g_FirstTrackSegment->GetNetCode();
TRACK* firstTrack = g_FirstTrackSegment; TRACK* firstTrack = g_FirstTrackSegment;
int newCount = g_CurrentTrackList.GetCount(); int newCount = g_CurrentTrackList.GetCount();

View File

@ -25,6 +25,7 @@
#include <fctsys.h> #include <fctsys.h>
#include <class_drawpanel.h> #include <class_drawpanel.h>
#include <class_drawpanel_gal.h>
#include <macros.h> #include <macros.h>
#include <pcbnew.h> #include <pcbnew.h>
@ -40,6 +41,10 @@
#include <class_zone.h> #include <class_zone.h>
#include <class_edge_mod.h> #include <class_edge_mod.h>
#include <ratsnest_data.h>
#include <tools/selection_tool.h>
#include <tool/tool_manager.h>
/* Functions to undo and redo edit commands. /* Functions to undo and redo edit commands.
* commands to undo are stored in CurrentScreen->m_UndoList * commands to undo are stored in CurrentScreen->m_UndoList
@ -292,6 +297,17 @@ void PCB_EDIT_FRAME::SaveCopyInUndoList( BOARD_ITEM* aItem,
if( aItem == NULL ) // Nothing to save if( aItem == NULL ) // Nothing to save
return; return;
// For texts belonging to modules, we need to save state of the parent module
if( aItem->Type() == PCB_MODULE_TEXT_T )
{
aItem = aItem->GetParent();
wxASSERT( aItem->Type() == PCB_MODULE_T );
aCommandType = UR_CHANGED;
if( aItem == NULL )
return;
}
PICKED_ITEMS_LIST* commandToUndo = new PICKED_ITEMS_LIST(); PICKED_ITEMS_LIST* commandToUndo = new PICKED_ITEMS_LIST();
commandToUndo->m_TransformPoint = aTransformPoint; commandToUndo->m_TransformPoint = aTransformPoint;
@ -346,7 +362,7 @@ void PCB_EDIT_FRAME::SaveCopyInUndoList( BOARD_ITEM* aItem,
} }
void PCB_EDIT_FRAME::SaveCopyInUndoList( PICKED_ITEMS_LIST& aItemsList, void PCB_EDIT_FRAME::SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList,
UNDO_REDO_T aTypeCommand, UNDO_REDO_T aTypeCommand,
const wxPoint& aTransformPoint ) const wxPoint& aTransformPoint )
{ {
@ -361,6 +377,20 @@ void PCB_EDIT_FRAME::SaveCopyInUndoList( PICKED_ITEMS_LIST& aItemsList,
for( unsigned ii = 0; ii < commandToUndo->GetCount(); ii++ ) for( unsigned ii = 0; ii < commandToUndo->GetCount(); ii++ )
{ {
BOARD_ITEM* item = (BOARD_ITEM*) commandToUndo->GetPickedItem( ii ); BOARD_ITEM* item = (BOARD_ITEM*) commandToUndo->GetPickedItem( ii );
// For texts belonging to modules, we need to save state of the parent module
if( item->Type() == PCB_MODULE_TEXT_T )
{
item = item->GetParent();
wxASSERT( item->Type() == PCB_MODULE_T );
if( item == NULL )
continue;
commandToUndo->SetPickedItem( item, ii );
commandToUndo->SetPickedItemStatus( UR_CHANGED, ii );
}
UNDO_REDO_T command = commandToUndo->GetPickedItemStatus( ii ); UNDO_REDO_T command = commandToUndo->GetPickedItemStatus( ii );
if( command == UR_UNSPECIFIED ) if( command == UR_UNSPECIFIED )
@ -424,6 +454,8 @@ void PCB_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed
BOARD_ITEM* item; BOARD_ITEM* item;
bool not_found = false; bool not_found = false;
bool reBuild_ratsnest = false; bool reBuild_ratsnest = false;
KIGFX::VIEW* view = GetGalCanvas()->GetView();
RN_DATA* ratsnest = GetBoard()->GetRatsnest();
// Undo in the reverse order of list creation: (this can allow stacked changes // Undo in the reverse order of list creation: (this can allow stacked changes
// like the same item can be changes and deleted in the same complex command // like the same item can be changes and deleted in the same complex command
@ -484,37 +516,85 @@ void PCB_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed
case UR_CHANGED: /* Exchange old and new data for each item */ case UR_CHANGED: /* Exchange old and new data for each item */
{ {
BOARD_ITEM* image = (BOARD_ITEM*) aList->GetPickedItemLink( ii ); BOARD_ITEM* image = (BOARD_ITEM*) aList->GetPickedItemLink( ii );
// Remove all pads/drawings/texts, as they become invalid
// for the VIEW after SwapData() called for modules
if( item->Type() == PCB_MODULE_T )
{
MODULE* oldModule = static_cast<MODULE*>( item );
oldModule->RunOnChildren( std::bind1st( std::mem_fun( &KIGFX::VIEW::Remove ), view ) );
}
ratsnest->Remove( item );
item->SwapData( image ); item->SwapData( image );
// Update all pads/drawings/texts, as they become invalid
// for the VIEW after SwapData() called for modules
if( item->Type() == PCB_MODULE_T )
{
MODULE* newModule = static_cast<MODULE*>( item );
newModule->RunOnChildren( std::bind1st( std::mem_fun( &KIGFX::VIEW::Add ), view ) );
}
ratsnest->Add( item );
item->ClearFlags( SELECTED );
item->ViewUpdate( KIGFX::VIEW_ITEM::LAYERS );
} }
break; break;
case UR_NEW: /* new items are deleted */ case UR_NEW: /* new items are deleted */
aList->SetPickedItemStatus( UR_DELETED, ii ); aList->SetPickedItemStatus( UR_DELETED, ii );
GetBoard()->Remove( item ); GetBoard()->Remove( item );
if( item->Type() == PCB_MODULE_T )
{
MODULE* module = static_cast<MODULE*>( item );
module->RunOnChildren( std::bind1st( std::mem_fun( &KIGFX::VIEW::Remove ), view ) );
}
view->Remove( item );
item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
break; break;
case UR_DELETED: /* deleted items are put in List, as new items */ case UR_DELETED: /* deleted items are put in List, as new items */
aList->SetPickedItemStatus( UR_NEW, ii ); aList->SetPickedItemStatus( UR_NEW, ii );
GetBoard()->Add( item ); GetBoard()->Add( item );
if( item->Type() == PCB_MODULE_T )
{
MODULE* module = static_cast<MODULE*>( item );
module->RunOnChildren( std::bind1st( std::mem_fun( &KIGFX::VIEW::Add ), view ) );
}
view->Add( item );
item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
build_item_list = true; build_item_list = true;
break; break;
case UR_MOVED: case UR_MOVED:
item->Move( aRedoCommand ? aList->m_TransformPoint : -aList->m_TransformPoint ); item->Move( aRedoCommand ? aList->m_TransformPoint : -aList->m_TransformPoint );
item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
ratsnest->Update( item );
break; break;
case UR_ROTATED: case UR_ROTATED:
item->Rotate( aList->m_TransformPoint, item->Rotate( aList->m_TransformPoint,
aRedoCommand ? m_rotationAngle : -m_rotationAngle ); aRedoCommand ? m_rotationAngle : -m_rotationAngle );
item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
ratsnest->Update( item );
break; break;
case UR_ROTATED_CLOCKWISE: case UR_ROTATED_CLOCKWISE:
item->Rotate( aList->m_TransformPoint, item->Rotate( aList->m_TransformPoint,
aRedoCommand ? -m_rotationAngle : m_rotationAngle ); aRedoCommand ? -m_rotationAngle : m_rotationAngle );
item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
ratsnest->Update( item );
break; break;
case UR_FLIPPED: case UR_FLIPPED:
item->Flip( aList->m_TransformPoint ); item->Flip( aList->m_TransformPoint );
item->ViewUpdate( KIGFX::VIEW_ITEM::LAYERS );
ratsnest->Update( item );
break; break;
default: default:
@ -533,15 +613,24 @@ void PCB_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed
// Rebuild pointers and ratsnest that can be changed. // Rebuild pointers and ratsnest that can be changed.
if( reBuild_ratsnest && aRebuildRatsnet ) if( reBuild_ratsnest && aRebuildRatsnet )
{
if( IsGalCanvasActive() )
ratsnest->Recalculate();
else
Compile_Ratsnest( NULL, true ); Compile_Ratsnest( NULL, true );
} }
}
void PCB_EDIT_FRAME::GetBoardFromUndoList( wxCommandEvent& event ) void PCB_EDIT_FRAME::GetBoardFromUndoList( wxCommandEvent& aEvent )
{ {
if( GetScreen()->GetUndoCommandCount() <= 0 ) if( GetScreen()->GetUndoCommandCount() <= 0 )
return; return;
// Inform tools that undo command was issued
TOOL_EVENT event( TC_MESSAGE, TA_UNDO_REDO, AS_GLOBAL );
m_toolManager->ProcessEvent( event );
/* Get the old list */ /* Get the old list */
PICKED_ITEMS_LIST* List = GetScreen()->PopCommandFromUndoList(); PICKED_ITEMS_LIST* List = GetScreen()->PopCommandFromUndoList();
/* Undo the command */ /* Undo the command */
@ -556,11 +645,14 @@ void PCB_EDIT_FRAME::GetBoardFromUndoList( wxCommandEvent& event )
} }
void PCB_EDIT_FRAME::GetBoardFromRedoList( wxCommandEvent& event ) void PCB_EDIT_FRAME::GetBoardFromRedoList( wxCommandEvent& aEvent )
{ {
if( GetScreen()->GetRedoCommandCount() == 0 ) if( GetScreen()->GetRedoCommandCount() == 0 )
return; return;
// Inform tools that redo command was issued
TOOL_EVENT event( TC_MESSAGE, TA_UNDO_REDO, AS_GLOBAL );
m_toolManager->ProcessEvent( event );
/* Get the old list */ /* Get the old list */
PICKED_ITEMS_LIST* List = GetScreen()->PopCommandFromRedoList(); PICKED_ITEMS_LIST* List = GetScreen()->PopCommandFromRedoList();

View File

@ -43,6 +43,8 @@
#include <reporter.h> #include <reporter.h>
#include <base_units.h> #include <base_units.h>
#include <ratsnest_data.h> #include <ratsnest_data.h>
#include <ratsnest_viewitem.h>
#include <worksheet_viewitem.h>
#include <pcbnew.h> #include <pcbnew.h>
#include <colors_selection.h> #include <colors_selection.h>
@ -104,22 +106,29 @@ BOARD::BOARD() :
SetCurrentNetClass( m_NetClasses.GetDefault()->GetName() ); SetCurrentNetClass( m_NetClasses.GetDefault()->GetName() );
// Initialize ratsnest
m_ratsnest = new RN_DATA( this ); m_ratsnest = new RN_DATA( this );
m_ratsnestViewItem = new KIGFX::RATSNEST_VIEWITEM( m_ratsnest );
// Initialize view item for displaying worksheet frame
m_worksheetViewItem = new KIGFX::WORKSHEET_VIEWITEM( &m_paper, &m_titles );
m_worksheetViewItem->SetFileName( std::string( m_fileName.mb_str() ) );
} }
BOARD::~BOARD() BOARD::~BOARD()
{ {
delete m_ratsnest;
while( m_ZoneDescriptorList.size() ) while( m_ZoneDescriptorList.size() )
{ {
ZONE_CONTAINER* area_to_remove = m_ZoneDescriptorList[0]; ZONE_CONTAINER* area_to_remove = m_ZoneDescriptorList[0];
Delete( area_to_remove ); Delete( area_to_remove );
} }
m_FullRatsnest.clear(); delete m_worksheetViewItem;
delete m_ratsnestViewItem;
delete m_ratsnest;
m_FullRatsnest.clear();
m_LocalRatsnest.clear(); m_LocalRatsnest.clear();
DeleteMARKERs(); DeleteMARKERs();
@ -206,7 +215,7 @@ void BOARD::chainMarkedSegments( wxPoint aPosition, LAYER_MSK aLayerMask, TRACK_
*/ */
for( ; ; ) for( ; ; )
{ {
if( GetPadFast( aPosition, aLayerMask ) != NULL ) if( GetPad( aPosition, aLayerMask ) != NULL )
return; return;
/* Test for a via: a via changes the layer mask and can connect a lot /* Test for a via: a via changes the layer mask and can connect a lot
@ -842,6 +851,8 @@ void BOARD::Add( BOARD_ITEM* aBoardItem, int aControl )
} }
break; break;
} }
m_ratsnest->Add( aBoardItem );
} }
@ -905,6 +916,8 @@ BOARD_ITEM* BOARD::Remove( BOARD_ITEM* aBoardItem )
wxFAIL_MSG( wxT( "BOARD::Remove() needs more ::Type() support" ) ); wxFAIL_MSG( wxT( "BOARD::Remove() needs more ::Type() support" ) );
} }
m_ratsnest->Remove( aBoardItem );
return aBoardItem; return aBoardItem;
} }
@ -1341,93 +1354,13 @@ NETINFO_ITEM* BOARD::FindNet( int aNetcode ) const
// NULL is returned for non valid netcodes // NULL is returned for non valid netcodes
NETINFO_ITEM* net = m_NetInfo.GetNetItem( aNetcode ); NETINFO_ITEM* net = m_NetInfo.GetNetItem( aNetcode );
#if defined(DEBUG)
if( net && aNetcode != net->GetNet()) // item can be NULL if anetcode is not valid
{
wxLogError( wxT( "FindNet() anetcode %d != GetNet() %d (net: %s)\n" ),
aNetcode, net->GetNet(), TO_UTF8( net->GetNetname() ) );
}
#endif
return net; return net;
} }
NETINFO_ITEM* BOARD::FindNet( const wxString& aNetname ) const NETINFO_ITEM* BOARD::FindNet( const wxString& aNetname ) const
{ {
// the first valid netcode is 1. return m_NetInfo.GetNetItem( aNetname );
// zero is reserved for "no connection" and is not used.
if( aNetname.IsEmpty() )
return NULL;
int ncount = m_NetInfo.GetNetCount();
// Search for a netname = aNetname
#if 0
// Use a sequential search: easy to understand, but slow
for( int ii = 1; ii < ncount; ii++ )
{
NETINFO_ITEM* item = m_NetInfo.GetNetItem( ii );
if( item && item->GetNetname() == aNetname )
{
return item;
}
}
#else
// Use a fast binary search,
// this is possible because Nets are alphabetically ordered in list
// see NETINFO_LIST::BuildListOfNets() and
// NETINFO_LIST::Build_Pads_Full_List()
int imax = ncount - 1;
int index = imax;
while( ncount > 0 )
{
int ii = ncount;
ncount >>= 1;
if( (ii & 1) && ( ii > 1 ) )
ncount++;
NETINFO_ITEM* item = m_NetInfo.GetNetItem( index );
if( item == NULL )
return NULL;
int icmp = item->GetNetname().Cmp( aNetname );
if( icmp == 0 ) // found !
{
return item;
}
if( icmp < 0 ) // must search after item
{
index += ncount;
if( index > imax )
index = imax;
continue;
}
if( icmp > 0 ) // must search before item
{
index -= ncount;
if( index < 1 )
index = 1;
continue;
}
}
#endif
return NULL;
} }
@ -1512,10 +1445,11 @@ int BOARD::ReturnSortedNetnamesList( wxArrayString& aNames, bool aSortbyPadsCoun
netBuffer.reserve( m_NetInfo.GetNetCount() ); netBuffer.reserve( m_NetInfo.GetNetCount() );
for( unsigned ii = 1; ii < m_NetInfo.GetNetCount(); ii++ ) for( NETINFO_LIST::iterator net( m_NetInfo.begin() ), netEnd( m_NetInfo.end() );
net != netEnd; ++net )
{ {
if( m_NetInfo.GetNetItem( ii )->GetNet() > 0 ) if( net->GetNet() > 0 )
netBuffer.push_back( m_NetInfo.GetNetItem( ii ) ); netBuffer.push_back( *net );
} }
// sort the list // sort the list
@ -1582,7 +1516,7 @@ ZONE_CONTAINER* BOARD::HitTestForAnyFilledArea( const wxPoint& aRefPos,
if( area->GetState( BUSY ) ) if( area->GetState( BUSY ) )
continue; continue;
if( aNetCode >= 0 && area->GetNet() != aNetCode ) if( aNetCode >= 0 && area->GetNetCode() != aNetCode )
continue; continue;
if( area->HitTestFilledArea( aRefPos ) ) if( area->HitTestFilledArea( aRefPos ) )
@ -1601,24 +1535,24 @@ int BOARD::SetAreasNetCodesFromNetNames( void )
{ {
if( !GetArea( ii )->IsOnCopperLayer() ) if( !GetArea( ii )->IsOnCopperLayer() )
{ {
GetArea( ii )->SetNet( 0 ); GetArea( ii )->SetNetCode( NETINFO_LIST::UNCONNECTED );
continue; continue;
} }
if( GetArea( ii )->GetNet() != 0 ) // i.e. if this zone is connected to a net if( GetArea( ii )->GetNetCode() != 0 ) // i.e. if this zone is connected to a net
{ {
const NETINFO_ITEM* net = FindNet( GetArea( ii )->GetNetName() ); const NETINFO_ITEM* net = GetArea( ii )->GetNet();
if( net ) if( net )
{ {
GetArea( ii )->SetNet( net->GetNet() ); GetArea( ii )->SetNetCode( net->GetNet() );
} }
else else
{ {
error_count++; error_count++;
// keep Net Name and set m_NetCode to -1 : error flag. // keep Net Name and set m_NetCode to -1 : error flag.
GetArea( ii )->SetNet( -1 ); GetArea( ii )->SetNetCode( -1 );
} }
} }
} }
@ -2338,7 +2272,7 @@ ZONE_CONTAINER* BOARD::InsertArea( int netcode, int iarea, LAYER_NUM layer, int
{ {
ZONE_CONTAINER* new_area = new ZONE_CONTAINER( this ); ZONE_CONTAINER* new_area = new ZONE_CONTAINER( this );
new_area->SetNet( netcode ); new_area->SetNetCode( netcode );
new_area->SetLayer( layer ); new_area->SetLayer( layer );
new_area->SetTimeStamp( GetNewTimeStamp() ); new_area->SetTimeStamp( GetNewTimeStamp() );
@ -2377,7 +2311,7 @@ bool BOARD::NormalizeAreaPolygon( PICKED_ITEMS_LIST * aNewZonesList, ZONE_CONTAI
{ {
// create new copper area and copy poly into it // create new copper area and copy poly into it
CPolyLine* new_p = (*pa)[ip - 1]; CPolyLine* new_p = (*pa)[ip - 1];
NewArea = AddArea( aNewZonesList, aCurrArea->GetNet(), aCurrArea->GetLayer(), NewArea = AddArea( aNewZonesList, aCurrArea->GetNetCode(), aCurrArea->GetLayer(),
wxPoint(0, 0), CPolyLine::NO_HATCH ); wxPoint(0, 0), CPolyLine::NO_HATCH );
// remove the poly that was automatically created for the new area // remove the poly that was automatically created for the new area
@ -2618,7 +2552,7 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets,
} }
if( !aNetlist.IsDryRun() ) if( !aNetlist.IsDryRun() )
pad->SetNetname( wxEmptyString ); pad->SetNetCode( NETINFO_LIST::UNCONNECTED );
} }
} }
else // Footprint pad has a net. else // Footprint pad has a net.
@ -2638,7 +2572,17 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets,
} }
if( !aNetlist.IsDryRun() ) if( !aNetlist.IsDryRun() )
pad->SetNetname( net.GetNetName() ); {
NETINFO_ITEM* netinfo = FindNet( net.GetNetName() );
if( netinfo == NULL )
{
// It is a new net, we have to add it
netinfo = new NETINFO_ITEM( this, net.GetNetName() );
m_NetInfo.AppendNet( netinfo );
}
pad->SetNetCode( netinfo->GetNet() );
}
} }
} }
} }
@ -2710,7 +2654,8 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets,
GetChars( previouspad->GetPadName() ) ); GetChars( previouspad->GetPadName() ) );
aReporter->Report( msg ); aReporter->Report( msg );
} }
previouspad->SetNetname( wxEmptyString );
previouspad->SetNetCode( NETINFO_LIST::UNCONNECTED );
} }
netname = pad->GetNetname(); netname = pad->GetNetname();
count = 1; count = 1;
@ -2723,7 +2668,7 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets,
// Examine last pad // Examine last pad
if( pad && count == 1 ) if( pad && count == 1 )
pad->SetNetname( wxEmptyString ); pad->SetNetCode( NETINFO_LIST::UNCONNECTED );
} }
// Last step: Some tests: // Last step: Some tests:
@ -2760,31 +2705,6 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets,
} }
} }
} }
// Verify zone net names validity:
// After schematic changes, a zone can have a non existing net name.
// It should be reported
if( aReporter && aReporter->ReportErrors() )
{
//Loop through all copper zones
for( i = 0; i < m_ZoneDescriptorList.size(); i++ )
{
ZONE_CONTAINER* zone = m_ZoneDescriptorList[i];
if( zone->GetNet() >= 0 || !zone->IsOnCopperLayer() )
continue;
// Net name not valid, report error
wxString coord;
coord << zone->GetPosition();
msg.Printf( _( "*** Error: Zone '%s' layer '%s'"
" has non-existent net name '%s' ***\n" ),
GetChars( coord ),
GetChars( zone->GetLayerName() ),
GetChars( zone->GetNetName() ) );
aReporter->Report( msg );
}
}
} }
/* Extracts the board outlines and build a closed polygon /* Extracts the board outlines and build a closed polygon

View File

@ -58,6 +58,12 @@ class NETLIST;
class REPORTER; class REPORTER;
class RN_DATA; class RN_DATA;
namespace KIGFX
{
class RATSNEST_VIEWITEM;
class WORKSHEET_VIEWITEM;
}
// non-owning container of item candidates when searching for items on the same track. // non-owning container of item candidates when searching for items on the same track.
typedef std::vector< TRACK* > TRACK_PTRS; typedef std::vector< TRACK* > TRACK_PTRS;
@ -227,6 +233,8 @@ private:
EDA_RECT m_BoundingBox; EDA_RECT m_BoundingBox;
NETINFO_LIST m_NetInfo; ///< net info list (name, design constraints .. NETINFO_LIST m_NetInfo; ///< net info list (name, design constraints ..
RN_DATA* m_ratsnest; RN_DATA* m_ratsnest;
KIGFX::RATSNEST_VIEWITEM* m_ratsnestViewItem; ///< VIEW_ITEM that draws ratsnest
KIGFX::WORKSHEET_VIEWITEM* m_worksheetViewItem; ///< VIEW_ITEM that draws worksheet frame
BOARD_DESIGN_SETTINGS m_designSettings; BOARD_DESIGN_SETTINGS m_designSettings;
ZONE_SETTINGS m_zoneSettings; ZONE_SETTINGS m_zoneSettings;
@ -367,6 +375,24 @@ public:
return m_ratsnest; return m_ratsnest;
} }
/**
* Function GetRatsnestViewItem()
* returns VIEW_ITEM responsible for drawing the ratsnest for the board.
*/
KIGFX::RATSNEST_VIEWITEM* GetRatsnestViewItem() const
{
return m_ratsnestViewItem;
}
/**
* Function GetWorksheetViewItem()
* returns VIEW_ITEM responsible for drawing the worksheet frame.
*/
KIGFX::WORKSHEET_VIEWITEM* GetWorksheetViewItem() const
{
return m_worksheetViewItem;
}
/** /**
* Function DeleteMARKERs * Function DeleteMARKERs
* deletes ALL MARKERS from the board. * deletes ALL MARKERS from the board.
@ -845,6 +871,24 @@ public:
m_NetInfo.AppendNet( aNewNet ); m_NetInfo.AppendNet( aNewNet );
} }
/**
* Function BeginNets
* @return iterator to the first element of the NETINFO_ITEMs list
*/
NETINFO_LIST::iterator BeginNets() const
{
return m_NetInfo.begin();
}
/**
* Function EndNets
* @return iterator to the last element of the NETINFO_ITEMs list
*/
NETINFO_LIST::iterator EndNets() const
{
return m_NetInfo.end();
}
/** /**
* Function GetNetCount * Function GetNetCount
* @return the number of nets (NETINFO_ITEM) * @return the number of nets (NETINFO_ITEM)

View File

@ -1,8 +1,3 @@
/**
* @file class_board_connected_item.cpp
* @brief BOARD_CONNECTED_ITEM class functions.
*/
/* /*
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
@ -28,76 +23,67 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
/**
* @file class_board_connected_item.cpp
* @brief BOARD_CONNECTED_ITEM class functions.
*/
#include <fctsys.h> #include <fctsys.h>
#include <pcbnew.h> #include <pcbnew.h>
#include <class_board.h> #include <class_board.h>
#include <class_board_item.h> #include <class_board_item.h>
BOARD_CONNECTED_ITEM::BOARD_CONNECTED_ITEM( BOARD_ITEM* aParent, KICAD_T idtype ) : BOARD_CONNECTED_ITEM::BOARD_CONNECTED_ITEM( BOARD_ITEM* aParent, KICAD_T idtype ) :
BOARD_ITEM( aParent, idtype ) BOARD_ITEM( aParent, idtype ), m_netinfo( &NETINFO_LIST::ORPHANED ),
m_Subnet( 0 ), m_ZoneSubnet( 0 )
{ {
m_NetCode = 0; // The unconnected net is set only in case the item belongs to a BOARD
m_Subnet = 0; SetNetCode( NETINFO_LIST::UNCONNECTED );
m_ZoneSubnet = 0;
} }
BOARD_CONNECTED_ITEM::BOARD_CONNECTED_ITEM( const BOARD_CONNECTED_ITEM& aItem ) : BOARD_CONNECTED_ITEM::BOARD_CONNECTED_ITEM( const BOARD_CONNECTED_ITEM& aItem ) :
BOARD_ITEM( aItem ) BOARD_ITEM( aItem ), m_netinfo( aItem.m_netinfo ), m_Subnet( aItem.m_Subnet ),
m_ZoneSubnet( aItem.m_ZoneSubnet )
{ {
m_NetCode = aItem.m_NetCode;
m_Subnet = aItem.m_Subnet;
m_ZoneSubnet = aItem.m_ZoneSubnet;
} }
/** int BOARD_CONNECTED_ITEM::GetNetCode() const
* Function GetNet
* @return int - the net code.
*/
int BOARD_CONNECTED_ITEM::GetNet() const
{ {
return m_NetCode; return m_netinfo->GetNet();
} }
void BOARD_CONNECTED_ITEM::SetNet( int aNetCode ) void BOARD_CONNECTED_ITEM::SetNetCode( int aNetCode )
{ {
m_NetCode = aNetCode; BOARD* board = GetBoard();
if( board )
{
m_netinfo = board->FindNet( aNetCode );
// The requested net does not exist, mark it as unconnected
if( m_netinfo == NULL )
m_netinfo = board->FindNet( NETINFO_LIST::UNCONNECTED );
}
else
{
// There is no board that contains list of nets, the item is orphaned
m_netinfo = &NETINFO_LIST::ORPHANED;
}
} }
/** const wxString& BOARD_CONNECTED_ITEM::GetNetname() const
* Function GetSubNet
* @return int - the sub net code.
*/
int BOARD_CONNECTED_ITEM::GetSubNet() const
{ {
return m_Subnet; return m_netinfo->GetNetname();
} }
void BOARD_CONNECTED_ITEM::SetSubNet( int aSubNetCode ) const wxString& BOARD_CONNECTED_ITEM::GetShortNetname() const
{ {
m_Subnet = aSubNetCode; return m_netinfo->GetShortNetname();
}
/**
* Function GetZoneSubNet
* @return int - the sub net code in zone connections.
*/
int BOARD_CONNECTED_ITEM::GetZoneSubNet() const
{
return m_ZoneSubnet;
}
void BOARD_CONNECTED_ITEM::SetZoneSubNet( int aSubNetCode )
{
m_ZoneSubnet = aSubNetCode;
} }
@ -132,11 +118,6 @@ int BOARD_CONNECTED_ITEM::GetClearance( BOARD_CONNECTED_ITEM* aItem ) const
} }
/** return a pointer to the netclass of the zone
* if the net is not found (can happen when a netlist is reread,
* and the net name is not existant, return the default net class
* So should not return a null pointer
*/
NETCLASS* BOARD_CONNECTED_ITEM::GetNetClass() const NETCLASS* BOARD_CONNECTED_ITEM::GetNetClass() const
{ {
// It is important that this be implemented without any sequential searching. // It is important that this be implemented without any sequential searching.
@ -155,8 +136,7 @@ NETCLASS* BOARD_CONNECTED_ITEM::GetNetClass() const
} }
NETCLASS* netclass = NULL; NETCLASS* netclass = NULL;
int netcode = GetNet(); NETINFO_ITEM* net = board->FindNet( GetNetCode() );
NETINFO_ITEM* net = board->FindNet( netcode );
if( net ) if( net )
{ {
@ -176,10 +156,7 @@ NETCLASS* BOARD_CONNECTED_ITEM::GetNetClass() const
return board->m_NetClasses.GetDefault(); return board->m_NetClasses.GetDefault();
} }
/**
* Function GetNetClassName
* @return the Net Class name of this item
*/
wxString BOARD_CONNECTED_ITEM::GetNetClassName() const wxString BOARD_CONNECTED_ITEM::GetNetClassName() const
{ {
wxString name; wxString name;

View File

@ -1,3 +1,28 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 1992-2012 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
*/
/** /**
* @file class_board_connected_item.h * @file class_board_connected_item.h
* @brief Class BOARD_CONNECTED_ITEM. * @brief Class BOARD_CONNECTED_ITEM.
@ -6,9 +31,9 @@
#ifndef BOARD_CONNECTED_ITEM_H #ifndef BOARD_CONNECTED_ITEM_H
#define BOARD_CONNECTED_ITEM_H #define BOARD_CONNECTED_ITEM_H
#include <class_board_item.h> #include <class_board_item.h>
class NETINFO_ITEM;
class NETCLASS; class NETCLASS;
class TRACK; class TRACK;
class D_PAD; class D_PAD;
@ -29,41 +54,78 @@ public:
std::vector<TRACK*> m_TracksConnected; // list of other tracks connected to me std::vector<TRACK*> m_TracksConnected; // list of other tracks connected to me
std::vector<D_PAD*> m_PadsConnected; // list of other pads connected to me std::vector<D_PAD*> m_PadsConnected; // list of other pads connected to me
private:
int m_NetCode; // Net number
int m_Subnet; /* In rastnest routines : for the current net, block number
* (number common to the current connected items found)
*/
int m_ZoneSubnet; // used in rastnest computations : for the current net,
// handle cluster number in zone connection
public:
BOARD_CONNECTED_ITEM( BOARD_ITEM* aParent, KICAD_T idtype ); BOARD_CONNECTED_ITEM( BOARD_ITEM* aParent, KICAD_T idtype );
BOARD_CONNECTED_ITEM( const BOARD_CONNECTED_ITEM& aItem ); BOARD_CONNECTED_ITEM( const BOARD_CONNECTED_ITEM& aItem );
///> @copydoc BOARD_ITEM::IsConnected()
bool IsConnected() const
{
return true;
}
/** /**
* Function GetNet * Function GetNet
* Returns NET_INFO object for a given item.
*/
NETINFO_ITEM* GetNet() const
{
return m_netinfo;
}
/**
* Function GetNetCode
* @return int - the net code. * @return int - the net code.
*/ */
int GetNet() const; int GetNetCode() const;
virtual void SetNet( int aNetCode );
/**
* Function SetNetCode
* sets net using a net code.
* @param aNetCode is a net code for the new net. It has to exist in NETINFO_LIST held by BOARD.
* Otherwise, item is assigned to the unconnected net.
*/
void SetNetCode( int aNetCode );
/** /**
* Function GetSubNet * Function GetSubNet
* @return int - the sub net code. * @return int - the sub net code.
*/ */
int GetSubNet() const; int GetSubNet() const
void SetSubNet( int aSubNetCode ); {
return m_Subnet;
}
void SetSubNet( int aSubNetCode )
{
m_Subnet = aSubNetCode;
}
/** /**
* Function GetZoneSubNet * Function GetZoneSubNet
* @return int - the sub net code in zone connections. * @return int - the sub net code in zone connections.
*/ */
int GetZoneSubNet() const; int GetZoneSubNet() const
void SetZoneSubNet( int aSubNetCode ); {
return m_ZoneSubnet;
}
void SetZoneSubNet( int aSubNetCode )
{
m_ZoneSubnet = aSubNetCode;
}
/**
* Function GetNetname
* @return wxString - the full netname
*/
const wxString& GetNetname() const;
/**
* Function GetShortNetname
* @return wxString - the short netname
*/
const wxString& GetShortNetname() const;
/** /**
* Function GetClearance * Function GetClearance
@ -84,9 +146,25 @@ public:
/** /**
* Function GetNetClassName * Function GetNetClassName
* returns a pointer to the netclass of the zone.
* If the net is not found (can happen when a netlist is reread,
* and the net name does not exist, return the default net class
* (should not return a null pointer).
* @return the Net Class name of this item * @return the Net Class name of this item
*/ */
wxString GetNetClassName() const; wxString GetNetClassName() const;
protected:
/// Stores all informations about the net that item belongs to
NETINFO_ITEM* m_netinfo;
private:
int m_Subnet; /* In rastnest routines : for the current net, block number
* (number common to the current connected items found)
*/
int m_ZoneSubnet; // used in rastnest computations : for the current net,
// handle cluster number in zone connection
}; };

View File

@ -52,7 +52,7 @@
BOARD_DESIGN_SETTINGS::BOARD_DESIGN_SETTINGS() : BOARD_DESIGN_SETTINGS::BOARD_DESIGN_SETTINGS() :
m_Pad_Master( 0 ) m_Pad_Master( NULL )
{ {
m_EnabledLayers = ALL_LAYERS; // All layers enabled at first. m_EnabledLayers = ALL_LAYERS; // All layers enabled at first.
// SetCopperLayerCount() will adjust this. // SetCopperLayerCount() will adjust this.

View File

@ -134,7 +134,7 @@ const wxPoint DRAWSEGMENT::GetArcEnd() const
return endPoint; // after rotation, the end of the arc. return endPoint; // after rotation, the end of the arc.
} }
const double DRAWSEGMENT::GetArcAngleStart() const double DRAWSEGMENT::GetArcAngleStart() const
{ {
// due to the Y axis orient atan2 needs - y value // due to the Y axis orient atan2 needs - y value
double angleStart = ArcTangente( GetArcStart().y - GetCenter().y, double angleStart = ArcTangente( GetArcStart().y - GetCenter().y,
@ -148,6 +148,7 @@ const double DRAWSEGMENT::GetArcAngleStart() const
return angleStart; return angleStart;
} }
void DRAWSEGMENT::SetAngle( double aAngle ) void DRAWSEGMENT::SetAngle( double aAngle )
{ {
NORMALIZE_ANGLE_360( aAngle ); NORMALIZE_ANGLE_360( aAngle );
@ -379,6 +380,59 @@ const EDA_RECT DRAWSEGMENT::GetBoundingBox() const
wxPoint end = m_End; wxPoint end = m_End;
RotatePoint( &end, m_Start, -m_Angle ); RotatePoint( &end, m_Start, -m_Angle );
bbox.Merge( end ); bbox.Merge( end );
// Determine the starting quarter
// 0 right-bottom
// 1 left-bottom
// 2 left-top
// 3 right-top
unsigned int quarter = 0; // assume right-bottom
if( m_End.y < m_Start.y ) // change to left-top
quarter |= 3;
if( m_End.x < m_Start.x ) // for left side, the LSB is 2nd bit negated
quarter ^= 1;
int radius = GetRadius();
int angle = (int) GetArcAngleStart() % 900 + m_Angle;
bool directionCW = ( m_Angle > 0 ); // Is the direction of arc clockwise?
if( !directionCW )
{
angle = 900 - angle;
quarter = ( quarter + 3 ) % 4; // -1 modulo arithmetic
}
while( angle > 900 )
{
switch( quarter )
{
case 0:
bbox.Merge( wxPoint( m_Start.x, m_Start.y + radius ) ); // down
break;
case 1:
bbox.Merge( wxPoint( m_Start.x - radius, m_Start.y ) ); // left
break;
case 2:
bbox.Merge( wxPoint( m_Start.x, m_Start.y - radius ) ); // up
break;
case 3:
bbox.Merge( wxPoint( m_Start.x + radius, m_Start.y ) ); // right
break;
}
if( directionCW )
++quarter;
else
quarter += 3; // -1 modulo arithmetic
quarter %= 4;
angle -= 900;
}
} }
break; break;

View File

@ -30,7 +30,6 @@
#ifndef CLASS_DRAWSEGMENT_H_ #ifndef CLASS_DRAWSEGMENT_H_
#define CLASS_DRAWSEGMENT_H_ #define CLASS_DRAWSEGMENT_H_
#include <class_board_item.h> #include <class_board_item.h>
#include <PolyLine.h> #include <PolyLine.h>
#include <math_for_graphics.h> #include <math_for_graphics.h>
@ -126,9 +125,9 @@ public:
/** /**
* function GetArcAngleStart() * function GetArcAngleStart()
* @return the angle of the stating point of this arc, between 0 and 3600 in 0.1 deg * @return the angle of the starting point of this arc, between 0 and 3600 in 0.1 deg
*/ */
const double GetArcAngleStart() const; double GetArcAngleStart() const;
/** /**
* Function GetRadius * Function GetRadius

View File

@ -728,6 +728,41 @@ EDA_ITEM* MODULE::Clone() const
} }
void MODULE::RunOnChildren( boost::function<void (BOARD_ITEM*)> aFunction )
{
for( D_PAD* pad = m_Pads.GetFirst(); pad; pad = pad->Next() )
aFunction( static_cast<BOARD_ITEM*>( pad ) );
for( BOARD_ITEM* drawing = m_Drawings.GetFirst(); drawing; drawing = drawing->Next() )
aFunction( drawing );
aFunction( static_cast<BOARD_ITEM*>( m_Reference ) );
aFunction( static_cast<BOARD_ITEM*>( m_Value ) );
}
void MODULE::ViewUpdate( int aUpdateFlags )
{
if( !m_view )
return;
// Update pads
for( D_PAD* pad = m_Pads.GetFirst(); pad; pad = pad->Next() )
m_view->InvalidateItem( pad, aUpdateFlags );
// Update module's drawing (mostly silkscreen)
for( BOARD_ITEM* drawing = m_Drawings.GetFirst(); drawing; drawing = drawing->Next() )
m_view->InvalidateItem( drawing, aUpdateFlags );
// Update module's texts
m_view->InvalidateItem( m_Reference, aUpdateFlags );
m_view->InvalidateItem( m_Value, aUpdateFlags );
// Update the module itself
m_view->InvalidateItem( this, aUpdateFlags );
}
/* Test for validity of the name in a library of the footprint /* Test for validity of the name in a library of the footprint
* ( no spaces, dir separators ... ) * ( no spaces, dir separators ... )
* return true if the given name is valid * return true if the given name is valid

View File

@ -41,6 +41,7 @@
#include <PolyLine.h> #include <PolyLine.h>
#include "zones.h" #include "zones.h"
#include <boost/function.hpp>
class LINE_READER; class LINE_READER;
class EDA_3D_CANVAS; class EDA_3D_CANVAS;
@ -453,6 +454,17 @@ public:
EDA_ITEM* Clone() const; EDA_ITEM* Clone() const;
/**
* Function RunOnChildren
*
* Invokes a function on all BOARD_ITEMs that belong to the module (pads, drawings, texts).
* @param aFunction is the function to be invoked.
*/
void RunOnChildren( boost::function<void (BOARD_ITEM*)> aFunction );
/// @copydoc VIEW_ITEM::ViewUpdate()
void ViewUpdate( int aUpdateFlags );
/** /**
* Function CopyNetlistSettings * Function CopyNetlistSettings
* copies the netlist settings to \a aModule. * copies the netlist settings to \a aModule.

View File

@ -203,11 +203,9 @@ void BOARD::SynchronizeNetsAndNetClasses()
// set all NETs to the default NETCLASS, then later override some // set all NETs to the default NETCLASS, then later override some
// as we go through the NETCLASSes. // as we go through the NETCLASSes.
int count = m_NetInfo.GetNetCount(); for( NETINFO_LIST::iterator net( m_NetInfo.begin() ), netEnd( m_NetInfo.end() );
for( int i=0; i<count; ++i ) net != netEnd; ++net )
{ {
NETINFO_ITEM* net = FindNet( i );
if( net )
net->SetClass( m_NetClasses.GetDefault() ); net->SetClass( m_NetClasses.GetDefault() );
} }
@ -248,10 +246,8 @@ void BOARD::SynchronizeNetsAndNetClasses()
m_NetClasses.GetDefault()->Clear(); m_NetClasses.GetDefault()->Clear();
for( int i=0; i<count; ++i ) for( NETINFO_LIST::iterator net( m_NetInfo.begin() ), netEnd( m_NetInfo.end() );
{ net != netEnd; ++net )
NETINFO_ITEM* net = FindNet( i );
if( net )
{ {
const wxString& classname = net->GetClassName(); const wxString& classname = net->GetClassName();
@ -263,7 +259,6 @@ void BOARD::SynchronizeNetsAndNetClasses()
netclass->Add( net->GetNetname() ); netclass->Add( net->GetNetname() );
} }
}
// D(printf("stop\n");) // D(printf("stop\n");)
} }
@ -338,7 +333,14 @@ void NETCLASS::Format( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aControl
aFormatter->Print( aNestLevel+1, "(uvia_drill %s)\n", FMT_IU( GetuViaDrill() ).c_str() ); aFormatter->Print( aNestLevel+1, "(uvia_drill %s)\n", FMT_IU( GetuViaDrill() ).c_str() );
for( NETCLASS::const_iterator it = begin(); it != end(); ++it ) for( NETCLASS::const_iterator it = begin(); it != end(); ++it )
{
NETINFO_ITEM* netinfo = m_Parent->FindNet( *it );
if( netinfo && netinfo->GetNodesCount() > 0 )
{
aFormatter->Print( aNestLevel+1, "(add_net %s)\n", aFormatter->Quotew( *it ).c_str() ); aFormatter->Print( aNestLevel+1, "(add_net %s)\n", aFormatter->Quotew( *it ).c_str() );
}
}
aFormatter->Print( aNestLevel, ")\n\n" ); aFormatter->Print( aNestLevel, ")\n\n" );
} }

View File

@ -34,9 +34,10 @@
#define __CLASSES_NETINFO__ #define __CLASSES_NETINFO__
#include <vector>
#include <gr_basic.h> #include <gr_basic.h>
#include <class_netclass.h> #include <class_netclass.h>
#include <boost/unordered_map.hpp>
#include <hashtables.h>
class wxDC; class wxDC;
@ -115,6 +116,120 @@ public:
}; };
class NETINFO_MAPPING
{
public:
/**
* Function SetBoard
* Sets a BOARD object that is used to prepare the net code map.
*/
void SetBoard( const BOARD* aBoard )
{
m_board = aBoard;
Update();
}
/**
* Function Update
* Prepares a mapping for net codes so they can be saved as consecutive numbers.
* To retrieve a mapped net code, use translateNet() function after calling this.
*/
void Update();
/**
* Function Translate
* Translates net number according to the map prepared by Update() function. It
* allows to have items stored with consecutive net codes.
* @param aNetCode is an old net code.
* @return Net code that follows the mapping.
*/
int Translate( int aNetCode ) const;
///> Wrapper class, so you can iterate through NETINFO_ITEM*s, not
///> std::pair<int/wxString, NETINFO_ITEM*>
class iterator
{
public:
iterator( std::map<int, int>::const_iterator aIter, const NETINFO_MAPPING* aMapping ) :
m_iterator( aIter ), m_mapping( aMapping )
{
}
/// pre-increment operator
const iterator& operator++()
{
++m_iterator;
return *this;
}
/// post-increment operator
iterator operator++( int )
{
iterator ret = *this;
++m_iterator;
return ret;
}
NETINFO_ITEM* operator*() const;
NETINFO_ITEM* operator->() const;
bool operator!=( const iterator& aOther ) const
{
return m_iterator != aOther.m_iterator;
}
bool operator==( const iterator& aOther ) const
{
return m_iterator == aOther.m_iterator;
}
private:
std::map<int, int>::const_iterator m_iterator;
const NETINFO_MAPPING* m_mapping;
};
/**
* Function begin()
* Returns iterator to the first entry in the mapping.
* NOTE: The entry is a pointer to the original NETINFO_ITEM object, this it contains
* not mapped net code.
*/
iterator begin() const
{
return iterator( m_netMapping.begin(), this );
}
/**
* Function end()
* Returns iterator to the last entry in the mapping.
* NOTE: The entry is a pointer to the original NETINFO_ITEM object, this it contains
* not mapped net code.
*/
iterator end() const
{
return iterator( m_netMapping.end(), this );
}
/**
* Function GetSize
* @return Number of mapped nets (i.e. not empty nets for a given BOARD object).
*/
int GetSize() const
{
return m_netMapping.size();
}
private:
///> Board for which mapping is prepared
const BOARD* m_board;
///> Map that allows saving net codes with consecutive numbers (for compatibility reasons)
std::map<int, int> m_netMapping;
};
/** /**
* Class NETINFO * Class NETINFO
@ -131,14 +246,30 @@ public:
/** /**
* Function GetItem * Function GetItem
* @param aNetcode = netcode to identify a given NETINFO_ITEM * @param aNetCode = netcode to identify a given NETINFO_ITEM
* @return NETINFO_ITEM* - by \a aNetcode, or NULL if not found * @return NETINFO_ITEM* - by \a aNetCode, or NULL if not found
*/ */
NETINFO_ITEM* GetNetItem( int aNetcode ) const NETINFO_ITEM* GetNetItem( int aNetCode ) const
{ {
if( unsigned( aNetcode ) >= GetNetCount() ) // catches < 0 too NETCODES_MAP::const_iterator result = m_netCodes.find( aNetCode );
if( result != m_netCodes.end() )
return (*result).second;
return NULL;
}
/**
* Function GetItem
* @param aNetName = net name to identify a given NETINFO_ITEM
* @return NETINFO_ITEM* - by \a aNetName, or NULL if not found
*/
NETINFO_ITEM* GetNetItem( const wxString& aNetName ) const
{
NETNAMES_MAP::const_iterator result = m_netNames.find( aNetName );
if( result != m_netNames.end() )
return (*result).second;
return NULL; return NULL;
return m_NetBuffer[aNetcode];
} }
/** /**
@ -146,7 +277,7 @@ public:
* @return the number of nets ( always >= 1 ) * @return the number of nets ( always >= 1 )
* because the first net is the "not connected" net and always exists * because the first net is the "not connected" net and always exists
*/ */
unsigned GetNetCount() const { return m_NetBuffer.size(); } unsigned GetNetCount() const { return m_netNames.size(); }
/** /**
* Function Append * Function Append
@ -184,12 +315,81 @@ public:
return NULL; return NULL;
} }
///> Constant that holds the unconnected net number
static const int UNCONNECTED;
///> NETINFO_ITEM meaning that there was no net assigned for an item, as there was no
///> board storing net list available.
static NETINFO_ITEM ORPHANED;
#if defined(DEBUG) #if defined(DEBUG)
void Show() const; void Show() const;
#endif #endif
private: typedef boost::unordered_map<const wxString, NETINFO_ITEM*, WXSTRING_HASH> NETNAMES_MAP;
typedef boost::unordered_map<const int, NETINFO_ITEM*> NETCODES_MAP;
///> Wrapper class, so you can iterate through NETINFO_ITEM*s, not
///> std::pair<int/wxString, NETINFO_ITEM*>
class iterator
{
public:
iterator( NETNAMES_MAP::const_iterator aIter ) : m_iterator( aIter )
{
}
/// pre-increment operator
const iterator& operator++()
{
++m_iterator;
return *this;
}
/// post-increment operator
iterator operator++( int )
{
iterator ret = *this;
++m_iterator;
return ret;
}
NETINFO_ITEM* operator*() const
{
return m_iterator->second;
}
NETINFO_ITEM* operator->() const
{
return m_iterator->second;
}
bool operator!=( const iterator& aOther ) const
{
return m_iterator != aOther.m_iterator;
}
bool operator==( const iterator& aOther ) const
{
return m_iterator == aOther.m_iterator;
}
private:
NETNAMES_MAP::const_iterator m_iterator;
};
iterator begin() const
{
return iterator( m_netNames.begin() );
}
iterator end() const
{
return iterator( m_netNames.end() );
}
private:
/** /**
* Function DeleteData * Function DeleteData
* deletes the list of nets (and free memory) * deletes the list of nets (and free memory)
@ -213,8 +413,16 @@ private:
*/ */
void buildPadsFullList(); void buildPadsFullList();
/**
* Function getFreeNetCode
* returns the first available net code that is not used by any other net.
*/
int getFreeNetCode() const;
BOARD* m_Parent; BOARD* m_Parent;
std::vector<NETINFO_ITEM*> m_NetBuffer; ///< net list (name, design constraints ..)
NETNAMES_MAP m_netNames; ///< map for a fast look up by net names
NETCODES_MAP m_netCodes; ///< map for a fast look up by net codes
std::vector<D_PAD*> m_PadsFullList; ///< contains all pads, sorted by pad's netname. std::vector<D_PAD*> m_PadsFullList; ///< contains all pads, sorted by pad's netname.
///< can be used in ratsnest calculations. ///< can be used in ratsnest calculations.
@ -227,14 +435,16 @@ private:
*/ */
class NETINFO_ITEM class NETINFO_ITEM
{ {
friend class NETINFO_LIST;
private: private:
int m_NetCode; ///< A number equivalent to the net name. const int m_NetCode; ///< A number equivalent to the net name.
///< Used for fast comparisons in ratsnest and DRC computations. ///< Used for fast comparisons in ratsnest and DRC computations.
wxString m_Netname; ///< Full net name like /mysheet/mysubsheet/vout const wxString m_Netname; ///< Full net name like /mysheet/mysubsheet/vout
///< used by Eeschema ///< used by Eeschema
wxString m_ShortNetname; // short net name, like vout from const wxString m_ShortNetname; // short net name, like vout from
// /mysheet/mysubsheet/vout // /mysheet/mysubsheet/vout
wxString m_NetClassName; // Net Class name. if void this is equivalent wxString m_NetClassName; // Net Class name. if void this is equivalent
@ -246,12 +456,6 @@ private:
BOARD_ITEM* m_parent; ///< The parent board item object the net belongs to. BOARD_ITEM* m_parent; ///< The parent board item object the net belongs to.
public: public:
int m_NbNodes; // Pads count for this net
int m_NbLink; // Ratsnets count for this net
int m_NbNoconn; // Ratsnets remaining to route count
int m_Flag; // used in some calculations. Had no
// special meaning
std::vector <D_PAD*> m_PadInNetList; // List of pads connected to this net std::vector <D_PAD*> m_PadInNetList; // List of pads connected to this net
unsigned m_RatsnestStartIdx; /* Starting point of ratsnests of this unsigned m_RatsnestStartIdx; /* Starting point of ratsnests of this
@ -262,7 +466,7 @@ public:
unsigned m_RatsnestEndIdx; // Ending point of ratsnests of this net unsigned m_RatsnestEndIdx; // Ending point of ratsnests of this net
// (excluded) in this buffer // (excluded) in this buffer
NETINFO_ITEM( BOARD_ITEM* aParent, const wxString& aNetName = wxEmptyString, int aNetCode = 0 ); NETINFO_ITEM( BOARD_ITEM* aParent, const wxString& aNetName = wxEmptyString, int aNetCode = -1 );
~NETINFO_ITEM(); ~NETINFO_ITEM();
/** /**
@ -386,27 +590,23 @@ public:
*/ */
int GetNet() const { return m_NetCode; } int GetNet() const { return m_NetCode; }
void SetNet( int aNetCode ) { m_NetCode = aNetCode; } /**
* Function GetNodesCount
* @return int - number of nodes in the net
*/
int GetNodesCount() const { return m_PadInNetList.size(); } int GetNodesCount() const { return m_PadInNetList.size(); }
/** /**
* Function GetNetname * Function GetNetname
* @return const wxString * , a pointer to the full netname * @return const wxString&, a reference to the full netname
*/ */
wxString GetNetname() const { return m_Netname; } const wxString& GetNetname() const { return m_Netname; }
/** /**
* Function GetShortNetname * Function GetShortNetname
* @return const wxString * , a pointer to the short netname * @return const wxString &, a reference to the short netname
*/ */
wxString GetShortNetname() const { return m_ShortNetname; } const wxString& GetShortNetname() const { return m_ShortNetname; }
/**
* Function SetNetname
* @param aNetname : the new netname
*/
void SetNetname( const wxString& aNetname );
/** /**
* Function GetMsgPanelInfo * Function GetMsgPanelInfo
@ -416,6 +616,21 @@ public:
* @param aList is the list in which to place the status information. * @param aList is the list in which to place the status information.
*/ */
void GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList ); void GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList );
/**
* Function Clear
* sets all fields to their defaults values.
*/
void Clear()
{
m_PadInNetList.clear();
m_RatsnestStartIdx = 0; // Starting point of ratsnests of this net in a
// general buffer of ratsnest
m_RatsnestEndIdx = 0; // Ending point of ratsnests of this net
SetClass( NULL );
}
}; };

View File

@ -49,25 +49,16 @@
/* class NETINFO_ITEM: handle data relative to a given net */ /* class NETINFO_ITEM: handle data relative to a given net */
/*********************************************************/ /*********************************************************/
NETINFO_ITEM::NETINFO_ITEM( BOARD_ITEM* aParent, const wxString& aNetName, int aNetCode ) NETINFO_ITEM::NETINFO_ITEM( BOARD_ITEM* aParent, const wxString& aNetName, int aNetCode ) :
m_NetCode( aNetCode ), m_Netname( aNetName ), m_ShortNetname( m_Netname.AfterLast( '/' ) )
{ {
SetNet( aNetCode );
if( aNetName.size() )
SetNetname( aNetName );
m_parent = aParent; m_parent = aParent;
m_NbNodes = 0;
m_NbLink = 0;
m_NbNoconn = 0;
m_Flag = 0;
m_RatsnestStartIdx = 0; // Starting point of ratsnests of this net in a m_RatsnestStartIdx = 0; // Starting point of ratsnests of this net in a
// general buffer of ratsnest // general buffer of ratsnest
m_RatsnestEndIdx = 0; // Ending point of ratsnests of this net m_RatsnestEndIdx = 0; // Ending point of ratsnests of this net
m_NetClassName = NETCLASS::Default; m_NetClassName = NETCLASS::Default;
m_NetClass = NULL;
m_NetClass = 0;
} }
@ -77,17 +68,6 @@ NETINFO_ITEM::~NETINFO_ITEM()
} }
/**
* Function SetNetname
* @param aNetname : the new netname
*/
void NETINFO_ITEM::SetNetname( const wxString& aNetname )
{
m_Netname = aNetname;
m_ShortNetname = m_Netname.AfterLast( '/' );
}
/** /**
* Function Draw (TODO) * Function Draw (TODO)
*/ */
@ -121,7 +101,7 @@ void NETINFO_ITEM::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList )
{ {
for( pad = module->Pads(); pad != 0; pad = pad->Next() ) for( pad = module->Pads(); pad != 0; pad = pad->Next() )
{ {
if( pad->GetNet() == GetNet() ) if( pad->GetNetCode() == GetNet() )
{ {
count++; count++;
lengthPadToDie += pad->GetPadToDieLength(); lengthPadToDie += pad->GetPadToDieLength();
@ -139,13 +119,13 @@ void NETINFO_ITEM::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList )
{ {
if( Struct->Type() == PCB_VIA_T ) if( Struct->Type() == PCB_VIA_T )
{ {
if( ( (SEGVIA*) Struct )->GetNet() == GetNet() ) if( ( (SEGVIA*) Struct )->GetNetCode() == GetNet() )
count++; count++;
} }
if( Struct->Type() == PCB_TRACE_T ) if( Struct->Type() == PCB_TRACE_T )
{ {
if( ( (TRACK*) Struct )->GetNet() == GetNet() ) if( ( (TRACK*) Struct )->GetNetCode() == GetNet() )
lengthnet += ( (TRACK*) Struct )->GetLength(); lengthnet += ( (TRACK*) Struct )->GetLength();
} }
} }

View File

@ -1,3 +1,27 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2009 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
* Copyright (C) 1992-2012 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
*/
/** /**
* @file class_netinfolist.cpp * @file class_netinfolist.cpp
*/ */
@ -11,13 +35,17 @@
#include <class_board.h> #include <class_board.h>
#include <class_module.h> #include <class_module.h>
#include <class_pad.h>
#include <class_track.h>
#include <class_zone.h>
#include <class_netinfo.h> #include <class_netinfo.h>
// Constructor and destructor // Constructor and destructor
NETINFO_LIST::NETINFO_LIST( BOARD* aParent ) NETINFO_LIST::NETINFO_LIST( BOARD* aParent ) : m_Parent( aParent )
{ {
m_Parent = aParent; // Make sure that the unconnected net has number 0
AppendNet( new NETINFO_ITEM( aParent, wxEmptyString, 0 ) );
} }
@ -29,23 +57,29 @@ NETINFO_LIST::~NETINFO_LIST()
void NETINFO_LIST::clear() void NETINFO_LIST::clear()
{ {
for( unsigned ii = 0; ii < GetNetCount(); ii++ ) NETNAMES_MAP::iterator it, itEnd;
delete m_NetBuffer[ii]; for( it = m_netNames.begin(), itEnd = m_netNames.end(); it != itEnd; ++it )
delete it->second;
m_NetBuffer.clear();
m_PadsFullList.clear(); m_PadsFullList.clear();
m_netNames.clear();
m_netCodes.clear();
} }
/**
* Function Append
* adds \a aNewElement to the end of the list.
*/
void NETINFO_LIST::AppendNet( NETINFO_ITEM* aNewElement ) void NETINFO_LIST::AppendNet( NETINFO_ITEM* aNewElement )
{ {
m_NetBuffer.push_back( aNewElement ); // negative net code means that it has to be auto assigned
if( aNewElement->m_NetCode < 0 )
const_cast<int&>( aNewElement->m_NetCode ) = getFreeNetCode();
// D(Show();) // net names & codes are supposed to be unique
assert( GetNetItem( aNewElement->GetNetname() ) == NULL );
assert( GetNetItem( aNewElement->GetNet() ) == NULL );
// add an entry for fast look up by a net name using a map
m_netNames.insert( std::make_pair( aNewElement->GetNetname(), aNewElement ) );
m_netCodes.insert( std::make_pair( aNewElement->GetNet(), aNewElement ) );
} }
@ -78,48 +112,31 @@ void NETINFO_LIST::buildListOfNets()
{ {
D_PAD* pad; D_PAD* pad;
int nodes_count = 0; int nodes_count = 0;
NETINFO_ITEM* net_item;
clear(); // Remove all nets info and free memory
// Create and add the "unconnected net", always existing,
// used to handle pads and tracks that are not member of a "real" net
net_item = new NETINFO_ITEM( m_Parent );
AppendNet( net_item );
// Build the PAD list, sorted by net // Build the PAD list, sorted by net
buildPadsFullList(); buildPadsFullList();
// Build netnames list, and create a netcode for each netname // Restore the initial state of NETINFO_ITEMs
D_PAD* last_pad = NULL; for( NETINFO_LIST::iterator net( begin() ), netEnd( end() ); net != netEnd; ++net )
int netcode = 0; net->Clear();
// Assign pads to appropriate NETINFO_ITEMs
for( unsigned ii = 0; ii < m_PadsFullList.size(); ii++ ) for( unsigned ii = 0; ii < m_PadsFullList.size(); ii++ )
{ {
pad = m_PadsFullList[ii]; pad = m_PadsFullList[ii];
if( pad->GetNetname().IsEmpty() ) // pad not connected if( pad->GetNetCode() == NETINFO_LIST::UNCONNECTED ) // pad not connected
{
pad->SetNet( 0 );
continue; continue;
}
/* if the current netname was already found: add pad to the current net_item , // Add pad to the appropriate list of pads
* else create a new net_code and a new net_item NETINFO_ITEM* net = pad->GetNet();
*/ // it should not be possible for BOARD_CONNECTED_ITEM to return NULL as a result of GetNet()
if( last_pad == NULL || ( pad->GetNetname() != last_pad->GetNetname() ) ) wxASSERT( net );
{
netcode++;
net_item = new NETINFO_ITEM( m_Parent, pad->GetNetname(), netcode );
AppendNet( net_item );
}
pad->SetNet( netcode ); if( net )
net_item->m_PadInNetList.push_back( pad ); net->m_PadInNetList.push_back( pad );
nodes_count++; ++nodes_count;
last_pad = pad;
} }
m_Parent->SetNodeCount( nodes_count ); m_Parent->SetNodeCount( nodes_count );
@ -129,18 +146,18 @@ void NETINFO_LIST::buildListOfNets()
m_Parent->m_Status_Pcb |= NET_CODES_OK; m_Parent->m_Status_Pcb |= NET_CODES_OK;
m_Parent->SetAreasNetCodesFromNetNames(); m_Parent->SetAreasNetCodesFromNetNames();
// D( Show(); )
} }
#if defined(DEBUG) #if defined(DEBUG)
void NETINFO_LIST::Show() const void NETINFO_LIST::Show() const
{ {
for( unsigned i=0; i < m_NetBuffer.size(); ++i ) int i = 0;
NETNAMES_MAP::const_iterator it, itEnd;
for( it = m_netNames.begin(), itEnd = m_netNames.end(); it != itEnd; ++it )
{ {
printf( "[%d]: netcode:%d netname:<%s>\n", printf( "[%d]: netcode:%d netname:<%s>\n",
i, m_NetBuffer[i]->GetNet(), i++, it->second->GetNet(),
TO_UTF8( m_NetBuffer[i]->GetNetname() ) ); TO_UTF8( it->second->GetNetname() ) );
} }
} }
#endif #endif
@ -183,3 +200,84 @@ void NETINFO_LIST::buildPadsFullList()
m_Parent->m_Status_Pcb = LISTE_PAD_OK; m_Parent->m_Status_Pcb = LISTE_PAD_OK;
} }
int NETINFO_LIST::getFreeNetCode() const
{
static int m_newNetCode = 0;
do {
if( m_newNetCode < 0 )
m_newNetCode = 0;
} while( m_netCodes.count( ++m_newNetCode ) != 0 );
return m_newNetCode;
}
int NETINFO_MAPPING::Translate( int aNetCode ) const
{
std::map<int, int>::const_iterator value = m_netMapping.find( aNetCode );
if( value != m_netMapping.end() )
return value->second;
// There was no entry for the given net code
return aNetCode;
}
void NETINFO_MAPPING::Update()
{
// Collect all the used nets
std::set<int> nets;
// Be sure that the unconnected gets 0 and is mapped as 0
nets.insert( 0 );
// Zones
for( int i = 0; i < m_board->GetAreaCount(); ++i )
nets.insert( m_board->GetArea( i )->GetNetCode() );
// Tracks
for( TRACK* track = m_board->m_Track; track; track = track->Next() )
nets.insert( track->GetNetCode() );
// Modules/pads
for( MODULE* module = m_board->m_Modules; module; module = module->Next() )
{
for( D_PAD* pad = module->Pads().GetFirst(); pad; pad = pad->Next() )
{
nets.insert( pad->GetNetCode() );
}
}
// Segzones
for( SEGZONE* zone = m_board->m_Zone; zone; zone = zone->Next() )
nets.insert( zone->GetNetCode() );
// Prepare the new mapping
m_netMapping.clear();
// Now the nets variable stores all the used net codes (not only for pads) and we are ready to
// assign new consecutive net numbers
int newNetCode = 0;
for( std::set<int>::const_iterator it = nets.begin(), itEnd = nets.end(); it != itEnd; ++it )
m_netMapping[*it] = newNetCode++;
}
NETINFO_ITEM* NETINFO_MAPPING::iterator::operator*() const
{
return m_mapping->m_board->FindNet( m_iterator->first );
}
NETINFO_ITEM* NETINFO_MAPPING::iterator::operator->() const
{
return m_mapping->m_board->FindNet( m_iterator->first );
}
const int NETINFO_LIST::UNCONNECTED = 0;
NETINFO_ITEM NETINFO_LIST::ORPHANED = NETINFO_ITEM( NULL, wxEmptyString, NETINFO_LIST::UNCONNECTED );

View File

@ -364,13 +364,6 @@ void D_PAD::SetPadName( const wxString& name )
} }
void D_PAD::SetNetname( const wxString& aNetname )
{
m_Netname = aNetname;
m_ShortNetname = m_Netname.AfterLast( '/' );
}
void D_PAD::Copy( D_PAD* source ) void D_PAD::Copy( D_PAD* source )
{ {
if( source == NULL ) if( source == NULL )
@ -380,7 +373,7 @@ void D_PAD::Copy( D_PAD* source )
m_layerMask = source->m_layerMask; m_layerMask = source->m_layerMask;
m_NumPadName = source->m_NumPadName; m_NumPadName = source->m_NumPadName;
SetNet( source->GetNet() ); m_netinfo = source->m_netinfo;
m_Drill = source->m_Drill; m_Drill = source->m_Drill;
m_drillShape = source->m_drillShape; m_drillShape = source->m_drillShape;
m_Offset = source->m_Offset; m_Offset = source->m_Offset;
@ -402,8 +395,6 @@ void D_PAD::Copy( D_PAD* source )
SetSubRatsnest( 0 ); SetSubRatsnest( 0 );
SetSubNet( 0 ); SetSubNet( 0 );
m_Netname = source->m_Netname;
m_ShortNetname = source->m_ShortNetname;
} }
@ -412,7 +403,7 @@ void D_PAD::CopyNetlistSettings( D_PAD* aPad )
// Don't do anything foolish like trying to copy to yourself. // Don't do anything foolish like trying to copy to yourself.
wxCHECK_RET( aPad != NULL && aPad != this, wxT( "Cannot copy to NULL or yourself." ) ); wxCHECK_RET( aPad != NULL && aPad != this, wxT( "Cannot copy to NULL or yourself." ) );
aPad->SetNetname( GetNetname() ); aPad->SetNetCode( GetNetCode() );
aPad->SetLocalClearance( m_LocalClearance ); aPad->SetLocalClearance( m_LocalClearance );
aPad->SetLocalSolderMaskMargin( m_LocalSolderMaskMargin ); aPad->SetLocalSolderMaskMargin( m_LocalSolderMaskMargin );
@ -577,7 +568,7 @@ void D_PAD::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM>& aList )
aList.push_back( MSG_PANEL_ITEM( _( "Pad" ), Line, BROWN ) ); aList.push_back( MSG_PANEL_ITEM( _( "Pad" ), Line, BROWN ) );
} }
aList.push_back( MSG_PANEL_ITEM( _( "Net" ), m_Netname, DARKCYAN ) ); aList.push_back( MSG_PANEL_ITEM( _( "Net" ), GetNetname(), DARKCYAN ) );
/* For test and debug only: display m_physical_connexion and /* For test and debug only: display m_physical_connexion and
* m_logical_connexion */ * m_logical_connexion */

View File

@ -118,24 +118,6 @@ public:
return m_NumPadName == other->m_NumPadName; // hide tricks behind sensible API return m_NumPadName == other->m_NumPadName; // hide tricks behind sensible API
} }
/**
* Function SetNetname
* @param aNetname: the new netname
*/
void SetNetname( const wxString& aNetname );
/**
* Function GetNetname
* @return const wxString& - the full netname
*/
const wxString& GetNetname() const { return m_Netname; }
/**
* Function GetShortNetname
* @return const wxString& - the short netname
*/
const wxString& GetShortNetname() const { return m_ShortNetname; }
/** /**
* Function GetShape * Function GetShape
* @return the shape of this pad. * @return the shape of this pad.
@ -470,10 +452,6 @@ private:
int m_boundingRadius; ///< radius of the circle containing the pad shape int m_boundingRadius; ///< radius of the circle containing the pad shape
wxString m_Netname; ///< Full net name like /mysheet/mysubsheet/vout used by Eeschema
wxString m_ShortNetname; ///< short net name, like vout from /mysheet/mysubsheet/vout
/// Pad name (4 char) or a long identifier (used in pad name /// Pad name (4 char) or a long identifier (used in pad name
/// comparisons because this is faster than string comparison) /// comparisons because this is faster than string comparison)
union union

View File

@ -473,7 +473,7 @@ void D_PAD::DrawShape( EDA_RECT* aClipBox, wxDC* aDC, PAD_DRAWINFO& aDrawInfo )
GRSetDrawMode( aDC, aDrawInfo.m_DrawMode ); GRSetDrawMode( aDC, aDrawInfo.m_DrawMode );
// Draw "No connect" ( / or \ or cross X ) if necessary // Draw "No connect" ( / or \ or cross X ) if necessary
if( m_Netname.IsEmpty() && aDrawInfo.m_ShowNCMark ) if( GetNetCode() == 0 && aDrawInfo.m_ShowNCMark )
{ {
int dx0 = std::min( halfsize.x, halfsize.y ); int dx0 = std::min( halfsize.x, halfsize.y );
EDA_COLOR_T nc_color = BLUE; EDA_COLOR_T nc_color = BLUE;
@ -499,7 +499,7 @@ void D_PAD::DrawShape( EDA_RECT* aClipBox, wxDC* aDC, PAD_DRAWINFO& aDrawInfo )
wxPoint tpos0 = shape_pos; // Position of the centre of text wxPoint tpos0 = shape_pos; // Position of the centre of text
wxPoint tpos = tpos0; wxPoint tpos = tpos0;
wxSize AreaSize; // size of text area, normalized to AreaSize.y < AreaSize.x wxSize AreaSize; // size of text area, normalized to AreaSize.y < AreaSize.x
int shortname_len = m_ShortNetname.Len(); int shortname_len = GetShortNetname().Len();
if( !aDrawInfo.m_Display_netname ) if( !aDrawInfo.m_Display_netname )
shortname_len = 0; shortname_len = 0;
@ -583,7 +583,7 @@ void D_PAD::DrawShape( EDA_RECT* aClipBox, wxDC* aDC, PAD_DRAWINFO& aDrawInfo )
tsize = ( tsize * 7 ) / 10; tsize = ( tsize * 7 ) / 10;
DrawGraphicHaloText( clipBox, aDC, tpos, DrawGraphicHaloText( clipBox, aDC, tpos,
aDrawInfo.m_Color, BLACK, WHITE, aDrawInfo.m_Color, BLACK, WHITE,
m_ShortNetname, t_angle, GetShortNetname(), t_angle,
wxSize( tsize, tsize ), GR_TEXT_HJUSTIFY_CENTER, wxSize( tsize, tsize ), GR_TEXT_HJUSTIFY_CENTER,
GR_TEXT_VJUSTIFY_CENTER, tsize / 7, false, false ); GR_TEXT_VJUSTIFY_CENTER, tsize / 7, false, false );
} }

View File

@ -415,6 +415,18 @@ EDA_ITEM* TEXTE_MODULE::Clone() const
} }
const BOX2I TEXTE_MODULE::ViewBBox() const
{
double angle = GetDrawRotation();
EDA_RECT text_area = GetTextBox( -1, -1 );
if( angle )
text_area = text_area.GetBoundingBoxRotated( m_Pos, angle );
return BOX2I( text_area.GetPosition(), text_area.GetSize() );
}
void TEXTE_MODULE::ViewGetLayers( int aLayers[], int& aCount ) const void TEXTE_MODULE::ViewGetLayers( int aLayers[], int& aCount ) const
{ {
if( m_NoShow ) // Hidden text if( m_NoShow ) // Hidden text

View File

@ -165,6 +165,9 @@ public:
EDA_ITEM* Clone() const; EDA_ITEM* Clone() const;
/// @copydoc VIEW_ITEM::ViewBBox()
virtual const BOX2I ViewBBox() const;
/// @copydoc VIEW_ITEM::ViewGetLayers() /// @copydoc VIEW_ITEM::ViewGetLayers()
virtual void ViewGetLayers( int aLayers[], int& aCount ) const; virtual void ViewGetLayers( int aLayers[], int& aCount ) const;

View File

@ -160,15 +160,11 @@ EDA_ITEM* SEGZONE::Clone() const
wxString SEGZONE::GetSelectMenuText() const wxString SEGZONE::GetSelectMenuText() const
{ {
wxString text, nettxt; wxString text, nettxt;
NETINFO_ITEM* net;
BOARD* board = GetBoard(); BOARD* board = GetBoard();
if( board ) if( board )
{ {
net = board->FindNet( GetNet() ); nettxt = GetNetname();
if( net )
nettxt = net->GetNetname();
} }
else else
{ {
@ -201,7 +197,6 @@ wxString SEGVIA::GetSelectMenuText() const
{ {
wxString text; wxString text;
wxString format; wxString format;
NETINFO_ITEM* net;
BOARD* board = GetBoard(); BOARD* board = GetBoard();
int shape = GetShape(); int shape = GetShape();
@ -215,18 +210,14 @@ wxString SEGVIA::GetSelectMenuText() const
if( board ) if( board )
{ {
net = board->FindNet( GetNet() ); wxString netname = GetNetname();
wxString netname;
if( net )
netname = net->GetNetname();
// say which layers, only two for now // say which layers, only two for now
LAYER_NUM topLayer; LAYER_NUM topLayer;
LAYER_NUM botLayer; LAYER_NUM botLayer;
ReturnLayerPair( &topLayer, &botLayer ); ReturnLayerPair( &topLayer, &botLayer );
text.Printf( format.GetData(), GetChars( ShowWidth() ), text.Printf( format.GetData(), GetChars( ShowWidth() ),
GetChars( netname ), GetNet(), GetChars( netname ), GetNetCode(),
GetChars( board->GetLayerName( topLayer ) ), GetChars( board->GetLayerName( topLayer ) ),
GetChars( board->GetLayerName( botLayer ) ) ); GetChars( board->GetLayerName( botLayer ) ) );
@ -496,7 +487,7 @@ TRACK* TRACK::GetBestInsertPoint( BOARD* aPcb )
for( ; track; track = track->Next() ) for( ; track; track = track->Next() )
{ {
if( GetNet() <= track->GetNet() ) if( GetNetCode() <= track->GetNetCode() )
return track; return track;
} }
@ -510,14 +501,14 @@ TRACK* TRACK::GetStartNetCode( int NetCode )
int ii = 0; int ii = 0;
if( NetCode == -1 ) if( NetCode == -1 )
NetCode = GetNet(); NetCode = GetNetCode();
while( Track != NULL ) while( Track != NULL )
{ {
if( Track->GetNet() > NetCode ) if( Track->GetNetCode() > NetCode )
break; break;
if( Track->GetNet() == NetCode ) if( Track->GetNetCode() == NetCode )
{ {
ii++; ii++;
break; break;
@ -542,19 +533,19 @@ TRACK* TRACK::GetEndNetCode( int NetCode )
return NULL; return NULL;
if( NetCode == -1 ) if( NetCode == -1 )
NetCode = GetNet(); NetCode = GetNetCode();
while( Track != NULL ) while( Track != NULL )
{ {
NextS = (TRACK*) Track->Pnext; NextS = (TRACK*) Track->Pnext;
if( Track->GetNet() == NetCode ) if( Track->GetNetCode() == NetCode )
ii++; ii++;
if( NextS == NULL ) if( NextS == NULL )
break; break;
if( NextS->GetNet() > NetCode ) if( NextS->GetNetCode() > NetCode )
break; break;
Track = NextS; Track = NextS;
@ -690,10 +681,10 @@ void TRACK::Draw( EDA_DRAW_PANEL* panel, wxDC* aDC, GR_DRAWMODE aDrawMode,
if( aDC->LogicalToDeviceXRel( m_Width ) < MIN_TEXT_SIZE ) if( aDC->LogicalToDeviceXRel( m_Width ) < MIN_TEXT_SIZE )
return; return;
if( GetNet() == 0 ) if( GetNetCode() == NETINFO_LIST::UNCONNECTED )
return; return;
NETINFO_ITEM* net = ( (BOARD*) GetParent() )->FindNet( GetNet() ); NETINFO_ITEM* net = GetNet();
if( net == NULL ) if( net == NULL )
return; return;
@ -952,13 +943,13 @@ void SEGVIA::Draw( EDA_DRAW_PANEL* panel, wxDC* aDC, GR_DRAWMODE aDrawMode,
} }
// Display the short netname: // Display the short netname:
if( GetNet() == 0 ) if( GetNetCode() == NETINFO_LIST::UNCONNECTED )
return; return;
if( DisplayOpt.DisplayNetNamesMode == 0 || DisplayOpt.DisplayNetNamesMode == 1 ) if( DisplayOpt.DisplayNetNamesMode == 0 || DisplayOpt.DisplayNetNamesMode == 1 )
return; return;
NETINFO_ITEM* net = ( (BOARD*) GetParent() )->FindNet( GetNet() ); NETINFO_ITEM* net = GetNet();
if( net == NULL ) if( net == NULL )
return; return;
@ -1095,7 +1086,7 @@ void TRACK::GetMsgPanelInfoBase( std::vector< MSG_PANEL_ITEM >& aList )
// Display Net Name (in Pcbnew) // Display Net Name (in Pcbnew)
if( board ) if( board )
{ {
NETINFO_ITEM* net = board->FindNet( GetNet() ); NETINFO_ITEM* net = GetNet();
if( net ) if( net )
msg = net->GetNetname(); msg = net->GetNetname();
@ -1105,7 +1096,7 @@ void TRACK::GetMsgPanelInfoBase( std::vector< MSG_PANEL_ITEM >& aList )
aList.push_back( MSG_PANEL_ITEM( _( "NetName" ), msg, RED ) ); aList.push_back( MSG_PANEL_ITEM( _( "NetName" ), msg, RED ) );
/* Display net code : (useful in test or debug) */ /* Display net code : (useful in test or debug) */
msg.Printf( wxT( "%d.%d" ), GetNet(), GetSubNet() ); msg.Printf( wxT( "%d.%d" ), GetNetCode(), GetSubNet() );
aList.push_back( MSG_PANEL_ITEM( _( "NetCode" ), msg, RED ) ); aList.push_back( MSG_PANEL_ITEM( _( "NetCode" ), msg, RED ) );
} }
@ -1576,7 +1567,7 @@ wxString TRACK::GetSelectMenuText() const
// disambiguate all the choices under the cursor! // disambiguate all the choices under the cursor!
if( board ) if( board )
{ {
net = board->FindNet( GetNet() ); net = GetNet();
if( net ) if( net )
netname = net->GetNetname(); netname = net->GetNetname();
@ -1591,7 +1582,7 @@ wxString TRACK::GetSelectMenuText() const
text.Printf( _("Track %s, net [%s] (%d) on layer %s, length: %s" ), text.Printf( _("Track %s, net [%s] (%d) on layer %s, length: %s" ),
GetChars( ShowWidth() ), GetChars( netname ), GetChars( ShowWidth() ), GetChars( netname ),
GetNet(), GetChars( GetLayerName() ), GetNetCode(), GetChars( GetLayerName() ),
GetChars( ::LengthDoubleToString( GetLength() ) ) ); GetChars( ::LengthDoubleToString( GetLength() ) ) );
return text; return text;

View File

@ -53,7 +53,6 @@
ZONE_CONTAINER::ZONE_CONTAINER( BOARD* aBoard ) : ZONE_CONTAINER::ZONE_CONTAINER( BOARD* aBoard ) :
BOARD_CONNECTED_ITEM( aBoard, PCB_ZONE_AREA_T ) BOARD_CONNECTED_ITEM( aBoard, PCB_ZONE_AREA_T )
{ {
SetNet( -1 ); // Net number for fast comparisons
m_CornerSelection = -1; m_CornerSelection = -1;
m_IsFilled = false; // fill status : true when the zone is filled m_IsFilled = false; // fill status : true when the zone is filled
m_FillMode = 0; // How to fill areas: 0 = use filled polygons, != 0 fill with segments m_FillMode = 0; // How to fill areas: 0 = use filled polygons, != 0 fill with segments
@ -75,7 +74,7 @@ ZONE_CONTAINER::ZONE_CONTAINER( const ZONE_CONTAINER& aZone ) :
BOARD_CONNECTED_ITEM( aZone ) BOARD_CONNECTED_ITEM( aZone )
{ {
// Should the copy be on the same net? // Should the copy be on the same net?
SetNet( aZone.GetNet() ); SetNetCode( aZone.GetNetCode() );
m_Poly = new CPolyLine( *aZone.m_Poly ); m_Poly = new CPolyLine( *aZone.m_Poly );
// For corner moving, corner index to drag, or -1 if no selection // For corner moving, corner index to drag, or -1 if no selection
@ -138,31 +137,6 @@ const wxPoint& ZONE_CONTAINER::GetPosition() const
} }
void ZONE_CONTAINER::SetNet( int aNetCode )
{
BOARD_CONNECTED_ITEM::SetNet( aNetCode );
if( aNetCode < 0 )
return;
BOARD* board = GetBoard();
if( board )
{
NETINFO_ITEM* net = board->FindNet( aNetCode );
if( net )
m_Netname = net->GetNetname();
else
m_Netname.Empty();
}
else
{
m_Netname.Empty();
}
}
void ZONE_CONTAINER::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE aDrawMode, void ZONE_CONTAINER::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE aDrawMode,
const wxPoint& offset ) const wxPoint& offset )
{ {
@ -614,10 +588,6 @@ void ZONE_CONTAINER::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList )
{ {
wxString msg; wxString msg;
BOARD* board = (BOARD*) m_Parent;
wxASSERT( board );
msg = _( "Zone Outline" ); msg = _( "Zone Outline" );
// Display Cutout instead of Outline for holes inside a zone // Display Cutout instead of Outline for holes inside a zone
@ -646,9 +616,9 @@ void ZONE_CONTAINER::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList )
} }
else if( IsOnCopperLayer() ) else if( IsOnCopperLayer() )
{ {
if( GetNet() >= 0 ) if( GetNetCode() >= 0 )
{ {
NETINFO_ITEM* equipot = board->FindNet( GetNet() ); NETINFO_ITEM* equipot = GetNet();
if( equipot ) if( equipot )
msg = equipot->GetNetname(); msg = equipot->GetNetname();
@ -658,7 +628,7 @@ void ZONE_CONTAINER::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList )
else // a netcode < 0 is an error else // a netcode < 0 is an error
{ {
msg = wxT( " [" ); msg = wxT( " [" );
msg << m_Netname + wxT( "]" ); msg << GetNetname() + wxT( "]" );
msg << wxT( " <" ) << _( "Not Found" ) << wxT( ">" ); msg << wxT( " <" ) << _( "Not Found" ) << wxT( ">" );
} }
@ -666,7 +636,7 @@ void ZONE_CONTAINER::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList )
#if 1 #if 1
// Display net code : (useful in test or debug) // Display net code : (useful in test or debug)
msg.Printf( wxT( "%d" ), GetNet() ); msg.Printf( wxT( "%d" ), GetNetCode() );
aList.push_back( MSG_PANEL_ITEM( _( "NetCode" ), msg, RED ) ); aList.push_back( MSG_PANEL_ITEM( _( "NetCode" ), msg, RED ) );
#endif #endif
@ -827,7 +797,7 @@ void ZONE_CONTAINER::Copy( ZONE_CONTAINER* src )
{ {
m_Parent = src->m_Parent; m_Parent = src->m_Parent;
m_Layer = src->m_Layer; m_Layer = src->m_Layer;
SetNet( src->GetNet() ); SetNetCode( src->GetNetCode() );
SetTimeStamp( src->m_TimeStamp ); SetTimeStamp( src->m_TimeStamp );
m_Poly->RemoveAllContours(); m_Poly->RemoveAllContours();
m_Poly->Copy( src->m_Poly ); // copy outlines m_Poly->Copy( src->m_Poly ); // copy outlines
@ -849,20 +819,6 @@ void ZONE_CONTAINER::Copy( ZONE_CONTAINER* src )
} }
bool ZONE_CONTAINER::SetNetNameFromNetCode( void )
{
NETINFO_ITEM* net;
if( m_Parent && ( net = ( (BOARD*) m_Parent )->FindNet( GetNet() ) ) )
{
m_Netname = net->GetNetname();
return true;
}
return false;
}
ZoneConnection ZONE_CONTAINER::GetPadConnection( D_PAD* aPad ) const ZoneConnection ZONE_CONTAINER::GetPadConnection( D_PAD* aPad ) const
{ {
if( aPad == NULL || aPad->GetZoneConnection() == UNDEFINED_CONNECTION ) if( aPad == NULL || aPad->GetZoneConnection() == UNDEFINED_CONNECTION )
@ -909,11 +865,11 @@ wxString ZONE_CONTAINER::GetSelectMenuText() const
// Display net name for copper zones // Display net name for copper zones
if( !GetIsKeepout() ) if( !GetIsKeepout() )
{ {
if( GetNet() >= 0 ) if( GetNetCode() >= 0 )
{ {
if( board ) if( board )
{ {
net = board->FindNet( GetNet() ); net = GetNet();
if( net ) if( net )
{ {
@ -928,7 +884,7 @@ wxString ZONE_CONTAINER::GetSelectMenuText() const
else else
{ // A netcode < 0 is an error: { // A netcode < 0 is an error:
// Netname not found or area not initialised // Netname not found or area not initialised
text << wxT( " [" ) << m_Netname << wxT( "]" ); text << wxT( " [" ) << GetNetname() << wxT( "]" );
text << wxT( " <" ) << _( "Not Found" ) << wxT( ">" ); text << wxT( " <" ) << _( "Not Found" ) << wxT( ">" );
} }
} }

View File

@ -186,31 +186,6 @@ public:
return ( GetLayer() < FIRST_NON_COPPER_LAYER ) ? true : false; return ( GetLayer() < FIRST_NON_COPPER_LAYER ) ? true : false;
} }
/**
* Function SetNet
* sets the netcode and the netname.
*
* @param aNetCode The net code of the zone container if greater than or equal to
* zero. Otherwise the current net code is kept and set the net
* code error flag.
*/
virtual void SetNet( int aNetCode );
/**
* Function SetNetNameFromNetCode
* Find the net name corresponding to the net code.
* @return bool - true if net found, else false
*/
bool SetNetNameFromNetCode( void );
/**
* Function GetNetName
* returns the net name.
* @return const wxString& - The net name.
*/
const wxString& GetNetName() const { return m_Netname; };
void SetNetName( const wxString& aName ) { m_Netname = aName; }
/// How to fill areas: 0 = use filled polygons, 1 => fill with segments. /// How to fill areas: 0 = use filled polygons, 1 => fill with segments.
void SetFillMode( int aFillMode ) { m_FillMode = aFillMode; } void SetFillMode( int aFillMode ) { m_FillMode = aFillMode; }
int GetFillMode() const { return m_FillMode; } int GetFillMode() const { return m_FillMode; }
@ -607,7 +582,6 @@ public:
private: private:
CPolyLine* m_Poly; ///< Outline of the zone. CPolyLine* m_Poly; ///< Outline of the zone.
wxString m_Netname; ///< Name of the net assigned to the zone.
CPolyLine* m_smoothedPoly; // Corner-smoothed version of m_Poly CPolyLine* m_smoothedPoly; // Corner-smoothed version of m_Poly
int m_cornerSmoothingType; int m_cornerSmoothingType;
unsigned int m_cornerRadius; unsigned int m_cornerRadius;

View File

@ -76,7 +76,7 @@ ZONE_SETTINGS& ZONE_SETTINGS::operator << ( const ZONE_CONTAINER& aSource )
m_FillMode = aSource.GetFillMode(); m_FillMode = aSource.GetFillMode();
m_ZoneClearance = aSource.GetClearance(); m_ZoneClearance = aSource.GetClearance();
m_ZoneMinThickness = aSource.GetMinThickness(); m_ZoneMinThickness = aSource.GetMinThickness();
m_NetcodeSelection = aSource.GetNet(); m_NetcodeSelection = aSource.GetNetCode();
m_CurrentZone_Layer = aSource.GetLayer(); m_CurrentZone_Layer = aSource.GetLayer();
m_Zone_HatchingStyle = aSource.GetHatchStyle(); m_Zone_HatchingStyle = aSource.GetHatchStyle();
m_ArcToSegmentsCount = aSource.GetArcSegmentCount(); m_ArcToSegmentsCount = aSource.GetArcSegmentCount();
@ -113,7 +113,7 @@ void ZONE_SETTINGS::ExportSetting( ZONE_CONTAINER& aTarget, bool aFullExport ) c
if( aFullExport ) if( aFullExport )
{ {
aTarget.SetPriority( m_ZonePriority ); aTarget.SetPriority( m_ZonePriority );
aTarget.SetNet( m_NetcodeSelection ); aTarget.SetNetCode( m_NetcodeSelection );
aTarget.SetLayer( m_CurrentZone_Layer ); aTarget.SetLayer( m_CurrentZone_Layer );
aTarget.Outline()->SetLayer( m_CurrentZone_Layer ); aTarget.Outline()->SetLayer( m_CurrentZone_Layer );
} }

View File

@ -323,14 +323,14 @@ bool TRACKS_CLEANER::deleteUnconnectedTracks()
zone = m_Brd->HitTestForAnyFilledArea( track->GetStart(), zone = m_Brd->HitTestForAnyFilledArea( track->GetStart(),
track->GetLayer(), track->GetLayer(),
track->GetLayer(), track->GetLayer(),
track->GetNet() ); track->GetNetCode() );
} }
else else
{ {
((SEGVIA*)track)->ReturnLayerPair( &top_layer, &bottom_layer ); ((SEGVIA*)track)->ReturnLayerPair( &top_layer, &bottom_layer );
zone = m_Brd->HitTestForAnyFilledArea( track->GetStart(), zone = m_Brd->HitTestForAnyFilledArea( track->GetStart(),
top_layer, bottom_layer, top_layer, bottom_layer,
track->GetNet() ); track->GetNetCode() );
} }
} }
@ -359,7 +359,7 @@ bool TRACKS_CLEANER::deleteUnconnectedTracks()
zone = m_Brd->HitTestForAnyFilledArea( via->GetStart(), zone = m_Brd->HitTestForAnyFilledArea( via->GetStart(),
bottom_layer, bottom_layer,
top_layer, top_layer,
via->GetNet() ); via->GetNetCode() );
} }
if( (other == NULL) && (zone == NULL) ) if( (other == NULL) && (zone == NULL) )
@ -383,14 +383,14 @@ bool TRACKS_CLEANER::deleteUnconnectedTracks()
zone = m_Brd->HitTestForAnyFilledArea( track->GetEnd(), zone = m_Brd->HitTestForAnyFilledArea( track->GetEnd(),
track->GetLayer(), track->GetLayer(),
track->GetLayer(), track->GetLayer(),
track->GetNet() ); track->GetNetCode() );
} }
else else
{ {
((SEGVIA*)track)->ReturnLayerPair( &top_layer, &bottom_layer ); ((SEGVIA*)track)->ReturnLayerPair( &top_layer, &bottom_layer );
zone = m_Brd->HitTestForAnyFilledArea( track->GetEnd(), zone = m_Brd->HitTestForAnyFilledArea( track->GetEnd(),
top_layer, bottom_layer, top_layer, bottom_layer,
track->GetNet() ); track->GetNetCode() );
} }
} }
@ -419,7 +419,7 @@ bool TRACKS_CLEANER::deleteUnconnectedTracks()
via->ReturnLayerPair( &top_layer, &bottom_layer ); via->ReturnLayerPair( &top_layer, &bottom_layer );
zone = m_Brd->HitTestForAnyFilledArea( via->GetEnd(), zone = m_Brd->HitTestForAnyFilledArea( via->GetEnd(),
bottom_layer, top_layer, bottom_layer, top_layer,
via->GetNet() ); via->GetNetCode() );
} }
if( (other == NULL) && (zone == NULL) ) if( (other == NULL) && (zone == NULL) )
@ -479,7 +479,7 @@ bool TRACKS_CLEANER::clean_segments()
if( segment->GetLayer() != other->GetLayer() ) if( segment->GetLayer() != other->GetLayer() )
continue; continue;
if( segment->GetNet() != other->GetNet() ) if( segment->GetNetCode() != other->GetNetCode() )
break; break;
if( ( segment->GetStart() == other->GetStart() ) && if( ( segment->GetStart() == other->GetStart() ) &&
@ -748,14 +748,14 @@ bool PCB_EDIT_FRAME::RemoveMisConnectedTracks()
if( segment->start && segment->start->Type()==PCB_PAD_T ) if( segment->start && segment->start->Type()==PCB_PAD_T )
{ {
// get the netcode of the pad to propagate. // get the netcode of the pad to propagate.
net_code_s = ((D_PAD*)(segment->start))->GetNet(); net_code_s = ((D_PAD*)(segment->start))->GetNetCode();
} }
else else
{ {
other = segment->GetTrace( GetBoard()->m_Track, NULL, FLG_START ); other = segment->GetTrace( GetBoard()->m_Track, NULL, FLG_START );
if( other ) if( other )
net_code_s = other->GetNet(); net_code_s = other->GetNetCode();
} }
if( net_code_s < 0 ) if( net_code_s < 0 )
@ -766,14 +766,14 @@ bool PCB_EDIT_FRAME::RemoveMisConnectedTracks()
if( segment->end && segment->end->Type()==PCB_PAD_T ) if( segment->end && segment->end->Type()==PCB_PAD_T )
{ {
net_code_e = ((D_PAD*)(segment->end))->GetNet(); net_code_e = ((D_PAD*)(segment->end))->GetNetCode();
} }
else else
{ {
other = segment->GetTrace( GetBoard()->m_Track, NULL, FLG_END ); other = segment->GetTrace( GetBoard()->m_Track, NULL, FLG_END );
if( other ) if( other )
net_code_e = other->GetNet(); net_code_e = other->GetNetCode();
} }
if( net_code_e < 0 ) if( net_code_e < 0 )

View File

@ -718,7 +718,7 @@ void PCB_BASE_FRAME::TestConnections()
for( TRACK* track = m_Pcb->m_Track; track; ) for( TRACK* track = m_Pcb->m_Track; track; )
{ {
// At this point, track is the first track of a given net // At this point, track is the first track of a given net
current_net_code = track->GetNet(); current_net_code = track->GetNetCode();
// Get last track of the current net // Get last track of the current net
TRACK* lastTrack = track->GetEndNetCode( current_net_code ); TRACK* lastTrack = track->GetEndNetCode( current_net_code );
@ -760,7 +760,7 @@ void PCB_BASE_FRAME::TestNetConnection( wxDC* aDC, int aNetCode )
for( unsigned i = 0; i < m_Pcb->GetPadCount(); ++i ) for( unsigned i = 0; i < m_Pcb->GetPadCount(); ++i )
{ {
D_PAD* pad = m_Pcb->GetPad(i); D_PAD* pad = m_Pcb->GetPad(i);
int pad_net_code = pad->GetNet(); int pad_net_code = pad->GetNetCode();
if( pad_net_code < aNetCode ) if( pad_net_code < aNetCode )
continue; continue;
@ -786,7 +786,7 @@ void PCB_BASE_FRAME::TestNetConnection( wxDC* aDC, int aNetCode )
if( firstTrack && lastTrack ) // i.e. if there are segments if( firstTrack && lastTrack ) // i.e. if there are segments
{ {
connections.Build_CurrNet_SubNets_Connections( firstTrack, lastTrack, firstTrack->GetNet() ); connections.Build_CurrNet_SubNets_Connections( firstTrack, lastTrack, firstTrack->GetNetCode() );
} }
} }
@ -842,7 +842,7 @@ void PCB_BASE_FRAME::RecalculateAllTracksNetcode()
curr_track->end = NULL; curr_track->end = NULL;
curr_track->SetState( BUSY | IN_EDIT | BEGIN_ONPAD | END_ONPAD, false ); curr_track->SetState( BUSY | IN_EDIT | BEGIN_ONPAD | END_ONPAD, false );
curr_track->SetZoneSubNet( 0 ); curr_track->SetZoneSubNet( 0 );
curr_track->SetNet( 0 ); // net code = 0 means not connected curr_track->SetNetCode( NETINFO_LIST::UNCONNECTED );
} }
// If no pad, reset pointers and netcode, and do nothing else // If no pad, reset pointers and netcode, and do nothing else
@ -863,7 +863,7 @@ void PCB_BASE_FRAME::RecalculateAllTracksNetcode()
for( ; curr_track != NULL; curr_track = curr_track->Next() ) for( ; curr_track != NULL; curr_track = curr_track->Next() )
{ {
if( curr_track->m_PadsConnected.size() ) if( curr_track->m_PadsConnected.size() )
curr_track->SetNet( curr_track->m_PadsConnected[0]->GetNet() ); curr_track->SetNetCode( curr_track->m_PadsConnected[0]->GetNetCode() );
} }
// Pass 2: build connections between track ends // Pass 2: build connections between track ends
@ -883,17 +883,17 @@ void PCB_BASE_FRAME::RecalculateAllTracksNetcode()
for( curr_track = m_Pcb->m_Track; curr_track; curr_track = curr_track->Next() ) for( curr_track = m_Pcb->m_Track; curr_track; curr_track = curr_track->Next() )
{ {
int netcode = curr_track->GetNet(); int netcode = curr_track->GetNetCode();
if( netcode == 0 ) if( netcode == 0 )
{ // try to find a connected item having a netcode { // try to find a connected item having a netcode
for( unsigned kk = 0; kk < curr_track->m_TracksConnected.size(); kk++ ) for( unsigned kk = 0; kk < curr_track->m_TracksConnected.size(); kk++ )
{ {
int altnetcode = curr_track->m_TracksConnected[kk]->GetNet(); int altnetcode = curr_track->m_TracksConnected[kk]->GetNetCode();
if( altnetcode ) if( altnetcode )
{ {
new_pass_request = true; new_pass_request = true;
netcode = altnetcode; netcode = altnetcode;
curr_track->SetNet(netcode); curr_track->SetNetCode(netcode);
break; break;
} }
} }
@ -902,10 +902,10 @@ void PCB_BASE_FRAME::RecalculateAllTracksNetcode()
{ // propagate this netcode to connected tracks having no netcode { // propagate this netcode to connected tracks having no netcode
for( unsigned kk = 0; kk < curr_track->m_TracksConnected.size(); kk++ ) for( unsigned kk = 0; kk < curr_track->m_TracksConnected.size(); kk++ )
{ {
int altnetcode = curr_track->m_TracksConnected[kk]->GetNet(); int altnetcode = curr_track->m_TracksConnected[kk]->GetNetCode();
if( altnetcode == 0 ) if( altnetcode == 0 )
{ {
curr_track->m_TracksConnected[kk]->SetNet(netcode); curr_track->m_TracksConnected[kk]->SetNetCode(netcode);
new_pass_request = true; new_pass_request = true;
} }
} }
@ -926,10 +926,10 @@ void PCB_BASE_FRAME::RecalculateAllTracksNetcode()
static bool SortTracksByNetCode( const TRACK* const & ref, const TRACK* const & compare ) static bool SortTracksByNetCode( const TRACK* const & ref, const TRACK* const & compare )
{ {
// For items having the same Net, keep the order in list // For items having the same Net, keep the order in list
if( ref->GetNet() == compare->GetNet()) if( ref->GetNetCode() == compare->GetNetCode())
return ref->m_Param < compare->m_Param; return ref->m_Param < compare->m_Param;
return ref->GetNet() < compare->GetNet(); return ref->GetNetCode() < compare->GetNetCode();
} }
/** /**

View File

@ -87,7 +87,7 @@ void PCB_EDIT_FRAME::ExecuteRemoteCommand( const char* cmdline )
if( pad ) if( pad )
{ {
netcode = pad->GetNet(); netcode = pad->GetNetCode();
// put cursor on the pad: // put cursor on the pad:
pos = pad->GetPosition(); pos = pad->GetPosition();

View File

@ -120,7 +120,7 @@ TRACK* PCB_EDIT_FRAME::Delete_Segment( wxDC* DC, TRACK* aTrack )
return NULL; return NULL;
} }
current_net_code = aTrack->GetNet(); current_net_code = aTrack->GetNetCode();
DLIST<TRACK>* container = (DLIST<TRACK>*)aTrack->GetList(); DLIST<TRACK>* container = (DLIST<TRACK>*)aTrack->GetList();
wxASSERT( container ); wxASSERT( container );
@ -142,7 +142,7 @@ void PCB_EDIT_FRAME::Delete_Track( wxDC* DC, TRACK* aTrack )
{ {
if( aTrack != NULL ) if( aTrack != NULL )
{ {
int current_net_code = aTrack->GetNet(); int current_net_code = aTrack->GetNetCode();
Remove_One_Track( DC, aTrack ); Remove_One_Track( DC, aTrack );
OnModify(); OnModify();
TestNetConnection( DC, current_net_code ); TestNetConnection( DC, current_net_code );
@ -160,7 +160,7 @@ void PCB_EDIT_FRAME::Delete_net( wxDC* DC, TRACK* aTrack )
PICKED_ITEMS_LIST itemsList; PICKED_ITEMS_LIST itemsList;
ITEM_PICKER picker( NULL, UR_DELETED ); ITEM_PICKER picker( NULL, UR_DELETED );
int net_code_delete = aTrack->GetNet(); int net_code_delete = aTrack->GetNetCode();
/* Search the first item for the given net code */ /* Search the first item for the given net code */
TRACK* trackList = GetBoard()->m_Track->GetStartNetCode( net_code_delete ); TRACK* trackList = GetBoard()->m_Track->GetStartNetCode( net_code_delete );
@ -171,7 +171,7 @@ void PCB_EDIT_FRAME::Delete_net( wxDC* DC, TRACK* aTrack )
for( TRACK* segm = trackList; segm; segm = next_track, ++ii ) for( TRACK* segm = trackList; segm; segm = next_track, ++ii )
{ {
next_track = segm->Next(); next_track = segm->Next();
if( segm->GetNet() != net_code_delete ) if( segm->GetNetCode() != net_code_delete )
break; break;
GetBoard()->m_Track.Remove( segm ); GetBoard()->m_Track.Remove( segm );
@ -202,7 +202,7 @@ void PCB_EDIT_FRAME::Remove_One_Track( wxDC* DC, TRACK* pt_segm )
if( segments_to_delete_count == 0 ) if( segments_to_delete_count == 0 )
return; return;
int net_code = pt_segm->GetNet(); int net_code = pt_segm->GetNetCode();
PICKED_ITEMS_LIST itemsList; PICKED_ITEMS_LIST itemsList;
ITEM_PICKER picker( NULL, UR_DELETED ); ITEM_PICKER picker( NULL, UR_DELETED );

View File

@ -151,7 +151,8 @@ DIALOG_PAD_PROPERTIES::DIALOG_PAD_PROPERTIES( PCB_BASE_FRAME* aParent, D_PAD* aP
m_parent = aParent; m_parent = aParent;
m_currentPad = aPad; m_currentPad = aPad;
m_board = m_parent->GetBoard(); m_board = m_parent->GetBoard();
m_dummyPad = new D_PAD( (MODULE*) NULL ); m_dummyPad = new D_PAD( aPad->GetParent() );
m_padMaster.SetParent( aPad->GetParent() );
if( aPad ) if( aPad )
m_dummyPad->Copy( aPad ); m_dummyPad->Copy( aPad );
@ -810,26 +811,17 @@ void DIALOG_PAD_PROPERTIES::PadPropertiesAccept( wxCommandEvent& event )
m_currentPad->SetPadName( m_padMaster.GetPadName() ); m_currentPad->SetPadName( m_padMaster.GetPadName() );
if( m_currentPad->GetNetname() != m_padMaster.GetNetname() ) if( m_currentPad->GetNetname() != m_PadNetNameCtrl->GetValue() )
{ {
if( m_padMaster.GetNetname().IsEmpty() ) if( !m_PadNetNameCtrl->GetValue().IsEmpty() && m_padMaster.GetNetCode() == 0 )
{ {
rastnestIsChanged = true;
m_currentPad->SetNet( 0 );
m_currentPad->SetNetname( wxEmptyString );
}
else
{
const NETINFO_ITEM* net = m_board->FindNet( m_padMaster.GetNetname() );
if( net )
{
rastnestIsChanged = true;
m_currentPad->SetNetname( m_padMaster.GetNetname() );
m_currentPad->SetNet( net->GetNet() );
}
else
DisplayError( NULL, _( "Unknown netname, netname not changed" ) ); DisplayError( NULL, _( "Unknown netname, netname not changed" ) );
} }
else
{
rastnestIsChanged = true;
m_currentPad->SetNetCode( m_padMaster.GetNetCode() );
}
} }
m_currentPad->SetLocalClearance( m_padMaster.GetLocalClearance() ); m_currentPad->SetLocalClearance( m_padMaster.GetLocalClearance() );
@ -987,7 +979,13 @@ bool DIALOG_PAD_PROPERTIES::transferDataToPad( D_PAD* aPad )
msg = m_PadNumCtrl->GetValue().Left( 4 ); msg = m_PadNumCtrl->GetValue().Left( 4 );
aPad->SetPadName( msg ); aPad->SetPadName( msg );
aPad->SetNetname( m_PadNetNameCtrl->GetValue() );
// Check if user has set an existing net name
const NETINFO_ITEM* netinfo = m_board->FindNet( m_PadNetNameCtrl->GetValue() );
if( netinfo != NULL )
aPad->SetNetCode( netinfo->GetNet() );
else
aPad->SetNetCode( NETINFO_LIST::UNCONNECTED );
// Clear some values, according to the pad type and shape // Clear some values, according to the pad type and shape
switch( aPad->GetShape() ) switch( aPad->GetShape() )
@ -1035,7 +1033,7 @@ bool DIALOG_PAD_PROPERTIES::transferDataToPad( D_PAD* aPad )
// no offset, no net name, no pad name allowed // no offset, no net name, no pad name allowed
aPad->SetOffset( wxPoint( 0, 0 ) ); aPad->SetOffset( wxPoint( 0, 0 ) );
aPad->SetPadName( wxEmptyString ); aPad->SetPadName( wxEmptyString );
aPad->SetNetname( wxEmptyString ); aPad->SetNetCode( NETINFO_LIST::UNCONNECTED );
break; break;
default: default:

View File

@ -342,7 +342,7 @@ void Collect_TrackSegmentsToDrag( BOARD* aPcb, const wxPoint& aRefPos, LAYER_MSK
for( ; track; track = track->Next() ) for( ; track; track = track->Next() )
{ {
if( track->GetNet() != aNetCode ) // not the same netcodenet code: all candidates tested if( track->GetNetCode() != aNetCode ) // not the same netcode: all candidates tested
break; break;
if( ( aLayerMask & track->GetLayerMask() ) == 0 ) if( ( aLayerMask & track->GetLayerMask() ) == 0 )

View File

@ -549,7 +549,7 @@ void DRC::testZones()
if( !test_area->IsOnCopperLayer() ) if( !test_area->IsOnCopperLayer() )
continue; continue;
if( test_area->GetNet() < 0 ) if( test_area->GetNetCode() < 0 )
{ {
m_currentMarker = fillMarker( test_area, m_currentMarker = fillMarker( test_area,
DRCE_NON_EXISTANT_NET_FOR_ZONE_OUTLINE, m_currentMarker ); DRCE_NON_EXISTANT_NET_FOR_ZONE_OUTLINE, m_currentMarker );
@ -756,7 +756,7 @@ bool DRC::doPadToPadsDrc( D_PAD* aRefPad, D_PAD** aStart, D_PAD** aEnd, int x_li
// The pad must be in a net (i.e pt_pad->GetNet() != 0 ), // The pad must be in a net (i.e pt_pad->GetNet() != 0 ),
// But no problem if pads have the same netcode (same net) // But no problem if pads have the same netcode (same net)
if( pad->GetNet() && ( aRefPad->GetNet() == pad->GetNet() ) ) if( pad->GetNetCode() && ( aRefPad->GetNetCode() == pad->GetNetCode() ) )
continue; continue;
// if pads are from the same footprint // if pads are from the same footprint

View File

@ -164,7 +164,7 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
m_segmAngle = 0; m_segmAngle = 0;
layerMask = aRefSeg->GetLayerMask(); layerMask = aRefSeg->GetLayerMask();
net_code_ref = aRefSeg->GetNet(); net_code_ref = aRefSeg->GetNetCode();
// Phase 0 : Test vias // Phase 0 : Test vias
if( aRefSeg->Type() == PCB_VIA_T ) if( aRefSeg->Type() == PCB_VIA_T )
@ -310,8 +310,8 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
// The pad must be in a net (i.e pt_pad->GetNet() != 0 ) // The pad must be in a net (i.e pt_pad->GetNet() != 0 )
// but no problem if the pad netcode is the current netcode (same net) // but no problem if the pad netcode is the current netcode (same net)
if( pad->GetNet() // the pad must be connected if( pad->GetNetCode() // the pad must be connected
&& net_code_ref == pad->GetNet() ) // the pad net is the same as current net -> Ok && net_code_ref == pad->GetNetCode() ) // the pad net is the same as current net -> Ok
continue; continue;
// DRC for the pad // DRC for the pad
@ -339,7 +339,7 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
for( track = aStart; track; track = track->Next() ) for( track = aStart; track; track = track->Next() )
{ {
// No problem if segments have the same net code: // No problem if segments have the same net code:
if( net_code_ref == track->GetNet() ) if( net_code_ref == track->GetNetCode() )
continue; continue;
// No problem if segment are on different layers : // No problem if segment are on different layers :

View File

@ -1493,7 +1493,7 @@ void EAGLE_PLUGIN::loadPlain( CPTREE& aGraphics )
zone->SetTimeStamp( timeStamp( gr->second ) ); zone->SetTimeStamp( timeStamp( gr->second ) );
zone->SetLayer( layer ); zone->SetLayer( layer );
zone->SetNet( 0 ); zone->SetNetCode( NETINFO_LIST::UNCONNECTED );
CPolyLine::HATCH_STYLE outline_hatch = CPolyLine::DIAGONAL_EDGE; CPolyLine::HATCH_STYLE outline_hatch = CPolyLine::DIAGONAL_EDGE;
@ -1696,8 +1696,7 @@ void EAGLE_PLUGIN::loadElements( CPTREE& aElements )
if( ni != m_pads_to_nets.end() ) if( ni != m_pads_to_nets.end() )
{ {
const ENET* enet = &ni->second; const ENET* enet = &ni->second;
pad->SetNetname( FROM_UTF8( enet->netname.c_str() ) ); pad->SetNetCode( enet->netcode );
pad->SetNet( enet->netcode );
} }
} }
@ -1880,7 +1879,7 @@ void EAGLE_PLUGIN::orientModuleText( MODULE* m, const EELEMENT& e,
MODULE* EAGLE_PLUGIN::makeModule( CPTREE& aPackage, const string& aPkgName ) const MODULE* EAGLE_PLUGIN::makeModule( CPTREE& aPackage, const string& aPkgName ) const
{ {
std::auto_ptr<MODULE> m( new MODULE( NULL ) ); std::auto_ptr<MODULE> m( new MODULE( m_board ) );
m->SetFPID( FPID( aPkgName ) ); m->SetFPID( FPID( aPkgName ) );
@ -2260,7 +2259,6 @@ void EAGLE_PLUGIN::packageHole( MODULE* aModule, CPTREE& aTree ) const
// no offset, no net name, no pad name allowed // no offset, no net name, no pad name allowed
// pad->SetOffset( wxPoint( 0, 0 ) ); // pad->SetOffset( wxPoint( 0, 0 ) );
// pad->SetPadName( wxEmptyString ); // pad->SetPadName( wxEmptyString );
// pad->SetNetname( wxEmptyString );
wxPoint padpos( kicad_x( e.x ), kicad_y( e.y ) ); wxPoint padpos( kicad_x( e.x ), kicad_y( e.y ) );
@ -2353,6 +2351,7 @@ void EAGLE_PLUGIN::loadSignals( CPTREE& aSignals )
const string& nname = net->second.get<string>( "<xmlattr>.name" ); const string& nname = net->second.get<string>( "<xmlattr>.name" );
wxString netName = FROM_UTF8( nname.c_str() ); wxString netName = FROM_UTF8( nname.c_str() );
m_board->AppendNet( new NETINFO_ITEM( m_board, netName, netCode ) );
m_xpath->Value( nname.c_str() ); m_xpath->Value( nname.c_str() );
@ -2388,7 +2387,7 @@ void EAGLE_PLUGIN::loadSignals( CPTREE& aSignals )
t->SetWidth( width ); t->SetWidth( width );
t->SetLayer( layer ); t->SetLayer( layer );
t->SetNet( netCode ); t->SetNetCode( netCode );
m_board->m_Track.Insert( t, NULL ); m_board->m_Track.Insert( t, NULL );
} }
@ -2453,7 +2452,7 @@ void EAGLE_PLUGIN::loadSignals( CPTREE& aSignals )
via->SetPosition( pos ); via->SetPosition( pos );
via->SetEnd( pos ); via->SetEnd( pos );
via->SetNet( netCode ); via->SetNetCode( netCode );
via->SetShape( S_CIRCLE ); // @todo should be in SEGVIA constructor via->SetShape( S_CIRCLE ); // @todo should be in SEGVIA constructor
} }
@ -2496,8 +2495,7 @@ void EAGLE_PLUGIN::loadSignals( CPTREE& aSignals )
zone->SetTimeStamp( timeStamp( it->second ) ); zone->SetTimeStamp( timeStamp( it->second ) );
zone->SetLayer( layer ); zone->SetLayer( layer );
zone->SetNet( netCode ); zone->SetNetCode( netCode );
zone->SetNetName( netName );
CPolyLine::HATCH_STYLE outline_hatch = CPolyLine::DIAGONAL_EDGE; CPolyLine::HATCH_STYLE outline_hatch = CPolyLine::DIAGONAL_EDGE;
@ -2553,15 +2551,12 @@ void EAGLE_PLUGIN::loadSignals( CPTREE& aSignals )
// KiCad does not support an unconnected zone with its own non-zero netcode, // KiCad does not support an unconnected zone with its own non-zero netcode,
// but only when assigned netcode = 0 w/o a name... // but only when assigned netcode = 0 w/o a name...
for( ZONES::iterator it = zones.begin(); it != zones.end(); ++it ) for( ZONES::iterator it = zones.begin(); it != zones.end(); ++it )
{ (*it)->SetNetCode( NETINFO_LIST::UNCONNECTED );
(*it)->SetNet( 0 );
(*it)->SetNetName( wxEmptyString );
}
// therefore omit this signal/net. // therefore omit this signal/net.
} }
else else
m_board->AppendNet( new NETINFO_ITEM( m_board, netName, netCode++ ) ); netCode++;
} }
m_xpath->pop(); // "signals.signal" m_xpath->pop(); // "signals.signal"

View File

@ -328,7 +328,7 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
if( type == PCB_TRACE_T || type == PCB_VIA_T ) if( type == PCB_TRACE_T || type == PCB_VIA_T )
{ {
BOARD_CONNECTED_ITEM*item = (BOARD_CONNECTED_ITEM*) GetCurItem(); BOARD_CONNECTED_ITEM*item = (BOARD_CONNECTED_ITEM*) GetCurItem();
DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS dlg( this, item->GetNet() ); DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS dlg( this, item->GetNetCode() );
dlg.ShowModal(); dlg.ShowModal();
} }
@ -468,11 +468,11 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
break; break;
case ID_POPUP_PCB_LOCK_ON_NET: case ID_POPUP_PCB_LOCK_ON_NET:
Attribut_net( &dc, ( (TRACK*) GetCurItem() )->GetNet(), true ); Attribut_net( &dc, ( (TRACK*) GetCurItem() )->GetNetCode(), true );
break; break;
case ID_POPUP_PCB_LOCK_OFF_NET: case ID_POPUP_PCB_LOCK_OFF_NET:
Attribut_net( &dc, ( (TRACK*) GetCurItem() )->GetNet(), false ); Attribut_net( &dc, ( (TRACK*) GetCurItem() )->GetNetCode(), false );
break; break;
case ID_POPUP_PCB_SETFLAGS_TRACK_MNU: case ID_POPUP_PCB_SETFLAGS_TRACK_MNU:
@ -486,7 +486,7 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
{ {
SEGZONE* zsegm = (SEGZONE*) GetCurItem(); SEGZONE* zsegm = (SEGZONE*) GetCurItem();
int netcode = zsegm->GetNet(); int netcode = zsegm->GetNetCode();
Delete_OldZone_Fill( zsegm ); Delete_OldZone_Fill( zsegm );
SetCurItem( NULL ); SetCurItem( NULL );
TestNetConnection( NULL, netcode ); TestNetConnection( NULL, netcode );
@ -523,7 +523,7 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
case ID_POPUP_PCB_DELETE_ZONE_CUTOUT: case ID_POPUP_PCB_DELETE_ZONE_CUTOUT:
m_canvas->MoveCursorToCrossHair(); m_canvas->MoveCursorToCrossHair();
{ {
int netcode = ( (ZONE_CONTAINER*) GetCurItem() )->GetNet(); int netcode = ( (ZONE_CONTAINER*) GetCurItem() )->GetNetCode();
Delete_Zone_Contour( &dc, (ZONE_CONTAINER*) GetCurItem() ); Delete_Zone_Contour( &dc, (ZONE_CONTAINER*) GetCurItem() );
SetCurItem( NULL ); SetCurItem( NULL );
TestNetConnection( NULL, netcode ); TestNetConnection( NULL, netcode );
@ -604,7 +604,7 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
{ {
ZONE_CONTAINER* zone_container = (ZONE_CONTAINER*) GetCurItem(); ZONE_CONTAINER* zone_container = (ZONE_CONTAINER*) GetCurItem();
zone_container->UnFill(); zone_container->UnFill();
TestNetConnection( NULL, zone_container->GetNet() ); TestNetConnection( NULL, zone_container->GetNetCode() );
OnModify(); OnModify();
SetMsgPanel( GetBoard() ); SetMsgPanel( GetBoard() );
m_canvas->Refresh(); m_canvas->Refresh();
@ -633,7 +633,7 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
case ID_POPUP_PCB_FILL_ZONE: case ID_POPUP_PCB_FILL_ZONE:
m_canvas->MoveCursorToCrossHair(); m_canvas->MoveCursorToCrossHair();
Fill_Zone( (ZONE_CONTAINER*) GetCurItem() ); Fill_Zone( (ZONE_CONTAINER*) GetCurItem() );
TestNetConnection( NULL, ( (ZONE_CONTAINER*) GetCurItem() )->GetNet() ); TestNetConnection( NULL, ( (ZONE_CONTAINER*) GetCurItem() )->GetNetCode() );
SetMsgPanel( GetBoard() ); SetMsgPanel( GetBoard() );
m_canvas->Refresh(); m_canvas->Refresh();
break; break;
@ -1156,7 +1156,7 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
newtrack->Draw( m_canvas, &dc, GR_XOR ); newtrack->Draw( m_canvas, &dc, GR_XOR );
// compute the new ratsnest, because connectivity could change // compute the new ratsnest, because connectivity could change
TestNetConnection( &dc, track->GetNet() ); TestNetConnection( &dc, track->GetNetCode() );
} }
break; break;
@ -1248,7 +1248,7 @@ void PCB_EDIT_FRAME::RemoveStruct( BOARD_ITEM* Item, wxDC* DC )
case PCB_ZONE_AREA_T: case PCB_ZONE_AREA_T:
{ {
SetCurItem( NULL ); SetCurItem( NULL );
int netcode = ( (ZONE_CONTAINER*) Item )->GetNet(); int netcode = ( (ZONE_CONTAINER*) Item )->GetNetCode();
Delete_Zone_Contour( DC, (ZONE_CONTAINER*) Item ); Delete_Zone_Contour( DC, (ZONE_CONTAINER*) Item );
TestNetConnection( NULL, netcode ); TestNetConnection( NULL, netcode );
SetMsgPanel( GetBoard() ); SetMsgPanel( GetBoard() );

View File

@ -36,7 +36,7 @@ bool PCB_EDIT_FRAME::SetTrackSegmentWidth( TRACK* aTrackItem,
NETINFO_ITEM* net = NULL; NETINFO_ITEM* net = NULL;
if( aUseNetclassValue ) if( aUseNetclassValue )
net = GetBoard()->FindNet( aTrackItem->GetNet() ); net = aTrackItem->GetNet();
initial_width = aTrackItem->GetWidth(); initial_width = aTrackItem->GetWidth();
@ -224,7 +224,7 @@ bool PCB_EDIT_FRAME::Change_Net_Tracks_And_Vias_Sizes( int aNetcode, bool aUseNe
for( pt_segm = GetBoard()->m_Track; pt_segm != NULL; pt_segm = pt_segm->Next() ) for( pt_segm = GetBoard()->m_Track; pt_segm != NULL; pt_segm = pt_segm->Next() )
{ {
if( aNetcode != pt_segm->GetNet() ) // not in net if( aNetcode != pt_segm->GetNetCode() ) // not in net
continue; continue;
// we have found a item member of the net // we have found a item member of the net

View File

@ -99,7 +99,7 @@ bool PCB_EDIT_FRAME::Other_Layer_Route( TRACK* aTrack, wxDC* DC )
via->SetFlags( IS_NEW ); via->SetFlags( IS_NEW );
via->SetShape( GetDesignSettings().m_CurrentViaType ); via->SetShape( GetDesignSettings().m_CurrentViaType );
via->SetWidth( GetBoard()->GetCurrentViaSize()); via->SetWidth( GetBoard()->GetCurrentViaSize());
via->SetNet( GetBoard()->GetHighLightNetCode() ); via->SetNetCode( GetBoard()->GetHighLightNetCode() );
via->SetEnd( g_CurrentTrackSegment->GetEnd() ); via->SetEnd( g_CurrentTrackSegment->GetEnd() );
via->SetStart( g_CurrentTrackSegment->GetEnd() ); via->SetStart( g_CurrentTrackSegment->GetEnd() );
@ -139,7 +139,7 @@ bool PCB_EDIT_FRAME::Other_Layer_Route( TRACK* aTrack, wxDC* DC )
// else error: will be removed later // else error: will be removed later
via->SetLayerPair( first_layer, last_layer ); via->SetLayerPair( first_layer, last_layer );
{ {
NETINFO_ITEM* net = GetBoard()->FindNet( via->GetNet() ); NETINFO_ITEM* net = via->GetNet();
via->SetWidth( net->GetMicroViaSize() ); via->SetWidth( net->GetMicroViaSize() );
} }
} }
@ -244,7 +244,7 @@ void PCB_EDIT_FRAME::Show_1_Ratsnest( EDA_ITEM* item, wxDC* DC )
{ {
RATSNEST_ITEM* net = &GetBoard()->m_FullRatsnest[ii]; RATSNEST_ITEM* net = &GetBoard()->m_FullRatsnest[ii];
if( net->GetNet() == pt_pad->GetNet() ) if( net->GetNet() == pt_pad->GetNetCode() )
{ {
if( ( net->m_Status & CH_VISIBLE ) != 0 ) if( ( net->m_Status & CH_VISIBLE ) != 0 )
continue; continue;

View File

@ -133,12 +133,12 @@ TRACK* PCB_EDIT_FRAME::Begin_Route( TRACK* aTrack, wxDC* aDC )
// A pad is found: put the starting point on pad center // A pad is found: put the starting point on pad center
pos = pad->GetPosition(); pos = pad->GetPosition();
GetBoard()->SetHighLightNet( pad->GetNet() ); GetBoard()->SetHighLightNet( pad->GetNetCode() );
} }
else // A track segment is found else // A track segment is found
{ {
TrackOnStartPoint = (TRACK*) LockPoint; TrackOnStartPoint = (TRACK*) LockPoint;
GetBoard()->SetHighLightNet( TrackOnStartPoint->GetNet() ); GetBoard()->SetHighLightNet( TrackOnStartPoint->GetNetCode() );
GetBoard()->CreateLockPoint( pos, TrackOnStartPoint, &s_ItemsListPicker ); GetBoard()->CreateLockPoint( pos, TrackOnStartPoint, &s_ItemsListPicker );
} }
} }
@ -153,7 +153,7 @@ TRACK* PCB_EDIT_FRAME::Begin_Route( TRACK* aTrack, wxDC* aDC )
-1 ); -1 );
if( zone ) if( zone )
GetBoard()->SetHighLightNet( zone->GetNet() ); GetBoard()->SetHighLightNet( zone->GetNetCode() );
} }
DBG( g_CurrentTrackList.VerifyListIntegrity() ); DBG( g_CurrentTrackList.VerifyListIntegrity() );
@ -166,7 +166,7 @@ TRACK* PCB_EDIT_FRAME::Begin_Route( TRACK* aTrack, wxDC* aDC )
GetBoard()->DrawHighLight( m_canvas, aDC, GetBoard()->GetHighLightNetCode() ); GetBoard()->DrawHighLight( m_canvas, aDC, GetBoard()->GetHighLightNetCode() );
// Display info about track Net class, and init track and vias sizes: // Display info about track Net class, and init track and vias sizes:
g_CurrentTrackSegment->SetNet( GetBoard()->GetHighLightNetCode() ); g_CurrentTrackSegment->SetNetCode( GetBoard()->GetHighLightNetCode() );
GetBoard()->SetCurrentNetClass( g_CurrentTrackSegment->GetNetClassName() ); GetBoard()->SetCurrentNetClass( g_CurrentTrackSegment->GetNetClassName() );
g_CurrentTrackSegment->SetLayer( GetScreen()->m_Active_Layer ); g_CurrentTrackSegment->SetLayer( GetScreen()->m_Active_Layer );
@ -476,7 +476,7 @@ bool PCB_EDIT_FRAME::End_Route( TRACK* aTrack, wxDC* aDC )
// g_FirstTrackSegment can be NULL on a double click on the starting point // g_FirstTrackSegment can be NULL on a double click on the starting point
if( g_FirstTrackSegment != NULL ) if( g_FirstTrackSegment != NULL )
{ {
int netcode = g_FirstTrackSegment->GetNet(); int netcode = g_FirstTrackSegment->GetNetCode();
TRACK* firstTrack = g_FirstTrackSegment; TRACK* firstTrack = g_FirstTrackSegment;
int newCount = g_CurrentTrackList.GetCount(); int newCount = g_CurrentTrackList.GetCount();
@ -540,7 +540,7 @@ bool PCB_EDIT_FRAME::End_Route( TRACK* aTrack, wxDC* aDC )
TRACK* LocateIntrusion( TRACK* listStart, TRACK* aTrack, LAYER_NUM aLayer, const wxPoint& aRef ) TRACK* LocateIntrusion( TRACK* listStart, TRACK* aTrack, LAYER_NUM aLayer, const wxPoint& aRef )
{ {
int net = aTrack->GetNet(); int net = aTrack->GetNetCode();
int width = aTrack->GetWidth(); int width = aTrack->GetWidth();
TRACK* found = NULL; TRACK* found = NULL;
@ -555,7 +555,7 @@ TRACK* LocateIntrusion( TRACK* listStart, TRACK* aTrack, LAYER_NUM aLayer, const
if( aLayer != track->GetLayer() ) if( aLayer != track->GetLayer() )
continue; continue;
if( track->GetNet() == net ) if( track->GetNetCode() == net )
continue; continue;
// TRACK::HitTest // TRACK::HitTest
@ -614,7 +614,7 @@ static void PushTrack( EDA_DRAW_PANEL* panel )
if( !other ) if( !other )
return; return;
if( other->GetNet() == track->GetNet() ) if( other->GetNetCode() == track->GetNetCode() )
return; return;
cv = cursor - other->GetStart(); cv = cursor - other->GetStart();

View File

@ -199,7 +199,7 @@ static void build_via_testpoints( BOARD *aPcb,
if( track->Type() == PCB_VIA_T ) if( track->Type() == PCB_VIA_T )
{ {
SEGVIA *via = (SEGVIA*) track; SEGVIA *via = (SEGVIA*) track;
NETINFO_ITEM *net = aPcb->FindNet( track->GetNet() ); NETINFO_ITEM *net = track->GetNet();
D356_RECORD rk; D356_RECORD rk;
rk.smd = false; rk.smd = false;

View File

@ -647,7 +647,6 @@ static void CreateSignalsSection( FILE* aFile, BOARD* aPcb )
if( net->GetNetname() == wxEmptyString ) // dummy netlist (no connection) if( net->GetNetname() == wxEmptyString ) // dummy netlist (no connection)
{ {
wxString msg; msg << wxT( "NoConnection" ) << NbNoConn++; wxString msg; msg << wxT( "NoConnection" ) << NbNoConn++;
net->SetNetname( msg );
} }
if( net->GetNet() <= 0 ) // dummy netlist (no connection) if( net->GetNet() <= 0 ) // dummy netlist (no connection)
@ -664,7 +663,7 @@ static void CreateSignalsSection( FILE* aFile, BOARD* aPcb )
{ {
wxString padname; wxString padname;
if( pad->GetNet() != net->GetNet() ) if( pad->GetNetCode() != net->GetNet() )
continue; continue;
pad->ReturnStringPadName( padname ); pad->ReturnStringPadName( padname );
@ -731,7 +730,7 @@ static int TrackListSortByNetcode( const void* refptr, const void* objptr )
ref = *( (TRACK**) refptr ); ref = *( (TRACK**) refptr );
cmp = *( (TRACK**) objptr ); cmp = *( (TRACK**) objptr );
if( ( diff = ref->GetNet() - cmp->GetNet() ) ) if( ( diff = ref->GetNetCode() - cmp->GetNetCode() ) )
return diff; return diff;
if( ( diff = ref->GetWidth() - cmp->GetWidth() ) ) if( ( diff = ref->GetWidth() - cmp->GetWidth() ) )
@ -798,10 +797,10 @@ static void CreateRoutesSection( FILE* aFile, BOARD* aPcb )
{ {
track = tracklist[ii]; track = tracklist[ii];
if( old_netcode != track->GetNet() ) if( old_netcode != track->GetNetCode() )
{ {
old_netcode = track->GetNet(); old_netcode = track->GetNetCode();
NETINFO_ITEM* net = aPcb->FindNet( track->GetNet() ); NETINFO_ITEM* net = track->GetNet();
wxString netname; wxString netname;
if( net && (net->GetNetname() != wxEmptyString) ) if( net && (net->GetNetname() != wxEmptyString) )

View File

@ -194,7 +194,7 @@ private:
*/ */
void OnLeftDClick( wxDC*, const wxPoint& ) {} void OnLeftDClick( wxDC*, const wxPoint& ) {}
void SaveCopyInUndoList( BOARD_ITEM*, UNDO_REDO_T, const wxPoint& ) {} void SaveCopyInUndoList( BOARD_ITEM*, UNDO_REDO_T, const wxPoint& ) {}
void SaveCopyInUndoList( PICKED_ITEMS_LIST&, UNDO_REDO_T, const wxPoint& ) {} void SaveCopyInUndoList( const PICKED_ITEMS_LIST&, UNDO_REDO_T, const wxPoint& ) {}
DECLARE_EVENT_TABLE() DECLARE_EVENT_TABLE()

View File

@ -142,7 +142,7 @@ int PCB_EDIT_FRAME::SelectHighLight( wxDC* DC )
switch( item->Type() ) switch( item->Type() )
{ {
case PCB_PAD_T: case PCB_PAD_T:
netcode = ( (D_PAD*) item )->GetNet(); netcode = ( (D_PAD*) item )->GetNetCode();
SendMessageToEESCHEMA( item ); SendMessageToEESCHEMA( item );
break; break;
@ -151,11 +151,11 @@ int PCB_EDIT_FRAME::SelectHighLight( wxDC* DC )
case PCB_ZONE_T: case PCB_ZONE_T:
// since these classes are all derived from TRACK, use a common // since these classes are all derived from TRACK, use a common
// GetNet() function: // GetNet() function:
netcode = ( (TRACK*) item )->GetNet(); netcode = ( (TRACK*) item )->GetNetCode();
break; break;
case PCB_ZONE_AREA_T: case PCB_ZONE_AREA_T:
netcode = ( (ZONE_CONTAINER*) item )->GetNet(); netcode = ( (ZONE_CONTAINER*) item )->GetNetCode();
break; break;
default: default:

View File

@ -380,6 +380,9 @@ void PCB_IO::Save( const wxString& aFileName, BOARD* aBoard, const PROPERTIES* a
m_board = aBoard; // after init() m_board = aBoard; // after init()
// Prepare net mapping that assures that net codes saved in a file are consecutive integers
m_mapping->SetBoard( aBoard );
FILE_OUTPUTFORMATTER formatter( aFileName ); FILE_OUTPUTFORMATTER formatter( aFileName );
m_out = &formatter; // no ownership m_out = &formatter; // no ownership
@ -499,7 +502,7 @@ void PCB_IO::format( BOARD* aBoard, int aNestLevel ) const
m_out->Print( aNestLevel+1, "(tracks %d)\n", aBoard->GetNumSegmTrack() ); m_out->Print( aNestLevel+1, "(tracks %d)\n", aBoard->GetNumSegmTrack() );
m_out->Print( aNestLevel+1, "(zones %d)\n", aBoard->GetNumSegmZone() ); m_out->Print( aNestLevel+1, "(zones %d)\n", aBoard->GetNumSegmZone() );
m_out->Print( aNestLevel+1, "(modules %d)\n", aBoard->m_Modules.GetCount() ); m_out->Print( aNestLevel+1, "(modules %d)\n", aBoard->m_Modules.GetCount() );
m_out->Print( aNestLevel+1, "(nets %d)\n", aBoard->GetNetCount() ); m_out->Print( aNestLevel+1, "(nets %d)\n", (int) m_mapping->GetSize() );
m_out->Print( aNestLevel, ")\n\n" ); m_out->Print( aNestLevel, ")\n\n" );
aBoard->GetPageSettings().Format( m_out, aNestLevel, m_ctl ); aBoard->GetPageSettings().Format( m_out, aNestLevel, m_ctl );
@ -654,13 +657,12 @@ void PCB_IO::format( BOARD* aBoard, int aNestLevel ) const
m_out->Print( aNestLevel, ")\n\n" ); m_out->Print( aNestLevel, ")\n\n" );
int netcount = aBoard->GetNetCount(); // Save net codes and names
for( NETINFO_MAPPING::iterator net = m_mapping->begin(), netEnd = m_mapping->end();
for( int i = 0; i < netcount; ++i ) net != netEnd; ++net )
{ {
NETINFO_ITEM* net = aBoard->FindNet( i );
m_out->Print( aNestLevel, "(net %d %s)\n", m_out->Print( aNestLevel, "(net %d %s)\n",
net->GetNet(), m_mapping->Translate( net->GetNet() ),
m_out->Quotew( net->GetNetname() ).c_str() ); m_out->Quotew( net->GetNetname() ).c_str() );
} }
@ -1228,8 +1230,9 @@ void PCB_IO::format( D_PAD* aPad, int aNestLevel ) const
std::string output; std::string output;
// Unconnected pad is default net so don't save it. // Unconnected pad is default net so don't save it.
if( !(m_ctl & CTL_OMIT_NETS) && aPad->GetNet() != 0 ) if( !(m_ctl & CTL_OMIT_NETS) && aPad->GetNetCode() != 0 )
StrPrintf( &output, " (net %d %s)", aPad->GetNet(), m_out->Quotew( aPad->GetNetname() ).c_str() ); StrPrintf( &output, " (net %d %s)", m_mapping->Translate( aPad->GetNetCode() ),
m_out->Quotew( aPad->GetNetname() ).c_str() );
if( aPad->GetPadToDieLength() != 0 ) if( aPad->GetPadToDieLength() != 0 )
StrPrintf( &output, " (die_length %s)", FMT_IU( aPad->GetPadToDieLength() ).c_str() ); StrPrintf( &output, " (die_length %s)", FMT_IU( aPad->GetPadToDieLength() ).c_str() );
@ -1386,7 +1389,7 @@ void PCB_IO::format( TRACK* aTrack, int aNestLevel ) const
m_out->Print( 0, " (layer %s)", m_out->Quotew( aTrack->GetLayerName() ).c_str() ); m_out->Print( 0, " (layer %s)", m_out->Quotew( aTrack->GetLayerName() ).c_str() );
} }
m_out->Print( 0, " (net %d)", aTrack->GetNet() ); m_out->Print( 0, " (net %d)", m_mapping->Translate( aTrack->GetNetCode() ) );
if( aTrack->GetTimeStamp() != 0 ) if( aTrack->GetTimeStamp() != 0 )
m_out->Print( 0, " (tstamp %lX)", aTrack->GetTimeStamp() ); m_out->Print( 0, " (tstamp %lX)", aTrack->GetTimeStamp() );
@ -1405,8 +1408,8 @@ void PCB_IO::format( ZONE_CONTAINER* aZone, int aNestLevel ) const
// so be sure a dummy value is stored, just for ZONE_CONTAINER compatibility // so be sure a dummy value is stored, just for ZONE_CONTAINER compatibility
// (perhaps netcode and netname should be not stored) // (perhaps netcode and netname should be not stored)
m_out->Print( aNestLevel, "(zone (net %d) (net_name %s)", m_out->Print( aNestLevel, "(zone (net %d) (net_name %s)",
aZone->GetIsKeepout() ? 0 : aZone->GetNet(), aZone->GetIsKeepout() ? 0 : m_mapping->Translate( aZone->GetNetCode() ),
m_out->Quotew( aZone->GetIsKeepout() ? wxT("") : aZone->GetNetName() ).c_str() ); m_out->Quotew( aZone->GetIsKeepout() ? wxT("") : aZone->GetNetname() ).c_str() );
formatLayer( aZone ); formatLayer( aZone );
@ -1622,20 +1625,11 @@ void PCB_IO::format( ZONE_CONTAINER* aZone, int aNestLevel ) const
} }
PCB_IO::PCB_IO() :
m_cache( 0 ),
m_ctl( CTL_FOR_BOARD ), // expecting to OUTPUTFORMAT into BOARD files.
m_parser( new PCB_PARSER() )
{
init( 0 );
m_out = &m_sf;
}
PCB_IO::PCB_IO( int aControlFlags ) : PCB_IO::PCB_IO( int aControlFlags ) :
m_cache( 0 ), m_cache( 0 ),
m_ctl( aControlFlags ), m_ctl( aControlFlags ),
m_parser( new PCB_PARSER() ) m_parser( new PCB_PARSER() ),
m_mapping( new NETINFO_MAPPING() )
{ {
init( 0 ); init( 0 );
m_out = &m_sf; m_out = &m_sf;
@ -1646,6 +1640,7 @@ PCB_IO::~PCB_IO()
{ {
delete m_cache; delete m_cache;
delete m_parser; delete m_parser;
delete m_mapping;
} }

View File

@ -32,6 +32,7 @@ class BOARD;
class BOARD_ITEM; class BOARD_ITEM;
class FP_CACHE; class FP_CACHE;
class PCB_PARSER; class PCB_PARSER;
class NETINFO_MAPPING;
/// Current s-expression file format version. 2 was the last legacy format version. /// Current s-expression file format version. 2 was the last legacy format version.
@ -122,9 +123,7 @@ public:
//-----</PLUGIN API>-------------------------------------------------------- //-----</PLUGIN API>--------------------------------------------------------
PCB_IO(); PCB_IO( int aControlFlags = CTL_FOR_BOARD );
PCB_IO( int aControlFlags );
~PCB_IO(); ~PCB_IO();
@ -171,6 +170,8 @@ protected:
OUTPUTFORMATTER* m_out; ///< output any Format()s to this, no ownership OUTPUTFORMATTER* m_out; ///< output any Format()s to this, no ownership
int m_ctl; int m_ctl;
PCB_PARSER* m_parser; PCB_PARSER* m_parser;
NETINFO_MAPPING* m_mapping; ///< mapping for net codes, so only not empty net codes
///< are stored with consecutive integers as net codes
/// we only cache one footprint library, this determines which one. /// we only cache one footprint library, this determines which one.
void cacheLib( const wxString& aLibraryPath, const wxString& aFootprintName = wxEmptyString ); void cacheLib( const wxString& aLibraryPath, const wxString& aFootprintName = wxEmptyString );

View File

@ -1299,11 +1299,14 @@ void LEGACY_PLUGIN::loadPAD( MODULE* aModule )
char buf[1024]; // can be fairly long char buf[1024]; // can be fairly long
int netcode = intParse( line + SZ( "Ne" ), &data ); int netcode = intParse( line + SZ( "Ne" ), &data );
pad->SetNet( netcode ); pad->SetNetCode( netcode );
// read Netname // read Netname
ReadDelimitedText( buf, data, sizeof(buf) ); ReadDelimitedText( buf, data, sizeof(buf) );
pad->SetNetname( FROM_UTF8( StrPurge( buf ) ) ); #ifndef NDEBUG
if( m_board )
assert( m_board->FindNet( netcode )->GetNetname() == FROM_UTF8( StrPurge( buf ) ) );
#endif /* NDEBUG */
} }
else if( TESTLINE( "Po" ) ) // (Po)sition else if( TESTLINE( "Po" ) ) // (Po)sition
@ -1811,7 +1814,7 @@ void LEGACY_PLUGIN::loadNETINFO_ITEM()
{ {
char buf[1024]; char buf[1024];
NETINFO_ITEM* net = new NETINFO_ITEM( m_board ); NETINFO_ITEM* net = NULL;
char* line; char* line;
while( ( line = READLINE( m_reader ) ) != NULL ) while( ( line = READLINE( m_reader ) ) != NULL )
@ -1822,18 +1825,17 @@ void LEGACY_PLUGIN::loadNETINFO_ITEM()
{ {
// e.g. "Na 58 "/cpu.sch/PAD7"\r\n" // e.g. "Na 58 "/cpu.sch/PAD7"\r\n"
int tmp = intParse( line + SZ( "Na" ), &data ); int netCode = intParse( line + SZ( "Na" ), &data );
net->SetNet( tmp );
ReadDelimitedText( buf, data, sizeof(buf) ); ReadDelimitedText( buf, data, sizeof(buf) );
net->SetNetname( FROM_UTF8( buf ) ); net = new NETINFO_ITEM( m_board, FROM_UTF8( buf ), netCode );
} }
else if( TESTLINE( "$EndEQUIPOT" ) ) else if( TESTLINE( "$EndEQUIPOT" ) )
{ {
// net 0 should be already in list, so store this net // net 0 should be already in list, so store this net
// if it is not the net 0, or if the net 0 does not exists. // if it is not the net 0, or if the net 0 does not exists.
if( net->GetNet() > 0 || m_board->FindNet( 0 ) == NULL ) if( net != NULL && ( net->GetNet() > 0 || m_board->FindNet( 0 ) == NULL ) )
m_board->AppendNet( net ); m_board->AppendNet( net );
else else
delete net; delete net;
@ -2088,7 +2090,7 @@ void LEGACY_PLUGIN::loadTrackList( int aStructType )
( (SEGVIA*) newTrack )->SetLayerPair( LAYER_N_FRONT, LAYER_N_BACK ); ( (SEGVIA*) newTrack )->SetLayerPair( LAYER_N_FRONT, LAYER_N_BACK );
} }
newTrack->SetNet( net_code ); newTrack->SetNetCode( net_code );
newTrack->SetState( flags, true ); newTrack->SetState( flags, true );
} }
@ -2238,8 +2240,7 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER()
// Init the net code only, not the netname, to be sure // Init the net code only, not the netname, to be sure
// the zone net name is the name read in file. // the zone net name is the name read in file.
// (When mismatch, the user will be prompted in DRC, to fix the actual name) // (When mismatch, the user will be prompted in DRC, to fix the actual name)
zc->BOARD_CONNECTED_ITEM::SetNet( netcode ); zc->BOARD_CONNECTED_ITEM::SetNetCode( netcode );
zc->SetNetName( FROM_UTF8( buf ) ); // init the net name here
} }
else if( TESTLINE( "ZLayer" ) ) // layer found else if( TESTLINE( "ZLayer" ) ) // layer found
@ -2256,7 +2257,7 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER()
if( !hopt ) if( !hopt )
{ {
m_error.Printf( wxT( "Bad ZAux for CZONE_CONTAINER '%s'" ), zc->GetNetName().GetData() ); m_error.Printf( wxT( "Bad ZAux for CZONE_CONTAINER '%s'" ), zc->GetNetname().GetData() );
THROW_IO_ERROR( m_error ); THROW_IO_ERROR( m_error );
} }
@ -2267,7 +2268,7 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER()
case 'F': outline_hatch = CPolyLine::DIAGONAL_FULL; break; case 'F': outline_hatch = CPolyLine::DIAGONAL_FULL; break;
default: default:
m_error.Printf( wxT( "Bad ZAux for CZONE_CONTAINER '%s'" ), zc->GetNetName().GetData() ); m_error.Printf( wxT( "Bad ZAux for CZONE_CONTAINER '%s'" ), zc->GetNetname().GetData() );
THROW_IO_ERROR( m_error ); THROW_IO_ERROR( m_error );
} }
@ -2284,7 +2285,7 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER()
if( smoothing >= ZONE_SETTINGS::SMOOTHING_LAST || smoothing < 0 ) if( smoothing >= ZONE_SETTINGS::SMOOTHING_LAST || smoothing < 0 )
{ {
m_error.Printf( wxT( "Bad ZSmoothing for CZONE_CONTAINER '%s'" ), zc->GetNetName().GetData() ); m_error.Printf( wxT( "Bad ZSmoothing for CZONE_CONTAINER '%s'" ), zc->GetNetname().GetData() );
THROW_IO_ERROR( m_error ); THROW_IO_ERROR( m_error );
} }
@ -2359,7 +2360,7 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER()
default: default:
m_error.Printf( wxT( "Bad ZClearance padoption for CZONE_CONTAINER '%s'" ), m_error.Printf( wxT( "Bad ZClearance padoption for CZONE_CONTAINER '%s'" ),
zc->GetNetName().GetData() ); zc->GetNetname().GetData() );
THROW_IO_ERROR( m_error ); THROW_IO_ERROR( m_error );
} }
@ -2423,10 +2424,7 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER()
// Ensure keepout does not have a net // Ensure keepout does not have a net
// (which have no sense for a keepout zone) // (which have no sense for a keepout zone)
if( zc->GetIsKeepout() ) if( zc->GetIsKeepout() )
{ zc->SetNetCode( NETINFO_LIST::UNCONNECTED );
zc->SetNet(0);
zc->SetNetName( wxEmptyString );
}
// should always occur, but who knows, a zone without two corners // should always occur, but who knows, a zone without two corners
// is no zone at all, it's a spot? // is no zone at all, it's a spot?
@ -2436,7 +2434,7 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER()
if( !zc->IsOnCopperLayer() ) if( !zc->IsOnCopperLayer() )
{ {
zc->SetFillMode( 0 ); zc->SetFillMode( 0 );
zc->SetNet( 0 ); zc->SetNetCode( NETINFO_LIST::UNCONNECTED );
} }
// Hatch here, after outlines corners are read // Hatch here, after outlines corners are read
@ -2904,6 +2902,8 @@ do { \
void LEGACY_PLUGIN::SaveBOARD( const BOARD* aBoard ) const void LEGACY_PLUGIN::SaveBOARD( const BOARD* aBoard ) const
{ {
m_mapping->SetBoard( aBoard );
saveGENERAL( aBoard ); saveGENERAL( aBoard );
saveSHEET( aBoard ); saveSHEET( aBoard );
@ -2952,7 +2952,7 @@ void LEGACY_PLUGIN::saveGENERAL( const BOARD* aBoard ) const
fprintf( m_fp, "Nzone %d\n", aBoard->GetNumSegmZone() ); fprintf( m_fp, "Nzone %d\n", aBoard->GetNumSegmZone() );
fprintf( m_fp, "BoardThickness %s\n", fmtBIU( aBoard->GetDesignSettings().GetBoardThickness() ).c_str() ); fprintf( m_fp, "BoardThickness %s\n", fmtBIU( aBoard->GetDesignSettings().GetBoardThickness() ).c_str() );
fprintf( m_fp, "Nmodule %d\n", aBoard->m_Modules.GetCount() ); fprintf( m_fp, "Nmodule %d\n", aBoard->m_Modules.GetCount() );
fprintf( m_fp, "Nnets %d\n", aBoard->GetNetCount() ); fprintf( m_fp, "Nnets %d\n", m_mapping->GetSize() );
fprintf( m_fp, "$EndGENERAL\n\n" ); fprintf( m_fp, "$EndGENERAL\n\n" );
} }
@ -3093,9 +3093,11 @@ void LEGACY_PLUGIN::saveSETUP( const BOARD* aBoard ) const
void LEGACY_PLUGIN::saveBOARD_ITEMS( const BOARD* aBoard ) const void LEGACY_PLUGIN::saveBOARD_ITEMS( const BOARD* aBoard ) const
{ {
// save the nets // save the nets
int netcount = aBoard->GetNetCount(); for( NETINFO_MAPPING::iterator net = m_mapping->begin(), netEnd = m_mapping->end();
for( int i = 0; i < netcount; ++i ) net != netEnd; ++net )
saveNETINFO_ITEM( aBoard->FindNet( i ) ); {
saveNETINFO_ITEM( *net );
}
// Saved nets do not include netclass names, so save netclasses after nets. // Saved nets do not include netclass names, so save netclasses after nets.
saveNETCLASSES( &aBoard->m_NetClasses ); saveNETCLASSES( &aBoard->m_NetClasses );
@ -3153,7 +3155,8 @@ void LEGACY_PLUGIN::saveBOARD_ITEMS( const BOARD* aBoard ) const
void LEGACY_PLUGIN::saveNETINFO_ITEM( const NETINFO_ITEM* aNet ) const void LEGACY_PLUGIN::saveNETINFO_ITEM( const NETINFO_ITEM* aNet ) const
{ {
fprintf( m_fp, "$EQUIPOT\n" ); fprintf( m_fp, "$EQUIPOT\n" );
fprintf( m_fp, "Na %d %s\n", aNet->GetNet(), EscapedUTF8( aNet->GetNetname() ).c_str() ); fprintf( m_fp, "Na %d %s\n", m_mapping->Translate( aNet->GetNet() ),
EscapedUTF8( aNet->GetNetname() ).c_str() );
fprintf( m_fp, "St %s\n", "~" ); fprintf( m_fp, "St %s\n", "~" );
fprintf( m_fp, "$EndEQUIPOT\n" ); fprintf( m_fp, "$EndEQUIPOT\n" );
@ -3370,7 +3373,7 @@ void LEGACY_PLUGIN::savePAD( const D_PAD* me ) const
fprintf( m_fp, "At %s N %08X\n", texttype, me->GetLayerMask() ); fprintf( m_fp, "At %s N %08X\n", texttype, me->GetLayerMask() );
fprintf( m_fp, "Ne %d %s\n", me->GetNet(), EscapedUTF8( me->GetNetname() ).c_str() ); fprintf( m_fp, "Ne %d %s\n", me->GetNetCode(), EscapedUTF8( me->GetNetname() ).c_str() );
fprintf( m_fp, "Po %s\n", fmtBIUPoint( me->GetPos0() ).c_str() ); fprintf( m_fp, "Po %s\n", fmtBIUPoint( me->GetPos0() ).c_str() );
@ -3630,7 +3633,7 @@ void LEGACY_PLUGIN::saveTRACK( const TRACK* me ) const
"-1" : fmtBIU( me->GetDrill() ).c_str() ); "-1" : fmtBIU( me->GetDrill() ).c_str() );
fprintf(m_fp, "De %d %d %d %lX %X\n", fprintf(m_fp, "De %d %d %d %lX %X\n",
me->GetLayer(), type, me->GetNet(), me->GetLayer(), type, me->GetNetCode(),
me->GetTimeStamp(), me->GetStatus() ); me->GetTimeStamp(), me->GetStatus() );
} }
@ -3644,8 +3647,8 @@ void LEGACY_PLUGIN::saveZONE_CONTAINER( const ZONE_CONTAINER* me ) const
// just for ZONE_CONTAINER compatibility // just for ZONE_CONTAINER compatibility
fprintf( m_fp, "ZInfo %lX %d %s\n", fprintf( m_fp, "ZInfo %lX %d %s\n",
me->GetTimeStamp(), me->GetTimeStamp(),
me->GetIsKeepout() ? 0 : me->GetNet(), me->GetIsKeepout() ? 0 : me->GetNetCode(),
EscapedUTF8( me->GetIsKeepout() ? wxT("") : me->GetNetName() ).c_str() ); EscapedUTF8( me->GetIsKeepout() ? wxT("") : me->GetNetname() ).c_str() );
// Save the outline layer info // Save the outline layer info
fprintf( m_fp, "ZLayer %d\n", me->GetLayer() ); fprintf( m_fp, "ZLayer %d\n", me->GetLayer() );
@ -4422,7 +4425,8 @@ LEGACY_PLUGIN::LEGACY_PLUGIN() :
m_props( 0 ), m_props( 0 ),
m_reader( 0 ), m_reader( 0 ),
m_fp( 0 ), m_fp( 0 ),
m_cache( 0 ) m_cache( 0 ),
m_mapping( new NETINFO_MAPPING() )
{ {
init( NULL ); init( NULL );
} }
@ -4431,4 +4435,5 @@ LEGACY_PLUGIN::LEGACY_PLUGIN() :
LEGACY_PLUGIN::~LEGACY_PLUGIN() LEGACY_PLUGIN::~LEGACY_PLUGIN()
{ {
delete m_cache; delete m_cache;
delete m_mapping;
} }

View File

@ -44,6 +44,7 @@ class NETCLASSES;
class ZONE_CONTAINER; class ZONE_CONTAINER;
class DIMENSION; class DIMENSION;
class NETINFO_ITEM; class NETINFO_ITEM;
class NETINFO_MAPPING;
class TEXTE_MODULE; class TEXTE_MODULE;
class EDGE_MODULE; class EDGE_MODULE;
class TRACK; class TRACK;
@ -124,6 +125,9 @@ protected:
int m_loading_format_version; ///< which BOARD_FORMAT_VERSION am I Load()ing? int m_loading_format_version; ///< which BOARD_FORMAT_VERSION am I Load()ing?
LP_CACHE* m_cache; LP_CACHE* m_cache;
NETINFO_MAPPING* m_mapping; ///< mapping for net codes, so only not empty net codes
///< are stored with consecutive integers as net codes
/// initialize PLUGIN like a constructor would, and futz with fresh BOARD if needed. /// initialize PLUGIN like a constructor would, and futz with fresh BOARD if needed.
void init( const PROPERTIES* aProperties ); void init( const PROPERTIES* aProperties );

View File

@ -161,7 +161,7 @@ bool Magnetize( PCB_EDIT_FRAME* frame, int aCurrentTool, wxSize aGridSize,
if( pad ) if( pad )
{ {
if( doCheckNet && currTrack && currTrack->GetNet() != pad->GetNet() ) if( doCheckNet && currTrack && currTrack->GetNetCode() != pad->GetNetCode() )
return false; return false;
*curpos = pad->GetPosition(); *curpos = pad->GetPosition();
@ -180,7 +180,7 @@ bool Magnetize( PCB_EDIT_FRAME* frame, int aCurrentTool, wxSize aGridSize,
{ {
if( via != currTrack ) // a via cannot influence itself if( via != currTrack ) // a via cannot influence itself
{ {
if( !doCheckNet || !currTrack || currTrack->GetNet() == via->GetNet() ) if( !doCheckNet || !currTrack || currTrack->GetNetCode() == via->GetNetCode() )
{ {
*curpos = via->GetStart(); *curpos = via->GetStart();
// D(printf("via hit\n");) // D(printf("via hit\n");)
@ -223,7 +223,7 @@ bool Magnetize( PCB_EDIT_FRAME* frame, int aCurrentTool, wxSize aGridSize,
if( track->Type() != PCB_TRACE_T ) if( track->Type() != PCB_TRACE_T )
continue; continue;
if( doCheckNet && currTrack && currTrack->GetNet() != track->GetNet() ) if( doCheckNet && currTrack && currTrack->GetNetCode() != track->GetNetCode() )
continue; continue;
if( m_Pcb->IsLayerVisible( track->GetLayer() ) == false ) if( m_Pcb->IsLayerVisible( track->GetLayer() ) == false )

View File

@ -314,11 +314,6 @@ void PCB_EDIT_FRAME::ReCreateMenuBar()
editMenu->AppendSeparator(); editMenu->AppendSeparator();
AddMenuItem( editMenu, ID_SELECTION_TOOL,
_( "Select Tool" ),
_( "Interactive selection and drag&drop tool." ),
KiBitmap( tools_xpm ) );
AddMenuItem( editMenu, ID_PNS_ROUTER_TOOL, AddMenuItem( editMenu, ID_PNS_ROUTER_TOOL,
_( "Interactive router" ), _( "Interactive router" ),
_( "Interactive router push&shove tool." ), _( "Interactive router push&shove tool." ),

View File

@ -69,7 +69,7 @@ MIN_SPAN_TREE::MIN_SPAN_TREE()
void MIN_SPAN_TREE::MSP_Init( int aNodesCount ) void MIN_SPAN_TREE::MSP_Init( int aNodesCount )
{ {
m_Size = aNodesCount; m_Size = std::max( aNodesCount, 1 );
inTree.clear(); inTree.clear();
linkedTo.clear(); linkedTo.clear();
distTo.clear(); distTo.clear();

View File

@ -46,7 +46,7 @@ void FOOTPRINT_EDIT_FRAME::SaveCopyInUndoList( BOARD_ITEM* aItem,
} }
void FOOTPRINT_EDIT_FRAME::SaveCopyInUndoList( PICKED_ITEMS_LIST& aItemsList, void FOOTPRINT_EDIT_FRAME::SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList,
UNDO_REDO_T aTypeCommand, UNDO_REDO_T aTypeCommand,
const wxPoint& aTransformPoint ) const wxPoint& aTransformPoint )
{ {

View File

@ -245,7 +245,7 @@ public:
* @param aTransformPoint = the reference point of the transformation, for * @param aTransformPoint = the reference point of the transformation, for
* commands like move * commands like move
*/ */
virtual void SaveCopyInUndoList( PICKED_ITEMS_LIST& aItemsList, virtual void SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList,
UNDO_REDO_T aTypeCommand, UNDO_REDO_T aTypeCommand,
const wxPoint& aTransformPoint = wxPoint( 0, 0 ) ); const wxPoint& aTransformPoint = wxPoint( 0, 0 ) );

View File

@ -201,7 +201,7 @@ private:
*/ */
void OnLeftDClick( wxDC*, const wxPoint& ) {} void OnLeftDClick( wxDC*, const wxPoint& ) {}
void SaveCopyInUndoList( BOARD_ITEM*, UNDO_REDO_T, const wxPoint& ) {} void SaveCopyInUndoList( BOARD_ITEM*, UNDO_REDO_T, const wxPoint& ) {}
void SaveCopyInUndoList( PICKED_ITEMS_LIST&, UNDO_REDO_T, const wxPoint &) {} void SaveCopyInUndoList( const PICKED_ITEMS_LIST&, UNDO_REDO_T, const wxPoint &) {}
DECLARE_EVENT_TABLE() DECLARE_EVENT_TABLE()

View File

@ -627,7 +627,7 @@ void PCB_EDIT_FRAME::StartMoveOneNodeOrSegment( TRACK* aTrack, wxDC* aDC, int aC
{ {
Collect_TrackSegmentsToDrag( GetBoard(), aTrack->GetStart(), Collect_TrackSegmentsToDrag( GetBoard(), aTrack->GetStart(),
aTrack->GetLayerMask(), aTrack->GetLayerMask(),
aTrack->GetNet(), aTrack->GetWidth() / 2 ); aTrack->GetNetCode(), aTrack->GetWidth() / 2 );
} }
PosInit = aTrack->GetStart(); PosInit = aTrack->GetStart();
@ -647,17 +647,17 @@ void PCB_EDIT_FRAME::StartMoveOneNodeOrSegment( TRACK* aTrack, wxDC* aDC, int aC
case ID_POPUP_PCB_DRAG_TRACK_SEGMENT: // drag a segment case ID_POPUP_PCB_DRAG_TRACK_SEGMENT: // drag a segment
pos = aTrack->GetStart(); pos = aTrack->GetStart();
Collect_TrackSegmentsToDrag( GetBoard(), pos, aTrack->GetLayerMask(), Collect_TrackSegmentsToDrag( GetBoard(), pos, aTrack->GetLayerMask(),
aTrack->GetNet(), aTrack->GetWidth() / 2 ); aTrack->GetNetCode(), aTrack->GetWidth() / 2 );
pos = aTrack->GetEnd(); pos = aTrack->GetEnd();
aTrack->SetFlags( IS_DRAGGED | ENDPOINT | STARTPOINT ); aTrack->SetFlags( IS_DRAGGED | ENDPOINT | STARTPOINT );
Collect_TrackSegmentsToDrag( GetBoard(), pos, aTrack->GetLayerMask(), Collect_TrackSegmentsToDrag( GetBoard(), pos, aTrack->GetLayerMask(),
aTrack->GetNet(), aTrack->GetWidth() / 2 ); aTrack->GetNetCode(), aTrack->GetWidth() / 2 );
break; break;
case ID_POPUP_PCB_MOVE_TRACK_NODE: // Drag via or move node case ID_POPUP_PCB_MOVE_TRACK_NODE: // Drag via or move node
pos = (diag & STARTPOINT) ? aTrack->GetStart() : aTrack->GetEnd(); pos = (diag & STARTPOINT) ? aTrack->GetStart() : aTrack->GetEnd();
Collect_TrackSegmentsToDrag( GetBoard(), pos, aTrack->GetLayerMask(), Collect_TrackSegmentsToDrag( GetBoard(), pos, aTrack->GetLayerMask(),
aTrack->GetNet(), aTrack->GetWidth() / 2 ); aTrack->GetNetCode(), aTrack->GetWidth() / 2 );
PosInit = pos; PosInit = pos;
break; break;
} }
@ -684,7 +684,7 @@ void PCB_EDIT_FRAME::StartMoveOneNodeOrSegment( TRACK* aTrack, wxDC* aDC, int aC
s_LastPos = PosInit; s_LastPos = PosInit;
m_canvas->SetMouseCapture( Show_MoveNode, Abort_MoveTrack ); m_canvas->SetMouseCapture( Show_MoveNode, Abort_MoveTrack );
GetBoard()->SetHighLightNet( aTrack->GetNet() ); GetBoard()->SetHighLightNet( aTrack->GetNetCode() );
GetBoard()->HighLightON(); GetBoard()->HighLightON();
GetBoard()->DrawHighLight( m_canvas, aDC, GetBoard()->GetHighLightNetCode() ); GetBoard()->DrawHighLight( m_canvas, aDC, GetBoard()->GetHighLightNetCode() );
@ -792,7 +792,7 @@ void PCB_EDIT_FRAME::Start_DragTrackSegmentAndKeepSlope( TRACK* track, wxDC* DC
s_LastPos = GetCrossHairPosition(); s_LastPos = GetCrossHairPosition();
m_canvas->SetMouseCapture( Show_Drag_Track_Segment_With_Cte_Slope, Abort_MoveTrack ); m_canvas->SetMouseCapture( Show_Drag_Track_Segment_With_Cte_Slope, Abort_MoveTrack );
GetBoard()->SetHighLightNet( track->GetNet() ); GetBoard()->SetHighLightNet( track->GetNetCode() );
GetBoard()->HighLightON(); GetBoard()->HighLightON();
GetBoard()->DrawHighLight( m_canvas, DC, GetBoard()->GetHighLightNetCode() ); GetBoard()->DrawHighLight( m_canvas, DC, GetBoard()->GetHighLightNetCode() );
@ -828,7 +828,7 @@ bool PCB_EDIT_FRAME::PlaceDraggedOrMovedTrackSegment( TRACK* Track, wxDC* DC )
if( Track == NULL ) if( Track == NULL )
return false; return false;
int current_net_code = Track->GetNet(); int current_net_code = Track->GetNetCode();
// DRC control: // DRC control:
if( g_Drc_On ) if( g_Drc_On )

View File

@ -163,7 +163,7 @@ void PCB_BASE_FRAME::AddPad( MODULE* aModule, bool draw )
// Update the pad properties. // Update the pad properties.
Import_Pad_Settings( pad, false ); Import_Pad_Settings( pad, false );
pad->SetNetname( wxEmptyString ); pad->SetNetCode( NETINFO_LIST::UNCONNECTED );
pad->SetPosition( GetCrossHairPosition() ); pad->SetPosition( GetCrossHairPosition() );

Some files were not shown because too many files have changed in this diff Show More