KiCad PCB EDA Suite
create_layer_items.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-2016 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 
33 #include "cinfo3d_visu.h"
34 #include "../3d_rendering/3d_render_raytracing/shapes2D/cring2d.h"
35 #include "../3d_rendering/3d_render_raytracing/shapes2D/cfilledcircle2d.h"
36 #include "../3d_rendering/3d_render_raytracing/shapes2D/croundsegment2d.h"
37 #include "../3d_rendering/3d_render_raytracing/shapes2D/cpolygon4pts2d.h"
38 #include "../3d_rendering/3d_render_raytracing/shapes2D/cpolygon2d.h"
39 #include "../3d_rendering/3d_render_raytracing/shapes2D/ctriangle2d.h"
40 #include "../3d_rendering/3d_render_raytracing/accelerators/ccontainer2d.h"
41 #include "../3d_rendering/3d_render_raytracing/shapes3D/ccylinder.h"
42 #include "../3d_rendering/3d_render_raytracing/shapes3D/clayeritem.h"
43 
44 #include <class_board.h>
45 #include <class_module.h>
46 #include <class_pad.h>
47 #include <class_pcb_text.h>
48 #include <class_edge_mod.h>
49 #include <class_zone.h>
50 #include <class_text_mod.h>
52 #include <trigo.h>
53 #include <utility>
54 #include <vector>
55 #include <thread>
56 #include <algorithm>
57 #include <atomic>
58 
59 #include <profile.h>
60 
62 {
63  if( !m_layers_poly.empty() )
64  {
65  for( MAP_POLY::iterator ii = m_layers_poly.begin();
66  ii != m_layers_poly.end();
67  ++ii )
68  {
69  delete ii->second;
70  ii->second = NULL;
71  }
72 
73  m_layers_poly.clear();
74  }
75 
76  if( !m_layers_inner_holes_poly.empty() )
77  {
78  for( MAP_POLY::iterator ii = m_layers_inner_holes_poly.begin();
79  ii != m_layers_inner_holes_poly.end();
80  ++ii )
81  {
82  delete ii->second;
83  ii->second = NULL;
84  }
85 
87  }
88 
89  if( !m_layers_outer_holes_poly.empty() )
90  {
91  for( MAP_POLY::iterator ii = m_layers_outer_holes_poly.begin();
92  ii != m_layers_outer_holes_poly.end();
93  ++ii )
94  {
95  delete ii->second;
96  ii->second = NULL;
97  }
98 
100  }
101 
102  if( !m_layers_container2D.empty() )
103  {
104  for( MAP_CONTAINER_2D::iterator ii = m_layers_container2D.begin();
105  ii != m_layers_container2D.end();
106  ++ii )
107  {
108  delete ii->second;
109  ii->second = NULL;
110  }
111 
112  m_layers_container2D.clear();
113  }
114 
115  if( !m_layers_holes2D.empty() )
116  {
117  for( MAP_CONTAINER_2D::iterator ii = m_layers_holes2D.begin();
118  ii != m_layers_holes2D.end();
119  ++ii )
120  {
121  delete ii->second;
122  ii->second = NULL;
123  }
124 
125  m_layers_holes2D.clear();
126  }
127 
134  //m_through_inner_holes_poly.RemoveAllContours();
135 
138 }
139 
140 
141 void CINFO3D_VISU::createLayers( REPORTER *aStatusTextReporter )
142 {
143  // Number of segments to draw a circle using segments (used on countour zones
144  // and text copper elements )
145  const int segcountforcircle = 12;
146  const double correctionFactor = GetCircleCorrectionFactor( segcountforcircle );
147 
148  // segments to draw a circle to build texts. Is is used only to build
149  // the shape of each segment of the stroke font, therefore no need to have
150  // many segments per circle.
151  const int segcountInStrokeFont = 12;
152  const double correctionFactorStroke = GetCircleCorrectionFactor( segcountInStrokeFont );
153 
154  destroyLayers();
155 
156  // Build Copper layers
157  // Based on: https://github.com/KiCad/kicad-source-mirror/blob/master/3d-viewer/3d_draw.cpp#L692
158  // /////////////////////////////////////////////////////////////////////////
159 
160  #ifdef PRINT_STATISTICS_3D_VIEWER
161  unsigned stats_startCopperLayersTime = GetRunningMicroSecs();
162 
163  unsigned start_Time = stats_startCopperLayersTime;
164 #endif
165 
166  PCB_LAYER_ID cu_seq[MAX_CU_LAYERS];
168 
169  m_stats_nr_tracks = 0;
171  m_stats_nr_vias = 0;
173  m_stats_nr_holes = 0;
175 
176  // Prepare track list, convert in a vector. Calc statistic for the holes
177  // /////////////////////////////////////////////////////////////////////////
178  std::vector< const TRACK *> trackList;
179  trackList.clear();
180  trackList.reserve( m_board->m_Track.GetCount() );
181 
182  for( const TRACK* track = m_board->m_Track; track; track = track->Next() )
183  {
184  if( !Is3DLayerEnabled( track->GetLayer() ) ) // Skip non enabled layers
185  continue;
186 
187  // Note: a TRACK holds normal segment tracks and
188  // also vias circles (that have also drill values)
189  trackList.push_back( track );
190 
191  if( track->Type() == PCB_VIA_T )
192  {
193  const VIA *via = static_cast< const VIA*>( track );
194  m_stats_nr_vias++;
196  }
197  else
198  {
200  }
201 
202  m_stats_track_med_width += track->GetWidth() * m_biuTo3Dunits;
203  }
204 
205  if( m_stats_nr_tracks )
207 
208  if( m_stats_nr_vias )
210 
211 #ifdef PRINT_STATISTICS_3D_VIEWER
212  printf( "T01: %.3f ms\n", (float)( GetRunningMicroSecs() - start_Time ) / 1e3 );
213  start_Time = GetRunningMicroSecs();
214 #endif
215 
216  // Prepare copper layers index and containers
217  // /////////////////////////////////////////////////////////////////////////
218  std::vector< PCB_LAYER_ID > layer_id;
219  layer_id.clear();
220  layer_id.reserve( m_copperLayersCount );
221 
222  for( unsigned i = 0; i < DIM( cu_seq ); ++i )
223  cu_seq[i] = ToLAYER_ID( B_Cu - i );
224 
225  for( LSEQ cu = cu_set.Seq( cu_seq, DIM( cu_seq ) ); cu; ++cu )
226  {
227  const PCB_LAYER_ID curr_layer_id = *cu;
228 
229  if( !Is3DLayerEnabled( curr_layer_id ) ) // Skip non enabled layers
230  continue;
231 
232  layer_id.push_back( curr_layer_id );
233 
234  CBVHCONTAINER2D *layerContainer = new CBVHCONTAINER2D;
235  m_layers_container2D[curr_layer_id] = layerContainer;
236 
239  {
240  SHAPE_POLY_SET *layerPoly = new SHAPE_POLY_SET;
241  m_layers_poly[curr_layer_id] = layerPoly;
242  }
243  }
244 
245 #ifdef PRINT_STATISTICS_3D_VIEWER
246  printf( "T02: %.3f ms\n", (float)( GetRunningMicroSecs() - start_Time ) / 1e3 );
247  start_Time = GetRunningMicroSecs();
248 #endif
249 
250  if( aStatusTextReporter )
251  aStatusTextReporter->Report( _( "Create tracks and vias" ) );
252 
253  // Create tracks as objects and add it to container
254  // /////////////////////////////////////////////////////////////////////////
255  for( unsigned int lIdx = 0; lIdx < layer_id.size(); ++lIdx )
256  {
257  const PCB_LAYER_ID curr_layer_id = layer_id[lIdx];
258 
259  wxASSERT( m_layers_container2D.find( curr_layer_id ) != m_layers_container2D.end() );
260 
261  CBVHCONTAINER2D *layerContainer = m_layers_container2D[curr_layer_id];
262 
263  // ADD TRACKS
264  unsigned int nTracks = trackList.size();
265 
266  for( unsigned int trackIdx = 0; trackIdx < nTracks; ++trackIdx )
267  {
268  const TRACK *track = trackList[trackIdx];
269 
270  // NOTE: Vias can be on multiple layers
271  if( !track->IsOnLayer( curr_layer_id ) )
272  continue;
273 
274  // Add object item to layer container
275  layerContainer->Add( createNewTrack( track, 0.0f ) );
276  }
277  }
278 
279 #ifdef PRINT_STATISTICS_3D_VIEWER
280  printf( "T03: %.3f ms\n", (float)( GetRunningMicroSecs() - start_Time ) / 1e3 );
281  start_Time = GetRunningMicroSecs();
282 #endif
283 
284  // Create VIAS and THTs objects and add it to holes containers
285  // /////////////////////////////////////////////////////////////////////////
286  for( unsigned int lIdx = 0; lIdx < layer_id.size(); ++lIdx )
287  {
288  const PCB_LAYER_ID curr_layer_id = layer_id[lIdx];
289 
290  // ADD TRACKS
291  unsigned int nTracks = trackList.size();
292 
293  for( unsigned int trackIdx = 0; trackIdx < nTracks; ++trackIdx )
294  {
295  const TRACK *track = trackList[trackIdx];
296 
297  if( !track->IsOnLayer( curr_layer_id ) )
298  continue;
299 
300  // ADD VIAS and THT
301  if( track->Type() == PCB_VIA_T )
302  {
303  const VIA *via = static_cast< const VIA*>( track );
304  const VIATYPE_T viatype = via->GetViaType();
305  const float holediameter = via->GetDrillValue() * BiuTo3Dunits();
306  const float thickness = GetCopperThickness3DU();
307  const float hole_inner_radius = ( holediameter / 2.0f );
308 
309  const SFVEC2F via_center( via->GetStart().x * m_biuTo3Dunits,
310  -via->GetStart().y * m_biuTo3Dunits );
311 
312  if( viatype != VIA_THROUGH )
313  {
314 
315  // Add hole objects
316  // /////////////////////////////////////////////////////////
317 
318  CBVHCONTAINER2D *layerHoleContainer = NULL;
319 
320  // Check if the layer is already created
321  if( m_layers_holes2D.find( curr_layer_id ) == m_layers_holes2D.end() )
322  {
323  // not found, create a new container
324  layerHoleContainer = new CBVHCONTAINER2D;
325  m_layers_holes2D[curr_layer_id] = layerHoleContainer;
326  }
327  else
328  {
329  // found
330  layerHoleContainer = m_layers_holes2D[curr_layer_id];
331  }
332 
333  // Add a hole for this layer
334  layerHoleContainer->Add( new CFILLEDCIRCLE2D( via_center,
335  hole_inner_radius + thickness,
336  *track ) );
337  }
338  else if( lIdx == 0 ) // it only adds once the THT holes
339  {
340  // Add through hole object
341  // /////////////////////////////////////////////////////////
342  m_through_holes_outer.Add( new CFILLEDCIRCLE2D( via_center,
343  hole_inner_radius + thickness,
344  *track ) );
345 
347  new CFILLEDCIRCLE2D( via_center,
348  hole_inner_radius + thickness,
349  *track ) );
350 
351  m_through_holes_inner.Add( new CFILLEDCIRCLE2D( via_center,
352  hole_inner_radius,
353  *track ) );
354 
355  //m_through_holes_vias_inner.Add( new CFILLEDCIRCLE2D( via_center,
356  // hole_inner_radius,
357  // *track ) );
358  }
359  }
360  }
361  }
362 
363 #ifdef PRINT_STATISTICS_3D_VIEWER
364  printf( "T04: %.3f ms\n", (float)( GetRunningMicroSecs() - start_Time ) / 1e3 );
365  start_Time = GetRunningMicroSecs();
366 #endif
367 
368  // Create VIAS and THTs objects and add it to holes containers
369  // /////////////////////////////////////////////////////////////////////////
370  for( unsigned int lIdx = 0; lIdx < layer_id.size(); ++lIdx )
371  {
372  const PCB_LAYER_ID curr_layer_id = layer_id[lIdx];
373 
374  // ADD TRACKS
375  const unsigned int nTracks = trackList.size();
376 
377  for( unsigned int trackIdx = 0; trackIdx < nTracks; ++trackIdx )
378  {
379  const TRACK *track = trackList[trackIdx];
380 
381  if( !track->IsOnLayer( curr_layer_id ) )
382  continue;
383 
384  // ADD VIAS and THT
385  if( track->Type() == PCB_VIA_T )
386  {
387  const VIA *via = static_cast< const VIA*>( track );
388  const VIATYPE_T viatype = via->GetViaType();
389 
390  if( viatype != VIA_THROUGH )
391  {
392 
393  // Add VIA hole contourns
394  // /////////////////////////////////////////////////////////
395 
396  // Add outter holes of VIAs
397  SHAPE_POLY_SET *layerOuterHolesPoly = NULL;
398  SHAPE_POLY_SET *layerInnerHolesPoly = NULL;
399 
400  // Check if the layer is already created
401  if( m_layers_outer_holes_poly.find( curr_layer_id ) ==
403  {
404  // not found, create a new container
405  layerOuterHolesPoly = new SHAPE_POLY_SET;
406  m_layers_outer_holes_poly[curr_layer_id] = layerOuterHolesPoly;
407 
408  wxASSERT( m_layers_inner_holes_poly.find( curr_layer_id ) ==
410 
411  layerInnerHolesPoly = new SHAPE_POLY_SET;
412  m_layers_inner_holes_poly[curr_layer_id] = layerInnerHolesPoly;
413  }
414  else
415  {
416  // found
417  layerOuterHolesPoly = m_layers_outer_holes_poly[curr_layer_id];
418 
419  wxASSERT( m_layers_inner_holes_poly.find( curr_layer_id ) !=
421 
422  layerInnerHolesPoly = m_layers_inner_holes_poly[curr_layer_id];
423  }
424 
425  const int holediameter = via->GetDrillValue();
426  const int hole_outer_radius = (holediameter / 2) + GetCopperThicknessBIU();
427 
428  TransformCircleToPolygon( *layerOuterHolesPoly,
429  via->GetStart(),
430  hole_outer_radius,
431  GetNrSegmentsCircle( hole_outer_radius * 2 ) );
432 
433  TransformCircleToPolygon( *layerInnerHolesPoly,
434  via->GetStart(),
435  holediameter / 2,
436  GetNrSegmentsCircle( holediameter ) );
437  }
438  else if( lIdx == 0 ) // it only adds once the THT holes
439  {
440  const int holediameter = via->GetDrillValue();
441  const int hole_outer_radius = (holediameter / 2)+ GetCopperThicknessBIU();
442 
443  // Add through hole contourns
444  // /////////////////////////////////////////////////////////
446  via->GetStart(),
447  hole_outer_radius,
448  GetNrSegmentsCircle( hole_outer_radius * 2 ) );
449 
451  via->GetStart(),
452  holediameter / 2,
453  GetNrSegmentsCircle( holediameter ) );
454 
455  // Add samething for vias only
456 
458  via->GetStart(),
459  hole_outer_radius,
460  GetNrSegmentsCircle( hole_outer_radius * 2 ) );
461 
462  //TransformCircleToPolygon( m_through_inner_holes_vias_poly,
463  // via->GetStart(),
464  // holediameter / 2,
465  // GetNrSegmentsCircle( holediameter ) );
466  }
467  }
468  }
469  }
470 
471 #ifdef PRINT_STATISTICS_3D_VIEWER
472  printf( "T05: %.3f ms\n", (float)( GetRunningMicroSecs() - start_Time ) / 1e3 );
473  start_Time = GetRunningMicroSecs();
474 #endif
475 
476  // Creates outline contours of the tracks and add it to the poly of the layer
477  // /////////////////////////////////////////////////////////////////////////
480  {
481  for( unsigned int lIdx = 0; lIdx < layer_id.size(); ++lIdx )
482  {
483  const PCB_LAYER_ID curr_layer_id = layer_id[lIdx];
484 
485  wxASSERT( m_layers_poly.find( curr_layer_id ) != m_layers_poly.end() );
486 
487  SHAPE_POLY_SET *layerPoly = m_layers_poly[curr_layer_id];
488 
489  // ADD TRACKS
490  unsigned int nTracks = trackList.size();
491 
492  for( unsigned int trackIdx = 0; trackIdx < nTracks; ++trackIdx )
493  {
494  const TRACK *track = trackList[trackIdx];
495 
496  if( !track->IsOnLayer( curr_layer_id ) )
497  continue;
498 
499  // Add the track contour
500  int nrSegments = GetNrSegmentsCircle( track->GetWidth() );
501 
503  *layerPoly,
504  0,
505  nrSegments,
506  GetCircleCorrectionFactor( nrSegments ) );
507  }
508  }
509  }
510 
511 #ifdef PRINT_STATISTICS_3D_VIEWER
512  printf( "T06: %.3f ms\n", (float)( GetRunningMicroSecs() - start_Time ) / 1e3 );
513  start_Time = GetRunningMicroSecs();
514 #endif
515 
516  // Add holes of modules
517  // /////////////////////////////////////////////////////////////////////////
518  for( const MODULE* module = m_board->m_Modules; module; module = module->Next() )
519  {
520  const D_PAD* pad = module->PadsList();
521 
522  for( ; pad; pad = pad->Next() )
523  {
524  const wxSize padHole = pad->GetDrillSize();
525 
526  if( !padHole.x ) // Not drilled pad like SMD pad
527  continue;
528 
529  // The hole in the body is inflated by copper thickness,
530  // if not plated, no copper
531  const int inflate = (pad->GetAttribute () != PAD_ATTRIB_HOLE_NOT_PLATED) ?
532  GetCopperThicknessBIU() : 0;
533 
535  m_stats_hole_med_diameter += ( ( pad->GetDrillSize().x +
536  pad->GetDrillSize().y ) / 2.0f ) * m_biuTo3Dunits;
537 
538  m_through_holes_outer.Add( createNewPadDrill( pad, inflate ) );
540  }
541  }
542  if( m_stats_nr_holes )
544 
545 #ifdef PRINT_STATISTICS_3D_VIEWER
546  printf( "T07: %.3f ms\n", (float)( GetRunningMicroSecs() - start_Time ) / 1e3 );
547  start_Time = GetRunningMicroSecs();
548 #endif
549 
550  // Add contours of the pad holes (pads can be Circle or Segment holes)
551  // /////////////////////////////////////////////////////////////////////////
552  for( const MODULE* module = m_board->m_Modules; module; module = module->Next() )
553  {
554  const D_PAD* pad = module->PadsList();
555 
556  for( ; pad; pad = pad->Next() )
557  {
558  const wxSize padHole = pad->GetDrillSize();
559 
560  if( !padHole.x ) // Not drilled pad like SMD pad
561  continue;
562 
563  // The hole in the body is inflated by copper thickness.
564  const int inflate = GetCopperThicknessBIU();
565 
566  // we use the hole diameter to calculate the seg count.
567  // for round holes, padHole.x == padHole.y
568  // for oblong holes, the diameter is the smaller of (padHole.x, padHole.y)
569  const int diam = std::min( padHole.x, padHole.y );
570 
571 
573  {
575  inflate,
576  GetNrSegmentsCircle( diam ) );
577 
579  0,
580  GetNrSegmentsCircle( diam ) );
581  }
582  else
583  {
584  // If not plated, no copper.
586  inflate,
587  GetNrSegmentsCircle( diam ) );
588  }
589  }
590  }
591 
592 #ifdef PRINT_STATISTICS_3D_VIEWER
593  printf( "T08: %.3f ms\n", (float)( GetRunningMicroSecs() - start_Time ) / 1e3 );
594  start_Time = GetRunningMicroSecs();
595 #endif
596 
597  // Add modules PADs objects to containers
598  // /////////////////////////////////////////////////////////////////////////
599  for( unsigned int lIdx = 0; lIdx < layer_id.size(); ++lIdx )
600  {
601  const PCB_LAYER_ID curr_layer_id = layer_id[lIdx];
602 
603  wxASSERT( m_layers_container2D.find( curr_layer_id ) != m_layers_container2D.end() );
604 
605  CBVHCONTAINER2D *layerContainer = m_layers_container2D[curr_layer_id];
606 
607  // ADD PADS
608  for( const MODULE* module = m_board->m_Modules; module; module = module->Next() )
609  {
610  // Note: NPTH pads are not drawn on copper layers when the pad
611  // has same shape as its hole
613  layerContainer,
614  curr_layer_id,
615  0,
616  true );
617 
618  // Micro-wave modules may have items on copper layers
620  layerContainer,
621  curr_layer_id,
622  0 );
623  }
624  }
625 
626 #ifdef PRINT_STATISTICS_3D_VIEWER
627  printf( "T09: %.3f ms\n", (float)( GetRunningMicroSecs() - start_Time ) / 1e3 );
628  start_Time = GetRunningMicroSecs();
629 #endif
630 
631  // Add modules PADs poly contourns
632  // /////////////////////////////////////////////////////////////////////////
635  {
636  for( unsigned int lIdx = 0; lIdx < layer_id.size(); ++lIdx )
637  {
638  const PCB_LAYER_ID curr_layer_id = layer_id[lIdx];
639 
640  wxASSERT( m_layers_poly.find( curr_layer_id ) != m_layers_poly.end() );
641 
642  SHAPE_POLY_SET *layerPoly = m_layers_poly[curr_layer_id];
643 
644  // ADD PADS
645  for( const MODULE* module = m_board->m_Modules; module; module = module->Next() )
646  {
647  // Construct polys
648  // /////////////////////////////////////////////////////////////
649 
650  // Note: NPTH pads are not drawn on copper layers when the pad
651  // has same shape as its hole
652  transformPadsShapesWithClearanceToPolygon( module->PadsList(),
653  curr_layer_id,
654  *layerPoly,
655  0,
656  true );
657 
658  // Micro-wave modules may have items on copper layers
659  module->TransformGraphicTextWithClearanceToPolygonSet( curr_layer_id,
660  *layerPoly,
661  0,
662  segcountforcircle,
663  correctionFactor );
664 
665  transformGraphicModuleEdgeToPolygonSet( module, curr_layer_id, *layerPoly );
666  }
667  }
668  }
669 
670 #ifdef PRINT_STATISTICS_3D_VIEWER
671  printf( "T10: %.3f ms\n", (float)( GetRunningMicroSecs() - start_Time ) / 1e3 );
672  start_Time = GetRunningMicroSecs();
673 #endif
674 
675  // Add graphic item on copper layers to object containers
676  // /////////////////////////////////////////////////////////////////////////
677  for( unsigned int lIdx = 0; lIdx < layer_id.size(); ++lIdx )
678  {
679  const PCB_LAYER_ID curr_layer_id = layer_id[lIdx];
680 
681  wxASSERT( m_layers_container2D.find( curr_layer_id ) != m_layers_container2D.end() );
682 
683  CBVHCONTAINER2D *layerContainer = m_layers_container2D[curr_layer_id];
684 
685  // ADD GRAPHIC ITEMS ON COPPER LAYERS (texts)
686  for( auto item : m_board->Drawings() )
687  {
688  if( !item->IsOnLayer( curr_layer_id ) )
689  continue;
690 
691  switch( item->Type() )
692  {
693  case PCB_LINE_T: // should not exist on copper layers
694  {
696  layerContainer,
697  curr_layer_id,
698  0 );
699  }
700  break;
701 
702  case PCB_TEXT_T:
704  layerContainer,
705  curr_layer_id,
706  0 );
707  break;
708 
709  case PCB_DIMENSION_T:
711  layerContainer,
712  curr_layer_id,
713  0 );
714  break;
715 
716  default:
717  wxLogTrace( m_logTrace,
718  wxT( "createLayers: item type: %d not implemented" ),
719  item->Type() );
720  break;
721  }
722  }
723  }
724 
725 #ifdef PRINT_STATISTICS_3D_VIEWER
726  printf( "T11: %.3f ms\n", (float)( GetRunningMicroSecs() - start_Time ) / 1e3 );
727  start_Time = GetRunningMicroSecs();
728 #endif
729 
730  // Add graphic item on copper layers to poly contourns
731  // /////////////////////////////////////////////////////////////////////////
734  {
735  for( unsigned int lIdx = 0; lIdx < layer_id.size(); ++lIdx )
736  {
737  const PCB_LAYER_ID curr_layer_id = layer_id[lIdx];
738 
739  wxASSERT( m_layers_poly.find( curr_layer_id ) != m_layers_poly.end() );
740 
741  SHAPE_POLY_SET *layerPoly = m_layers_poly[curr_layer_id];
742 
743  // ADD GRAPHIC ITEMS ON COPPER LAYERS (texts)
744  for( auto item : m_board->Drawings() )
745  {
746  if( !item->IsOnLayer( curr_layer_id ) )
747  continue;
748 
749  switch( item->Type() )
750  {
751  case PCB_LINE_T:
752  {
753  const int nrSegments =
754  GetNrSegmentsCircle( item->GetBoundingBox().GetSizeMax() );
755 
756  ( (DRAWSEGMENT*) item )->TransformShapeWithClearanceToPolygon(
757  *layerPoly,
758  0,
759  nrSegments,
760  GetCircleCorrectionFactor( nrSegments ) );
761  }
762  break;
763 
764  case PCB_TEXT_T:
765  ( (TEXTE_PCB*) item )->TransformShapeWithClearanceToPolygonSet(
766  *layerPoly,
767  0,
768  segcountforcircle,
769  correctionFactor );
770  break;
771 
772  default:
773  wxLogTrace( m_logTrace,
774  wxT( "createLayers: item type: %d not implemented" ),
775  item->Type() );
776  break;
777  }
778  }
779  }
780  }
781 
782 #ifdef PRINT_STATISTICS_3D_VIEWER
783  printf( "T12: %.3f ms\n", (float)( GetRunningMicroSecs() - start_Time ) / 1e3 );
784  start_Time = GetRunningMicroSecs();
785 #endif
786 
787  if( GetFlag( FL_ZONE ) )
788  {
789  if( aStatusTextReporter )
790  aStatusTextReporter->Report( _( "Create zones" ) );
791 
792  // Add zones objects
793  // /////////////////////////////////////////////////////////////////////
794  std::atomic<size_t> nextZone( 0 );
795  std::atomic<size_t> threadsFinished( 0 );
796 
797  size_t parallelThreadCount = std::max<size_t>( std::thread::hardware_concurrency(), 2 );
798  for( size_t ii = 0; ii < parallelThreadCount; ++ii )
799  {
800  std::thread t = std::thread( [&]()
801  {
802  for( size_t areaId = nextZone.fetch_add( 1 );
803  areaId < static_cast<size_t>( m_board->GetAreaCount() );
804  areaId = nextZone.fetch_add( 1 ) )
805  {
806  const ZONE_CONTAINER* zone = m_board->GetArea( areaId );
807 
808  if( zone == nullptr )
809  break;
810 
811  auto layerContainer = m_layers_container2D.find( zone->GetLayer() );
812 
813  if( layerContainer != m_layers_container2D.end() )
814  AddSolidAreasShapesToContainer( zone, layerContainer->second,
815  zone->GetLayer() );
816  }
817 
818  threadsFinished++;
819  } );
820 
821  t.detach();
822  }
823 
824  while( threadsFinished < parallelThreadCount )
825  std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) );
826 
827  }
828 
829 #ifdef PRINT_STATISTICS_3D_VIEWER
830  printf( "fill zones T13: %.3f ms\n", (float)( GetRunningMicroSecs() - start_Time ) / 1e3 );
831  start_Time = GetRunningMicroSecs();
832 #endif
833 
834  if( GetFlag( FL_ZONE ) &&
837  {
838  // ADD COPPER ZONES
839  for( int ii = 0; ii < m_board->GetAreaCount(); ++ii )
840  {
841  const ZONE_CONTAINER* zone = m_board->GetArea( ii );
842 
843  if( zone == nullptr )
844  break;
845 
846  auto layerContainer = m_layers_poly.find( zone->GetLayer() );
847 
848  if( layerContainer != m_layers_poly.end() )
849  zone->TransformSolidAreasShapesToPolygonSet( *layerContainer->second, segcountforcircle, correctionFactor );
850  }
851  }
852 
853 #ifdef PRINT_STATISTICS_3D_VIEWER
854  printf( "T14: %.3f ms\n", (float)( GetRunningMicroSecs() - start_Time ) / 1e3 );
855  start_Time = GetRunningMicroSecs();
856 #endif
857 
858  // Simplify layer polygons
859  // /////////////////////////////////////////////////////////////////////////
860 
861  if( aStatusTextReporter )
862  aStatusTextReporter->Report( _( "Simplifying copper layers polygons" ) );
863 
866  {
867  std::atomic<size_t> nextItem( 0 );
868  std::atomic<size_t> threadsFinished( 0 );
869 
870  size_t parallelThreadCount = std::min<size_t>(
871  std::max<size_t>( std::thread::hardware_concurrency(), 2 ),
872  layer_id.size() );
873  for( size_t ii = 0; ii < parallelThreadCount; ++ii )
874  {
875  std::thread t = std::thread( [&nextItem, &threadsFinished, &layer_id, this]()
876  {
877  for( size_t i = nextItem.fetch_add( 1 );
878  i < layer_id.size();
879  i = nextItem.fetch_add( 1 ) )
880  {
881  auto layerPoly = m_layers_poly.find( layer_id[i] );
882 
883  if( layerPoly != m_layers_poly.end() )
884  // This will make a union of all added contours
885  layerPoly->second->Simplify( SHAPE_POLY_SET::PM_FAST );
886  }
887 
888  threadsFinished++;
889  } );
890 
891  t.detach();
892  }
893 
894  while( threadsFinished < parallelThreadCount )
895  std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) );
896  }
897 
898 #ifdef PRINT_STATISTICS_3D_VIEWER
899  printf( "T15: %.3f ms\n", (float)( GetRunningMicroSecs() - start_Time ) / 1e3 );
900  start_Time = GetRunningMicroSecs();
901 #endif
902 
903  // Simplify holes polygon contours
904  // /////////////////////////////////////////////////////////////////////////
905  if( aStatusTextReporter )
906  aStatusTextReporter->Report( _( "Simplify holes contours" ) );
907 
908  for( unsigned int lIdx = 0; lIdx < layer_id.size(); ++lIdx )
909  {
910  const PCB_LAYER_ID curr_layer_id = layer_id[lIdx];
911 
912  if( m_layers_outer_holes_poly.find( curr_layer_id ) !=
914  {
915  // found
916  SHAPE_POLY_SET *polyLayer = m_layers_outer_holes_poly[curr_layer_id];
917  polyLayer->Simplify( SHAPE_POLY_SET::PM_FAST );
918 
919  wxASSERT( m_layers_inner_holes_poly.find( curr_layer_id ) !=
921 
922  polyLayer = m_layers_inner_holes_poly[curr_layer_id];
923  polyLayer->Simplify( SHAPE_POLY_SET::PM_FAST );
924  }
925  }
926 
927 #ifdef PRINT_STATISTICS_3D_VIEWER
928  printf( "T16: %.3f ms\n", (float)( GetRunningMicroSecs() - start_Time ) / 1e3 );
929 #endif
930  // End Build Copper layers
931 
932 
933  // This will make a union of all added contourns
938  //m_through_inner_holes_vias_poly.Simplify( SHAPE_POLY_SET::PM_FAST ); // Not in use
939 
940 #ifdef PRINT_STATISTICS_3D_VIEWER
941  unsigned stats_endCopperLayersTime = GetRunningMicroSecs();
942 #endif
943 
944  // Build Tech layers
945  // Based on: https://github.com/KiCad/kicad-source-mirror/blob/master/3d-viewer/3d_draw.cpp#L1059
946  // /////////////////////////////////////////////////////////////////////////
947 #ifdef PRINT_STATISTICS_3D_VIEWER
948  unsigned stats_startTechLayersTime = GetRunningMicroSecs();
949 #endif
950 
951  if( aStatusTextReporter )
952  aStatusTextReporter->Report( _( "Build Tech layers" ) );
953 
954  // draw graphic items, on technical layers
955  static const PCB_LAYER_ID teckLayerList[] = {
956  B_Adhes,
957  F_Adhes,
958  B_Paste,
959  F_Paste,
960  B_SilkS,
961  F_SilkS,
962  B_Mask,
963  F_Mask,
964 
965  // Aux Layers
966  Dwgs_User,
967  Cmts_User,
968  Eco1_User,
969  Eco2_User,
970  Edge_Cuts,
971  Margin
972  };
973 
974  // User layers are not drawn here, only technical layers
975 
976  for( LSEQ seq = LSET::AllNonCuMask().Seq( teckLayerList, DIM( teckLayerList ) );
977  seq;
978  ++seq )
979  {
980  const PCB_LAYER_ID curr_layer_id = *seq;
981 
982  if( !Is3DLayerEnabled( curr_layer_id ) )
983  continue;
984 
985  CBVHCONTAINER2D *layerContainer = new CBVHCONTAINER2D;
986  m_layers_container2D[curr_layer_id] = layerContainer;
987 
988  SHAPE_POLY_SET *layerPoly = new SHAPE_POLY_SET;
989  m_layers_poly[curr_layer_id] = layerPoly;
990 
991  // Add drawing objects
992  // /////////////////////////////////////////////////////////////////////
993  for( auto item : m_board->Drawings() )
994  {
995  if( !item->IsOnLayer( curr_layer_id ) )
996  continue;
997 
998  switch( item->Type() )
999  {
1000  case PCB_LINE_T:
1002  layerContainer,
1003  curr_layer_id,
1004  0 );
1005  break;
1006 
1007  case PCB_TEXT_T:
1009  layerContainer,
1010  curr_layer_id,
1011  0 );
1012  break;
1013 
1014  case PCB_DIMENSION_T:
1016  layerContainer,
1017  curr_layer_id,
1018  0 );
1019  break;
1020 
1021  default:
1022  break;
1023  }
1024  }
1025 
1026 
1027  // Add drawing contours
1028  // /////////////////////////////////////////////////////////////////////
1029  for( auto item : m_board->Drawings() )
1030  {
1031  if( !item->IsOnLayer( curr_layer_id ) )
1032  continue;
1033 
1034  switch( item->Type() )
1035  {
1036  case PCB_LINE_T:
1037  {
1038  const unsigned int nr_segments =
1039  GetNrSegmentsCircle( item->GetBoundingBox().GetSizeMax() );
1040 
1041  ((DRAWSEGMENT*) item)->TransformShapeWithClearanceToPolygon( *layerPoly,
1042  0,
1043  nr_segments,
1044  0.0 );
1045  }
1046  break;
1047 
1048  case PCB_TEXT_T:
1049  ((TEXTE_PCB*) item)->TransformShapeWithClearanceToPolygonSet( *layerPoly,
1050  0,
1051  segcountInStrokeFont,
1052  1.0 );
1053  break;
1054 
1055  default:
1056  break;
1057  }
1058  }
1059 
1060 
1061  // Add modules tech layers - objects
1062  // /////////////////////////////////////////////////////////////////////
1063  for( MODULE* module = m_board->m_Modules; module; module = module->Next() )
1064  {
1065  if( (curr_layer_id == F_SilkS) || (curr_layer_id == B_SilkS) )
1066  {
1067  D_PAD* pad = module->PadsList();
1068  int linewidth = g_DrawDefaultLineThickness;
1069 
1070  for( ; pad; pad = pad->Next() )
1071  {
1072  if( !pad->IsOnLayer( curr_layer_id ) )
1073  continue;
1074 
1076  layerContainer,
1077  linewidth );
1078  }
1079  }
1080  else
1081  {
1083  layerContainer,
1084  curr_layer_id,
1085  0,
1086  false );
1087  }
1088 
1090  layerContainer,
1091  curr_layer_id,
1092  0 );
1093  }
1094 
1095 
1096  // Add modules tech layers - contours
1097  // /////////////////////////////////////////////////////////////////////
1098  for( MODULE* module = m_board->m_Modules; module; module = module->Next() )
1099  {
1100  if( (curr_layer_id == F_SilkS) || (curr_layer_id == B_SilkS) )
1101  {
1102  D_PAD* pad = module->PadsList();
1103  const int linewidth = g_DrawDefaultLineThickness;
1104 
1105  for( ; pad; pad = pad->Next() )
1106  {
1107  if( !pad->IsOnLayer( curr_layer_id ) )
1108  continue;
1109 
1110  buildPadShapeThickOutlineAsPolygon( pad, *layerPoly, linewidth );
1111  }
1112  }
1113  else
1114  {
1115  transformPadsShapesWithClearanceToPolygon( module->PadsList(),
1116  curr_layer_id,
1117  *layerPoly,
1118  0,
1119  false );
1120  }
1121 
1122  // On tech layers, use a poor circle approximation, only for texts (stroke font)
1123  module->TransformGraphicTextWithClearanceToPolygonSet( curr_layer_id,
1124  *layerPoly,
1125  0,
1126  segcountInStrokeFont,
1127  correctionFactorStroke,
1128  segcountInStrokeFont );
1129 
1130  // Add the remaining things with dynamic seg count for circles
1131  transformGraphicModuleEdgeToPolygonSet( module, curr_layer_id, *layerPoly );
1132  }
1133 
1134 
1135  // Draw non copper zones
1136  // /////////////////////////////////////////////////////////////////////
1137  if( GetFlag( FL_ZONE ) )
1138  {
1139  for( int ii = 0; ii < m_board->GetAreaCount(); ++ii )
1140  {
1141  ZONE_CONTAINER* zone = m_board->GetArea( ii );
1142 
1143  if( !zone->IsOnLayer( curr_layer_id ) )
1144  continue;
1145 
1147  layerContainer,
1148  curr_layer_id );
1149  }
1150 
1151  for( int ii = 0; ii < m_board->GetAreaCount(); ++ii )
1152  {
1153  ZONE_CONTAINER* zone = m_board->GetArea( ii );
1154 
1155  if( !zone->IsOnLayer( curr_layer_id ) )
1156  continue;
1157 
1158  zone->TransformSolidAreasShapesToPolygonSet( *layerPoly,
1159  // Use the same segcount as stroke font
1160  segcountInStrokeFont,
1161  correctionFactorStroke );
1162  }
1163  }
1164 
1165  // This will make a union of all added contours
1166  layerPoly->Simplify( SHAPE_POLY_SET::PM_FAST );
1167  }
1168  // End Build Tech layers
1169 
1170 #ifdef PRINT_STATISTICS_3D_VIEWER
1171  unsigned stats_endTechLayersTime = GetRunningMicroSecs();
1172 #endif
1173 
1174 
1175  // Build BVH for holes and vias
1176  // /////////////////////////////////////////////////////////////////////////
1177 
1178 #ifdef PRINT_STATISTICS_3D_VIEWER
1179  unsigned stats_startHolesBVHTime = GetRunningMicroSecs();
1180 #endif
1181  if( aStatusTextReporter )
1182  aStatusTextReporter->Report( _( "Build BVH for holes and vias" ) );
1183 
1186 
1187  if( !m_layers_holes2D.empty() )
1188  {
1189  for( MAP_CONTAINER_2D::iterator ii = m_layers_holes2D.begin();
1190  ii != m_layers_holes2D.end();
1191  ++ii )
1192  {
1193  ((CBVHCONTAINER2D *)(ii->second))->BuildBVH();
1194  }
1195  }
1196 
1197  // We only need the Solder mask to initialize the BVH
1198  // because..?
1200  ((CBVHCONTAINER2D *)m_layers_container2D[B_Mask])->BuildBVH();
1201 
1203  ((CBVHCONTAINER2D *)m_layers_container2D[F_Mask])->BuildBVH();
1204 
1205 #ifdef PRINT_STATISTICS_3D_VIEWER
1206  unsigned stats_endHolesBVHTime = GetRunningMicroSecs();
1207 
1208  printf( "CINFO3D_VISU::createLayers times\n" );
1209  printf( " Copper Layers: %.3f ms\n",
1210  (float)( stats_endCopperLayersTime - stats_startCopperLayersTime ) / 1e3 );
1211  printf( " Holes BVH creation: %.3f ms\n",
1212  (float)( stats_endHolesBVHTime - stats_startHolesBVHTime ) / 1e3 );
1213  printf( " Tech Layers: %.3f ms\n",
1214  (float)( stats_endTechLayersTime - stats_startTechLayersTime ) / 1e3 );
1215  printf( "Statistics:\n" );
1216  printf( " m_stats_nr_tracks %u\n", m_stats_nr_tracks );
1217  printf( " m_stats_nr_vias %u\n", m_stats_nr_vias );
1218  printf( " m_stats_nr_holes %u\n", m_stats_nr_holes );
1219  printf( " m_stats_via_med_hole_diameter (3DU) %f\n", m_stats_via_med_hole_diameter );
1220  printf( " m_stats_hole_med_diameter (3DU) %f\n", m_stats_hole_med_diameter );
1221  printf( " m_calc_seg_min_factor3DU (3DU) %f\n", m_calc_seg_min_factor3DU );
1222  printf( " m_calc_seg_max_factor3DU (3DU) %f\n", m_calc_seg_max_factor3DU );
1223 #endif
1224 }
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Function AllCuMask returns a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:676
void AddShapeWithClearanceToContainer(const TEXTE_PCB *aTextPCB, CGENERICCONTAINER2D *aDstContainer, PCB_LAYER_ID aLayerId, int aClearanceValue)
KICAD_T Type() const
Function Type()
Definition: base_struct.h:201
#define DIM(x)
of elements in an array
Definition: macros.h:98
Class ZONE_CONTAINER handles a list of polygons defining a copper zone.
Definition: class_zone.h:60
COBJECT2D * createNewTrack(const TRACK *aTrack, int aClearanceValue) const
PAD_ATTR_T GetAttribute() const
Definition: class_pad.h:405
TEXTE_PCB class definition.
float GetCopperThickness3DU() const
GetCopperThickness3DU - Get the current copper layer thickness.
Definition: cinfo3d_visu.h:165
like PAD_STANDARD, but not plated mechanical use only, no connection allowed
Definition: pad_shapes.h:65
CBVHCONTAINER2D m_through_holes_vias_outer
It contains the list of throughHoles vias of the board, the radius of the hole is inflated with the c...
Definition: cinfo3d_visu.h:602
void TransformShapeWithClearanceToPolygon(SHAPE_POLY_SET &aCornerBuffer, int aClearanceValue, int aCircleToSegmentsCount, double aCorrectionFactor, bool ignoreLineWidth=false) const override
Function TransformShapeWithClearanceToPolygon Convert the track shape to a closed polygon Used in fil...
virtual bool IsOnLayer(PCB_LAYER_ID aLayer) const
Function IsOnLayer tests to see if this object is on the given layer.
void TransformCircleToPolygon(SHAPE_POLY_SET &aCornerBuffer, wxPoint aCenter, int aRadius, int aCircleToSegmentsCount)
Function TransformCircleToPolygon convert a circle to a polygon, using multiple straight lines...
virtual bool IsOnLayer(PCB_LAYER_ID) const override
Function IsOnLayer tests to see if this object is on the given layer.
Definition: class_zone.cpp:265
Class BOARD to handle a board.
float m_calc_seg_min_factor3DU
min factor used for cicle segment approximation calculation
Definition: cinfo3d_visu.h:641
SHAPE_POLY_SET m_through_inner_holes_poly
It contains polygon contours for through holes (inner cylinder)
Definition: cinfo3d_visu.h:572
static LSET AllNonCuMask()
Function AllNonCuMask returns a mask holding all layer minus CU layers.
Definition: lset.cpp:699
MODULE * Next() const
Definition: class_module.h:123
MAP_POLY m_layers_inner_holes_poly
It contains polygon contours for holes of each layer (inner holes)
Definition: cinfo3d_visu.h:563
virtual PCB_LAYER_ID GetLayer() const override
Function GetLayer returns the primary layer this item is on.
Definition: class_zone.cpp:175
Handles data related with the board to be visualized.
class TEXTE_PCB, text on a layer
Definition: typeinfo.h:92
float m_calc_seg_max_factor3DU
max factor used for cicle segment approximation calculation
Definition: cinfo3d_visu.h:644
Classes to handle copper zones.
int GetCopperThicknessBIU() const
GetCopperThicknessBIU - Get the current copper layer thickness.
BOARD * m_board
Current board.
Definition: cinfo3d_visu.h:515
unsigned int m_stats_nr_holes
number of holes in the board
Definition: cinfo3d_visu.h:662
const wxSize & GetDrillSize() const
Definition: class_pad.h:275
Class REPORTER is a pure virtual class used to derive REPORTER objects from.
Definition: reporter.h:61
VIATYPE_T
Definition: class_track.h:50
CBVHCONTAINER2D m_through_holes_inner
It contains the list of throughHoles of the board, the radius is the inner hole.
Definition: cinfo3d_visu.h:598
float m_stats_via_med_hole_diameter
Computed medium diameter of the via holes in 3D units.
Definition: cinfo3d_visu.h:659
#define cu(a)
Definition: auxiliary.h:88
MAP_CONTAINER_2D m_layers_container2D
It contains the 2d elements of each layer.
Definition: cinfo3d_visu.h:587
float m_stats_hole_med_diameter
Computed medium diameter of the holes in 3D units.
Definition: cinfo3d_visu.h:665
void TransformSolidAreasShapesToPolygonSet(SHAPE_POLY_SET &aCornerBuffer, int aCircleToSegmentsCount, double aCorrectionFactor) const
Function TransformSolidAreasShapesToPolygonSet Convert solid areas full shapes to polygon set (the fu...
LSEQ Seq(const PCB_LAYER_ID *aWishListSequence, unsigned aCount) const
Function Seq returns an LSEQ from the union of this LSET and a desired sequence.
Definition: lset.cpp:367
PCB_LAYER_ID
A quick note on layer IDs:
MAP_POLY m_layers_poly
It contains polygon contours for each layer.
Definition: cinfo3d_visu.h:557
Class LSET is a set of PCB_LAYER_IDs.
Footprint text class description.
SHAPE_POLY_SET m_through_inner_holes_vias_poly
It contains polygon contours for through holes vias (inner cylinder)
Definition: cinfo3d_visu.h:578
glm::vec2 SFVEC2F
Definition: xv3d_types.h:45
VIATYPE_T GetViaType() const
Definition: class_track.h:461
unsigned int m_stats_nr_vias
Nr of vias.
Definition: cinfo3d_visu.h:656
Class SHAPE_POLY_SET.
const wxPoint & GetStart() const
Definition: class_track.h:126
void createLayers(REPORTER *aStatusTextReporter)
int g_DrawDefaultLineThickness
Default line thickness in internal units used to draw or plot items using a default thickness line va...
double m_biuTo3Dunits
Normalization scale to convert board internal units to 3D units to normalize 3D units between -1...
Definition: cinfo3d_visu.h:616
D_PAD * Next() const
Definition: class_pad.h:160
SHAPE_POLY_SET m_through_outer_holes_poly_NPTH
It contains polygon contours for (just) non plated through holes (outer cylinder) ...
Definition: cinfo3d_visu.h:566
MAP_POLY m_layers_outer_holes_poly
It contains polygon contours for holes of each layer (outer holes)
Definition: cinfo3d_visu.h:560
void Simplify(POLYGON_MODE aFastMode)
Simplifies the polyset (merges overlapping polys, eliminates degeneracy/self-intersections) For aFast...
int GetAreaCount() const
Function GetAreaCount.
Definition: class_board.h:1025
void AddSolidAreasShapesToContainer(const ZONE_CONTAINER *aZoneContainer, CGENERICCONTAINER2D *aDstContainer, PCB_LAYER_ID aLayerId)
static const wxChar * m_logTrace
Trace mask used to enable or disable the trace output of this class.
Definition: cinfo3d_visu.h:673
class DIMENSION, a dimension (graphic item)
Definition: typeinfo.h:100
bool Is3DLayerEnabled(PCB_LAYER_ID aLayer) const
Is3DLayerEnabled - Check if a layer is enabled.
Class LSEQ is a sequence (and therefore also a set) of PCB_LAYER_IDs.
Pad object description.
unsigned int GetNrSegmentsCircle(float aDiameter3DU) const
GetNrSegmentsCircle.
void Add(COBJECT2D *aObject)
Definition: ccontainer2d.h:52
bool GetFlag(DISPLAY3D_FLG aFlag) const
GetFlag - get a configuration status of a flag.
SHAPE_POLY_SET m_through_outer_holes_poly
It contains polygon contours for through holes (outer cylinder)
Definition: cinfo3d_visu.h:569
void transformPadsShapesWithClearanceToPolygon(const DLIST< D_PAD > &aPads, PCB_LAYER_ID aLayer, SHAPE_POLY_SET &aCornerBuffer, int aInflateValue, bool aSkipNPTHPadsWihNoCopper) const
TRACK * Next() const
Definition: class_track.h:103
double GetCircleCorrectionFactor(int aNrSides) const
GetCircleCorrectionFactor - computes a angle correction factor used when creating circles...
ZONE_CONTAINER * GetArea(int index) const
Function GetArea returns the Area (Zone Container) at a given index.
Definition: class_board.h:996
int GetDrillValue() const
Function GetDrillValue "calculates" the drill value for vias (m-Drill if > 0, or default drill value ...
DLIST< MODULE > m_Modules
Definition: class_board.h:248
unsigned GetRunningMicroSecs()
Function GetRunningMicroSecs An alternate way to calculate an elapset time (in microsecondes) to clas...
int GetWidth() const
Definition: class_track.h:120
size_t i
Definition: json11.cpp:597
void RemoveAllContours()
Removes all outlines & holes (clears) the polygon set.
float m_stats_track_med_width
Track average width.
Definition: cinfo3d_visu.h:653
unsigned int m_copperLayersCount
Number of copper layers actually used by the board.
Definition: cinfo3d_visu.h:612
MAP_CONTAINER_2D m_layers_holes2D
It contains the holes per each layer.
Definition: cinfo3d_visu.h:590
RENDER_ENGINE m_render_engine
render engine currently on use
Definition: cinfo3d_visu.h:530
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_UNDEFINED)=0
Function Report is a pure virtual function to override in the derived object.
CBVHCONTAINER2D m_through_holes_vias_inner
It contains the list of throughHoles vias of the board, the radius of the hole.
Definition: cinfo3d_visu.h:606
unsigned GetCount() const
Function GetCount returns the number of elements in the list.
Definition: dlist.h:126
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:96
SHAPE_POLY_SET m_through_outer_holes_vias_poly
It contains polygon contours for through holes vias (outer cylinder)
Definition: cinfo3d_visu.h:575
DLIST< TRACK > m_Track
Definition: class_board.h:249
Module description (excepted pads)
CBVHCONTAINER2D m_through_holes_outer
It contains the list of throughHoles of the board, the radius of the hole is inflated with the copper...
Definition: cinfo3d_visu.h:594
bool IsOnLayer(PCB_LAYER_ID aLayer) const override
Function IsOnLayer tests to see if this object is on the given layer.
Definition: class_pad.h:663
EDGE_MODULE class definition.
class DRAWSEGMENT, a segment not on copper layers
Definition: typeinfo.h:91
void buildPadShapeThickOutlineAsSegments(const D_PAD *aPad, CGENERICCONTAINER2D *aDstContainer, int aWidth)
COBJECT2D * createNewPadDrill(const D_PAD *aPad, int aInflateValue)
bool BuildPadDrillShapePolygon(SHAPE_POLY_SET &aCornerBuffer, int aInflateValue, int aSegmentsPerCircle) const
Function BuildPadDrillShapePolygon Build the Corner list of the polygonal drill shape, depending on shape pad hole and orientation.
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:813
Class DIMENSION.
unsigned int m_stats_nr_tracks
Number of tracks in the board.
Definition: cinfo3d_visu.h:650
void transformGraphicModuleEdgeToPolygonSet(const MODULE *aModule, PCB_LAYER_ID aLayer, SHAPE_POLY_SET &aCornerBuffer) const
void AddGraphicsShapesWithClearanceToContainer(const MODULE *aModule, CGENERICCONTAINER2D *aDstContainer, PCB_LAYER_ID aLayerId, int aInflateValue)
DLIST_ITERATOR_WRAPPER< BOARD_ITEM > Drawings()
Definition: class_board.h:255
void buildPadShapeThickOutlineAsPolygon(const D_PAD *aPad, SHAPE_POLY_SET &aCornerBuffer, int aWidth) const
double BiuTo3Dunits() const
BiuTo3Dunits - Board integer units To 3D units.
Definition: cinfo3d_visu.h:141
#define min(a, b)
Definition: auxiliary.h:85
void AddPadsShapesWithClearanceToContainer(const MODULE *aModule, CGENERICCONTAINER2D *aDstContainer, PCB_LAYER_ID aLayerId, int aInflateValue, bool aSkipNPTHPadsWihNoCopper)