KiCad PCB EDA Suite
board_adapter.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) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
5  * Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
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 "../3d_rendering/camera.h"
26 #include "board_adapter.h"
27 #include <board_design_settings.h>
30 #include <board.h>
32 #include <3d_math.h>
33 #include "3d_fastmath.h"
35 #include <convert_to_biu.h>
36 #include <pgm_base.h>
38 #include <wx/log.h>
39 
40 
46 
54 
55 static bool g_ColorsLoaded = false;
56 
65 const wxChar *BOARD_ADAPTER::m_logTrace = wxT( "KI_TRACE_EDA_CINFO3D_VISU" );
66 
67 
69  m_board( nullptr ),
70  m_3dModelManager( nullptr ),
71  m_colors( nullptr ),
72  m_layerZcoordTop(),
73  m_layerZcoordBottom()
74 {
75  wxLogTrace( m_logTrace, wxT( "BOARD_ADAPTER::BOARD_ADAPTER" ) );
76 
79  m_drawFlags.resize( FL_LAST, false );
80 
81  if( PgmOrNull() )
82  m_colors = Pgm().GetSettingsManager().GetColorSettings();
83 
86 
87  m_boardPos = wxPoint();
88  m_boardSize = wxSize();
89  m_boardCenter = SFVEC3F( 0.0f );
90 
92 
96 
98  m_epoxyThickness3DU = 0.0f;
99  m_copperThickness3DU = 0.0f;
102  m_biuTo3Dunits = 1.0;
103 
104  m_trackCount = 0;
105  m_viaCount = 0;
107  m_holeCount = 0;
108  m_averageHoleDiameter = 0.0f;
109  m_averageTrackWidth = 0.0f;
110 
113  SetFlag( FL_SHOW_BOARD_BODY, true );
118  SetFlag( FL_ZONE, true );
119  SetFlag( FL_SILKSCREEN, true );
120  SetFlag( FL_SOLDERMASK, true );
122 
128 
129  SetFlag( FL_USE_SELECTION, true );
131 
132  m_BgColorBot = SFVEC4F( 0.4, 0.4, 0.5, 1.0 );
133  m_BgColorTop = SFVEC4F( 0.8, 0.8, 0.9, 1.0 );
134  m_BoardBodyColor = SFVEC4F( 0.4, 0.4, 0.5, 0.9 );
135  m_SolderMaskColorTop = SFVEC4F( 0.1, 0.2, 0.1, 0.83 );
136  m_SolderMaskColorBot = SFVEC4F( 0.1, 0.2, 0.1, 0.83 );
137  m_SolderPasteColor = SFVEC4F( 0.4, 0.4, 0.4, 1.0 );
138  m_SilkScreenColorTop = SFVEC4F( 0.9, 0.9, 0.9, 1.0 );
139  m_SilkScreenColorBot = SFVEC4F( 0.9, 0.9, 0.9, 1.0 );
140  m_CopperColor = SFVEC4F( 0.75, 0.61, 0.23, 1.0 );
141 
142  m_platedPadsFront = nullptr;
143  m_platedPadsBack = nullptr;
144 
145  m_frontPlatedPadPolys = nullptr;
146  m_backPlatedPadPolys = nullptr;
147 
148  // Avoid raytracing options not initialized:
152 
153  m_RtSpreadShadows = 0.0;
154  m_RtSpreadReflections = 0.0;
155  m_RtSpreadRefractions = 0.0;
156 
159 
160  if( !g_ColorsLoaded )
161  {
162 #define ADD_COLOR( list, r, g, b, a, name ) \
163  list.push_back( CUSTOM_COLOR_ITEM( r/255.0, g/255.0, b/255.0, a, name ) )
164 
165  ADD_COLOR( g_SilkscreenColors, 20, 51, 36, 1.0, "Green" );
166  ADD_COLOR( g_SilkscreenColors, 181, 19, 21, 1.0, "Red" );
167  ADD_COLOR( g_SilkscreenColors, 2, 59, 162, 1.0, "Blue" );
168  ADD_COLOR( g_SilkscreenColors, 11, 11, 11, 1.0, "Black" );
169  ADD_COLOR( g_SilkscreenColors, 245, 245, 245, 1.0, "White" );
170  ADD_COLOR( g_SilkscreenColors, 32, 2, 53, 1.0, "Purple" );
171  ADD_COLOR( g_SilkscreenColors, 194, 195, 0, 1.0, "Yellow" );
172 
173  ADD_COLOR( g_MaskColors, 20, 51, 36, 0.83, "Green" );
174  ADD_COLOR( g_MaskColors, 91, 168, 12, 0.83, "Light Green" );
175  ADD_COLOR( g_MaskColors, 13, 104, 11, 0.83, "Saturated Green" );
176  ADD_COLOR( g_MaskColors, 181, 19, 21, 0.83, "Red" );
177  ADD_COLOR( g_MaskColors, 210, 40, 14, 0.83, "Light Red" );
178  ADD_COLOR( g_MaskColors, 239, 53, 41, 0.83, "Red/Orange" );
179  ADD_COLOR( g_MaskColors, 2, 59, 162, 0.83, "Blue" );
180  ADD_COLOR( g_MaskColors, 54, 79, 116, 0.83, "Light Blue 1" );
181  ADD_COLOR( g_MaskColors, 61, 85, 130, 0.83, "Light Blue 2" );
182  ADD_COLOR( g_MaskColors, 21, 70, 80, 0.83, "Green/Blue" );
183  ADD_COLOR( g_MaskColors, 11, 11, 11, 0.83, "Black" );
184  ADD_COLOR( g_MaskColors, 245, 245, 245, 0.83, "White" );
185  ADD_COLOR( g_MaskColors, 32, 2, 53, 0.83, "Purple" );
186  ADD_COLOR( g_MaskColors, 119, 31, 91, 0.83, "Light Purple" );
187  ADD_COLOR( g_MaskColors, 194, 195, 0, 0.83, "Yellow" );
188 
189  ADD_COLOR( g_PasteColors, 128, 128, 128, 1.0, "Grey" );
190  ADD_COLOR( g_PasteColors, 90, 90, 90, 1.0, "Dark Grey" );
191  ADD_COLOR( g_PasteColors, 213, 213, 213, 1.0, "Silver" );
192 
193  ADD_COLOR( g_FinishColors, 184, 115, 50, 1.0, "Copper" );
194  ADD_COLOR( g_FinishColors, 178, 156, 0, 1.0, "Gold" );
195  ADD_COLOR( g_FinishColors, 213, 213, 213, 1.0, "Silver" );
196  ADD_COLOR( g_FinishColors, 160, 160, 160, 1.0, "Tin" );
197 
198  ADD_COLOR( g_BoardColors, 51, 43, 22, 0.83, "FR4 natural, dark" );
199  ADD_COLOR( g_BoardColors, 109, 116, 75, 0.83, "FR4 natural" );
200  ADD_COLOR( g_BoardColors, 252, 252, 250, 0.90, "PTFE natural" );
201  ADD_COLOR( g_BoardColors, 205, 130, 0, 0.68, "Polyimide" );
202  ADD_COLOR( g_BoardColors, 92, 17, 6, 0.90, "Phenolic natural" );
203  ADD_COLOR( g_BoardColors, 146, 99, 47, 0.83, "Brown 1" );
204  ADD_COLOR( g_BoardColors, 160, 123, 54, 0.83, "Brown 2" );
205  ADD_COLOR( g_BoardColors, 146, 99, 47, 0.83, "Brown 3" );
206  ADD_COLOR( g_BoardColors, 213, 213, 213, 1.0, "Aluminum" );
207 
208  g_DefaultBackgroundTop = COLOR4D( 0.80, 0.80, 0.90, 1.0 );
209  g_DefaultBackgroundBot = COLOR4D( 0.40, 0.40, 0.50, 1.0 );
210 
211  g_DefaultSilkscreen = COLOR4D( 0.94, 0.94, 0.94, 1.0 );
212  g_DefaultSolderMask = COLOR4D( 0.08, 0.20, 0.14, 0.83 );
213  g_DefaultSolderPaste = COLOR4D( 0.50, 0.50, 0.50, 1.0 );
214  g_DefaultSurfaceFinish = COLOR4D( 0.75, 0.61, 0.23, 1.0 );
215  g_DefaultBoardBody = COLOR4D( 0.43, 0.45, 0.30, 0.90 );
216 
217  g_ColorsLoaded = true;
218  }
219 #undef ADD_COLOR
220 }
221 
222 
224 {
225  destroyLayers();
226 }
227 
228 
230 {
231  wxASSERT( aLayer < PCB_LAYER_ID_COUNT );
232 
233  if( m_board && !m_board->IsLayerEnabled( aLayer ) )
234  return false;
235 
236  // see if layer needs to be shown
237  // check the flags
238  switch( aLayer )
239  {
240  case B_Adhes:
241  case F_Adhes:
242  return GetFlag( FL_ADHESIVE );
243 
244  case B_Paste:
245  case F_Paste:
246  return GetFlag( FL_SOLDERPASTE );
247 
248  case B_SilkS:
249  case F_SilkS:
250  return GetFlag( FL_SILKSCREEN );
251 
252  case B_Mask:
253  case F_Mask:
254  return GetFlag( FL_SOLDERMASK );
255 
256  case Dwgs_User:
257  case Cmts_User:
259  return false;
260 
261  return GetFlag( FL_COMMENTS );
262 
263  case Eco1_User:
264  case Eco2_User:
266  return false;
267 
268  return GetFlag( FL_ECO );
269 
270  case Edge_Cuts:
272  return false;
273 
274  return true;
275 
276  case Margin:
278  return false;
279 
280  return true;
281 
282  case B_Cu:
283  case F_Cu:
285  : true;
286 
287  default:
288  // the layer is an internal copper layer, used the visibility
289  return m_board && m_board->IsLayerVisible( aLayer );
290  }
291 }
292 
293 
295 {
296  wxASSERT( aFlag < FL_LAST );
297 
298  return m_drawFlags[aFlag];
299 }
300 
301 
302 void BOARD_ADAPTER::SetFlag( DISPLAY3D_FLG aFlag, bool aState )
303 {
304  wxASSERT( aFlag < FL_LAST );
305 
306  m_drawFlags[aFlag] = aState;
307 }
308 
309 
311 {
312  if( aFPAttributes & FP_SMD )
314  else if( aFPAttributes & FP_THROUGH_HOLE )
316  else
318 }
319 
320 
321 // !TODO: define the actual copper thickness by user from board stackup
322 #define COPPER_THICKNESS Millimeter2iu( 0.035 ) // for 35 um
323 // The solder mask layer (and silkscreen) thickness
324 #define TECH_LAYER_THICKNESS Millimeter2iu( 0.025 )
325 // The solder paste thickness is chosen bigger than the solder mask layer
326 // to be sure is covers the mask when overlapping.
327 #define SOLDERPASTE_LAYER_THICKNESS Millimeter2iu( 0.04 )
328 
330 {
332  : 0.035 * PCB_IU_PER_MM;
333 }
334 
335 
336 unsigned int BOARD_ADAPTER::GetCircleSegmentCount( float aDiameter3DU ) const
337 {
338  wxASSERT( aDiameter3DU > 0.0f );
339 
340  return GetCircleSegmentCount( (int)( aDiameter3DU / m_biuTo3Dunits ) );
341 }
342 
343 
344 unsigned int BOARD_ADAPTER::GetCircleSegmentCount( int aDiameterBIU ) const
345 {
346  wxASSERT( aDiameterBIU > 0 );
347 
348  return GetArcToSegmentCount( aDiameterBIU / 2, ARC_HIGH_DEF, 360.0 );
349 }
350 
351 
352 void BOARD_ADAPTER::InitSettings( REPORTER* aStatusReporter, REPORTER* aWarningReporter )
353 {
354  wxLogTrace( m_logTrace, wxT( "BOARD_ADAPTER::InitSettings" ) );
355 
356  if( aStatusReporter )
357  aStatusReporter->Report( _( "Build board outline" ) );
358 
359  wxString msg;
360 
361  const bool succeedToGetBoardPolygon = createBoardPolygon( &msg );
362 
363  if( aWarningReporter )
364  {
365  if( !succeedToGetBoardPolygon )
366  aWarningReporter->Report( msg, RPT_SEVERITY_WARNING );
367  else
368  aWarningReporter->Report( wxEmptyString );
369  }
370 
371  // Calculates the board bounding box (board outlines + items)
372  // to ensure any item, even outside the board outlines can be seen
373  bool boardEdgesOnly = true;
374 
376  || !succeedToGetBoardPolygon )
377  {
378  boardEdgesOnly = false;
379  }
380 
381  EDA_RECT bbbox;
382 
383  if( m_board )
384  bbbox = m_board->ComputeBoundingBox( boardEdgesOnly );
385 
386  // Gives a non null size to avoid issues in zoom / scale calculations
387  if( ( bbbox.GetWidth() == 0 ) && ( bbbox.GetHeight() == 0 ) )
388  bbbox.Inflate( Millimeter2iu( 10 ) );
389 
390  m_boardSize = bbbox.GetSize();
391  m_boardPos = bbbox.Centre();
392 
393  wxASSERT( (m_boardSize.x > 0) && (m_boardSize.y > 0) );
394 
395  m_boardPos.y = -m_boardPos.y; // The y coord is inverted in 3D viewer
396 
398 
399  // Ensure the board has 2 sides for 3D views, because it is hard to find
400  // a *really* single side board in the true life...
401  if( m_copperLayersCount < 2 )
403 
404  // Calculate the conversion to apply to all positions.
406 
409  : 1.6 * PCB_IU_PER_MM * m_biuTo3Dunits;
410 
411  // !TODO: use value defined by user (currently use default values by ctor
415 
416  // Init Z position of each layer
417  // calculate z position for each copper layer
418  // Zstart = -m_epoxyThickness / 2.0 is the z position of the back (bottom layer) (layer id = 31)
419  // Zstart = +m_epoxyThickness / 2.0 is the z position of the front (top layer) (layer id = 0)
420  // all unused copper layer z position are set to 0
421 
422  // ____==__________==________==______ <- Bottom = +m_epoxyThickness / 2.0,
423  // | | Top = Bottom + m_copperThickness
424  // |__________________________________|
425  // == == == == <- Bottom = -m_epoxyThickness / 2.0,
426  // Top = Bottom - m_copperThickness
427 
428  unsigned int layer;
429 
430  for( layer = 0; layer < m_copperLayersCount; ++layer )
431  {
432  m_layerZcoordBottom[layer] = m_epoxyThickness3DU / 2.0f -
433  (m_epoxyThickness3DU * layer / (m_copperLayersCount - 1) );
434 
435  if( layer < (m_copperLayersCount / 2) )
437  else
439  }
440 
441  #define layerThicknessMargin 1.1
442  const float zpos_offset = m_nonCopperLayerThickness3DU * layerThicknessMargin;
443 
444  // Fill remaining unused copper layers and back layer zpos
445  // with -m_epoxyThickness / 2.0
446  for( ; layer < MAX_CU_LAYERS; layer++ )
447  {
448  m_layerZcoordBottom[layer] = -(m_epoxyThickness3DU / 2.0f);
450  }
451 
452  // This is the top of the copper layer thickness.
453  const float zpos_copperTop_back = m_layerZcoordTop[B_Cu];
454  const float zpos_copperTop_front = m_layerZcoordTop[F_Cu];
455 
456  // calculate z position for each non copper layer
457  // Solder mask and Solder paste have the same Z position
458  for( int layer_id = MAX_CU_LAYERS; layer_id < PCB_LAYER_ID_COUNT; ++layer_id )
459  {
460  float zposTop;
461  float zposBottom;
462 
463  switch( layer_id )
464  {
465  case B_Adhes:
466  zposBottom = zpos_copperTop_back - 2.0f * zpos_offset;
467  zposTop = zposBottom - m_nonCopperLayerThickness3DU;
468  break;
469 
470  case F_Adhes:
471  zposBottom = zpos_copperTop_front + 2.0f * zpos_offset;
472  zposTop = zposBottom + m_nonCopperLayerThickness3DU;
473  break;
474 
475  case B_Mask:
476  zposBottom = zpos_copperTop_back;
477  zposTop = zpos_copperTop_back - m_nonCopperLayerThickness3DU;
478  break;
479 
480  case B_Paste:
481  zposBottom = zpos_copperTop_back;
482  zposTop = zpos_copperTop_back - m_solderPasteLayerThickness3DU;
483  break;
484 
485  case F_Mask:
486  zposBottom = zpos_copperTop_front;
487  zposTop = zpos_copperTop_front + m_nonCopperLayerThickness3DU;
488  break;
489 
490  case F_Paste:
491  zposBottom = zpos_copperTop_front;
492  zposTop = zpos_copperTop_front + m_solderPasteLayerThickness3DU;
493  break;
494 
495  case B_SilkS:
496  zposBottom = zpos_copperTop_back - 1.0f * zpos_offset;
497  zposTop = zposBottom - m_nonCopperLayerThickness3DU;
498  break;
499 
500  case F_SilkS:
501  zposBottom = zpos_copperTop_front + 1.0f * zpos_offset;
502  zposTop = zposBottom + m_nonCopperLayerThickness3DU;
503  break;
504 
505  // !TODO: review
506  default:
507  zposTop = zpos_copperTop_front + (layer_id - MAX_CU_LAYERS + 3.0f) * zpos_offset;
508  zposBottom = zposTop - m_nonCopperLayerThickness3DU;
509  break;
510  }
511 
512  m_layerZcoordTop[layer_id] = zposTop;
513  m_layerZcoordBottom[layer_id] = zposBottom;
514  }
515 
517 
519  0.0f );
520  boardSize /= 2.0f;
521 
522  SFVEC3F boardMin = ( m_boardCenter - boardSize );
523  SFVEC3F boardMax = ( m_boardCenter + boardSize );
524 
525  boardMin.z = m_layerZcoordTop[B_Adhes];
526  boardMax.z = m_layerZcoordTop[F_Adhes];
527 
528  m_boardBoundingBox = BBOX_3D( boardMin, boardMax );
529 
530 #ifdef PRINT_STATISTICS_3D_VIEWER
531  unsigned stats_startCreateBoardPolyTime = GetRunningMicroSecs();
532 #endif
533 
534  if( aStatusReporter )
535  aStatusReporter->Report( _( "Create layers" ) );
536 
537  createLayers( aStatusReporter );
538 
539  COLOR_SETTINGS* colors = Pgm().GetSettingsManager().GetColorSettings();
540 
541  auto to_SFVEC4F =
542  []( const COLOR4D& src )
543  {
544  return SFVEC4F( src.r, src.g, src.b, src.a );
545  };
546 
547  m_BgColorTop = to_SFVEC4F( colors->GetColor( LAYER_3D_BACKGROUND_TOP ) );
548  m_BgColorBot = to_SFVEC4F( colors->GetColor( LAYER_3D_BACKGROUND_BOTTOM ) );
549 
550  m_SolderPasteColor = to_SFVEC4F( colors->GetColor( LAYER_3D_SOLDERPASTE ) );
551 
552  if( m_board && colors->GetUseBoardStackupColors() )
553  {
555 
556  auto findColor =
557  []( const wxString& aColorName, const CUSTOM_COLORS_LIST& aColorSet )
558  {
559  if( aColorName.StartsWith( "#" ) )
560  {
561  return KIGFX::COLOR4D( wxColour( aColorName ) );
562  }
563  else
564  {
565  for( const CUSTOM_COLOR_ITEM& color : aColorSet )
566  {
567  if( color.m_ColorName == aColorName )
568  return color.m_Color;
569  }
570  }
571 
572  return KIGFX::COLOR4D();
573  };
574 
579 
580  KIGFX::COLOR4D bodyColor( 0, 0, 0, 0 );
581 
582  for( const BOARD_STACKUP_ITEM* stackupItem : stackup.GetList() )
583  {
584  wxString colorName = stackupItem->GetColor();
585 
586  switch( stackupItem->GetType() )
587  {
589  if( stackupItem->GetBrdLayerId() == F_SilkS )
590  m_SilkScreenColorTop = to_SFVEC4F( findColor( colorName, g_SilkscreenColors ) );
591  else
592  m_SilkScreenColorBot = to_SFVEC4F( findColor( colorName, g_SilkscreenColors ) );
593  break;
594 
596  if( stackupItem->GetBrdLayerId() == F_Mask )
597  m_SolderMaskColorTop = to_SFVEC4F( findColor( colorName, g_MaskColors ) );
598  else
599  m_SolderMaskColorBot = to_SFVEC4F( findColor( colorName, g_MaskColors ) );
600 
601  break;
602 
604  {
605  KIGFX::COLOR4D layerColor = COLOR4D::UNSPECIFIED;
606  const wxString& materialName = stackupItem->GetMaterial();
607 
608  if( materialName.StartsWith( "FR4" ) )
609  {
610  layerColor = findColor( "FR4 natural", g_BoardColors );
611  }
612  else if( materialName.IsSameAs( "PTFE" )
613  || materialName.IsSameAs( "Teflon" ) )
614  {
615  layerColor = findColor( "PTFE natural", g_BoardColors );
616  }
617  else if( materialName.IsSameAs( "Polyimide" )
618  || materialName.IsSameAs( "Kapton" ) )
619  {
620  layerColor = findColor( "Polyimide", g_BoardColors );
621  }
622  else if( materialName.IsSameAs( "Al" ) )
623  {
624  layerColor = findColor( "Aluminum", g_BoardColors );
625  }
626  else // A default color value for unknown dielectric material
627  // (i.e. an exotic name entered by hand)
628  {
629  layerColor = findColor( "FR4 natural", g_BoardColors );
630  }
631 
632  if( bodyColor == COLOR4D( 0, 0, 0, 0 ) )
633  bodyColor = layerColor;
634  else
635  bodyColor = bodyColor.Mix( layerColor, 1.0 - layerColor.a );
636 
637  bodyColor.a += ( 1.0 - bodyColor.a ) * layerColor.a / 2;
638  break;
639  }
640 
641  default:
642  break;
643  }
644  }
645 
646  if( bodyColor != COLOR4D( 0, 0, 0, 0 ) )
647  m_BoardBodyColor = to_SFVEC4F( bodyColor );
648  else
649  m_BoardBodyColor = to_SFVEC4F( g_DefaultBoardBody );
650 
651  const wxString& finishName = stackup.m_FinishType;
652 
653  if( finishName.EndsWith( "OSP" ) )
654  {
655  m_CopperColor = to_SFVEC4F( findColor( "Copper", g_FinishColors ) );
656  }
657  else if( finishName.EndsWith( "IG" )
658  || finishName.EndsWith( "gold" ) )
659  {
660  m_CopperColor = to_SFVEC4F( findColor( "Gold", g_FinishColors ) );
661  }
662  else if( finishName.StartsWith( "HAL" )
663  || finishName.StartsWith( "HASL" )
664  || finishName.EndsWith( "tin" )
665  || finishName.EndsWith( "nickel" ) )
666  {
667  m_CopperColor = to_SFVEC4F( findColor( "Tin", g_FinishColors ) );
668  }
669  else if( finishName.EndsWith( "silver" ) )
670  {
671  m_CopperColor = to_SFVEC4F( findColor( "Silver", g_FinishColors ) );
672  }
673  else
674  {
675  m_CopperColor = to_SFVEC4F( g_DefaultSurfaceFinish );
676  }
677  }
678  else
679  {
680  m_SilkScreenColorBot = to_SFVEC4F( colors->GetColor( LAYER_3D_SILKSCREEN_BOTTOM ) );
681  m_SilkScreenColorTop = to_SFVEC4F( colors->GetColor( LAYER_3D_SILKSCREEN_TOP ) );
682  m_SolderMaskColorBot = to_SFVEC4F( colors->GetColor( LAYER_3D_SOLDERMASK_BOTTOM ) );
683  m_SolderMaskColorTop = to_SFVEC4F( colors->GetColor( LAYER_3D_SOLDERMASK_TOP ) );
684  m_CopperColor = to_SFVEC4F( colors->GetColor( LAYER_3D_COPPER ) );
685  m_BoardBodyColor = to_SFVEC4F( colors->GetColor( LAYER_3D_BOARD ) );
686  }
687 }
688 
689 
690 extern bool BuildFootprintPolygonOutlines( BOARD* aBoard, SHAPE_POLY_SET& aOutlines,
691  int aErrorMax, int aChainingEpsilon,
692  OUTLINE_ERROR_HANDLER* aErrorHandler = nullptr );
693 
694 
695 bool BOARD_ADAPTER::createBoardPolygon( wxString* aErrorMsg )
696 {
698 
699  if( !m_board )
700  return false;
701 
702  bool success;
703 
704  if( m_board->IsFootprintHolder() )
705  {
706  if( !m_board->GetFirstFootprint() )
707  {
708  if( aErrorMsg )
709  *aErrorMsg = _( "No footprint loaded." );
710 
711  return false;
712  }
713 
714  int chainingEpsilon = Millimeter2iu( 0.02 ); // max dist from one endPt to next startPt
715 
718  chainingEpsilon );
719 
720  // Make polygon strictly simple to avoid issues (especially in 3D viewer)
722 
723  if( !success && aErrorMsg )
724  {
725  *aErrorMsg = _( "Footprint outline is missing or malformed. Run Footprint Checker for "
726  "a full analysis." );
727  }
728  }
729  else
730  {
732 
733  if( !success && aErrorMsg )
734  *aErrorMsg = _( "Board outline is missing or malformed. Run DRC for a full analysis." );
735  }
736 
737  return success;
738 }
739 
740 
741 float BOARD_ADAPTER::GetFootprintZPos( bool aIsFlipped ) const
742 {
743  if( aIsFlipped )
744  {
745  if( GetFlag( FL_SOLDERPASTE ) )
747  else
749  }
750  else
751  {
752  if( GetFlag( FL_SOLDERPASTE ) )
753  return m_layerZcoordTop[F_SilkS];
754  else
755  return m_layerZcoordTop[F_Paste];
756  }
757 }
758 
759 
761 {
762  wxASSERT( aLayerId < PCB_LAYER_ID_COUNT );
763 
764  const COLOR4D color = m_colors->GetColor( aLayerId );
765 
766  return SFVEC4F( color.r, color.g, color.b, color.a );
767 }
768 
769 
771 {
772  return GetColor( m_colors->GetColor( aItemId ) );
773 }
774 
775 
777 {
778  return SFVEC4F( aColor.r, aColor.g, aColor.b, aColor.a );
779 }
bool GetFlag(DISPLAY3D_FLG aFlag) const
Get a configuration status of a flag.
BVH_CONTAINER_2D * m_platedPadsFront
static bool g_ColorsLoaded
int m_RtShadowSampleCount
Defines math related functions.
#define TECH_LAYER_THICKNESS
SFVEC4F m_SilkScreenColorBot
in realistic mode: SilkScreen color ( bot )
bool GetBoardPolygonOutlines(SHAPE_POLY_SET &aOutlines, OUTLINE_ERROR_HANDLER *aErrorHandler=nullptr)
Extract the board outlines and build a closed polygon from lines, arcs and circle items on edge cut l...
Definition: board.cpp:1899
bool GetUseBoardStackupColors() const
bool BuildFootprintPolygonOutlines(BOARD *aBoard, SHAPE_POLY_SET &aOutlines, int aErrorMax, int aChainingEpsilon, OUTLINE_ERROR_HANDLER *aErrorHandler=nullptr)
This function is used to extract a board outline for a footprint view.
SHAPE_POLY_SET * m_backPlatedPadPolys
Polygon contours for hole outer diameters for each layer.
float m_solderPasteLayerThickness3DU
Number of tracks in the board.
BVH_CONTAINER_2D m_throughHoleIds
List of through hole vias with the radius of the hole inflated with the copper thickness.
Manage layers needed to make a physical board.
bool IsFootprintShown(FOOTPRINT_ATTR_T aFPAttributes) const
Test if footprint should be displayed in relation to attributes and the flags.
float m_nonCopperLayerThickness3DU
solder paste layers thickness in 3D units.
SHAPE_POLY_SET * m_frontPlatedPadPolys
wxString m_FinishType
The name of external copper finish.
Manage a bounding box defined by two SFVEC3F min max points.
Definition: bbox_3d.h:41
SFVEC4F GetColor(const COLOR4D &aColor) const
float m_averageHoleDiameter
glm::vec4 SFVEC4F
Definition: xv3d_types.h:46
int GetHolePlatingThickness() const
Pad & via drills are finish size.
static KIGFX::COLOR4D g_DefaultSilkscreen
void SetFlag(DISPLAY3D_FLG aFlag, bool aState)
Set the status of a flag.
COLOR_SETTINGS * m_colors
SFVEC4F m_SolderMaskColorTop
in realistic mode: solder mask color ( top )
int color
Definition: DXF_plotter.cpp:57
int GetWidth() const
Definition: eda_rect.h:109
static KIGFX::COLOR4D g_DefaultSurfaceFinish
BVH_CONTAINER_2D m_throughHoleOds
List of plated through hole annular rings.
void InitSettings(REPORTER *aStatusReporter, REPORTER *aWarningReporter)
Function to be called by the render when it need to reload the settings for the board.
SFVEC4F m_BoardBodyColor
in realistic mode: FR4 board color
SFVEC4F m_SolderPasteColor
in realistic mode: solder paste color
double g
Green component.
Definition: color4d.h:372
#define layerThicknessMargin
float m_averageTrackWidth
Number of through hole vias in the board.
A class to handle a custom color (predefined color) for the color picker dialog.
SFVEC4F m_SolderMaskColorBot
in realistic mode: solder mask color ( bot )
wxPoint m_boardPos
Board center position in board internal units.
bool IsFootprintHolder() const
Find out if the board is being used to hold a single footprint for editing/viewing.
Definition: board.h:221
std::vector< CUSTOM_COLOR_ITEM > CUSTOM_COLORS_LIST
A pure virtual class used to derive REPORTER objects from.
Definition: reporter.h:70
std::array< float, PCB_LAYER_ID_COUNT > m_layerZcoordBottom
Copper thickness in 3D units.
bool IsLayerEnabled(PCB_LAYER_ID aLayer) const
A proxy function that calls the correspondent function in m_BoardSettings tests whether a given layer...
Definition: board.cpp:492
float m_epoxyThickness3DU
Non copper layers thickness in 3D units.
static CUSTOM_COLORS_LIST g_BoardColors
float m_copperThickness3DU
Epoxy thickness in 3D units.
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:106
static KIGFX::COLOR4D g_DefaultBackgroundBot
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:589
float m_RtSpreadRefractions
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)=0
Report a string with a given severity.
FOOTPRINT_ATTR_T
The set of attributes allowed within a FOOTPRINT, using FOOTPRINT::SetAttributes() and FOOTPRINT::Get...
Definition: footprint.h:66
double b
Blue component.
Definition: color4d.h:373
static CUSTOM_COLORS_LIST g_FinishColors
static CUSTOM_COLORS_LIST g_PasteColors
bool Is3dLayerEnabled(PCB_LAYER_ID aLayer) const
Check if a layer is enabled.
static KIGFX::COLOR4D g_DefaultSolderMask
BOARD_STACKUP & GetStackupDescriptor()
double a
Alpha component.
Definition: color4d.h:374
static KIGFX::COLOR4D g_DefaultBoardBody
int m_RtRecursiveReflectionCount
float m_RtSpreadReflections
SFVEC4F m_BgColorTop
background top color
unsigned int m_trackCount
Track average width.
std::vector< bool > m_drawFlags
std::array< float, PCB_LAYER_ID_COUNT > m_layerZcoordTop
Bottom (Start) Z position of each layer in 3D units.
FOOTPRINT * GetFirstFootprint() const
Get the first footprint on the board or nullptr.
Definition: board.h:317
#define ADD_COLOR(list, r, g, b, a, name)
#define MAX_CU_LAYERS
Definition: layer_ids.h:146
GRID3D_TYPE m_gridType
SHAPE_POLY_SET m_board_poly
Board outline polygon.
PGM_BASE * PgmOrNull()
similar to PGM_BASE& Pgm(), but return a reference that can be nullptr when running a shared lib from...
Definition: cvpcb.cpp:125
BVH_CONTAINER_2D * m_platedPadsBack
The holes per each layer.
BBOX_3D m_boardBoundingBox
3D bounding box of the board in 3D units.
Represent a set of closed polygons.
constexpr double PCB_IU_PER_MM
Use all material properties from model file.
static KIGFX::COLOR4D g_DefaultBackgroundTop
double m_biuTo3Dunits
Top (End) Z position of each layer in 3D units.
#define _(s)
SFVEC4F m_BgColorBot
background bottom color
a few functions useful in geometry calculations.
void Simplify(POLYGON_MODE aFastMode)
BVH_CONTAINER_2D m_throughHoleAnnularRings
List of through hole inner diameters.
unsigned int m_viaCount
Computed average diameter of the via holes in 3D units.
int m_RtRecursiveRefractionCount
Manage one layer needed to make a physical board.
Definition: board_stackup.h:89
int m_RtRefractionSampleCount
SFVEC4F GetItemColor(int aItemId) const
Get the technical color of a layer.
void createLayers(REPORTER *aStatusReporter)
int GetHeight() const
Definition: eda_rect.h:110
const std::vector< BOARD_STACKUP_ITEM * > & GetList() const
#define SOLDERPASTE_LAYER_THICKNESS
float GetFootprintZPos(bool aIsFlipped) const
Get the position of the footprint in 3d integer units considering if it is flipped or not.
DISPLAY3D_FLG
Flags used in rendering options.
Definition: 3d_enums.h:34
RENDER_ENGINE m_renderEngine
COLOR4D GetColor(int aLayer) const
wxSize m_boardSize
Board size in board internal units.
bool IsLayerVisible(PCB_LAYER_ID aLayer) const
A proxy function that calls the correspondent function in m_BoardSettings tests whether a given layer...
Definition: board.cpp:472
SFVEC4F GetLayerColor(PCB_LAYER_ID aLayerId) const
Get the technical color of a layer.
see class PGM_BASE
MATERIAL_MODE m_materialMode
static const wxChar * m_logTrace
Trace mask used to enable or disable the trace output of this class.
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:190
unsigned GetRunningMicroSecs()
An alternate way to calculate an elapset time (in microsecondes) to class PROF_COUNTER.
static KIGFX::COLOR4D g_DefaultSolderPaste
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:64
glm::vec3 SFVEC3F
Definition: xv3d_types.h:44
unsigned int m_copperLayersCount
Scale factor to convert board internal units to 3D units normalized between -1.0 and 1....
bool createBoardPolygon(wxString *aErrorMsg)
Create the board outline polygon.
SFVEC4F m_CopperColor
in realistic mode: copper color
Definition: layer_ids.h:70
int GetCopperLayerCount() const
Definition: board.cpp:454
Handle the component boundary box.
Definition: eda_rect.h:42
const std::function< void(const wxString &msg, BOARD_ITEM *itemA, BOARD_ITEM *itemB, const wxPoint &pt)> OUTLINE_ERROR_HANDLER
wxPoint Centre() const
Definition: eda_rect.h:55
EDA_RECT ComputeBoundingBox(bool aBoardEdgesOnly=false) const
Calculate the bounding box containing all board items (or board edge segments).
Definition: board.cpp:1105
Defines math related functions.
Color settings are a bit different than most of the settings objects in that there can be more than o...
SFVEC4F m_SilkScreenColorTop
in realistic mode: SilkScreen color ( top )
static CUSTOM_COLORS_LIST g_MaskColors
ANTIALIASING_MODE m_antiAliasingMode
static CUSTOM_COLORS_LIST g_SilkscreenColors
SFVEC3F m_boardCenter
3D center position of the board in 3D units.
#define COPPER_THICKNESS
double r
Red component.
Definition: color4d.h:371
float m_averageViaHoleDiameter
Number of holes in the board.
COLOR4D Mix(const COLOR4D &aColor, double aFactor) const
Return a color that is mixed with the input by a factor.
Definition: color4d.h:292
float m_RtSpreadShadows
static constexpr int Millimeter2iu(double mm)
void Clear() override
#define RANGE_SCALE_3D
This defines the range that all coord will have to be rendered.
Definition: board_adapter.h:62
void Reset()
Reset the bounding box to zero and de-initialize it.
Definition: bbox_3d.cpp:95
int GetArcToSegmentCount(int aRadius, int aErrorMax, double aArcAngleDegree)
unsigned int GetCircleSegmentCount(float aDiameter3DU) const
int m_RtReflectionSampleCount
EDA_RECT & Inflate(wxCoord dx, wxCoord dy)
Inflate the rectangle horizontally by dx and vertically by dy.
Definition: eda_rect.cpp:364
unsigned int m_holeCount
Computed average diameter of the holes in 3D units.
const wxSize GetSize() const
Definition: eda_rect.h:91
int GetHolePlatingThickness() const noexcept
Get the current copper layer thickness.
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:103