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 #include <openmp_mutex.h>
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 
56 #include <profile.h>
57 
59 {
60  if( !m_layers_poly.empty() )
61  {
62  for( MAP_POLY::iterator ii = m_layers_poly.begin();
63  ii != m_layers_poly.end();
64  ++ii )
65  {
66  delete ii->second;
67  ii->second = NULL;
68  }
69 
70  m_layers_poly.clear();
71  }
72 
73  if( !m_layers_inner_holes_poly.empty() )
74  {
75  for( MAP_POLY::iterator ii = m_layers_inner_holes_poly.begin();
76  ii != m_layers_inner_holes_poly.end();
77  ++ii )
78  {
79  delete ii->second;
80  ii->second = NULL;
81  }
82 
84  }
85 
86  if( !m_layers_outer_holes_poly.empty() )
87  {
88  for( MAP_POLY::iterator ii = m_layers_outer_holes_poly.begin();
89  ii != m_layers_outer_holes_poly.end();
90  ++ii )
91  {
92  delete ii->second;
93  ii->second = NULL;
94  }
95 
97  }
98 
99  if( !m_layers_container2D.empty() )
100  {
101  for( MAP_CONTAINER_2D::iterator ii = m_layers_container2D.begin();
102  ii != m_layers_container2D.end();
103  ++ii )
104  {
105  delete ii->second;
106  ii->second = NULL;
107  }
108 
109  m_layers_container2D.clear();
110  }
111 
112  if( !m_layers_holes2D.empty() )
113  {
114  for( MAP_CONTAINER_2D::iterator ii = m_layers_holes2D.begin();
115  ii != m_layers_holes2D.end();
116  ++ii )
117  {
118  delete ii->second;
119  ii->second = NULL;
120  }
121 
122  m_layers_holes2D.clear();
123  }
124 
131  //m_through_inner_holes_poly.RemoveAllContours();
132 
135 }
136 
137 
138 void CINFO3D_VISU::createLayers( REPORTER *aStatusTextReporter )
139 {
140  // Number of segments to draw a circle using segments (used on countour zones
141  // and text copper elements )
142  const int segcountforcircle = 12;
143  const double correctionFactor = GetCircleCorrectionFactor( segcountforcircle );
144 
145  // segments to draw a circle to build texts. Is is used only to build
146  // the shape of each segment of the stroke font, therefore no need to have
147  // many segments per circle.
148  const int segcountInStrokeFont = 12;
149  const double correctionFactorStroke = GetCircleCorrectionFactor( segcountInStrokeFont );
150 
151  destroyLayers();
152 
153  // Build Copper layers
154  // Based on: https://github.com/KiCad/kicad-source-mirror/blob/master/3d-viewer/3d_draw.cpp#L692
155  // /////////////////////////////////////////////////////////////////////////
156 
157  #ifdef PRINT_STATISTICS_3D_VIEWER
158  unsigned stats_startCopperLayersTime = GetRunningMicroSecs();
159 
160  unsigned start_Time = stats_startCopperLayersTime;
161 #endif
162 
163  PCB_LAYER_ID cu_seq[MAX_CU_LAYERS];
165 
166  m_stats_nr_tracks = 0;
168  m_stats_nr_vias = 0;
170  m_stats_nr_holes = 0;
172 
173  // Prepare track list, convert in a vector. Calc statistic for the holes
174  // /////////////////////////////////////////////////////////////////////////
175  std::vector< const TRACK *> trackList;
176  trackList.clear();
177  trackList.reserve( m_board->m_Track.GetCount() );
178 
179  for( const TRACK* track = m_board->m_Track; track; track = track->Next() )
180  {
181  if( !Is3DLayerEnabled( track->GetLayer() ) ) // Skip non enabled layers
182  continue;
183 
184  // Note: a TRACK holds normal segment tracks and
185  // also vias circles (that have also drill values)
186  trackList.push_back( track );
187 
188  if( track->Type() == PCB_VIA_T )
189  {
190  const VIA *via = static_cast< const VIA*>( track );
191  m_stats_nr_vias++;
193  }
194  else
195  {
197  }
198 
199  m_stats_track_med_width += track->GetWidth() * m_biuTo3Dunits;
200  }
201 
202  if( m_stats_nr_tracks )
204 
205  if( m_stats_nr_vias )
207 
208 #ifdef PRINT_STATISTICS_3D_VIEWER
209  printf( "T01: %.3f ms\n", (float)( GetRunningMicroSecs() - start_Time ) / 1e3 );
210  start_Time = GetRunningMicroSecs();
211 #endif
212 
213  // Prepare copper layers index and containers
214  // /////////////////////////////////////////////////////////////////////////
215  std::vector< PCB_LAYER_ID > layer_id;
216  layer_id.clear();
217  layer_id.reserve( m_copperLayersCount );
218 
219  for( unsigned i = 0; i < DIM( cu_seq ); ++i )
220  cu_seq[i] = ToLAYER_ID( B_Cu - i );
221 
222  for( LSEQ cu = cu_set.Seq( cu_seq, DIM( cu_seq ) ); cu; ++cu )
223  {
224  const PCB_LAYER_ID curr_layer_id = *cu;
225 
226  if( !Is3DLayerEnabled( curr_layer_id ) ) // Skip non enabled layers
227  continue;
228 
229  layer_id.push_back( curr_layer_id );
230 
231  CBVHCONTAINER2D *layerContainer = new CBVHCONTAINER2D;
232  m_layers_container2D[curr_layer_id] = layerContainer;
233 
236  {
237  SHAPE_POLY_SET *layerPoly = new SHAPE_POLY_SET;
238  m_layers_poly[curr_layer_id] = layerPoly;
239  }
240  }
241 
242 #ifdef PRINT_STATISTICS_3D_VIEWER
243  printf( "T02: %.3f ms\n", (float)( GetRunningMicroSecs() - start_Time ) / 1e3 );
244  start_Time = GetRunningMicroSecs();
245 #endif
246 
247  if( aStatusTextReporter )
248  aStatusTextReporter->Report( _( "Create tracks and vias" ) );
249 
250  // Create tracks as objects and add it to container
251  // /////////////////////////////////////////////////////////////////////////
252  for( unsigned int lIdx = 0; lIdx < layer_id.size(); ++lIdx )
253  {
254  const PCB_LAYER_ID curr_layer_id = layer_id[lIdx];
255 
256  wxASSERT( m_layers_container2D.find( curr_layer_id ) != m_layers_container2D.end() );
257 
258  CBVHCONTAINER2D *layerContainer = m_layers_container2D[curr_layer_id];
259 
260  // ADD TRACKS
261  unsigned int nTracks = trackList.size();
262 
263  for( unsigned int trackIdx = 0; trackIdx < nTracks; ++trackIdx )
264  {
265  const TRACK *track = trackList[trackIdx];
266 
267  // NOTE: Vias can be on multiple layers
268  if( !track->IsOnLayer( curr_layer_id ) )
269  continue;
270 
271  // Add object item to layer container
272  layerContainer->Add( createNewTrack( track, 0.0f ) );
273  }
274  }
275 
276 #ifdef PRINT_STATISTICS_3D_VIEWER
277  printf( "T03: %.3f ms\n", (float)( GetRunningMicroSecs() - start_Time ) / 1e3 );
278  start_Time = GetRunningMicroSecs();
279 #endif
280 
281  // Create VIAS and THTs objects and add it to holes containers
282  // /////////////////////////////////////////////////////////////////////////
283  for( unsigned int lIdx = 0; lIdx < layer_id.size(); ++lIdx )
284  {
285  const PCB_LAYER_ID curr_layer_id = layer_id[lIdx];
286 
287  // ADD TRACKS
288  unsigned int nTracks = trackList.size();
289 
290  for( unsigned int trackIdx = 0; trackIdx < nTracks; ++trackIdx )
291  {
292  const TRACK *track = trackList[trackIdx];
293 
294  if( !track->IsOnLayer( curr_layer_id ) )
295  continue;
296 
297  // ADD VIAS and THT
298  if( track->Type() == PCB_VIA_T )
299  {
300  const VIA *via = static_cast< const VIA*>( track );
301  const VIATYPE_T viatype = via->GetViaType();
302  const float holediameter = via->GetDrillValue() * BiuTo3Dunits();
303  const float thickness = GetCopperThickness3DU();
304  const float hole_inner_radius = ( holediameter / 2.0f );
305 
306  const SFVEC2F via_center( via->GetStart().x * m_biuTo3Dunits,
307  -via->GetStart().y * m_biuTo3Dunits );
308 
309  if( viatype != VIA_THROUGH )
310  {
311 
312  // Add hole objects
313  // /////////////////////////////////////////////////////////
314 
315  CBVHCONTAINER2D *layerHoleContainer = NULL;
316 
317  // Check if the layer is already created
318  if( m_layers_holes2D.find( curr_layer_id ) == m_layers_holes2D.end() )
319  {
320  // not found, create a new container
321  layerHoleContainer = new CBVHCONTAINER2D;
322  m_layers_holes2D[curr_layer_id] = layerHoleContainer;
323  }
324  else
325  {
326  // found
327  layerHoleContainer = m_layers_holes2D[curr_layer_id];
328  }
329 
330  // Add a hole for this layer
331  layerHoleContainer->Add( new CFILLEDCIRCLE2D( via_center,
332  hole_inner_radius + thickness,
333  *track ) );
334  }
335  else if( lIdx == 0 ) // it only adds once the THT holes
336  {
337  // Add through hole object
338  // /////////////////////////////////////////////////////////
339  m_through_holes_outer.Add( new CFILLEDCIRCLE2D( via_center,
340  hole_inner_radius + thickness,
341  *track ) );
342 
344  new CFILLEDCIRCLE2D( via_center,
345  hole_inner_radius + thickness,
346  *track ) );
347 
348  m_through_holes_inner.Add( new CFILLEDCIRCLE2D( via_center,
349  hole_inner_radius,
350  *track ) );
351 
352  //m_through_holes_vias_inner.Add( new CFILLEDCIRCLE2D( via_center,
353  // hole_inner_radius,
354  // *track ) );
355  }
356  }
357  }
358  }
359 
360 #ifdef PRINT_STATISTICS_3D_VIEWER
361  printf( "T04: %.3f ms\n", (float)( GetRunningMicroSecs() - start_Time ) / 1e3 );
362  start_Time = GetRunningMicroSecs();
363 #endif
364 
365  // Create VIAS and THTs objects and add it to holes containers
366  // /////////////////////////////////////////////////////////////////////////
367  for( unsigned int lIdx = 0; lIdx < layer_id.size(); ++lIdx )
368  {
369  const PCB_LAYER_ID curr_layer_id = layer_id[lIdx];
370 
371  // ADD TRACKS
372  const unsigned int nTracks = trackList.size();
373 
374  for( unsigned int trackIdx = 0; trackIdx < nTracks; ++trackIdx )
375  {
376  const TRACK *track = trackList[trackIdx];
377 
378  if( !track->IsOnLayer( curr_layer_id ) )
379  continue;
380 
381  // ADD VIAS and THT
382  if( track->Type() == PCB_VIA_T )
383  {
384  const VIA *via = static_cast< const VIA*>( track );
385  const VIATYPE_T viatype = via->GetViaType();
386 
387  if( viatype != VIA_THROUGH )
388  {
389 
390  // Add VIA hole contourns
391  // /////////////////////////////////////////////////////////
392 
393  // Add outter holes of VIAs
394  SHAPE_POLY_SET *layerOuterHolesPoly = NULL;
395  SHAPE_POLY_SET *layerInnerHolesPoly = NULL;
396 
397  // Check if the layer is already created
398  if( m_layers_outer_holes_poly.find( curr_layer_id ) ==
400  {
401  // not found, create a new container
402  layerOuterHolesPoly = new SHAPE_POLY_SET;
403  m_layers_outer_holes_poly[curr_layer_id] = layerOuterHolesPoly;
404 
405  wxASSERT( m_layers_inner_holes_poly.find( curr_layer_id ) ==
407 
408  layerInnerHolesPoly = new SHAPE_POLY_SET;
409  m_layers_inner_holes_poly[curr_layer_id] = layerInnerHolesPoly;
410  }
411  else
412  {
413  // found
414  layerOuterHolesPoly = m_layers_outer_holes_poly[curr_layer_id];
415 
416  wxASSERT( m_layers_inner_holes_poly.find( curr_layer_id ) !=
418 
419  layerInnerHolesPoly = m_layers_inner_holes_poly[curr_layer_id];
420  }
421 
422  const int holediameter = via->GetDrillValue();
423  const int hole_outer_radius = (holediameter / 2) + GetCopperThicknessBIU();
424 
425  TransformCircleToPolygon( *layerOuterHolesPoly,
426  via->GetStart(),
427  hole_outer_radius,
428  GetNrSegmentsCircle( hole_outer_radius * 2 ) );
429 
430  TransformCircleToPolygon( *layerInnerHolesPoly,
431  via->GetStart(),
432  holediameter / 2,
433  GetNrSegmentsCircle( holediameter ) );
434  }
435  else if( lIdx == 0 ) // it only adds once the THT holes
436  {
437  const int holediameter = via->GetDrillValue();
438  const int hole_outer_radius = (holediameter / 2)+ GetCopperThicknessBIU();
439 
440  // Add through hole contourns
441  // /////////////////////////////////////////////////////////
443  via->GetStart(),
444  hole_outer_radius,
445  GetNrSegmentsCircle( hole_outer_radius * 2 ) );
446 
448  via->GetStart(),
449  holediameter / 2,
450  GetNrSegmentsCircle( holediameter ) );
451 
452  // Add samething for vias only
453 
455  via->GetStart(),
456  hole_outer_radius,
457  GetNrSegmentsCircle( hole_outer_radius * 2 ) );
458 
459  //TransformCircleToPolygon( m_through_inner_holes_vias_poly,
460  // via->GetStart(),
461  // holediameter / 2,
462  // GetNrSegmentsCircle( holediameter ) );
463  }
464  }
465  }
466  }
467 
468 #ifdef PRINT_STATISTICS_3D_VIEWER
469  printf( "T05: %.3f ms\n", (float)( GetRunningMicroSecs() - start_Time ) / 1e3 );
470  start_Time = GetRunningMicroSecs();
471 #endif
472 
473  // Creates outline contours of the tracks and add it to the poly of the layer
474  // /////////////////////////////////////////////////////////////////////////
477  {
478  for( unsigned int lIdx = 0; lIdx < layer_id.size(); ++lIdx )
479  {
480  const PCB_LAYER_ID curr_layer_id = layer_id[lIdx];
481 
482  wxASSERT( m_layers_poly.find( curr_layer_id ) != m_layers_poly.end() );
483 
484  SHAPE_POLY_SET *layerPoly = m_layers_poly[curr_layer_id];
485 
486  // ADD TRACKS
487  unsigned int nTracks = trackList.size();
488 
489  for( unsigned int trackIdx = 0; trackIdx < nTracks; ++trackIdx )
490  {
491  const TRACK *track = trackList[trackIdx];
492 
493  if( !track->IsOnLayer( curr_layer_id ) )
494  continue;
495 
496  // Add the track contour
497  int nrSegments = GetNrSegmentsCircle( track->GetWidth() );
498 
500  *layerPoly,
501  0,
502  nrSegments,
503  GetCircleCorrectionFactor( nrSegments ) );
504  }
505  }
506  }
507 
508 #ifdef PRINT_STATISTICS_3D_VIEWER
509  printf( "T06: %.3f ms\n", (float)( GetRunningMicroSecs() - start_Time ) / 1e3 );
510  start_Time = GetRunningMicroSecs();
511 #endif
512 
513  // Add holes of modules
514  // /////////////////////////////////////////////////////////////////////////
515  for( const MODULE* module = m_board->m_Modules; module; module = module->Next() )
516  {
517  const D_PAD* pad = module->PadsList();
518 
519  for( ; pad; pad = pad->Next() )
520  {
521  const wxSize padHole = pad->GetDrillSize();
522 
523  if( !padHole.x ) // Not drilled pad like SMD pad
524  continue;
525 
526  // The hole in the body is inflated by copper thickness,
527  // if not plated, no copper
528  const int inflate = (pad->GetAttribute () != PAD_ATTRIB_HOLE_NOT_PLATED) ?
529  GetCopperThicknessBIU() : 0;
530 
532  m_stats_hole_med_diameter += ( ( pad->GetDrillSize().x +
533  pad->GetDrillSize().y ) / 2.0f ) * m_biuTo3Dunits;
534 
535  m_through_holes_outer.Add( createNewPadDrill( pad, inflate ) );
537  }
538  }
539  if( m_stats_nr_holes )
541 
542 #ifdef PRINT_STATISTICS_3D_VIEWER
543  printf( "T07: %.3f ms\n", (float)( GetRunningMicroSecs() - start_Time ) / 1e3 );
544  start_Time = GetRunningMicroSecs();
545 #endif
546 
547  // Add contours of the pad holes (pads can be Circle or Segment holes)
548  // /////////////////////////////////////////////////////////////////////////
549  for( const MODULE* module = m_board->m_Modules; module; module = module->Next() )
550  {
551  const D_PAD* pad = module->PadsList();
552 
553  for( ; pad; pad = pad->Next() )
554  {
555  const wxSize padHole = pad->GetDrillSize();
556 
557  if( !padHole.x ) // Not drilled pad like SMD pad
558  continue;
559 
560  // The hole in the body is inflated by copper thickness.
561  const int inflate = GetCopperThicknessBIU();
562 
563  // we use the hole diameter to calculate the seg count.
564  // for round holes, padHole.x == padHole.y
565  // for oblong holes, the diameter is the smaller of (padHole.x, padHole.y)
566  const int diam = std::min( padHole.x, padHole.y );
567 
568 
570  {
572  inflate,
573  GetNrSegmentsCircle( diam ) );
574 
576  0,
577  GetNrSegmentsCircle( diam ) );
578  }
579  else
580  {
581  // If not plated, no copper.
583  inflate,
584  GetNrSegmentsCircle( diam ) );
585  }
586  }
587  }
588 
589 #ifdef PRINT_STATISTICS_3D_VIEWER
590  printf( "T08: %.3f ms\n", (float)( GetRunningMicroSecs() - start_Time ) / 1e3 );
591  start_Time = GetRunningMicroSecs();
592 #endif
593 
594  // Add modules PADs objects to containers
595  // /////////////////////////////////////////////////////////////////////////
596  for( unsigned int lIdx = 0; lIdx < layer_id.size(); ++lIdx )
597  {
598  const PCB_LAYER_ID curr_layer_id = layer_id[lIdx];
599 
600  wxASSERT( m_layers_container2D.find( curr_layer_id ) != m_layers_container2D.end() );
601 
602  CBVHCONTAINER2D *layerContainer = m_layers_container2D[curr_layer_id];
603 
604  // ADD PADS
605  for( const MODULE* module = m_board->m_Modules; module; module = module->Next() )
606  {
607  // Note: NPTH pads are not drawn on copper layers when the pad
608  // has same shape as its hole
610  layerContainer,
611  curr_layer_id,
612  0,
613  true );
614 
615  // Micro-wave modules may have items on copper layers
617  layerContainer,
618  curr_layer_id,
619  0 );
620  }
621  }
622 
623 #ifdef PRINT_STATISTICS_3D_VIEWER
624  printf( "T09: %.3f ms\n", (float)( GetRunningMicroSecs() - start_Time ) / 1e3 );
625  start_Time = GetRunningMicroSecs();
626 #endif
627 
628  // Add modules PADs poly contourns
629  // /////////////////////////////////////////////////////////////////////////
632  {
633  for( unsigned int lIdx = 0; lIdx < layer_id.size(); ++lIdx )
634  {
635  const PCB_LAYER_ID curr_layer_id = layer_id[lIdx];
636 
637  wxASSERT( m_layers_poly.find( curr_layer_id ) != m_layers_poly.end() );
638 
639  SHAPE_POLY_SET *layerPoly = m_layers_poly[curr_layer_id];
640 
641  // ADD PADS
642  for( const MODULE* module = m_board->m_Modules; module; module = module->Next() )
643  {
644  // Construct polys
645  // /////////////////////////////////////////////////////////////
646 
647  // Note: NPTH pads are not drawn on copper layers when the pad
648  // has same shape as its hole
649  transformPadsShapesWithClearanceToPolygon( module->PadsList(),
650  curr_layer_id,
651  *layerPoly,
652  0,
653  true );
654 
655  // Micro-wave modules may have items on copper layers
656  module->TransformGraphicTextWithClearanceToPolygonSet( curr_layer_id,
657  *layerPoly,
658  0,
659  segcountforcircle,
660  correctionFactor );
661 
662  transformGraphicModuleEdgeToPolygonSet( module, curr_layer_id, *layerPoly );
663  }
664  }
665  }
666 
667 #ifdef PRINT_STATISTICS_3D_VIEWER
668  printf( "T10: %.3f ms\n", (float)( GetRunningMicroSecs() - start_Time ) / 1e3 );
669  start_Time = GetRunningMicroSecs();
670 #endif
671 
672  // Add graphic item on copper layers to object containers
673  // /////////////////////////////////////////////////////////////////////////
674  for( unsigned int lIdx = 0; lIdx < layer_id.size(); ++lIdx )
675  {
676  const PCB_LAYER_ID curr_layer_id = layer_id[lIdx];
677 
678  wxASSERT( m_layers_container2D.find( curr_layer_id ) != m_layers_container2D.end() );
679 
680  CBVHCONTAINER2D *layerContainer = m_layers_container2D[curr_layer_id];
681 
682  // ADD GRAPHIC ITEMS ON COPPER LAYERS (texts)
683  for( auto item : m_board->Drawings() )
684  {
685  if( !item->IsOnLayer( curr_layer_id ) )
686  continue;
687 
688  switch( item->Type() )
689  {
690  case PCB_LINE_T: // should not exist on copper layers
691  {
693  layerContainer,
694  curr_layer_id,
695  0 );
696  }
697  break;
698 
699  case PCB_TEXT_T:
701  layerContainer,
702  curr_layer_id,
703  0 );
704  break;
705 
706  case PCB_DIMENSION_T:
708  layerContainer,
709  curr_layer_id,
710  0 );
711  break;
712 
713  default:
714  wxLogTrace( m_logTrace,
715  wxT( "createLayers: item type: %d not implemented" ),
716  item->Type() );
717  break;
718  }
719  }
720  }
721 
722 #ifdef PRINT_STATISTICS_3D_VIEWER
723  printf( "T11: %.3f ms\n", (float)( GetRunningMicroSecs() - start_Time ) / 1e3 );
724  start_Time = GetRunningMicroSecs();
725 #endif
726 
727  // Add graphic item on copper layers to poly contourns
728  // /////////////////////////////////////////////////////////////////////////
731  {
732  for( unsigned int lIdx = 0; lIdx < layer_id.size(); ++lIdx )
733  {
734  const PCB_LAYER_ID curr_layer_id = layer_id[lIdx];
735 
736  wxASSERT( m_layers_poly.find( curr_layer_id ) != m_layers_poly.end() );
737 
738  SHAPE_POLY_SET *layerPoly = m_layers_poly[curr_layer_id];
739 
740  // ADD GRAPHIC ITEMS ON COPPER LAYERS (texts)
741  for( auto item : m_board->Drawings() )
742  {
743  if( !item->IsOnLayer( curr_layer_id ) )
744  continue;
745 
746  switch( item->Type() )
747  {
748  case PCB_LINE_T: // should not exist on copper layers
749  {
750  const int nrSegments =
751  GetNrSegmentsCircle( item->GetBoundingBox().GetSizeMax() );
752 
753  ( (DRAWSEGMENT*) item )->TransformShapeWithClearanceToPolygon(
754  *layerPoly,
755  0,
756  nrSegments,
757  GetCircleCorrectionFactor( nrSegments ) );
758  }
759  break;
760 
761  case PCB_TEXT_T:
762  ( (TEXTE_PCB*) item )->TransformShapeWithClearanceToPolygonSet(
763  *layerPoly,
764  0,
765  segcountforcircle,
766  correctionFactor );
767  break;
768 
769  default:
770  wxLogTrace( m_logTrace,
771  wxT( "createLayers: item type: %d not implemented" ),
772  item->Type() );
773  break;
774  }
775  }
776  }
777  }
778 
779 #ifdef PRINT_STATISTICS_3D_VIEWER
780  printf( "T12: %.3f ms\n", (float)( GetRunningMicroSecs() - start_Time ) / 1e3 );
781  start_Time = GetRunningMicroSecs();
782 #endif
783 
784  if( GetFlag( FL_ZONE ) )
785  {
786  if( aStatusTextReporter )
787  aStatusTextReporter->Report( _( "Create zones" ) );
788 
789  // Add zones objects
790  // /////////////////////////////////////////////////////////////////////
791  for( unsigned int lIdx = 0; lIdx < layer_id.size(); ++lIdx )
792  {
793  const PCB_LAYER_ID curr_layer_id = layer_id[lIdx];
794 
795  if( aStatusTextReporter )
796  aStatusTextReporter->Report( wxString::Format( _( "Create zones of layer %s" ),
797  LSET::Name( curr_layer_id ) ) );
798 
799  wxASSERT( m_layers_container2D.find( curr_layer_id ) != m_layers_container2D.end() );
800 
801  CBVHCONTAINER2D *layerContainer = m_layers_container2D[curr_layer_id];
802 
803  // ADD COPPER ZONES
804  for( int ii = 0; ii < m_board->GetAreaCount(); ++ii )
805  {
806  const ZONE_CONTAINER* zone = m_board->GetArea( ii );
807  const PCB_LAYER_ID zonelayer = zone->GetLayer();
808 
809  if( zonelayer == curr_layer_id )
810  {
812  layerContainer,
813  curr_layer_id );
814  }
815  }
816  }
817  }
818 
819 #ifdef PRINT_STATISTICS_3D_VIEWER
820  printf( "T13: %.3f ms\n", (float)( GetRunningMicroSecs() - start_Time ) / 1e3 );
821  start_Time = GetRunningMicroSecs();
822 #endif
823 
824  if( GetFlag( FL_ZONE ) &&
827  {
828  // Add zones poly contourns
829  // /////////////////////////////////////////////////////////////////////
830  for( unsigned int lIdx = 0; lIdx < layer_id.size(); ++lIdx )
831  {
832  const PCB_LAYER_ID curr_layer_id = layer_id[lIdx];
833 
834  wxASSERT( m_layers_poly.find( curr_layer_id ) != m_layers_poly.end() );
835 
836  SHAPE_POLY_SET *layerPoly = m_layers_poly[curr_layer_id];
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  const LAYER_NUM zonelayer = zone->GetLayer();
843 
844  if( zonelayer == curr_layer_id )
845  {
846  zone->TransformSolidAreasShapesToPolygonSet( *layerPoly,
847  segcountforcircle,
848  correctionFactor );
849  }
850  }
851  }
852  }
853 
854 #ifdef PRINT_STATISTICS_3D_VIEWER
855  printf( "T14: %.3f ms\n", (float)( GetRunningMicroSecs() - start_Time ) / 1e3 );
856  start_Time = GetRunningMicroSecs();
857 #endif
858 
859  // Simplify layer polygons
860  // /////////////////////////////////////////////////////////////////////////
861 
862  if( aStatusTextReporter )
863  aStatusTextReporter->Report( _( "Simplifying copper layers polygons" ) );
864 
867  {
868  const int nLayers = layer_id.size();
869 
870  #pragma omp parallel for
871  for( signed int lIdx = 0; lIdx < nLayers; ++lIdx )
872  {
873  const PCB_LAYER_ID curr_layer_id = layer_id[lIdx];
874 
875  wxASSERT( m_layers_poly.find( curr_layer_id ) != m_layers_poly.end() );
876 
877  SHAPE_POLY_SET *layerPoly = m_layers_poly[curr_layer_id];
878 
879  wxASSERT( layerPoly != NULL );
880 
881  // This will make a union of all added contourns
882  layerPoly->Simplify( SHAPE_POLY_SET::PM_FAST );
883  }
884  }
885 
886 #ifdef PRINT_STATISTICS_3D_VIEWER
887  printf( "T15: %.3f ms\n", (float)( GetRunningMicroSecs() - start_Time ) / 1e3 );
888  start_Time = GetRunningMicroSecs();
889 #endif
890 
891  // Simplify holes polygon contours
892  // /////////////////////////////////////////////////////////////////////////
893  if( aStatusTextReporter )
894  aStatusTextReporter->Report( _( "Simplify holes contours" ) );
895 
896  for( unsigned int lIdx = 0; lIdx < layer_id.size(); ++lIdx )
897  {
898  const PCB_LAYER_ID curr_layer_id = layer_id[lIdx];
899 
900  if( m_layers_outer_holes_poly.find( curr_layer_id ) !=
902  {
903  // found
904  SHAPE_POLY_SET *polyLayer = m_layers_outer_holes_poly[curr_layer_id];
905  polyLayer->Simplify( SHAPE_POLY_SET::PM_FAST );
906 
907  wxASSERT( m_layers_inner_holes_poly.find( curr_layer_id ) !=
909 
910  polyLayer = m_layers_inner_holes_poly[curr_layer_id];
911  polyLayer->Simplify( SHAPE_POLY_SET::PM_FAST );
912  }
913  }
914 
915 #ifdef PRINT_STATISTICS_3D_VIEWER
916  printf( "T16: %.3f ms\n", (float)( GetRunningMicroSecs() - start_Time ) / 1e3 );
917 #endif
918  // End Build Copper layers
919 
920 
921  // This will make a union of all added contourns
926  //m_through_inner_holes_vias_poly.Simplify( SHAPE_POLY_SET::PM_FAST ); // Not in use
927 
928 #ifdef PRINT_STATISTICS_3D_VIEWER
929  unsigned stats_endCopperLayersTime = GetRunningMicroSecs();
930 #endif
931 
932  // Build Tech layers
933  // Based on: https://github.com/KiCad/kicad-source-mirror/blob/master/3d-viewer/3d_draw.cpp#L1059
934  // /////////////////////////////////////////////////////////////////////////
935 #ifdef PRINT_STATISTICS_3D_VIEWER
936  unsigned stats_startTechLayersTime = GetRunningMicroSecs();
937 #endif
938 
939  if( aStatusTextReporter )
940  aStatusTextReporter->Report( _( "Build Tech layers" ) );
941 
942  // draw graphic items, on technical layers
943  static const PCB_LAYER_ID teckLayerList[] = {
944  B_Adhes,
945  F_Adhes,
946  B_Paste,
947  F_Paste,
948  B_SilkS,
949  F_SilkS,
950  B_Mask,
951  F_Mask,
952 
953  // Aux Layers
954  Dwgs_User,
955  Cmts_User,
956  Eco1_User,
957  Eco2_User,
958  Edge_Cuts,
959  Margin
960  };
961 
962  // User layers are not drawn here, only technical layers
963 
964  for( LSEQ seq = LSET::AllNonCuMask().Seq( teckLayerList, DIM( teckLayerList ) );
965  seq;
966  ++seq )
967  {
968  const PCB_LAYER_ID curr_layer_id = *seq;
969 
970  if( !Is3DLayerEnabled( curr_layer_id ) )
971  continue;
972 
973  CBVHCONTAINER2D *layerContainer = new CBVHCONTAINER2D;
974  m_layers_container2D[curr_layer_id] = layerContainer;
975 
976  SHAPE_POLY_SET *layerPoly = new SHAPE_POLY_SET;
977  m_layers_poly[curr_layer_id] = layerPoly;
978 
979  // Add drawing objects
980  // /////////////////////////////////////////////////////////////////////
981  for( auto item : m_board->Drawings() )
982  {
983  if( !item->IsOnLayer( curr_layer_id ) )
984  continue;
985 
986  switch( item->Type() )
987  {
988  case PCB_LINE_T:
990  layerContainer,
991  curr_layer_id,
992  0 );
993  break;
994 
995  case PCB_TEXT_T:
997  layerContainer,
998  curr_layer_id,
999  0 );
1000  break;
1001 
1002  case PCB_DIMENSION_T:
1004  layerContainer,
1005  curr_layer_id,
1006  0 );
1007  break;
1008 
1009  default:
1010  break;
1011  }
1012  }
1013 
1014 
1015  // Add drawing contours
1016  // /////////////////////////////////////////////////////////////////////
1017  for( auto item : m_board->Drawings() )
1018  {
1019  if( !item->IsOnLayer( curr_layer_id ) )
1020  continue;
1021 
1022  switch( item->Type() )
1023  {
1024  case PCB_LINE_T:
1025  {
1026  const unsigned int nr_segments =
1027  GetNrSegmentsCircle( item->GetBoundingBox().GetSizeMax() );
1028 
1029  ((DRAWSEGMENT*) item)->TransformShapeWithClearanceToPolygon( *layerPoly,
1030  0,
1031  nr_segments,
1032  0.0 );
1033  }
1034  break;
1035 
1036  case PCB_TEXT_T:
1037  ((TEXTE_PCB*) item)->TransformShapeWithClearanceToPolygonSet( *layerPoly,
1038  0,
1039  segcountInStrokeFont,
1040  1.0 );
1041  break;
1042 
1043  default:
1044  break;
1045  }
1046  }
1047 
1048 
1049  // Add modules tech layers - objects
1050  // /////////////////////////////////////////////////////////////////////
1051  for( MODULE* module = m_board->m_Modules; module; module = module->Next() )
1052  {
1053  if( (curr_layer_id == F_SilkS) || (curr_layer_id == B_SilkS) )
1054  {
1055  D_PAD* pad = module->PadsList();
1056  int linewidth = g_DrawDefaultLineThickness;
1057 
1058  for( ; pad; pad = pad->Next() )
1059  {
1060  if( !pad->IsOnLayer( curr_layer_id ) )
1061  continue;
1062 
1064  layerContainer,
1065  linewidth );
1066  }
1067  }
1068  else
1069  {
1071  layerContainer,
1072  curr_layer_id,
1073  0,
1074  false );
1075  }
1076 
1078  layerContainer,
1079  curr_layer_id,
1080  0 );
1081  }
1082 
1083 
1084  // Add modules tech layers - contours
1085  // /////////////////////////////////////////////////////////////////////
1086  for( MODULE* module = m_board->m_Modules; module; module = module->Next() )
1087  {
1088  if( (curr_layer_id == F_SilkS) || (curr_layer_id == B_SilkS) )
1089  {
1090  D_PAD* pad = module->PadsList();
1091  const int linewidth = g_DrawDefaultLineThickness;
1092 
1093  for( ; pad; pad = pad->Next() )
1094  {
1095  if( !pad->IsOnLayer( curr_layer_id ) )
1096  continue;
1097 
1098  buildPadShapeThickOutlineAsPolygon( pad, *layerPoly, linewidth );
1099  }
1100  }
1101  else
1102  {
1103  transformPadsShapesWithClearanceToPolygon( module->PadsList(),
1104  curr_layer_id,
1105  *layerPoly,
1106  0,
1107  false );
1108  }
1109 
1110  // On tech layers, use a poor circle approximation, only for texts (stroke font)
1111  module->TransformGraphicTextWithClearanceToPolygonSet( curr_layer_id,
1112  *layerPoly,
1113  0,
1114  segcountInStrokeFont,
1115  correctionFactorStroke,
1116  segcountInStrokeFont );
1117 
1118  // Add the remaining things with dynamic seg count for circles
1119  transformGraphicModuleEdgeToPolygonSet( module, curr_layer_id, *layerPoly );
1120  }
1121 
1122 
1123  // Draw non copper zones
1124  // /////////////////////////////////////////////////////////////////////
1125  if( GetFlag( FL_ZONE ) )
1126  {
1127  for( int ii = 0; ii < m_board->GetAreaCount(); ++ii )
1128  {
1129  ZONE_CONTAINER* zone = m_board->GetArea( ii );
1130 
1131  if( !zone->IsOnLayer( curr_layer_id ) )
1132  continue;
1133 
1135  layerContainer,
1136  curr_layer_id );
1137  }
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 
1146  zone->TransformSolidAreasShapesToPolygonSet( *layerPoly,
1147  // Use the same segcount as stroke font
1148  segcountInStrokeFont,
1149  correctionFactorStroke );
1150  }
1151  }
1152 
1153  // This will make a union of all added contours
1154  layerPoly->Simplify( SHAPE_POLY_SET::PM_FAST );
1155  }
1156  // End Build Tech layers
1157 
1158 #ifdef PRINT_STATISTICS_3D_VIEWER
1159  unsigned stats_endTechLayersTime = GetRunningMicroSecs();
1160 #endif
1161 
1162 
1163  // Build BVH for holes and vias
1164  // /////////////////////////////////////////////////////////////////////////
1165 
1166 #ifdef PRINT_STATISTICS_3D_VIEWER
1167  unsigned stats_startHolesBVHTime = GetRunningMicroSecs();
1168 #endif
1169  if( aStatusTextReporter )
1170  aStatusTextReporter->Report( _( "Build BVH for holes and vias" ) );
1171 
1174 
1175  if( !m_layers_holes2D.empty() )
1176  {
1177  for( MAP_CONTAINER_2D::iterator ii = m_layers_holes2D.begin();
1178  ii != m_layers_holes2D.end();
1179  ++ii )
1180  {
1181  ((CBVHCONTAINER2D *)(ii->second))->BuildBVH();
1182  }
1183  }
1184 
1185  // We only need the Solder mask to initialize the BVH
1186  // because..?
1188  ((CBVHCONTAINER2D *)m_layers_container2D[B_Mask])->BuildBVH();
1189 
1191  ((CBVHCONTAINER2D *)m_layers_container2D[F_Mask])->BuildBVH();
1192 
1193 #ifdef PRINT_STATISTICS_3D_VIEWER
1194  unsigned stats_endHolesBVHTime = GetRunningMicroSecs();
1195 
1196  printf( "CINFO3D_VISU::createLayers times\n" );
1197  printf( " Copper Layers: %.3f ms\n",
1198  (float)( stats_endCopperLayersTime - stats_startCopperLayersTime ) / 1e3 );
1199  printf( " Holes BVH creation: %.3f ms\n",
1200  (float)( stats_endHolesBVHTime - stats_startHolesBVHTime ) / 1e3 );
1201  printf( " Tech Layers: %.3f ms\n",
1202  (float)( stats_endTechLayersTime - stats_startTechLayersTime ) / 1e3 );
1203  printf( "Statistics:\n" );
1204  printf( " m_stats_nr_tracks %u\n", m_stats_nr_tracks );
1205  printf( " m_stats_nr_vias %u\n", m_stats_nr_vias );
1206  printf( " m_stats_nr_holes %u\n", m_stats_nr_holes );
1207  printf( " m_stats_via_med_hole_diameter (3DU) %f\n", m_stats_via_med_hole_diameter );
1208  printf( " m_stats_hole_med_diameter (3DU) %f\n", m_stats_hole_med_diameter );
1209  printf( " m_calc_seg_min_factor3DU (3DU) %f\n", m_calc_seg_min_factor3DU );
1210  printf( " m_calc_seg_max_factor3DU (3DU) %f\n", m_calc_seg_max_factor3DU );
1211 #endif
1212 }
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:673
void AddShapeWithClearanceToContainer(const TEXTE_PCB *aTextPCB, CGENERICCONTAINER2D *aDstContainer, PCB_LAYER_ID aLayerId, int aClearanceValue)
KICAD_T Type() const
Function Type()
Definition: base_struct.h:209
#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
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:696
MODULE * Next() const
Definition: class_module.h:121
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:364
a mutex for openmp got from the website: http://bisqwit.iki.fi/story/howto/openmp/ by Joel Yliluoma b...
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:460
unsigned int m_stats_nr_vias
Nr of vias.
Definition: cinfo3d_visu.h:656
static const wxChar * Name(PCB_LAYER_ID aLayerId)
Function Name returns the fixed name association with aLayerId.
Definition: lset.cpp:73
Class SHAPE_POLY_SET.
const wxPoint & GetStart() const
Definition: class_track.h:122
void createLayers(REPORTER *aStatusTextReporter)
void TransformShapeWithClearanceToPolygon(SHAPE_POLY_SET &aCornerBuffer, int aClearanceValue, int aCircleToSegmentsCount, double aCorrectionFactor) const override
Function TransformShapeWithClearanceToPolygon Convert the track shape to a closed polygon Used in fil...
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:1015
int g_DrawDefaultLineThickness
Default line thickness in internal units used to draw or plot items using a default thickness line va...
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.
int LAYER_NUM
Type LAYER_NUM can be replaced with int and removed.
unsigned int GetNrSegmentsCircle(float aDiameter3DU) const
GetNrSegmentsCircle.
void Add(COBJECT2D *aObject)
Definition: ccontainer2d.h:51
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:99
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:986
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
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:247
unsigned GetRunningMicroSecs()
Function GetRunningMicroSecs An alternate way to calculate an elapset time (in microsecondes) to clas...
int GetWidth() const
Definition: class_track.h:116
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:248
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:650
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:796
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:254
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)