KiCad PCB EDA Suite
ratsnest_viewitem.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KICAD, a free EDA CAD application.
3  *
4  * Copyright (C) 2013 CERN
5  * Copyright (C) 2018-2019 KiCad Developers, see AUTHORS.txt for contributors.
6  *
7  * @author Maciej Suminski <maciej.suminski@cern.ch>
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2
12  * of the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, you may find one here:
21  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
22  * or you may search the http://www.gnu.org website for the version 2 license,
23  * or you may write to the Free Software Foundation, Inc.,
24  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
25  */
26 
33 
35 #include <pcb_painter.h>
36 #include <ratsnest/ratsnest_data.h>
37 
39 #include <pcb_base_frame.h>
40 
41 #include <memory>
42 #include <utility>
43 
44 #include <view/view.h>
45 
46 namespace KIGFX {
47 
48 RATSNEST_VIEWITEM::RATSNEST_VIEWITEM( std::shared_ptr<CONNECTIVITY_DATA> aData ) :
49  EDA_ITEM( NOT_USED ), m_data( std::move(aData) )
50 {
51 }
52 
53 
55 {
56  // Make it always visible
57  BOX2I bbox;
58  bbox.SetMaximum();
59 
60  return bbox;
61 }
62 
63 
64 void RATSNEST_VIEWITEM::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const
65 {
66  std::unique_lock<std::mutex> lock( m_data->GetLock(), std::try_to_lock );
67 
68  if( !lock )
69  return;
70 
71  constexpr int CROSS_SIZE = 200000;
72 
73  auto gal = aView->GetGAL();
74  gal->SetIsStroke( true );
75  gal->SetIsFill( false );
76  gal->SetLineWidth( 1.0 );
77  auto rs = static_cast<PCB_RENDER_SETTINGS*>( aView->GetPainter()->GetSettings() );
78 
79  COLOR4D defaultColor = rs->GetColor( nullptr, LAYER_RATSNEST );
80  COLOR4D color = defaultColor;
81  const bool colorByNet = rs->GetNetColorMode() != NET_COLOR_MODE::OFF;
82 
83  std::set<int> highlightedNets = rs->GetHighlightNetCodes();
84  const std::set<int>& hiddenNets = rs->GetHiddenNets();
85 
86  std::map<int, KIGFX::COLOR4D>& netColors = rs->GetNetColorMap();
87  std::map<wxString, KIGFX::COLOR4D>& netclassColors = rs->GetNetclassColorMap();
88  const std::map<int, wxString>& netclassMap = m_data->GetNetclassMap();
89 
90  const bool onlyVisibleLayers = rs->GetRatsnestDisplayMode() == RATSNEST_MODE::VISIBLE;
91 
92  LSET visibleLayers;
93 
94  for( PCB_LAYER_ID layer : LSET::AllCuMask().Seq() )
95  if( aView->IsLayerVisible( layer ) )
96  visibleLayers.set( layer );
97 
98  const bool curved_ratsnest = rs->GetCurvedRatsnestLinesEnabled();
99 
100  // Draw the "dynamic" ratsnest (i.e. for objects that may be currently being moved)
101  for( const RN_DYNAMIC_LINE& l : m_data->GetDynamicRatsnest() )
102  {
103  if( hiddenNets.count( l.netCode ) )
104  continue;
105 
106  if( colorByNet && netColors.count( l.netCode ) )
107  color = netColors.at( l.netCode );
108  else if( colorByNet && netclassMap.count( l.netCode )
109  && netclassColors.count( netclassMap.at( l.netCode ) ) )
110  color = netclassColors.at( netclassMap.at( l.netCode ) );
111  else
112  color = defaultColor;
113 
114  if( color == COLOR4D::UNSPECIFIED )
115  color = defaultColor;
116 
117  gal->SetStrokeColor( color.Brightened( 0.5 ) );
118 
119  if ( l.a == l.b )
120  {
121  gal->DrawLine( VECTOR2I( l.a.x - CROSS_SIZE, l.a.y - CROSS_SIZE ),
122  VECTOR2I( l.b.x + CROSS_SIZE, l.b.y + CROSS_SIZE ) );
123  gal->DrawLine( VECTOR2I( l.a.x - CROSS_SIZE, l.a.y + CROSS_SIZE ),
124  VECTOR2I( l.b.x + CROSS_SIZE, l.b.y - CROSS_SIZE ) );
125  }
126  else
127  {
128  if( curved_ratsnest )
129  {
130  auto dx = l.b.x - l.a.x;
131  auto dy = l.b.y - l.a.y;
132  const auto center = VECTOR2I( l.a.x + 0.5 * dx - 0.1 * dy,
133  l.a.y + 0.5 * dy + 0.1 * dx );
134  gal->DrawCurve( l.a, center, center, l.b );
135  }
136  else
137  {
138  gal->DrawLine( l.a, l.b );
139  }
140  }
141  }
142 
143  for( int i = 1 /* skip "No Net" at [0] */; i < m_data->GetNetCount(); ++i )
144  {
145  if( hiddenNets.count( i ) )
146  continue;
147 
148  RN_NET* net = m_data->GetRatsnestForNet( i );
149 
150  if( !net )
151  continue;
152 
153  if( colorByNet && netColors.count( i ) )
154  color = netColors.at( i );
155  else if( colorByNet && netclassMap.count( i )
156  && netclassColors.count( netclassMap.at( i ) ) )
157  color = netclassColors.at( netclassMap.at( i ) );
158  else
159  color = defaultColor;
160 
161  if( color == COLOR4D::UNSPECIFIED )
162  color = defaultColor;
163 
164  // Draw the "static" ratsnest
165  if( highlightedNets.count( i ) )
166  gal->SetStrokeColor( color.Brightened(0.8) );
167  else
168  gal->SetStrokeColor( color ); // using the default ratsnest color for not highlighted
169 
170  for( const auto& edge : net->GetUnconnected() )
171  {
172  //if ( !edge.IsVisible() )
173  // continue;
174 
175  const auto& sourceNode = edge.GetSourceNode();
176  const auto& targetNode = edge.GetTargetNode();
177  const VECTOR2I source( sourceNode->Pos() );
178  const VECTOR2I target( targetNode->Pos() );
179 
180  if( !sourceNode->Valid() || !targetNode->Valid() )
181  continue;
182 
183  bool enable = !sourceNode->GetNoLine() && !targetNode->GetNoLine();
184  bool show;
185 
186  // If the global ratsnest is currently enabled, the local ratsnest
187  // should be easy to turn off, so either element can disable it
188  // If the global ratsnest is disabled, the local ratsnest should be easy to turn on
189  // so either element can enable it.
190  if( rs->GetGlobalRatsnestLinesEnabled() )
191  show = sourceNode->Parent()->GetLocalRatsnestVisible() &&
192  targetNode->Parent()->GetLocalRatsnestVisible();
193  else
194  show = sourceNode->Parent()->GetLocalRatsnestVisible() ||
195  targetNode->Parent()->GetLocalRatsnestVisible();
196 
197  if( onlyVisibleLayers && show )
198  {
199  LSET sourceLayers = sourceNode->Parent()->GetLayerSet();
200  LSET targetLayers = targetNode->Parent()->GetLayerSet();
201 
202  if( !( sourceLayers & visibleLayers ).any() ||
203  !( targetLayers & visibleLayers ).any() )
204  show = false;
205  }
206 
207  if ( enable && show )
208  {
209  if ( source == target )
210  {
211  gal->DrawLine( VECTOR2I( source.x - CROSS_SIZE, source.y - CROSS_SIZE ),
212  VECTOR2I( source.x + CROSS_SIZE, source.y + CROSS_SIZE ) );
213  gal->DrawLine( VECTOR2I( source.x - CROSS_SIZE, source.y + CROSS_SIZE ),
214  VECTOR2I( source.x + CROSS_SIZE, source.y - CROSS_SIZE ) );
215  }
216  else
217  {
218  if( curved_ratsnest )
219  {
220  auto dx = target.x - source.x;
221  auto dy = target.y - source.y;
222  const auto center = VECTOR2I( source.x + 0.5 * dx - 0.1 * dy,
223  source.y + 0.5 * dy + 0.1 * dx );
224  gal->DrawCurve( source, center, center, target );
225  }
226  else
227  {
228  gal->DrawLine( source, target );
229  }
230  }
231  }
232  }
233  }
234 }
235 
236 
237 void RATSNEST_VIEWITEM::ViewGetLayers( int aLayers[], int& aCount ) const
238 {
239  aCount = 1;
240  aLayers[0] = LAYER_RATSNEST;
241 }
242 
243 }
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:749
const BOX2I ViewBBox() const override
Function ViewBBox() returns the bounding box of the item covering all its layers.
Class that draws missing connections on a PCB.
const std::vector< CN_EDGE > GetUnconnected() const
Function GetUnconnected() Returns pointer to a vector of edges that makes ratsnest for a given net.
Class CAIRO_GAL is the cairo implementation of the graphics abstraction layer.
Definition: color4d.cpp:175
RATSNEST_VIEWITEM(std::shared_ptr< CONNECTIVITY_DATA > aData)
Ratsnest lines are drawn to items on visible layers only.
std::shared_ptr< CONNECTIVITY_DATA > m_data
Object containing ratsnest data.
Class that computes missing connections on a PCB.
the 3d code uses this value
Definition: typeinfo.h:80
int color
Definition: DXF_plotter.cpp:60
GAL * GetGAL() const
Function GetGAL() Returns the GAL this view is using to draw graphical primitives.
Definition: view.h:182
Template specialization to enable wxStrings for certain containers (e.g. unordered_map)
Definition: bitmap.cpp:58
VECTOR2< int > VECTOR2I
Definition: vector2d.h:594
PAINTER * GetPainter() const
Function GetPainter() Returns the painter object used by the view for drawing VIEW_ITEMS.
Definition: view.h:201
static const COLOR4D UNSPECIFIED
For legacy support; used as a value to indicate color hasn't been set yet.
Definition: color4d.h:380
Classes used in Pcbnew, CvPcb and GerbView.
PCB_LAYER_ID
A quick note on layer IDs:
LSET is a set of PCB_LAYER_IDs.
void SetMaximum()
Definition: box2.h:73
virtual RENDER_SETTINGS * GetSettings()=0
Function GetAdapter Returns pointer to current settings that are going to be used when drawing items.
void ViewGetLayers(int aLayers[], int &aCount) const override
Function ViewGetLayers() Returns the all the layers within the VIEW the object is painted on.
Board layer functions and definitions.
Net (and netclass) colors are not shown.
void ViewDraw(int aLayer, KIGFX::VIEW *aView) const override
Function ViewDraw() Draws the parts of the object belonging to layer aLayer.
EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boards.
Definition: eda_item.h:148
RN_NET Describes ratsnest for a single net.
Definition: ratsnest_data.h:61
VIEW.
Definition: view.h:63
virtual void SetIsStroke(bool aIsStrokeEnabled)
Enable/disable stroked outlines.
bool IsLayerVisible(int aLayer) const
Function IsLayerVisible() Returns information about visibility of a particular layer.
Definition: view.h:402
COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:100