KiCad PCB EDA Suite
Loading...
Searching...
No Matches
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-2023 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>
35#include <pcbnew_settings.h>
36#include <pcb_painter.h>
38#include <layer_ids.h>
39#include <pcb_base_frame.h>
40#include <view/view.h>
41
42#include <memory>
43#include <utility>
44
45
46RATSNEST_VIEW_ITEM::RATSNEST_VIEW_ITEM( std::shared_ptr<CONNECTIVITY_DATA> aData ) :
48 m_data( std::move( aData ) )
49{
50}
51
52
54{
55 // Make it always visible
56 BOX2I bbox;
57 bbox.SetMaximum();
58
59 return bbox;
60}
61
62
63void RATSNEST_VIEW_ITEM::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const
64{
65 std::unique_lock<KISPINLOCK> lock( m_data->GetLock(), std::try_to_lock );
66
67 if( !lock )
68 return;
69
70 constexpr int CROSS_SIZE = 200000;
71
72 PCBNEW_SETTINGS* cfg = dynamic_cast<PCBNEW_SETTINGS*>( Kiface().KifaceSettings() );
73
74 if( !cfg )
75 return;
76
77 auto rs = static_cast<KIGFX::PCB_RENDER_SETTINGS*>( aView->GetPainter()->GetSettings() );
78 KIGFX::GAL* gal = aView->GetGAL();
79 gal->SetIsStroke( true );
80 gal->SetIsFill( false );
82
83 std::set<int> highlightedNets = rs->GetHighlightNetCodes();
84 const std::set<int>& hiddenNets = rs->GetHiddenNets();
85
86 COLOR4D defaultColor = rs->GetColor( nullptr, LAYER_RATSNEST );
87 COLOR4D color = defaultColor;
88 const bool colorByNet = rs->GetNetColorMode() != NET_COLOR_MODE::OFF;
89 const bool dimStatic = m_data->GetLocalRatsnest().size() > 0 || highlightedNets.size() > 0;
90
91 std::map<int, KIGFX::COLOR4D>& netColors = rs->GetNetColorMap();
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 {
104 [&]( PCB_LAYER_ID layer )
105 {
106 if( aView->IsLayerVisible( layer ) )
107 visibleLayers.set( layer );
108 } );
109 }
110
111 auto adjustColor =
112 [&]( COLOR4D& color_base, double brightnessDelta, double alpha )
113 {
114 if( rs->GetColor( nullptr, LAYER_PCB_BACKGROUND ).GetBrightness() < 0.5 )
115 return color_base.Brightened( brightnessDelta ).WithAlpha( std::min( alpha, 1.0 ) );
116 else
117 return color_base.Darkened( brightnessDelta ).WithAlpha( std::min( alpha, 1.0 ) );
118 };
119
121
122 // Draw the "dynamic" ratsnest (i.e. for objects that may be currently being moved)
123 for( const RN_DYNAMIC_LINE& l : m_data->GetLocalRatsnest() )
124 {
125 if( hiddenNets.count( l.netCode ) )
126 continue;
127
128 const NETCLASS* nc = nullptr;
129 const NET_SETTINGS* netSettings = m_data->GetNetSettings();
130
131 if( m_data->HasNetNameForNetCode( l.netCode ) )
132 {
133 const wxString& netName = m_data->GetNetNameForNetCode( l.netCode );
134
135 if( netSettings && netSettings->HasEffectiveNetClass( netName ) )
136 nc = netSettings->GetCachedEffectiveNetClass( netName ).get();
137 }
138
139 if( colorByNet && netColors.count( l.netCode ) )
140 color = netColors.at( l.netCode );
141 else if( colorByNet && nc && nc->HasPcbColor() )
142 color = nc->GetPcbColor();
143 else
144 color = defaultColor;
145
146 if( color == COLOR4D::UNSPECIFIED )
147 color = defaultColor;
148
149 gal->SetStrokeColor( adjustColor( color, 0.5, color.a + 0.3 ) );
150
151 if( l.a == l.b )
152 {
153 gal->DrawLine( VECTOR2I( l.a.x - CROSS_SIZE, l.a.y - CROSS_SIZE ),
154 VECTOR2I( l.b.x + CROSS_SIZE, l.b.y + CROSS_SIZE ) );
155 gal->DrawLine( VECTOR2I( l.a.x - CROSS_SIZE, l.a.y + CROSS_SIZE ),
156 VECTOR2I( l.b.x + CROSS_SIZE, l.b.y - CROSS_SIZE ) );
157 }
158 else
159 {
160 if( curved_ratsnest )
161 {
162 int dx = l.b.x - l.a.x;
163 int dy = l.b.y - l.a.y;
164 const VECTOR2I center = VECTOR2I( l.a.x + 0.5 * dx - 0.1 * dy,
165 l.a.y + 0.5 * dy + 0.1 * dx );
166 gal->DrawCurve( l.a, center, center, l.b );
167 }
168 else
169 {
170 gal->DrawLine( l.a, l.b );
171 }
172 }
173 }
174
175 for( int i = 1 /* skip "No Net" at [0] */; i < m_data->GetNetCount(); ++i )
176 {
177 if( hiddenNets.count( i ) )
178 continue;
179
180 RN_NET* net = m_data->GetRatsnestForNet( i );
181
182 if( !net || m_data->GetConnectivityAlgo()->IsNetDirty( i ) )
183 continue;
184
185 const NETCLASS* nc = nullptr;
186 const NET_SETTINGS* netSettings = m_data->GetNetSettings();
187
188 if( m_data->HasNetNameForNetCode( i ) )
189 {
190 const wxString& netName = m_data->GetNetNameForNetCode( i );
191
192 if( netSettings && netSettings->HasEffectiveNetClass( netName ) )
193 nc = netSettings->GetCachedEffectiveNetClass( netName ).get();
194 }
195
196 if( colorByNet && netColors.count( i ) )
197 color = netColors.at( i );
198 else if( colorByNet && nc && nc->HasPcbColor() )
199 color = nc->GetPcbColor();
200 else
201 color = defaultColor;
202
203 if( color == COLOR4D::UNSPECIFIED )
204 color = defaultColor;
205
206 if( dimStatic )
207 color = adjustColor( color, 0.0, color.a / 2 );
208
209 // Draw the "static" ratsnest
210 if( highlightedNets.count( i ) )
211 gal->SetStrokeColor( adjustColor( color, 0.8, color.a + 0.4 ) );
212 else
213 gal->SetStrokeColor( color ); // using the default ratsnest color for not highlighted
214
215 for( const CN_EDGE& edge : net->GetEdges() )
216 {
217 if( !edge.IsVisible() )
218 continue;
219
220 const std::shared_ptr<const CN_ANCHOR>& sourceNode = edge.GetSourceNode();
221 const std::shared_ptr<const CN_ANCHOR>& targetNode = edge.GetTargetNode();
222
223 if( !sourceNode || sourceNode->Dirty() || !targetNode || targetNode->Dirty() )
224 continue;
225
226 const VECTOR2I source( sourceNode->Pos() );
227 const VECTOR2I target( targetNode->Pos() );
228
229 bool enable = !sourceNode->GetNoLine() && !targetNode->GetNoLine();
230 bool show;
231
232 // If the global ratsnest is currently enabled, the local ratsnest should be easy to
233 // turn off, so either element can disable it.
234 // If the global ratsnest is disabled, the local ratsnest should be easy to turn on
235 // so either element can enable it.
237 {
238 show = sourceNode->Parent()->GetLocalRatsnestVisible() &&
239 targetNode->Parent()->GetLocalRatsnestVisible();
240 }
241 else
242 {
243 show = sourceNode->Parent()->GetLocalRatsnestVisible() ||
244 targetNode->Parent()->GetLocalRatsnestVisible();
245 }
246
247 if( onlyVisibleLayers && show )
248 {
249 LSET sourceLayers = sourceNode->Parent()->GetLayerSet();
250 LSET targetLayers = targetNode->Parent()->GetLayerSet();
251
252 if( !( sourceLayers & visibleLayers ).any() ||
253 !( targetLayers & visibleLayers ).any() )
254 {
255 show = false;
256 }
257 }
258
259 if ( enable && show )
260 {
261 if ( source == target )
262 {
263 gal->DrawLine( VECTOR2I( source.x - CROSS_SIZE, source.y - CROSS_SIZE ),
264 VECTOR2I( source.x + CROSS_SIZE, source.y + CROSS_SIZE ) );
265 gal->DrawLine( VECTOR2I( source.x - CROSS_SIZE, source.y + CROSS_SIZE ),
266 VECTOR2I( source.x + CROSS_SIZE, source.y - CROSS_SIZE ) );
267 }
268 else
269 {
270 if( curved_ratsnest )
271 {
272 int dx = target.x - source.x;
273 int dy = target.y - source.y;
274 const VECTOR2I center = VECTOR2I( source.x + 0.5 * dx - 0.1 * dy,
275 source.y + 0.5 * dy + 0.1 * dx );
276 gal->DrawCurve( source, center, center, target );
277 }
278 else
279 {
280 gal->DrawLine( source, target );
281 }
282 }
283 }
284 }
285 }
286}
287
288
289std::vector<int> RATSNEST_VIEW_ITEM::ViewGetLayers() const
290{
291 return { LAYER_RATSNEST };
292}
293
int color
Definition: DXF_plotter.cpp:58
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
@ curved_ratsnest
BASE_SET & set(size_t pos)
Definition: base_set.h:115
constexpr void SetMaximum()
Definition: box2.h:80
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:89
APP_SETTINGS_BASE * KifaceSettings() const
Definition: kiface_base.h:95
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:104
COLOR4D WithAlpha(double aAlpha) const
Return a color with the same color, but the given alpha.
Definition: color4d.h:311
COLOR4D Darkened(double aFactor) const
Return a color that is darker by a given factor, without modifying object.
Definition: color4d.h:282
COLOR4D Brightened(double aFactor) const
Return a color that is brighter by a given factor, without modifying object.
Definition: color4d.h:268
Abstract interface for drawing on a 2D-surface.
virtual void SetIsFill(bool aIsFillEnabled)
Enable/disable fill.
virtual void SetLineWidth(float aLineWidth)
Set the line width.
virtual void SetStrokeColor(const COLOR4D &aColor)
Set the stroke color.
virtual void SetIsStroke(bool aIsStrokeEnabled)
Enable/disable stroked outlines.
virtual void DrawLine(const VECTOR2D &aStartPoint, const VECTOR2D &aEndPoint)
Draw a line.
virtual void DrawCurve(const VECTOR2D &startPoint, const VECTOR2D &controlPointA, const VECTOR2D &controlPointB, const VECTOR2D &endPoint, double aFilterValue=0.0)
Draw a cubic bezier spline.
double GetWorldScale() const
Get the world scale.
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:78
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
Definition: view.h:68
GAL * GetGAL() const
Return the #GAL this view is using to draw graphical primitives.
Definition: view.h:199
bool IsLayerVisible(int aLayer) const
Return information about visibility of a particular layer.
Definition: view.h:419
PAINTER * GetPainter() const
Return the painter object used by the view for drawing #VIEW_ITEMS.
Definition: view.h:217
LSET is a set of PCB_LAYER_IDs.
Definition: lset.h:36
void RunOnLayers(const std::function< void(PCB_LAYER_ID)> &aFunction) const
Execute a function on each layer of the LSET.
Definition: lset.h:243
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:686
A collection of nets and the parameters used to route or test these nets.
Definition: netclass.h:44
COLOR4D GetPcbColor(bool aIsForSave=false) const
Definition: netclass.h:176
bool HasPcbColor() const
Definition: netclass.h:175
NET_SETTINGS stores various net-related settings in a project context.
Definition: net_settings.h:39
bool HasEffectiveNetClass(const wxString &aNetName) const
Determines if an effective netclass for the given net name has been cached.
std::shared_ptr< NETCLASS > GetCachedEffectiveNetClass(const wxString &aNetName) const
Returns an already cached effective netclass for the given net name.
DISPLAY_OPTIONS m_Display
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 ViewDraw(int aLayer, KIGFX::VIEW *aView) const override
std::vector< int > ViewGetLayers() const override
Describe ratsnest for a single net.
Definition: ratsnest_data.h:63
const std::vector< CN_EDGE > & GetEdges() const
Definition: ratsnest_data.h:96
@ LAYER_PCB_BACKGROUND
PCB background color.
Definition: layer_ids.h:221
@ LAYER_RATSNEST
Definition: layer_ids.h:205
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:60
STL namespace.
Class that computes missing connections on a PCB.
@ NOT_USED
the 3d code uses this value
Definition: typeinfo.h:79
VECTOR2< int32_t > VECTOR2I
Definition: vector2d.h:691