KiCad PCB EDA Suite
pcb_draw_panel_gal.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) 2014-2017 CERN
5  * @author Maciej Suminski <maciej.suminski@cern.ch>
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, you may find one here:
19  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20  * or you may search the http://www.gnu.org website for the version 2 license,
21  * or you may write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23  */
24 
25 #include "pcb_draw_panel_gal.h"
26 #include <pcb_view.h>
27 #include <view/wx_view_controls.h>
28 #include <pcb_painter.h>
29 #include <ws_proxy_view_item.h>
30 #include <ratsnest_viewitem.h>
31 #include <ratsnest_data.h>
33 
34 #include <class_board.h>
35 #include <class_module.h>
36 #include <class_track.h>
37 #include <class_marker_pcb.h>
38 #include <pcb_base_frame.h>
39 #include <pcbnew_settings.h>
40 #include <pgm_base.h>
42 #include <confirm.h>
43 
45 
46 #include <functional>
47 #include <memory>
48 #include <thread>
49 using namespace std::placeholders;
50 
52 {
58 
61 
66 
69 
100 
103 
106 };
107 
108 
109 PCB_DRAW_PANEL_GAL::PCB_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWindowId,
110  const wxPoint& aPosition, const wxSize& aSize,
111  KIGFX::GAL_DISPLAY_OPTIONS& aOptions, GAL_TYPE aGalType ) :
112  EDA_DRAW_PANEL_GAL( aParentWindow, aWindowId, aPosition, aSize, aOptions, aGalType )
113 {
114  m_view = new KIGFX::PCB_VIEW( true );
115  m_view->SetGAL( m_gal );
116 
117  m_painter = std::make_unique<KIGFX::PCB_PAINTER>( m_gal );
118  m_view->SetPainter( m_painter.get() );
119 
122 
123  // View controls is the first in the event handler chain, so the Tool Framework operates
124  // on updated viewport data.
126 
127  // Load display options (such as filled/outline display of items).
128  // Can be made only if the parent window is an EDA_DRAW_FRAME (or a derived class)
129  // which is not always the case (namely when it is used from a wxDialog like the pad editor)
130  PCB_BASE_FRAME* frame = dynamic_cast<PCB_BASE_FRAME*>( GetParentEDAFrame() );
131 
132  if( frame )
133  static_cast<KIGFX::PCB_VIEW*>( m_view )->UpdateDisplayOptions(
134  frame->GetDisplayOptions() );
135 }
136 
137 
139 {
140 }
141 
142 
144 {
145 
146  m_view->Clear();
147 
148  auto zones = aBoard->Zones();
149  std::atomic<size_t> next( 0 );
150  std::atomic<size_t> count_done( 0 );
151  size_t parallelThreadCount = std::max<size_t>( std::thread::hardware_concurrency(), 2 );
152 
153  for( size_t ii = 0; ii < parallelThreadCount; ++ii )
154  {
155  std::thread t = std::thread( [ &count_done, &next, &zones ]( )
156  {
157  for( size_t i = next.fetch_add( 1 ); i < zones.size(); i = next.fetch_add( 1 ) )
158  zones[i]->CacheTriangulation();
159 
160  count_done++;
161  } );
162 
163  t.detach();
164  }
165 
166  if( m_worksheet )
167  m_worksheet->SetFileName( TO_UTF8( aBoard->GetFileName() ) );
168 
169  // Load drawings
170  for( auto drawing : const_cast<BOARD*>(aBoard)->Drawings() )
171  m_view->Add( drawing );
172 
173  // Load tracks
174  for( auto track : aBoard->Tracks() )
175  m_view->Add( track );
176 
177  // Load modules and its additional elements
178  for( auto module : aBoard->Modules() )
179  m_view->Add( module );
180 
181  // DRC markers
182  for( auto marker : aBoard->Markers() )
183  m_view->Add( marker );
184 
185  // Finalize the triangulation threads
186  while( count_done < parallelThreadCount )
187  std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) );
188 
189  // Load zones
190  for( auto zone : aBoard->Zones() )
191  m_view->Add( zone );
192 
193  // Ratsnest
194  m_ratsnest = std::make_unique<KIGFX::RATSNEST_VIEWITEM>( aBoard->GetConnectivity() );
195  m_view->Add( m_ratsnest.get() );
196 }
197 
198 
200 {
201  m_worksheet.reset( aWorksheet );
202  m_view->Add( m_worksheet.get() );
203 }
204 
205 
207 {
208  COLOR_SETTINGS* cs = nullptr;
209 
210  auto frame = dynamic_cast<PCB_BASE_FRAME*>( GetParentEDAFrame() );
211 
212  if( frame )
213  {
214  cs = frame->GetColorSettings();
215  }
216  else
217  {
218  PCBNEW_SETTINGS* app = Pgm().GetSettingsManager().GetAppSettings<PCBNEW_SETTINGS>();
219 
220  if( app )
221  cs = Pgm().GetSettingsManager().GetColorSettings( app->m_ColorTheme );
222  else
223  cs = Pgm().GetSettingsManager().GetColorSettings();
224  }
225 
226  wxCHECK_RET( cs, "null COLOR_SETTINGS" );
227 
228  Pgm().GetSettingsManager().SaveColorSettings( cs, "board" );
229 
230  auto rs = static_cast<KIGFX::PCB_RENDER_SETTINGS*>( m_view->GetPainter()->GetSettings() );
231  rs->LoadColors( cs );
232 
235 }
236 
237 
239 {
240  // Set display settings for high contrast mode
242 
243  SetTopLayer( aLayer );
244 
245  rSettings->ClearActiveLayers();
246  rSettings->SetActiveLayer( aLayer );
247 
248  if( IsCopperLayer( aLayer ) )
249  {
250  // Bring some other layers to the front in case of copper layers and make them colored
251  // fixme do not like the idea of storing the list of layers here,
252  // should be done in some other way I guess..
253  LAYER_NUM layers[] = {
254  GetNetnameLayer( aLayer ),
259  };
260 
261  for( unsigned int i : layers )
262  rSettings->SetActiveLayer( i );
263 
264  // Pads should be shown too
265  if( aLayer == B_Cu )
266  {
267  rSettings->SetActiveLayer( LAYER_PAD_BK );
268  rSettings->SetActiveLayer( LAYER_MOD_BK );
270  }
271  else if( aLayer == F_Cu )
272  {
273  rSettings->SetActiveLayer( LAYER_PAD_FR );
274  rSettings->SetActiveLayer( LAYER_MOD_FR );
276  }
277  }
278 
280 }
281 
282 
284 {
287  m_view->SetTopLayer( aLayer );
288 
289  // Layers that should always have on-top attribute enabled
290  const std::vector<LAYER_NUM> layers = {
295  };
296 
297  for( auto layer : layers )
298  m_view->SetTopLayer( layer );
299 
300  // Extra layers that are brought to the top if a F.* or B.* is selected
301  const std::vector<LAYER_NUM> frontLayers = {
304  };
305 
306  const std::vector<LAYER_NUM> backLayers = {
309  };
310 
311  const std::vector<LAYER_NUM>* extraLayers = NULL;
312 
313  // Bring a few more extra layers to the top depending on the selected board side
314  if( IsFrontLayer( aLayer ) )
315  extraLayers = &frontLayers;
316  else if( IsBackLayer( aLayer ) )
317  extraLayers = &backLayers;
318 
319  if( extraLayers )
320  {
321  for( auto layer : *extraLayers )
322  m_view->SetTopLayer( layer );
323 
324  // Move the active layer to the top
325  if( !IsCopperLayer( aLayer ) )
327  }
328  else if( IsCopperLayer( aLayer ) )
329  {
330  // Display labels for copper layers on the top
331  m_view->SetTopLayer( GetNetnameLayer( aLayer ) );
332  }
333 
334  m_view->EnableTopLayer( true );
336 }
337 
338 
340 {
341  // Load layer & elements visibility settings
342  for( LAYER_NUM i = 0; i < PCB_LAYER_ID_COUNT; ++i )
343  m_view->SetLayerVisible( i, aBoard->IsLayerVisible( PCB_LAYER_ID( i ) ) );
344 
346  m_view->SetLayerVisible( i, aBoard->IsElementVisible( i ) );
347 
348  // Always enable netname layers, as their visibility is controlled by layer dependencies
350  m_view->SetLayerVisible( i, true );
351 
352  // Enable some layers that are GAL specific
358 }
359 
360 
362  std::vector<MSG_PANEL_ITEM>& aList )
363 {
364  BOARD* board = static_cast<PCB_BASE_FRAME*>( GetParentEDAFrame() )->GetBoard();
365  wxString txt;
366  int viasCount = 0;
367  int trackSegmentsCount = 0;
368 
369  for( auto item : board->Tracks() )
370  {
371  if( item->Type() == PCB_VIA_T )
372  viasCount++;
373  else
374  trackSegmentsCount++;
375  }
376 
377  txt.Printf( wxT( "%d" ), board->GetPadCount() );
378  aList.emplace_back( _( "Pads" ), txt, DARKGREEN );
379 
380  txt.Printf( wxT( "%d" ), viasCount );
381  aList.emplace_back( _( "Vias" ), txt, DARKGREEN );
382 
383  txt.Printf( wxT( "%d" ), trackSegmentsCount );
384  aList.emplace_back( _( "Track Segments" ), txt, DARKGREEN );
385 
386  txt.Printf( wxT( "%d" ), board->GetNodesCount() );
387  aList.emplace_back( _( "Nodes" ), txt, DARKCYAN );
388 
389  txt.Printf( wxT( "%d" ), board->GetNetCount() - 1 /* don't include "No Net" in count */ );
390  aList.emplace_back( _( "Nets" ), txt, RED );
391 
392  txt.Printf( wxT( "%d" ), board->GetConnectivity()->GetUnconnectedCount() );
393  aList.emplace_back( _( "Unrouted" ), txt, BLUE );
394 }
395 
396 
398 {
399  PCB_BASE_FRAME* frame = dynamic_cast<PCB_BASE_FRAME*>( GetParentEDAFrame() );
400 
401  try
402  {
403  // Check if the current rendering backend can be properly initialized
404  m_view->UpdateItems();
405  }
406  catch( const std::runtime_error& e )
407  {
408  // Fallback to software renderer
409  DisplayError( GetParent(), e.what() );
411 
412  if( frame )
413  frame->ActivateGalCanvas();
414  }
415 
416  if( frame )
417  {
418  SetTopLayer( frame->GetActiveLayer() );
419  KIGFX::PAINTER* painter = m_view->GetPainter();
420  auto settings = static_cast<KIGFX::PCB_RENDER_SETTINGS*>( painter->GetSettings() );
421  settings->LoadDisplayOptions( frame->GetDisplayOptions(), frame->ShowPageLimits() );
422  }
423 }
424 
425 
427 {
428  for( LAYER_NUM i = 0; (unsigned) i < sizeof( GAL_LAYER_ORDER ) / sizeof( LAYER_NUM ); ++i )
429  {
430  LAYER_NUM layer = GAL_LAYER_ORDER[i];
431  wxASSERT( layer < KIGFX::VIEW::VIEW_MAX_LAYERS );
432 
433  m_view->SetLayerOrder( layer, i );
434  }
435 }
436 
437 
439 {
440  bool rv = EDA_DRAW_PANEL_GAL::SwitchBackend( aGalType );
442  m_gal->SetWorldUnitLength( 1e-9 /* 1 nm */ / 0.0254 /* 1 inch in meters */ );
443  return rv;
444 }
445 
446 
448 {
449  if( m_ratsnest )
450  m_view->Update( m_ratsnest.get() );
451 }
452 
453 
455 {
457  return m_worksheet->ViewBBox();
458 
459  return BOX2I();
460 }
461 
462 
464 {
465  // caching makes no sense for Cairo and other software renderers
467 
468  for( int i = 0; i < KIGFX::VIEW::VIEW_MAX_LAYERS; i++ )
469  m_view->SetLayerTarget( i, target );
470 
471  for( LAYER_NUM i = 0; (unsigned) i < sizeof( GAL_LAYER_ORDER ) / sizeof( LAYER_NUM ); ++i )
472  {
473  LAYER_NUM layer = GAL_LAYER_ORDER[i];
474  wxASSERT( layer < KIGFX::VIEW::VIEW_MAX_LAYERS );
475 
476  // Set layer display dependencies & targets
477  if( IsCopperLayer( layer ) )
478  m_view->SetRequired( GetNetnameLayer( layer ), layer );
479  else if( IsNetnameLayer( layer ) )
480  m_view->SetLayerDisplayOnly( layer );
481  }
482 
485 
486  // Some more required layers settings
492 
493  // Front modules
497 
498  // Back modules
502 
509 
513 }
514 
515 
517 {
518  return static_cast<KIGFX::PCB_VIEW*>( m_view );
519 }
Definition: colors.h:57
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:239
CITER next(CITER it)
Definition: ptree.cpp:130
KIGFX::GAL * m_gal
Interface for drawing objects on a 2D-surface.
to draw blind/buried vias
BOX2< VECTOR2I > BOX2I
Definition: box2.h:521
void setDefaultLayerDeps()
Sets rendering targets & dependencies for layers.
Class that draws missing connections on a PCB.
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:104
KIGFX::WX_VIEW_CONTROLS * m_viewControls
Control for VIEW (moving, zooming, etc.)
void SetRequired(int aLayerId, int aRequiredId, bool aRequired=true)
Function SetRequired() Marks the aRequiredId layer as required for the aLayerId layer.
Definition: view.cpp:416
void SetLayerOrder(int aLayer, int aRenderingOrder)
Function SetLayerOrder() Sets rendering order of a particular layer.
Definition: view.cpp:664
GAL_TYPE m_backend
Currently used GAL.
virtual void SetTopLayer(int aLayer, bool aEnabled=true)
Function SetTopLayer() Sets given layer to be displayed on the top or sets back the default order of ...
Definition: view.cpp:860
RENDER_SETTINGS Contains all the knowledge about how graphical objects are drawn on any output surfac...
multilayer pads, usually with holes
int GetNetnameLayer(int aLayer)
Returns a netname layer corresponding to the given layer.
This file is part of the common library.
WX_VIEW_CONTROLS is a specific implementation of class VIEW_CONTROLS for wxWidgets library.
virtual bool SwitchBackend(GAL_TYPE aGalType)
Function SwitchBackend Switches method of rendering graphics.
handle color for not plated holes (holes, not pads)
anchor of items having an anchor point (texts, footprints)
bool IsBackLayer(PCB_LAYER_ID aLayerId)
Layer classification: check if it's a back layer.
void setDefaultLayerOrder()
Reassigns layer order to the initial settings.
MARKERS & Markers()
Definition: class_board.h:275
Class that computes missing connections on a PCB.
GAL_LAYER_ID
GAL layers are "virtual" layers, i.e.
to draw via holes (pad holes do not use this layer)
show modules values (when texts are visibles)
void UpdateAllLayersOrder()
Function UpdateLayerOrder() Does everything that is needed to apply the rendering order of layers.
Definition: view.cpp:927
Add new GAL layers here.
The base class for create windows for drawing purpose.
const wxString & GetFileName() const
Definition: class_board.h:245
const PCB_DISPLAY_OPTIONS & GetDisplayOptions() const
Function GetDisplayOptions returns the display options current in use Display options are relative to...
virtual void EnableTopLayer(bool aEnable)
Function EnableTopLayer() Enables or disables display of the top layer.
Definition: view.cpp:887
PAINTER * GetPainter() const
Function GetPainter() Returns the painter object used by the view for drawing VIEW_ITEMS.
Definition: view.h:199
WX_VIEW_CONTROLS class definition.
void RedrawRatsnest()
Forces refresh of the ratsnest visual representation
static constexpr int VIEW_MAX_LAYERS
maximum number of layers that may be shown
Definition: view.h:701
void SetActiveLayer(int aLayerId, bool aEnabled=true)
Function SetActiveLayer Sets the specified layer as active - it means that it can be drawn in a speci...
const LAYER_NUM GAL_LAYER_ORDER[]
A single base class (TRACK) represents both tracks and vias, with subclasses for curved tracks (ARC) ...
bool ShowPageLimits() const
Auxiliary rendering target (noncached)
Definition: definitions.h:49
Classes used in Pcbnew, CvPcb and GerbView.
void GetMsgPanelInfo(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList) override
show modules on front
std::unique_ptr< KIGFX::RATSNEST_VIEWITEM > m_ratsnest
Ratsnest view item
virtual PCB_LAYER_ID GetActiveLayer() const
Function GetActiveLayer returns the active layer.
void SetLayerTarget(int aLayer, RENDER_TARGET aTarget)
Function SetLayerTarget() Changes the rendering target for a particular layer.
Definition: view.h:434
void SetGridColor(const COLOR4D &aGridColor)
Set the grid color.
Markers used to show a drc problem on boards.
PCB_LAYER_ID
A quick note on layer IDs:
PAINTER contains all the knowledge about how to draw graphical object onto any particular output devi...
Definition: painter.h:58
virtual void ActivateGalCanvas() override
#define NULL
unsigned GetNodesCount(int aNet=-1)
Function GetNodesCount.
unsigned GetNetCount() const
Function GetNetCount.
Definition: class_board.h:760
void ClearActiveLayers()
Function ClearActiveLayers Clears the list of active layers.
MODULES & Modules()
Definition: class_board.h:256
void DisplayBoard(BOARD *aBoard)
Function DisplayBoard adds all items from the current board to the VIEW, so they can be displayed by ...
void Clear()
Function Clear() Removes all items from the view.
Definition: view.cpp:1111
std::unique_ptr< KIGFX::WS_PROXY_VIEW_ITEM > m_worksheet
Currently used worksheet
std::unique_ptr< KIGFX::PAINTER > m_painter
Contains information about how to draw items using GAL.
void SetLayerDisplayOnly(int aLayer, bool aDisplayOnly=true)
Definition: view.h:422
to draw usual through hole vias
virtual BOARD * GetBoard() const
Function GetBoard returns the BOARD in which this BOARD_ITEM resides, or NULL if none.
std::shared_ptr< CONNECTIVITY_DATA > GetConnectivity() const
Function GetConnectivity() returns list of missing connections between components/tracks.
Definition: class_board.h:335
PCB_DRAW_PANEL_GAL(wxWindow *aParentWindow, wxWindowID aWindowId, const wxPoint &aPosition, const wxSize &aSize, KIGFX::GAL_DISPLAY_OPTIONS &aOptions, GAL_TYPE aGalType=GAL_TYPE_OPENGL)
Items that may change while the view stays the same (noncached)
Definition: definitions.h:50
Definition: colors.h:60
void SetLayerVisible(int aLayer, bool aVisible=true)
Function SetLayerVisible() Controls the visibility of a particular layer.
Definition: view.h:399
void UpdateItems()
Function UpdateItems() Iterates through the list of items that asked for updating and updates them.
Definition: view.cpp:1421
void SetCursorColor(const COLOR4D &aCursorColor)
Set the cursor color.
void SyncLayersVisibility(const BOARD *aBoard)
Function SyncLayersVisibility Updates "visibility" property of each layer of a given BOARD.
virtual void Update(VIEW_ITEM *aItem, int aUpdateFlags)
For dynamic VIEWs, informs the associated VIEW that the graphical representation of this item has cha...
Definition: view.cpp:1540
virtual KIGFX::PCB_VIEW * GetView() const override
Function GetView() Returns a pointer to the VIEW instance used in the panel.
unsigned GetPadCount()
Function GetPadCount.
void SetWorldUnitLength(double aWorldUnitLength)
Set the unit length.
BOX2I GetDefaultViewBBox() const override
void UpdateColors()
Updates the color settings in the painter and GAL.
void ClearTopLayers()
Function ClearTopLayers() Removes all layers from the on-the-top set (they are no longer displayed ov...
Definition: view.cpp:912
virtual void SetHighContrastLayer(int aLayer) override
int LAYER_NUM
Type LAYER_NUM can be replaced with int and removed.
bool IsElementVisible(GAL_LAYER_ID aLayer) const
Function IsElementVisible tests whether a given element category is visible.
bool SwitchBackend(GAL_TYPE aGalType) override
Function SwitchBackend Switches method of rendering graphics.
layer for drc markers with SEVERITY_WARNING
bool IsFrontLayer(PCB_LAYER_ID aLayerId)
Layer classification: check if it's a front layer.
virtual RENDER_SETTINGS * GetSettings()=0
Function GetAdapter Returns pointer to current settings that are going to be used when drawing items.
COLOR4D GetColor(int aLayer) const
bool IsLayerVisible(PCB_LAYER_ID aLayer) const
Function IsLayerVisible is a proxy function that calls the correspondent function in m_BoardSettings ...
Definition: class_board.h:461
ZONE_CONTAINERS & Zones()
Definition: class_board.h:270
smd pads, front layer
see class PGM_BASE
void SetWorksheet(KIGFX::WS_PROXY_VIEW_ITEM *aWorksheet)
Function SetWorksheet Sets (or updates) worksheet used by the draw panel.
Main rendering target (cached)
Definition: definitions.h:48
KIGFX::VIEW * m_view
Stores view settings (scale, center, etc.) and items to be drawn.
BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:181
#define _(s)
Definition: 3d_actions.cpp:33
int GetLayerOrder(int aLayer) const
Function GetLayerOrder() Returns rendering order of a particular layer.
Definition: view.cpp:672
EDA_DRAW_FRAME * GetParentEDAFrame() const
Function GetParentEDAFrame() Returns parent EDA_DRAW_FRAME, if available or NULL otherwise.
currently selected items overlay
#define TO_UTF8(wxstring)
bool IsCopperLayer(LAYER_NUM aLayerId)
Function IsCopperLayer tests whether a layer is a copper layer.
void SetPainter(PAINTER *aPainter)
Function SetPainter() Sets the painter object used by the view for drawing VIEW_ITEMS.
Definition: view.h:189
Color settings are a bit different than most of the settings objects in that there can be more than o...
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:97
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Function Add() Adds a VIEW_ITEM to the view.
Definition: view.cpp:346
virtual void SetTopLayer(int aLayer) override
void UpdateAllLayersColor()
Function UpdateAllLayersColor() Applies the new coloring scheme to all layers.
Definition: view.cpp:798
void SetGAL(GAL *aGal)
Function SetGAL() Assigns a rendering device for the VIEW.
Definition: view.cpp:519
#define NETNAMES_LAYER_INDEX(layer)
Macro for obtaining netname layer for a given PCB layer.
PCB_BASE_FRAME basic PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer.
TRACKS & Tracks()
Definition: class_board.h:247
show modules references (when texts are visibles)
layer for drc markers with SEVERITY_ERROR
Additional netnames layers (not associated with a PCB layer)
bool IsNetnameLayer(LAYER_NUM aLayer)
Function IsNetnameLayer tests whether a layer is a netname layer.
bool IsLayerVisible(int aLayer) const
Function IsLayerVisible() Returns information about visibility of a particular layer.
Definition: view.h:416
wxString m_ColorTheme
Active color theme name.
Definition: app_settings.h:136