KiCad PCB EDA Suite
ratsnest_view_item.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-2021 KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * @author Maciej Suminski <[email protected]>
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
32
33#include <kiface_base.h>
34#include <pcbnew_settings.h>
35#include <pcb_painter.h>
37#include <layer_ids.h>
38#include <pcb_base_frame.h>
39#include <view/view.h>
40
41#include <memory>
42#include <utility>
43
44
45RATSNEST_VIEW_ITEM::RATSNEST_VIEW_ITEM( std::shared_ptr<CONNECTIVITY_DATA> aData ) :
46 EDA_ITEM( NOT_USED ), m_data( std::move(aData) )
47{
48}
49
50
52{
53 // Make it always visible
54 BOX2I bbox;
55 bbox.SetMaximum();
56
57 return bbox;
58}
59
60
61void RATSNEST_VIEW_ITEM::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const
62{
63 std::unique_lock<KISPINLOCK> lock( m_data->GetLock(), std::try_to_lock );
64
65 if( !lock )
66 return;
67
68 constexpr int CROSS_SIZE = 200000;
69
70 auto gal = aView->GetGAL();
71 gal->SetIsStroke( true );
72 gal->SetIsFill( false );
73 gal->SetLineWidth( 1.0 );
74 auto cfg = static_cast<PCBNEW_SETTINGS*>( Kiface().KifaceSettings() );
75
76 if( !cfg )
77 return;
78
79 auto rs = static_cast<KIGFX::PCB_RENDER_SETTINGS*>( aView->GetPainter()->GetSettings() );
80
81 std::set<int> highlightedNets = rs->GetHighlightNetCodes();
82 const std::set<int>& hiddenNets = rs->GetHiddenNets();
83
84 COLOR4D defaultColor = rs->GetColor( nullptr, LAYER_RATSNEST );
85 COLOR4D color = defaultColor;
86 const bool colorByNet = rs->GetNetColorMode() != NET_COLOR_MODE::OFF;
87 const bool dimStatic = m_data->GetLocalRatsnest().size() > 0 || highlightedNets.size() > 0;
88
89 std::map<int, KIGFX::COLOR4D>& netColors = rs->GetNetColorMap();
90 std::map<wxString, KIGFX::COLOR4D>& ncColors = rs->GetNetclassColorMap();
91 const std::map<int, wxString>& ncMap = m_data->GetNetclassMap();
92
93 const bool onlyVisibleLayers = cfg->m_Display.m_RatsnestMode == RATSNEST_MODE::VISIBLE;
94 LSET visibleLayers;
95
96 // If we are in "other layers off" mode, the active layer is the only visible layer
97 if( rs->m_ContrastModeDisplay == HIGH_CONTRAST_MODE::HIDDEN )
98 {
99 visibleLayers.set( rs->GetPrimaryHighContrastLayer() );
100 }
101 else
102 {
103 for( PCB_LAYER_ID layer : LSET::AllCuMask().Seq() )
104 {
105 if( aView->IsLayerVisible( layer ) )
106 visibleLayers.set( layer );
107 }
108 }
109
110 const bool curved_ratsnest = cfg->m_Display.m_DisplayRatsnestLinesCurved;
111
112 // Draw the "dynamic" ratsnest (i.e. for objects that may be currently being moved)
113 for( const RN_DYNAMIC_LINE& l : m_data->GetLocalRatsnest() )
114 {
115 if( hiddenNets.count( l.netCode ) )
116 continue;
117
118 if( colorByNet && netColors.count( l.netCode ) )
119 color = netColors.at( l.netCode );
120 else if( colorByNet && ncMap.count( l.netCode ) && ncColors.count( ncMap.at( l.netCode ) ) )
121 color = ncColors.at( ncMap.at( l.netCode ) );
122 else
123 color = defaultColor;
124
125 if( color == COLOR4D::UNSPECIFIED )
126 color = defaultColor;
127
128 gal->SetStrokeColor( color.Brightened( 0.5 ).WithAlpha( std::min( 1.0, color.a + 0.3 ) ) );
129
130 if( l.a == l.b )
131 {
132 gal->DrawLine( VECTOR2I( l.a.x - CROSS_SIZE, l.a.y - CROSS_SIZE ),
133 VECTOR2I( l.b.x + CROSS_SIZE, l.b.y + CROSS_SIZE ) );
134 gal->DrawLine( VECTOR2I( l.a.x - CROSS_SIZE, l.a.y + CROSS_SIZE ),
135 VECTOR2I( l.b.x + CROSS_SIZE, l.b.y - CROSS_SIZE ) );
136 }
137 else
138 {
139 if( curved_ratsnest )
140 {
141 int dx = l.b.x - l.a.x;
142 int dy = l.b.y - l.a.y;
143 const VECTOR2I center = VECTOR2I( l.a.x + 0.5 * dx - 0.1 * dy,
144 l.a.y + 0.5 * dy + 0.1 * dx );
145 gal->DrawCurve( l.a, center, center, l.b );
146 }
147 else
148 {
149 gal->DrawLine( l.a, l.b );
150 }
151 }
152 }
153
154 for( int i = 1 /* skip "No Net" at [0] */; i < m_data->GetNetCount(); ++i )
155 {
156 if( hiddenNets.count( i ) )
157 continue;
158
159 RN_NET* net = m_data->GetRatsnestForNet( i );
160
161 if( !net )
162 continue;
163
164 if( colorByNet && netColors.count( i ) )
165 color = netColors.at( i );
166 else if( colorByNet && ncMap.count( i ) && ncColors.count( ncMap.at( i ) ) )
167 color = ncColors.at( ncMap.at( i ) );
168 else
169 color = defaultColor;
170
171 if( color == COLOR4D::UNSPECIFIED )
172 color = defaultColor;
173
174 if( dimStatic )
175 color = color.WithAlpha( std::max( 0.0, color.a / 2 ) );
176
177 // Draw the "static" ratsnest
178 if( highlightedNets.count( i ) )
179 gal->SetStrokeColor(
180 color.Brightened( 0.8 ).WithAlpha( std::min( 1.0, color.a + 0.4 ) ) );
181 else
182 gal->SetStrokeColor( color ); // using the default ratsnest color for not highlighted
183
184 for( const CN_EDGE& edge : net->GetEdges() )
185 {
186 if( !edge.IsVisible() )
187 continue;
188
189 const std::shared_ptr<const CN_ANCHOR>& sourceNode = edge.GetSourceNode();
190 const std::shared_ptr<const CN_ANCHOR>& targetNode = edge.GetTargetNode();
191 const VECTOR2I source( sourceNode->Pos() );
192 const VECTOR2I target( targetNode->Pos() );
193
194 if( !sourceNode->Valid() || !targetNode->Valid() )
195 continue;
196
197 bool enable = !sourceNode->GetNoLine() && !targetNode->GetNoLine();
198 bool show;
199
200 // If the global ratsnest is currently enabled, the local ratsnest should be easy to
201 // turn off, so either element can disable it.
202 // If the global ratsnest is disabled, the local ratsnest should be easy to turn on
203 // so either element can enable it.
204 if( cfg->m_Display.m_ShowGlobalRatsnest )
205 {
206 show = sourceNode->Parent()->GetLocalRatsnestVisible() &&
207 targetNode->Parent()->GetLocalRatsnestVisible();
208 }
209 else
210 {
211 show = sourceNode->Parent()->GetLocalRatsnestVisible() ||
212 targetNode->Parent()->GetLocalRatsnestVisible();
213 }
214
215 if( onlyVisibleLayers && show )
216 {
217 LSET sourceLayers = sourceNode->Parent()->GetLayerSet();
218 LSET targetLayers = targetNode->Parent()->GetLayerSet();
219
220 if( !( sourceLayers & visibleLayers ).any() ||
221 !( targetLayers & visibleLayers ).any() )
222 {
223 show = false;
224 }
225 }
226
227 if ( enable && show )
228 {
229 if ( source == target )
230 {
231 gal->DrawLine( VECTOR2I( source.x - CROSS_SIZE, source.y - CROSS_SIZE ),
232 VECTOR2I( source.x + CROSS_SIZE, source.y + CROSS_SIZE ) );
233 gal->DrawLine( VECTOR2I( source.x - CROSS_SIZE, source.y + CROSS_SIZE ),
234 VECTOR2I( source.x + CROSS_SIZE, source.y - CROSS_SIZE ) );
235 }
236 else
237 {
238 if( curved_ratsnest )
239 {
240 int dx = target.x - source.x;
241 int dy = target.y - source.y;
242 const VECTOR2I center = VECTOR2I( source.x + 0.5 * dx - 0.1 * dy,
243 source.y + 0.5 * dy + 0.1 * dx );
244 gal->DrawCurve( source, center, center, target );
245 }
246 else
247 {
248 gal->DrawLine( source, target );
249 }
250 }
251 }
252 }
253 }
254}
255
256
257void RATSNEST_VIEW_ITEM::ViewGetLayers( int aLayers[], int& aCount ) const
258{
259 aCount = 1;
260 aLayers[0] = LAYER_RATSNEST;
261}
262
int color
Definition: DXF_plotter.cpp:57
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
@ curved_ratsnest
@ HIDDEN
Inactive layers are hidden.
@ OFF
Net (and netclass) colors are not shown.
@ VISIBLE
Ratsnest lines are drawn to items on visible layers only.
void SetMaximum()
Definition: box2.h:63
CN_EDGE represents a point-to-point connection, whether realized or unrealized (ie: tracks etc.
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:85
APP_SETTINGS_BASE * KifaceSettings() const
Definition: kiface_base.h:95
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:102
double b
Blue component.
Definition: color4d.h:374
virtual void SetIsStroke(bool aIsStrokeEnabled)
Enable/disable stroked outlines.
virtual RENDER_SETTINGS * GetSettings()=0
Return a pointer to current settings that are going to be used when drawing items.
PCB specific render settings.
Definition: pcb_painter.h:72
const std::set< int > & GetHighlightNetCodes() const
Return the netcode of currently highlighted net.
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
Definition: view.h:69
GAL * GetGAL() const
Return the #GAL this view is using to draw graphical primitives.
Definition: view.h:195
bool IsLayerVisible(int aLayer) const
Return information about visibility of a particular layer.
Definition: view.h:410
PAINTER * GetPainter() const
Return the painter object used by the view for drawing #VIEW_ITEMS.
Definition: view.h:213
LSET is a set of PCB_LAYER_IDs.
Definition: layer_ids.h:532
LSEQ Seq(const PCB_LAYER_ID *aWishListSequence, unsigned aCount) const
Return an LSEQ from the union of this LSET and a desired sequence.
Definition: lset.cpp:411
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:773
const BOX2I ViewBBox() const override
RATSNEST_VIEW_ITEM(std::shared_ptr< CONNECTIVITY_DATA > aData)
Class that draws missing connections on a PCB.
std::shared_ptr< CONNECTIVITY_DATA > m_data
Object containing ratsnest data.
void ViewGetLayers(int aLayers[], int &aCount) const override
void ViewDraw(int aLayer, KIGFX::VIEW *aView) const override
Describe ratsnest for a single net.
Definition: ratsnest_data.h:63
const std::vector< CN_EDGE > & GetEdges() const
Definition: ratsnest_data.h:85
@ LAYER_RATSNEST
Definition: layer_ids.h:204
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:59
Definition: bitmap.cpp:65
Class that computes missing connections on a PCB.
@ NOT_USED
the 3d code uses this value
Definition: typeinfo.h:79
VECTOR2< int > VECTOR2I
Definition: vector2d.h:590