Commit ff6a7e64 authored by Maciej Suminski's avatar Maciej Suminski Committed by Wayne Stambaugh

OpenGL canvas rats nest merge request.

parents dd3da842 c7996263
include_directories(BEFORE ${INC_BEFORE})
include_directories(
./dialogs
......@@ -37,6 +36,7 @@ set(GAL_SRCS
gal/stroke_font.cpp
gal/color4d.cpp
view/wx_view_controls.cpp
geometry/hetriang.cpp
# OpenGL GAL
gal/opengl/opengl_gal.cpp
......
This diff is collapsed.
/*
* Copyright (C) 1998, 2000-2007, 2010, 2011, 2012, 2013 SINTEF ICT,
* Applied Mathematics, Norway.
*
* Contact information: E-mail: tor.dokken@sintef.no
* SINTEF ICT, Department of Applied Mathematics,
* P.O. Box 124 Blindern,
* 0314 Oslo, Norway.
*
* This file is part of TTL.
*
* TTL is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* TTL 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public
* License along with TTL. If not, see
* <http://www.gnu.org/licenses/>.
*
* In accordance with Section 7(b) of the GNU Affero General Public
* License, a covered work must retain the producer line in every data
* file that is created or manipulated using TTL.
*
* Other Usage
* You can be released from the requirements of the license by purchasing
* a commercial license. Buying such a license is mandatory as soon as you
* develop commercial activities involving the TTL library without
* disclosing the source code of your own applications.
*
* This file may be used in accordance with the terms contained in a
* written agreement between you and SINTEF ICT.
*/
#ifndef _HALF_EDGE_DART_
#define _HALF_EDGE_DART_
#include <ttl/halfedge/hetriang.h>
namespace hed {
//------------------------------------------------------------------------------------------------
// Dart class for the half-edge data structure
//------------------------------------------------------------------------------------------------
/** \class Dart
* \brief \b %Dart class for the half-edge data structure.
*
* See \ref api for a detailed description of how the member functions
* should be implemented.
*/
class Dart {
EdgePtr edge_;
bool dir_; // true if dart is counterclockwise in face
public:
/// Default constructor
Dart() { dir_ = true; }
/// Constructor
Dart(const EdgePtr& edge, bool dir = true) { edge_ = edge; dir_ = dir; }
/// Copy constructor
Dart(const Dart& dart) { edge_ = dart.edge_; dir_ = dart.dir_; }
/// Destructor
~Dart() {}
/// Assignment operator
Dart& operator = (const Dart& dart) {
if (this == &dart)
return *this;
edge_ = dart.edge_;
dir_ = dart.dir_;
return *this;
}
/// Comparing dart objects
bool operator==(const Dart& dart) const {
if (dart.edge_ == edge_ && dart.dir_ == dir_)
return true;
return false;
}
/// Comparing dart objects
bool operator!=(const Dart& dart) const {
return !(dart==*this);
}
/// Maps the dart to a different node
Dart& alpha0() { dir_ = !dir_; return *this; }
/// Maps the dart to a different edge
Dart& alpha1() {
if (dir_) {
edge_ = edge_->getNextEdgeInFace()->getNextEdgeInFace();
dir_ = false;
}
else {
edge_ = edge_->getNextEdgeInFace();
dir_ = true;
}
return *this;
}
/// Maps the dart to a different triangle. \b Note: the dart is not changed if it is at the boundary!
Dart& alpha2() {
if (edge_->getTwinEdge()) {
edge_ = edge_->getTwinEdge();
dir_ = !dir_;
}
// else, the dart is at the boundary and should not be changed
return *this;
}
// Utilities not required by TTL
// -----------------------------
/** @name Utilities not required by TTL */
//@{
void init(const EdgePtr& edge, bool dir = true) { edge_ = edge; dir_ = dir; }
double x() const { return getNode()->GetX(); } // x-coordinate of source node
double y() const { return getNode()->GetY(); } // y-coordinate of source node
bool isCounterClockWise() const { return dir_; }
const NodePtr& getNode() const { return dir_ ? edge_->getSourceNode() : edge_->getTargetNode(); }
const NodePtr& getOppositeNode() const { return dir_ ? edge_->getTargetNode() : edge_->getSourceNode(); }
EdgePtr& getEdge() { return edge_; }
//@} // End of Utilities not required by TTL
};
}; // End of hed namespace
#endif
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
* Copyright (C) 1998, 2000-2007, 2010, 2011, 2012, 2013 SINTEF ICT,
* Applied Mathematics, Norway.
*
* Contact information: E-mail: tor.dokken@sintef.no
* SINTEF ICT, Department of Applied Mathematics,
* P.O. Box 124 Blindern,
* 0314 Oslo, Norway.
*
* This file is part of TTL.
*
* TTL is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* TTL 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public
* License along with TTL. If not, see
* <http://www.gnu.org/licenses/>.
*
* In accordance with Section 7(b) of the GNU Affero General Public
* License, a covered work must retain the producer line in every data
* file that is created or manipulated using TTL.
*
* Other Usage
* You can be released from the requirements of the license by purchasing
* a commercial license. Buying such a license is mandatory as soon as you
* develop commercial activities involving the TTL library without
* disclosing the source code of your own applications.
*
* This file may be used in accordance with the terms contained in a
* written agreement between you and SINTEF ICT.
*/
#ifndef _TTL_UTIL_H_
#define _TTL_UTIL_H_
#include <vector>
#include <algorithm>
#ifdef _MSC_VER
# if _MSC_VER < 1300
# include <minmax.h>
# endif
#endif
//using namespace std;
/** \brief Utilities
*
* This name space contains utility functions for TTL.\n
*
* Point and vector algebra such as scalar product and cross product
* between vectors are implemented here.
* These functions are required by functions in the \ref ttl namespace,
* where they are assumed to be present in the \ref hed::TTLtraits "TTLtraits" class.
* Thus, the user can call these functions from the traits class.
* For efficiency reasons, the user may consider implementing these
* functions in the the API directly on the actual data structure;
* see \ref api.
*
* \note
* - Cross product between vectors in the xy-plane delivers a scalar,
* which is the z-component of the actual cross product
* (the x and y components are both zero).
*
* \see
* ttl and \ref api
*
* \author
* Øyvind Hjelle, oyvindhj@ifi.uio.no
*/
namespace ttl_util {
//------------------------------------------------------------------------------------------------
// ------------------------------ Computational Geometry Group ----------------------------------
//------------------------------------------------------------------------------------------------
/** @name Computational geometry */
//@{
//------------------------------------------------------------------------------------------------
/** Scalar product between two 2D vectors.
*
* \par Returns:
* \code
* dx1*dx2 + dy1*dy2
* \endcode
*/
template <class real_type>
real_type scalarProduct2d(real_type dx1, real_type dy1, real_type dx2, real_type dy2) {
return dx1*dx2 + dy1*dy2;
}
//------------------------------------------------------------------------------------------------
/** Cross product between two 2D vectors. (The z-component of the actual cross product.)
*
* \par Returns:
* \code
* dx1*dy2 - dy1*dx2
* \endcode
*/
template <class real_type>
real_type crossProduct2d(real_type dx1, real_type dy1, real_type dx2, real_type dy2) {
return dx1*dy2 - dy1*dx2;
}
//------------------------------------------------------------------------------------------------
/** Returns a positive value if the 2D nodes/points \e pa, \e pb, and
* \e pc occur in counterclockwise order; a negative value if they occur
* in clockwise order; and zero if they are collinear.
*
* \note
* - This is a finite arithmetic fast version. It can be made more robust using
* exact arithmetic schemes by Jonathan Richard Shewchuk. See
* http://www-2.cs.cmu.edu/~quake/robust.html
*/
template <class real_type>
real_type orient2dfast(real_type pa[2], real_type pb[2], real_type pc[2]) {
real_type acx = pa[0] - pc[0];
real_type bcx = pb[0] - pc[0];
real_type acy = pa[1] - pc[1];
real_type bcy = pb[1] - pc[1];
return acx * bcy - acy * bcx;
}
}; // End of ttl_util namespace scope
#endif // _TTL_UTIL_H_
......@@ -183,7 +183,7 @@ public:
* BOARD.
* @param aBoard The BOARD to put into the frame.
*/
void SetBoard( BOARD* aBoard );
virtual void SetBoard( BOARD* aBoard );
BOARD* GetBoard() const
{
......@@ -191,8 +191,6 @@ public:
return m_Pcb;
}
void ViewReloadBoard( const BOARD* aBoard ) const;
/**
* Function SetFootprintLibTable
* set the footprint library table to \a aFootprintLibTable.
......@@ -727,8 +725,6 @@ public:
void OnUpdateSelectGrid( wxUpdateUIEvent& aEvent );
void OnUpdateSelectZoom( wxUpdateUIEvent& aEvent );
virtual void UseGalCanvas( bool aEnable );
DECLARE_EVENT_TABLE()
};
......
......@@ -228,7 +228,7 @@ public:
const wxPoint& pos, const wxSize& size,
long style = KICAD_DEFAULT_DRAWFRAME_STYLE );
~PCB_EDIT_FRAME();
virtual ~PCB_EDIT_FRAME();
void OnQuit( wxCommandEvent& event );
......@@ -609,6 +609,13 @@ public:
*/
void Show3D_Frame( wxCommandEvent& event );
/**
* Function UseGalCanvas
* Enables/disables GAL canvas.
* @param aEnable determines if GAL should be active or not.
*/
void UseGalCanvas( bool aEnable );
/**
* Function ChangeCanvas
* switches currently used canvas (default / Cairo / OpenGL).
......@@ -894,6 +901,15 @@ public:
*/
bool Clear_Pcb( bool aQuery );
/// @copydoc PCB_BASE_FRAME::SetBoard()
void SetBoard( BOARD* aBoard );
/**
* Function ViewReloadBoard
* adds all items from the current board to the VIEW, so they can be displayed by GAL.
*/
void ViewReloadBoard( const BOARD* aBoard ) const;
// Drc control
/* function GetDrcController
......
......@@ -213,6 +213,8 @@ set( PCBNEW_CLASS_SRCS
print_board_functions.cpp
printout_controler.cpp
ratsnest.cpp
ratsnest_data.cpp
ratsnest_viewitem.cpp
# specctra.cpp #moved in pcbcommon lib
# specctra_export.cpp
# specctra_keywords.cpp
......
......@@ -54,6 +54,8 @@
#include <trigo.h>
#include <pcb_painter.h>
#include <worksheet_viewitem.h>
#include <ratsnest_data.h>
#include <ratsnest_viewitem.h>
#include <tool/tool_manager.h>
#include <tool/tool_dispatcher.h>
......@@ -79,6 +81,7 @@ const LAYER_NUM PCB_BASE_FRAME::GAL_LAYER_ORDER[] =
ITEM_GAL_LAYER( MOD_TEXT_FR_VISIBLE ),
ITEM_GAL_LAYER( MOD_REFERENCES_VISIBLE), ITEM_GAL_LAYER( MOD_VALUES_VISIBLE ),
ITEM_GAL_LAYER( RATSNEST_VISIBLE ),
ITEM_GAL_LAYER( VIAS_HOLES_VISIBLE ), ITEM_GAL_LAYER( PADS_HOLES_VISIBLE ),
ITEM_GAL_LAYER( VIAS_VISIBLE ), ITEM_GAL_LAYER( PADS_VISIBLE ),
......@@ -171,102 +174,6 @@ void PCB_BASE_FRAME::SetBoard( BOARD* aBoard )
{
delete m_Pcb;
m_Pcb = aBoard;
if( m_galCanvas )
{
KIGFX::VIEW* view = m_galCanvas->GetView();
try
{
ViewReloadBoard( m_Pcb );
}
catch( const std::exception& ex )
{
DBG(printf( "ViewReloadBoard: exception: %s\n", ex.what() );)
}
// update the tool manager with the new board and its view.
if( m_toolManager )
m_toolManager->SetEnvironment( m_Pcb, view, m_galCanvas->GetViewControls(), this );
}
}
void PCB_BASE_FRAME::ViewReloadBoard( const BOARD* aBoard ) const
{
KIGFX::VIEW* view = m_galCanvas->GetView();
view->Clear();
// All of PCB drawing elements should be added to the VIEW
// in order to be displayed
// Load zones
for( int i = 0; i < aBoard->GetAreaCount(); ++i )
{
view->Add( (KIGFX::VIEW_ITEM*) ( aBoard->GetArea( i ) ) );
}
// Load drawings
for( BOARD_ITEM* drawing = aBoard->m_Drawings; drawing; drawing = drawing->Next() )
{
view->Add( drawing );
}
// Load tracks
for( TRACK* track = aBoard->m_Track; track; track = track->Next() )
{
view->Add( track );
}
// Load modules and its additional elements
for( MODULE* module = aBoard->m_Modules; module; module = module->Next() )
{
// Load module's pads
for( D_PAD* pad = module->Pads().GetFirst(); pad; pad = pad->Next() )
{
view->Add( pad );
}
// Load module's drawing (mostly silkscreen)
for( BOARD_ITEM* drawing = module->GraphicalItems().GetFirst(); drawing;
drawing = drawing->Next() )
{
view->Add( drawing );
}
// Load module's texts (name and value)
view->Add( &module->Reference() );
view->Add( &module->Value() );
// Add the module itself
view->Add( module );
}
// Segzones (equivalent of ZONE_CONTAINER for legacy boards)
for( SEGZONE* zone = aBoard->m_Zone; zone; zone = zone->Next() )
{
view->Add( zone );
}
// Add an entry for the worksheet layout
KIGFX::WORKSHEET_VIEWITEM* worksheet = new KIGFX::WORKSHEET_VIEWITEM(
std::string( aBoard->GetFileName().mb_str() ),
std::string( GetScreenDesc().mb_str() ),
&GetPageSettings(), &GetTitleBlock() );
BASE_SCREEN* screen = GetScreen();
if( screen != NULL )
{
worksheet->SetSheetNumber( GetScreen()->m_ScreenNumber );
worksheet->SetSheetCount( GetScreen()->m_NumberOfScreens );
}
view->Add( worksheet );
view->SetPanBoundary( worksheet->ViewBBox() );
view->RecacheAllItems( true );
if( m_galCanvasActive )
m_galCanvas->Refresh();
}
......@@ -604,17 +511,6 @@ void PCB_BASE_FRAME::OnUpdateSelectZoom( wxUpdateUIEvent& aEvent )
}
void PCB_BASE_FRAME::UseGalCanvas( bool aEnable )
{
EDA_DRAW_FRAME::UseGalCanvas( aEnable );
ViewReloadBoard( m_Pcb );
m_toolManager->SetEnvironment( m_Pcb, m_galCanvas->GetView(),
m_galCanvas->GetViewControls(), this );
}
void PCB_BASE_FRAME::ProcessItemSelection( wxCommandEvent& aEvent )
{
int id = aEvent.GetId();
......@@ -908,6 +804,7 @@ void PCB_BASE_FRAME::LoadSettings()
view->SetRequired( SOLDERMASK_N_BACK, ITEM_GAL_LAYER( PAD_BK_VISIBLE ) );
view->SetLayerTarget( ITEM_GAL_LAYER( GP_OVERLAY ), KIGFX::TARGET_OVERLAY );
view->SetLayerTarget( ITEM_GAL_LAYER( RATSNEST_VISIBLE ), KIGFX::TARGET_OVERLAY );
// Apply layer coloring scheme & display options
if( view->GetPainter() )
......
......@@ -42,6 +42,7 @@
#include <pcb_netlist.h>
#include <reporter.h>
#include <base_units.h>
#include <ratsnest_data.h>
#include <pcbnew.h>
#include <colors_selection.h>
......@@ -102,11 +103,15 @@ BOARD::BOARD() :
m_NetClasses.GetDefault()->SetParams();
SetCurrentNetClass( m_NetClasses.GetDefault()->GetName() );
m_ratsnest = new RN_DATA( this );
}
BOARD::~BOARD()
{
delete m_ratsnest;
while( m_ZoneDescriptorList.size() )
{
ZONE_CONTAINER* area_to_remove = m_ZoneDescriptorList[0];
......
......@@ -56,6 +56,7 @@ class MARKER_PCB;
class MSG_PANEL_ITEM;
class NETLIST;
class REPORTER;
class RN_DATA;
// non-owning container of item candidates when searching for items on the same track.
......@@ -225,6 +226,7 @@ private:
EDA_RECT m_BoundingBox;
NETINFO_LIST m_NetInfo; ///< net info list (name, design constraints ..
RN_DATA* m_ratsnest;
BOARD_DESIGN_SETTINGS m_designSettings;
ZONE_SETTINGS m_zoneSettings;
......@@ -355,6 +357,16 @@ public:
*/
BOARD_ITEM* Remove( BOARD_ITEM* aBoardItem );
/**
* Function GetRatsnest()
* returns list of missing connections between components/tracks.
* @return RATSNEST* is an object that contains informations about missing connections.
*/
RN_DATA* GetRatsnest() const
{
return m_ratsnest;
}
/**
* Function DeleteMARKERs
* deletes ALL MARKERS from the board.
......
......@@ -59,6 +59,13 @@
#include <view/view.h>
#include <painter.h>
#include <class_track.h>
#include <class_board.h>
#include <class_module.h>
#include <worksheet_viewitem.h>
#include <ratsnest_data.h>
#include <ratsnest_viewitem.h>
#include <tool/tool_manager.h>
#include <tool/tool_dispatcher.h>
......@@ -328,6 +335,16 @@ PCB_EDIT_FRAME::PCB_EDIT_FRAME( wxWindow* parent, const wxString& title,
SetBoard( new BOARD() );
if( m_galCanvas )
{
ViewReloadBoard( m_Pcb );
// update the tool manager with the new board and its view.
if( m_toolManager )
m_toolManager->SetEnvironment( m_Pcb, m_galCanvas->GetView(),
m_galCanvas->GetViewControls(), this );
}
// Create the PCB_LAYER_WIDGET *after* SetBoard():
wxFont font = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT );
......@@ -517,6 +534,106 @@ PCB_EDIT_FRAME::~PCB_EDIT_FRAME()
}
void PCB_EDIT_FRAME::SetBoard( BOARD* aBoard )
{
PCB_BASE_FRAME::SetBoard( aBoard );
if( m_galCanvas )
{
ViewReloadBoard( aBoard );
// update the tool manager with the new board and its view.
if( m_toolManager )
m_toolManager->SetEnvironment( aBoard, m_galCanvas->GetView(),
m_galCanvas->GetViewControls(), this );
}
}
void PCB_EDIT_FRAME::ViewReloadBoard( const BOARD* aBoard ) const
{
KIGFX::VIEW* view = m_galCanvas->GetView();
view->Clear();
// All of PCB drawing elements should be added to the VIEW
// in order to be displayed
// Load zones
for( int i = 0; i < aBoard->GetAreaCount(); ++i )
{
view->Add( (KIGFX::VIEW_ITEM*) ( aBoard->GetArea( i ) ) );
}
// Load drawings
for( BOARD_ITEM* drawing = aBoard->m_Drawings; drawing; drawing = drawing->Next() )
{
view->Add( drawing );
}
// Load tracks
for( TRACK* track = aBoard->m_Track; track; track = track->Next() )
{
view->Add( track );
}
// Load modules and its additional elements
for( MODULE* module = aBoard->m_Modules; module; module = module->Next() )
{
// Load module's pads
for( D_PAD* pad = module->Pads().GetFirst(); pad; pad = pad->Next() )
{
view->Add( pad );
}
// Load module's drawing (mostly silkscreen)
for( BOARD_ITEM* drawing = module->GraphicalItems().GetFirst(); drawing;
drawing = drawing->Next() )
{
view->Add( drawing );
}
// Load module's texts (name and value)
view->Add( &module->Reference() );
view->Add( &module->Value() );
// Add the module itself
view->Add( module );
}
// Segzones (equivalent of ZONE_CONTAINER for legacy boards)
for( SEGZONE* zone = aBoard->m_Zone; zone; zone = zone->Next() )
{
view->Add( zone );
}
// Add an entry for the worksheet layout
KIGFX::WORKSHEET_VIEWITEM* worksheet = new KIGFX::WORKSHEET_VIEWITEM(
std::string( aBoard->GetFileName().mb_str() ),
std::string( GetScreenDesc().mb_str() ),
&GetPageSettings(), &GetTitleBlock() );
BASE_SCREEN* screen = GetScreen();
if( screen != NULL )
{
worksheet->SetSheetNumber( GetScreen()->m_ScreenNumber );
worksheet->SetSheetCount( GetScreen()->m_NumberOfScreens );
}
view->Add( worksheet );
// Add an entry for the ratsnest
RN_DATA* ratsnest = aBoard->GetRatsnest();
ratsnest->ProcessBoard();
ratsnest->Recalculate();
view->Add( new KIGFX::RATSNEST_VIEWITEM( ratsnest ) );
view->SetPanBoundary( worksheet->ViewBBox() );
view->RecacheAllItems( true );
if( m_galCanvasActive )
m_galCanvas->Refresh();
}
bool PCB_EDIT_FRAME::isAutoSaveRequired() const
{
return GetScreen()->IsSave();
......@@ -629,6 +746,17 @@ void PCB_EDIT_FRAME::Show3D_Frame( wxCommandEvent& event )
}
void PCB_EDIT_FRAME::UseGalCanvas( bool aEnable )
{
EDA_DRAW_FRAME::UseGalCanvas( aEnable );
m_toolManager->SetEnvironment( m_Pcb, m_galCanvas->GetView(),
m_galCanvas->GetViewControls(), this );
ViewReloadBoard( m_Pcb );
}
void PCB_EDIT_FRAME::SwitchCanvas( wxCommandEvent& aEvent )
{
int id = aEvent.GetId();
......@@ -791,7 +919,7 @@ void PCB_EDIT_FRAME::setHighContrastLayer( LAYER_NUM aLayer )
GetNetnameLayer( aLayer ), ITEM_GAL_LAYER( VIAS_VISIBLE ),
ITEM_GAL_LAYER( VIAS_HOLES_VISIBLE ), ITEM_GAL_LAYER( PADS_VISIBLE ),
ITEM_GAL_LAYER( PADS_HOLES_VISIBLE ), ITEM_GAL_LAYER( PADS_NETNAMES_VISIBLE ),
ITEM_GAL_LAYER( GP_OVERLAY )
ITEM_GAL_LAYER( GP_OVERLAY ), ITEM_GAL_LAYER( RATSNEST_VISIBLE )
};
for( unsigned int i = 0; i < sizeof( layers ) / sizeof( LAYER_NUM ); ++i )
......@@ -831,7 +959,7 @@ void PCB_EDIT_FRAME::setTopLayer( LAYER_NUM aLayer )
GetNetnameLayer( aLayer ), ITEM_GAL_LAYER( VIAS_VISIBLE ),
ITEM_GAL_LAYER( VIAS_HOLES_VISIBLE ), ITEM_GAL_LAYER( PADS_VISIBLE ),
ITEM_GAL_LAYER( PADS_HOLES_VISIBLE ), ITEM_GAL_LAYER( PADS_NETNAMES_VISIBLE ),
ITEM_GAL_LAYER( GP_OVERLAY ), DRAW_N
ITEM_GAL_LAYER( GP_OVERLAY ), ITEM_GAL_LAYER( RATSNEST_VISIBLE ), DRAW_N
};
for( unsigned int i = 0; i < sizeof( layers ) / sizeof( LAYER_NUM ); ++i )
......
This diff is collapsed.
This diff is collapsed.
/*
* This program source code file is part of KICAD, a free EDA CAD application.
*
* Copyright (C) 2013 CERN
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* 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 ratsnest_viewitem.cpp
* @brief Class that draws missing connections on a PCB.
*/
#include <ratsnest_viewitem.h>
#include <ratsnest_data.h>
#include <gal/graphics_abstraction_layer.h>
#include <layers_id_colors_and_visibility.h>
#include <boost/foreach.hpp>
using namespace KIGFX;
RATSNEST_VIEWITEM::RATSNEST_VIEWITEM( RN_DATA* aData ) :
EDA_ITEM( NOT_USED ), m_data( aData )
{
}
const BOX2I RATSNEST_VIEWITEM::ViewBBox() const
{
// Make it always visible
BOX2I bbox;
bbox.SetMaximum();
return bbox;
}
void RATSNEST_VIEWITEM::ViewDraw( int aLayer, GAL* aGal ) const
{
aGal->SetIsStroke( true );
aGal->SetIsFill( false );
aGal->SetLineWidth( 1.0 );
aGal->SetStrokeColor( COLOR4D( 1.0, 1.0, 1.0, 0.4 ) );
// Draw the temporary ratsnest
BOOST_FOREACH( const RN_NET& net, m_data->GetNets() )
{
if( !net.IsVisible() )
continue;
// Avoid duplicate destinations for ratsnest lines by storing already used nodes
boost::unordered_set<RN_NODE_PTR> usedDestinations;
// Draw the "dynamic" ratsnest (ie. for objects that may be currently being moved)
BOOST_FOREACH( const RN_NODE_PTR& node, net.GetSimpleNodes() )
{
RN_NODE_PTR dest = net.GetClosestNode( node, WITHOUT_FLAG() );
if( dest && usedDestinations.find( dest ) == usedDestinations.end() )
{
VECTOR2D origin( node->GetX(), node->GetY() );
VECTOR2D end( dest->GetX(), dest->GetY() );
aGal->DrawLine( origin, end );
usedDestinations.insert( dest );
}
}
// Draw the "static" ratsnest
const std::vector<RN_EDGE_PTR>* edges = net.GetUnconnected();
if( edges == NULL )
continue;
BOOST_FOREACH( const RN_EDGE_PTR& edge, *edges )
{
const RN_NODE_PTR& sourceNode = edge->getSourceNode();
const RN_NODE_PTR& targetNode = edge->getTargetNode();
VECTOR2D source( sourceNode->GetX(), sourceNode->GetY() );
VECTOR2D target( targetNode->GetX(), targetNode->GetY() );
aGal->DrawLine( source, target );
}
}
}
void RATSNEST_VIEWITEM::ViewGetLayers( int aLayers[], int& aCount ) const
{
aCount = 1;
aLayers[0] = ITEM_GAL_LAYER( RATSNEST_VISIBLE );
}
/*
* This program source code file is part of KICAD, a free EDA CAD application.
*
* Copyright (C) 2013 CERN
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* 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 ratsnest_viewitem.h
* @brief Class that draws missing connections on a PCB.
*/
#ifndef RATSNEST_VIEWITEM_H
#define RATSNEST_VIEWITEM_H
#include <base_struct.h>
#include <math/vector2d.h>
class GAL;
class RN_DATA;
namespace KIGFX
{
class RATSNEST_VIEWITEM : public EDA_ITEM
{
public:
RATSNEST_VIEWITEM( RN_DATA* aData );
/// @copydoc VIEW_ITEM::ViewBBox()
const BOX2I ViewBBox() const;
/// @copydoc VIEW_ITEM::ViewDraw()
void ViewDraw( int aLayer, GAL* aGal ) const;
/// @copydoc VIEW_ITEM::ViewGetLayers()
void ViewGetLayers( int aLayers[], int& aCount ) const;
/// @copydoc EDA_ITEM::Show()
void Show( int x, std::ostream& st ) const
{
}
protected:
///> Object containing ratsnest data.
RN_DATA* m_data;
};
} // namespace KIGFX
#endif /* RATSNEST_VIEWITEM_H */
......@@ -49,6 +49,7 @@
#include <class_board_item.h>
#include <class_pad.h>
#include <class_track.h>
#include <ratsnest_data.h>
#include <layers_id_colors_and_visibility.h>
// an ugly singleton for drawing debug items within the router context.
......@@ -626,6 +627,7 @@ void PNS_ROUTER::commitRouting( PNS_NODE* aNode )
newBI->ClearFlags();
m_view->Add( newBI );
m_board->Add( newBI );
m_board->GetRatsnest()->Update( static_cast<BOARD_CONNECTED_ITEM*>( newBI ) );
newBI->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
}
}
......@@ -757,6 +759,8 @@ void PNS_ROUTER::StopRouting()
// highlightCurrent(false);
// Update the ratsnest
m_board->GetRatsnest()->Recalculate( m_currentNet );
EraseView();
m_state = IDLE;
......
......@@ -26,8 +26,11 @@
#include <class_module.h>
#include <tool/tool_manager.h>
#include <view/view_controls.h>
#include <ratsnest_data.h>
#include <confirm.h>
#include <boost/foreach.hpp>
#include "common_actions.h"
#include "selection_tool.h"
#include "move_tool.h"
......@@ -41,11 +44,6 @@ MOVE_TOOL::MOVE_TOOL() :
}
MOVE_TOOL::~MOVE_TOOL()
{
}
void MOVE_TOOL::Reset()
{
// The tool launches upon reception of action event ("pcbnew.InteractiveMove")
......@@ -111,11 +109,13 @@ int MOVE_TOOL::Main( TOOL_EVENT& aEvent )
{
m_state.Rotate( cursorPos, 900.0 );
selection.group->ViewUpdate( VIEW_ITEM::GEOMETRY );
updateRatsnest( true );
}
else if( evt->IsAction( &COMMON_ACTIONS::flip ) ) // got flip event?
{
m_state.Flip( cursorPos );
selection.group->ViewUpdate( VIEW_ITEM::GEOMETRY );
updateRatsnest( true );
}
}
......@@ -126,6 +126,8 @@ int MOVE_TOOL::Main( TOOL_EVENT& aEvent )
// Drag items to the current cursor position
VECTOR2D movement = ( evt->Position() - dragPosition );
m_state.Move( movement );
updateRatsnest( true );
}
else
{
......@@ -153,17 +155,50 @@ int MOVE_TOOL::Main( TOOL_EVENT& aEvent )
// Modifications has to be rollbacked, so restore the previous state of items
selection.group->ItemsViewUpdate( VIEW_ITEM::APPEARANCE );
m_state.RestoreAll();
updateRatsnest( false );
}
else
{
// Changes are applied, so update the items
selection.group->ItemsViewUpdate( m_state.GetUpdateFlag() );
m_state.Apply();
}
RN_DATA* ratsnest = static_cast<BOARD*>( m_toolMgr->GetModel() )->GetRatsnest();
ratsnest->Recalculate();
controls->ShowCursor( false );
controls->SetSnapping( false );
controls->SetAutoPan( false );
return 0;
}
void MOVE_TOOL::updateRatsnest( bool aRedraw )
{
const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection();
RN_DATA* ratsnest = static_cast<BOARD*>( m_toolMgr->GetModel() )->GetRatsnest();
ratsnest->ClearSimple();
BOOST_FOREACH( BOARD_ITEM* item, selection.items )
{
if( item->Type() == PCB_PAD_T || item->Type() == PCB_TRACE_T ||
item->Type() == PCB_VIA_T || item->Type() == PCB_ZONE_AREA_T )
{
ratsnest->Update( static_cast<BOARD_CONNECTED_ITEM*>( item ) );
if( aRedraw )
ratsnest->AddSimple( static_cast<BOARD_CONNECTED_ITEM*>( item ) );
}
else if( item->Type() == PCB_MODULE_T )
{
ratsnest->Update( static_cast<MODULE*>( item ) );
if( aRedraw )
ratsnest->AddSimple( static_cast<MODULE*>( item ) );
}
}
}
......@@ -49,7 +49,6 @@ class MOVE_TOOL : public TOOL_INTERACTIVE
{
public:
MOVE_TOOL();
~MOVE_TOOL();
/// @copydoc TOOL_INTERACTIVE::Reset()
void Reset();
......@@ -65,6 +64,8 @@ public:
int Main( TOOL_EVENT& aEvent );
private:
void updateRatsnest( bool aRedraw );
/// Saves the state of items and allows to restore them
ITEM_STATE m_state;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment