KiCad PCB EDA Suite
c3d_render_createscene.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 
31 #include "c3d_render_raytracing.h"
32 #include "shapes3D/cplane.h"
33 #include "shapes3D/croundseg.h"
34 #include "shapes3D/clayeritem.h"
35 #include "shapes3D/ccylinder.h"
36 #include "shapes3D/ctriangle.h"
38 #include "shapes2D/cring2d.h"
39 #include "shapes2D/cpolygon2d.h"
41 #include "accelerators/cbvh_pbrt.h"
42 #include "3d_fastmath.h"
43 #include "3d_math.h"
44 
45 #include <class_board.h>
46 #include <class_module.h>
47 
48 #include <base_units.h>
49 #include <profile.h> // To use GetRunningMicroSecs or another profiling utility
50 
54 #define UNITS3D_TO_UNITSPCB (IU_PER_MM)
55 
57 {
58 
60  {
62 
65 
67 
69 
71 
73  }
74 
75  // http://devernay.free.fr/cours/opengl/materials.html
76 
77  // Copper
80  (SFVEC3F)(0.18f), // ambient
81  SFVEC3F( 0.0f, 0.0f, 0.0f ), // emissive
82  glm::clamp( ((SFVEC3F)(1.0f) -
84  SFVEC3F( 0.0f ),
85  SFVEC3F( 0.35f ) ), // specular
86  0.4f * 128.0f, // shiness
87  0.0f, // transparency
88  0.0f );
89 
91  m_materials.m_Copper.SetNormalPerturbator( &m_copper_normal_perturbator );
92 
96  SFVEC3F( 0.0f, 0.0f, 0.0f ), // emissive
99  0.10f * 128.0f, // shiness
100  0.0f, // transparency
101  0.0f );
102 
104  ConvertSRGBToLinear( SFVEC3F( 0.11f ) ),// ambient
105  SFVEC3F( 0.0f, 0.0f, 0.0f ), // emissive
106  glm::clamp( ((SFVEC3F)(1.0f) -
108  SFVEC3F( 0.0f ),
109  SFVEC3F( 0.10f ) ), // specular
110  0.078125f * 128.0f, // shiness
111  0.0f, // transparency
112  0.0f );
113 
114  const float solderMask_gray = ( m_settings.m_SolderMaskColor.r +
116  m_settings.m_SolderMaskColor.b ) / 3.0f;
117 
118  const float solderMask_transparency = solderMask_gray * 0.40f + 0.005f;
119 
120  m_materials.m_SolderMask = CBLINN_PHONG_MATERIAL(
122  0.10f, // ambient
123  SFVEC3F( 0.0f, 0.0f, 0.0f ), // emissive
124  glm::clamp( ( (SFVEC3F)( 1.0f ) -
126  SFVEC3F( 0.0f ),
127  SFVEC3F( solderMask_gray * 2.0f ) ), // specular
128  0.85f * 128.0f, // shiness
129  solderMask_transparency, // transparency
130  0.16f ); // reflection
131 
132  m_materials.m_SolderMask.SetCastShadows( true );
133  m_materials.m_SolderMask.SetNrRefractionsSamples( 1 );
134  m_materials.m_SolderMask.SetNrReflectionsSamples( 2 );
135 
137  m_materials.m_SolderMask.SetNormalPerturbator( &m_solder_mask_normal_perturbator );
138 
139  m_materials.m_EpoxyBoard = CBLINN_PHONG_MATERIAL(
140  ConvertSRGBToLinear( SFVEC3F( 16.0f / 255.0f,
141  14.0f / 255.0f,
142  10.0f / 255.0f ) ), // ambient
143  SFVEC3F( 0.0f, 0.0f, 0.0f ), // emissive
144  ConvertSRGBToLinear( SFVEC3F( 10.0f / 255.0f,
145  8.0f / 255.0f,
146  10.0f / 255.0f ) ), // specular
147  0.1f * 128.0f, // shiness
148  0.10f, // transparency
149  0.0f ); // reflection
150 
151  m_materials.m_EpoxyBoard.SetAbsorvance( 10.0f );
152  m_materials.m_EpoxyBoard.SetNrRefractionsSamples( 3 );
153 
155  m_materials.m_EpoxyBoard.SetNormalPerturbator( &m_board_normal_perturbator );
156 
158  //SFVEC3F bgBot = (SFVEC3F)m_settings.m_BgColorBot;
159 
161  bgTop * 0.125f, // ambient
162  SFVEC3F( 0.0f, 0.0f, 0.0f ), // emissive
163  (SFVEC3F(1.0f) - bgTop) / 3.0f, // specular
164  0.10f * 128.0f, // shiness
165  0.0f, // transparency
166  0.50f ); // reflection
167 }
168 
169 
170 
180  const COBJECT2D *aObject2D,
181  float aZMin, float aZMax,
182  const CMATERIAL *aMaterial,
183  const SFVEC3F &aObjColor )
184 {
185  switch( aObject2D->GetObjectType() )
186  {
187  case OBJ2D_DUMMYBLOCK:
188  {
190 #if 1
191  CXYPLANE *objPtr;
192  objPtr = new CXYPLANE( CBBOX ( SFVEC3F( aObject2D->GetBBox().Min().x,
193  aObject2D->GetBBox().Min().y,
194  aZMin ),
195  SFVEC3F( aObject2D->GetBBox().Max().x,
196  aObject2D->GetBBox().Max().y,
197  aZMin ) ) );
198  objPtr->SetMaterial( aMaterial );
199  objPtr->SetColor( ConvertSRGBToLinear( aObjColor ) );
200  aDstContainer.Add( objPtr );
201 
202  objPtr = new CXYPLANE( CBBOX ( SFVEC3F( aObject2D->GetBBox().Min().x,
203  aObject2D->GetBBox().Min().y,
204  aZMax ),
205  SFVEC3F( aObject2D->GetBBox().Max().x,
206  aObject2D->GetBBox().Max().y,
207  aZMax ) ) );
208  objPtr->SetMaterial( aMaterial );
209  objPtr->SetColor( ConvertSRGBToLinear( aObjColor ) );
210  aDstContainer.Add( objPtr );
211 #else
212  objPtr = new CDUMMYBLOCK( CBBOX ( SFVEC3F( aObject2D->GetBBox().Min().x,
213  aObject2D->GetBBox().Min().y,
214  aZMin ),
215  SFVEC3F( aObject2D->GetBBox().Max().x,
216  aObject2D->GetBBox().Max().y,
217  aZMax ) ) );
218  objPtr->SetMaterial( aMaterial );
219  aDstContainer.Add( objPtr );
220 #endif
221  }
222  break;
223 
224  case OBJ2D_ROUNDSEG:
225  {
227 
228  const CROUNDSEGMENT2D *aRoundSeg2D = static_cast<const CROUNDSEGMENT2D *>( aObject2D );
229  CROUNDSEG *objPtr = new CROUNDSEG( *aRoundSeg2D, aZMin, aZMax );
230  objPtr->SetMaterial( aMaterial );
231  objPtr->SetColor( ConvertSRGBToLinear( aObjColor ) );
232  aDstContainer.Add( objPtr );
233  }
234  break;
235 
236 
237  default:
238  {
239  CLAYERITEM *objPtr = new CLAYERITEM( aObject2D, aZMin, aZMax );
240  objPtr->SetMaterial( aMaterial );
241  objPtr->SetColor( ConvertSRGBToLinear( aObjColor ) );
242  aDstContainer.Add( objPtr );
243  }
244  break;
245  }
246 }
247 
248 
249 void C3D_RENDER_RAYTRACING::reload( REPORTER *aStatusTextReporter )
250 {
251  m_reloadRequested = false;
252 
253  m_model_materials.clear();
254 
257 
258 #ifdef PRINT_STATISTICS_3D_VIEWER
259  printf("InitSettings...\n");
260 #endif
261 
262  unsigned stats_startReloadTime = GetRunningMicroSecs();
263 
264  m_settings.InitSettings( aStatusTextReporter );
265 
266 #ifdef PRINT_STATISTICS_3D_VIEWER
267  unsigned stats_endReloadTime = GetRunningMicroSecs();
268  unsigned stats_startConvertTime = GetRunningMicroSecs();
269  #endif
270 
271  SFVEC3F camera_pos = m_settings.GetBoardCenter3DU();
272  m_settings.CameraGet().SetBoardLookAtPos( camera_pos );
273 
276 
277 
278  // Create and add the outline board
279  // /////////////////////////////////////////////////////////////////////////
280 
281 #ifdef PRINT_STATISTICS_3D_VIEWER
282  printf("Create outline board...\n");
283 #endif
284 
286 
288 
289  if( ((const SHAPE_POLY_SET &)m_settings.GetBoardPoly()).OutlineCount() == 1 )
290  {
291  float divFactor = 0.0f;
292 
294  divFactor = m_settings.GetStats_Med_Via_Hole_Diameter3DU() * 18.0f;
295  else
297  divFactor = m_settings.GetStats_Med_Hole_Diameter3DU() * 8.0f;
298 
299  SHAPE_POLY_SET boardPolyCopy = m_settings.GetBoardPoly();
300  boardPolyCopy.Fracture( SHAPE_POLY_SET::PM_FAST );
301 
303  boardPolyCopy,
306  divFactor,
307  (const BOARD_ITEM &)*m_settings.GetBoard() );
308 
310  {
311  const LIST_OBJECT2D &listObjects = m_outlineBoard2dObjects->GetList();
312 
313  for( LIST_OBJECT2D::const_iterator object2d_iterator = listObjects.begin();
314  object2d_iterator != listObjects.end();
315  ++object2d_iterator )
316  {
317  const COBJECT2D *object2d_A = static_cast<const COBJECT2D *>(*object2d_iterator);
318 
319  std::vector<const COBJECT2D *> *object2d_B = new std::vector<const COBJECT2D *>();
320 
321  // Check if there are any THT that intersects this outline object part
322  if( !m_settings.GetThroughHole_Outer().GetList().empty() )
323  {
324 
325  CONST_LIST_OBJECT2D intersectionList;
327  object2d_A->GetBBox(),
328  intersectionList );
329 
330  if( !intersectionList.empty() )
331  {
332  for( CONST_LIST_OBJECT2D::const_iterator hole = intersectionList.begin();
333  hole != intersectionList.end();
334  ++hole )
335  {
336  const COBJECT2D *hole2d = static_cast<const COBJECT2D *>(*hole);
337 
338  if( object2d_A->Intersects( hole2d->GetBBox() ) )
339  //if( object2d_A->GetBBox().Intersects( hole2d->GetBBox() ) )
340  object2d_B->push_back( hole2d );
341  }
342  }
343  }
344 
345  if( object2d_B->empty() )
346  {
347  delete object2d_B;
348  object2d_B = CSGITEM_EMPTY;
349  }
350 
351  if( object2d_B == CSGITEM_EMPTY )
352  {
353  #if 0
357  &m_materials.m_EpoxyBoard,
358  g_epoxyColor );
359  #else
360  CLAYERITEM *objPtr = new CLAYERITEM( object2d_A,
363 
364  objPtr->SetMaterial( &m_materials.m_EpoxyBoard );
365  objPtr->SetColor( ConvertSRGBToLinear( (SFVEC3F)m_settings.m_BoardBodyColor ) );
366  m_object_container.Add( objPtr );
367  #endif
368  }
369  else
370  {
371  CITEMLAYERCSG2D *itemCSG2d = new CITEMLAYERCSG2D(
372  object2d_A,
373  object2d_B,
374  CSGITEM_FULL,
375  (const BOARD_ITEM &)*m_settings.GetBoard() );
376 
377  m_containerWithObjectsToDelete.Add( itemCSG2d );
378 
379  CLAYERITEM *objPtr = new CLAYERITEM( itemCSG2d,
382 
383  objPtr->SetMaterial( &m_materials.m_EpoxyBoard );
385  m_object_container.Add( objPtr );
386  }
387  }
388 
389  // Add cylinders of the board body to container
390  // Note: This is actually a workarround for the holes in the board.
391  // The issue is because if a hole is in a border of a divided polygon ( ex
392  // a polygon or dummyblock) it will cut also the render of the hole.
393  // So this will add a full hole.
394  // In fact, that is not need if the hole have copper.
395  // /////////////////////////////////////////////////////////////////////////
396  if( !m_settings.GetThroughHole_Outer().GetList().empty() )
397  {
399 
400  for( LIST_OBJECT2D::const_iterator hole = holeList.begin();
401  hole != holeList.end();
402  ++hole )
403  {
404  const COBJECT2D *hole2d = static_cast<const COBJECT2D *>(*hole);
405 
406  switch( hole2d->GetObjectType() )
407  {
408  case OBJ2D_FILLED_CIRCLE:
409  {
410  const float radius = hole2d->GetBBox().GetExtent().x * 0.5f * 0.999f;
411 
412  CVCYLINDER *objPtr = new CVCYLINDER(
413  hole2d->GetCentroid(),
416  radius );
417 
418  objPtr->SetMaterial( &m_materials.m_EpoxyBoard );
420 
421  m_object_container.Add( objPtr );
422  }
423  break;
424 
425  default:
426  break;
427  }
428  }
429  }
430  }
431  }
432 
433 
434  // Add layers maps (except B_Mask and F_Mask)
435  // /////////////////////////////////////////////////////////////////////////
436 
437 #ifdef PRINT_STATISTICS_3D_VIEWER
438  printf("Add layers maps...\n");
439 #endif
440 
441  for( MAP_CONTAINER_2D::const_iterator ii = m_settings.GetMapLayers().begin();
442  ii != m_settings.GetMapLayers().end();
443  ++ii )
444  {
445  PCB_LAYER_ID layer_id = static_cast<PCB_LAYER_ID>(ii->first);
446 
447  // Mask kayers are not processed here because they are a special case
448  if( (layer_id == B_Mask) || (layer_id == F_Mask) )
449  continue;
450 
451  CMATERIAL *materialLayer = &m_materials.m_SilkS;
452  SFVEC3F layerColor = SFVEC3F( 0.0f, 0.0f, 0.0f );
453 
454  switch( layer_id )
455  {
456  case B_Adhes:
457  case F_Adhes:
458  break;
459 
460  case B_Paste:
461  case F_Paste:
462  materialLayer = &m_materials.m_Paste;
463 
465  layerColor = m_settings.m_SolderPasteColor;
466  else
467  layerColor = m_settings.GetLayerColor( layer_id );
468  break;
469 
470  case B_SilkS:
471  case F_SilkS:
472  materialLayer = &m_materials.m_SilkS;
473 
475  layerColor = m_settings.m_SilkScreenColor;
476  else
477  layerColor = m_settings.GetLayerColor( layer_id );
478  break;
479 
480  case Dwgs_User:
481  case Cmts_User:
482  case Eco1_User:
483  case Eco2_User:
484  case Edge_Cuts:
485  case Margin:
486  break;
487 
488  case B_CrtYd:
489  case F_CrtYd:
490  break;
491 
492  case B_Fab:
493  case F_Fab:
494  break;
495 
496  default:
497  materialLayer = &m_materials.m_Copper;
498 
500  layerColor = m_settings.m_CopperColor;
501  else
502  layerColor = m_settings.GetLayerColor( layer_id );
503  break;
504  }
505 
506  const CBVHCONTAINER2D *container2d = static_cast<const CBVHCONTAINER2D *>(ii->second);
507  const LIST_OBJECT2D &listObject2d = container2d->GetList();
508 
509  for( LIST_OBJECT2D::const_iterator itemOnLayer = listObject2d.begin();
510  itemOnLayer != listObject2d.end();
511  ++itemOnLayer )
512  {
513  const COBJECT2D *object2d_A = static_cast<const COBJECT2D *>(*itemOnLayer);
514 
515  // not yet used / implemented (can be used in future to clip the objects in the board borders
516  COBJECT2D *object2d_C = CSGITEM_FULL;
517 
518  std::vector<const COBJECT2D *> *object2d_B = CSGITEM_EMPTY;
519 
520  if( true ) // previously, was a option, now holes are always drawn in zones
521  {
522  object2d_B = new std::vector<const COBJECT2D *>();
523 
524  // Check if there are any layerhole that intersects this object
525  // Eg: a segment is cutted by a via hole or THT hole.
526  // /////////////////////////////////////////////////////////////
527  const MAP_CONTAINER_2D &layerHolesMap = m_settings.GetMapLayersHoles();
528 
529  if( layerHolesMap.find(layer_id) != layerHolesMap.end() )
530  {
531  MAP_CONTAINER_2D::const_iterator ii_hole = layerHolesMap.find(layer_id);
532 
533  const CBVHCONTAINER2D *containerLayerHoles2d =
534  static_cast<const CBVHCONTAINER2D *>(ii_hole->second);
535 
536 
537  CONST_LIST_OBJECT2D intersectionList;
538  containerLayerHoles2d->GetListObjectsIntersects( object2d_A->GetBBox(),
539  intersectionList );
540 
541  if( !intersectionList.empty() )
542  {
543  for( CONST_LIST_OBJECT2D::const_iterator holeOnLayer =
544  intersectionList.begin();
545  holeOnLayer != intersectionList.end();
546  ++holeOnLayer )
547  {
548  const COBJECT2D *hole2d = static_cast<const COBJECT2D *>(*holeOnLayer);
549 
550  //if( object2d_A->Intersects( hole2d->GetBBox() ) )
551  //if( object2d_A->GetBBox().Intersects( hole2d->GetBBox() ) )
552  object2d_B->push_back( hole2d );
553  }
554  }
555  }
556 
557  // Check if there are any THT that intersects this object
558  // /////////////////////////////////////////////////////////////
559  if( !m_settings.GetThroughHole_Outer().GetList().empty() )
560  {
561  CONST_LIST_OBJECT2D intersectionList;
562 
564  object2d_A->GetBBox(),
565  intersectionList );
566 
567  if( !intersectionList.empty() )
568  {
569  for( CONST_LIST_OBJECT2D::const_iterator hole = intersectionList.begin();
570  hole != intersectionList.end();
571  ++hole )
572  {
573  const COBJECT2D *hole2d = static_cast<const COBJECT2D *>(*hole);
574 
575  //if( object2d_A->Intersects( hole2d->GetBBox() ) )
576  //if( object2d_A->GetBBox().Intersects( hole2d->GetBBox() ) )
577  object2d_B->push_back( hole2d );
578  }
579  }
580  }
581 
582  if( object2d_B->empty() )
583  {
584  delete object2d_B;
585  object2d_B = CSGITEM_EMPTY;
586  }
587  }
588 
589  if( (object2d_B == CSGITEM_EMPTY) &&
590  (object2d_C == CSGITEM_FULL) )
591  {
592 #if 0
594  object2d_A,
595  m_settings.GetLayerBottomZpos3DU( layer_id ),
596  m_settings.GetLayerTopZpos3DU( layer_id ),
597  materialLayer,
598  layerColor );
599 #else
600  CLAYERITEM *objPtr = new CLAYERITEM( object2d_A,
601  m_settings.GetLayerBottomZpos3DU( layer_id ),
602  m_settings.GetLayerTopZpos3DU( layer_id ) );
603  objPtr->SetMaterial( materialLayer );
604  objPtr->SetColor( ConvertSRGBToLinear( layerColor ) );
605  m_object_container.Add( objPtr );
606 #endif
607  }
608  else
609  {
610 #if 1
611  CITEMLAYERCSG2D *itemCSG2d = new CITEMLAYERCSG2D( object2d_A,
612  object2d_B,
613  object2d_C,
614  object2d_A->GetBoardItem() );
615  m_containerWithObjectsToDelete.Add( itemCSG2d );
616 
617  CLAYERITEM *objPtr = new CLAYERITEM( itemCSG2d,
618  m_settings.GetLayerBottomZpos3DU( layer_id ),
619  m_settings.GetLayerTopZpos3DU( layer_id ) );
620 
621  objPtr->SetMaterial( materialLayer );
622  objPtr->SetColor( ConvertSRGBToLinear( layerColor ) );
623 
624  m_object_container.Add( objPtr );
625 #endif
626  }
627  }
628  }// for each layer on map
629 
630 
631 
632  // Add Mask layer
633  // Solder mask layers are "negative" layers so the elements that we have
634  // (in the container) should remove the board outline.
635  // We will check for all objects in the outline if it intersects any object
636  // in the layer container and also any hole.
637  // /////////////////////////////////////////////////////////////////////////
639  (m_outlineBoard2dObjects->GetList().size() >= 1) )
640  {
641  CMATERIAL *materialLayer = &m_materials.m_SolderMask;
642 
643  for( MAP_CONTAINER_2D::const_iterator ii = m_settings.GetMapLayers().begin();
644  ii != m_settings.GetMapLayers().end();
645  ++ii )
646  {
647  PCB_LAYER_ID layer_id = static_cast<PCB_LAYER_ID>(ii->first);
648 
649  const CBVHCONTAINER2D *containerLayer2d =
650  static_cast<const CBVHCONTAINER2D *>(ii->second);
651 
652  // Only get the Solder mask layers
653  if( !((layer_id == B_Mask) || (layer_id == F_Mask)) )
654  continue;
655 
656  SFVEC3F layerColor;
658  layerColor = m_settings.m_SolderMaskColor;
659  else
660  layerColor = m_settings.GetLayerColor( layer_id );
661 
662  const float zLayerMin = m_settings.GetLayerBottomZpos3DU( layer_id );
663  const float zLayerMax = m_settings.GetLayerTopZpos3DU( layer_id );
664 
665  // Get the outline board objects
666  const LIST_OBJECT2D &listObjects = m_outlineBoard2dObjects->GetList();
667 
668  for( LIST_OBJECT2D::const_iterator object2d_iterator = listObjects.begin();
669  object2d_iterator != listObjects.end();
670  ++object2d_iterator )
671  {
672  const COBJECT2D *object2d_A = static_cast<const COBJECT2D *>(*object2d_iterator);
673 
674  std::vector<const COBJECT2D *> *object2d_B = new std::vector<const COBJECT2D *>();
675 
676  // Check if there are any THT that intersects this outline object part
677  if( !m_settings.GetThroughHole_Outer().GetList().empty() )
678  {
679 
680  CONST_LIST_OBJECT2D intersectionList;
681 
683  object2d_A->GetBBox(),
684  intersectionList );
685 
686  if( !intersectionList.empty() )
687  {
688  for( CONST_LIST_OBJECT2D::const_iterator hole = intersectionList.begin();
689  hole != intersectionList.end();
690  ++hole )
691  {
692  const COBJECT2D *hole2d = static_cast<const COBJECT2D *>(*hole);
693 
694  if( object2d_A->Intersects( hole2d->GetBBox() ) )
695  //if( object2d_A->GetBBox().Intersects( hole2d->GetBBox() ) )
696  object2d_B->push_back( hole2d );
697  }
698  }
699  }
700 
701  // Check if there are any objects in the layer to subtract with the
702  // corrent object
703  if( !containerLayer2d->GetList().empty() )
704  {
705  CONST_LIST_OBJECT2D intersectionList;
706 
707  containerLayer2d->GetListObjectsIntersects( object2d_A->GetBBox(),
708  intersectionList );
709 
710  if( !intersectionList.empty() )
711  {
712  for( CONST_LIST_OBJECT2D::const_iterator obj = intersectionList.begin();
713  obj != intersectionList.end();
714  ++obj )
715  {
716  const COBJECT2D *obj2d = static_cast<const COBJECT2D *>(*obj);
717 
718  //if( object2d_A->Intersects( obj2d->GetBBox() ) )
719  //if( object2d_A->GetBBox().Intersects( obj2d->GetBBox() ) )
720  object2d_B->push_back( obj2d );
721  }
722  }
723  }
724 
725  if( object2d_B->empty() )
726  {
727  delete object2d_B;
728  object2d_B = CSGITEM_EMPTY;
729  }
730 
731  if( object2d_B == CSGITEM_EMPTY )
732  {
733  #if 0
735  object2d_A,
736  zLayerMin,
737  zLayerMax,
738  materialLayer,
739  layerColor );
740  #else
741  CLAYERITEM *objPtr = new CLAYERITEM( object2d_A,
742  zLayerMin,
743  zLayerMax );
744 
745  objPtr->SetMaterial( materialLayer );
746  objPtr->SetColor( ConvertSRGBToLinear( layerColor ) );
747 
748  m_object_container.Add( objPtr );
749  #endif
750  }
751  else
752  {
753  CITEMLAYERCSG2D *itemCSG2d = new CITEMLAYERCSG2D( object2d_A,
754  object2d_B,
755  CSGITEM_FULL,
756  object2d_A->GetBoardItem() );
757 
758  m_containerWithObjectsToDelete.Add( itemCSG2d );
759 
760  CLAYERITEM *objPtr = new CLAYERITEM( itemCSG2d,
761  zLayerMin,
762  zLayerMax );
763  objPtr->SetMaterial( materialLayer );
764  objPtr->SetColor( ConvertSRGBToLinear( layerColor ) );
765 
766  m_object_container.Add( objPtr );
767  }
768  }
769  }
770  }
771 
773 
774 #ifdef PRINT_STATISTICS_3D_VIEWER
775  unsigned stats_endConvertTime = GetRunningMicroSecs();
776  unsigned stats_startLoad3DmodelsTime = stats_endConvertTime;
777 #endif
778 
779 
780  load_3D_models();
781 
782 
783 #ifdef PRINT_STATISTICS_3D_VIEWER
784  unsigned stats_endLoad3DmodelsTime = GetRunningMicroSecs();
785 #endif
786 
787  // Add floor
788  // /////////////////////////////////////////////////////////////////////////
790  {
791  CBBOX boardBBox = m_settings.GetBBox3DU();
792 
793  if( boardBBox.IsInitialized() )
794  {
795  boardBBox.Scale( 3.0f );
796 
797  if( m_object_container.GetList().size() > 0 )
798  {
799  CBBOX containerBBox = m_object_container.GetBBox();
800 
801  containerBBox.Scale( 1.3f );
802 
803  const SFVEC3F centerBBox = containerBBox.GetCenter();
804 
805  const float minZ = glm::min( containerBBox.Min().z,
806  boardBBox.Min().z );
807 
808  const SFVEC3F v1 = SFVEC3F( -RANGE_SCALE_3D * 4.0f,
809  -RANGE_SCALE_3D * 4.0f,
810  minZ ) +
811  SFVEC3F( centerBBox.x,
812  centerBBox.y,
813  0.0f );
814 
815  const SFVEC3F v3 = SFVEC3F( +RANGE_SCALE_3D * 4.0f,
816  +RANGE_SCALE_3D * 4.0f,
817  minZ ) +
818  SFVEC3F( centerBBox.x,
819  centerBBox.y,
820  0.0f );
821 
822  const SFVEC3F v2 = SFVEC3F( v1.x, v3.y, v1.z );
823  const SFVEC3F v4 = SFVEC3F( v3.x, v1.y, v1.z );
824 
825  CTRIANGLE *newTriangle1 = new CTRIANGLE( v1, v2, v3 );
826  CTRIANGLE *newTriangle2 = new CTRIANGLE( v3, v4, v1 );
827 
828  m_object_container.Add( newTriangle1 );
829  m_object_container.Add( newTriangle2 );
830 
831  newTriangle1->SetMaterial( (const CMATERIAL *)&m_materials.m_Floor );
832  newTriangle2->SetMaterial( (const CMATERIAL *)&m_materials.m_Floor );
833 
836  }
837  }
838  }
839 
840 
841  // Init initial lights
842  // /////////////////////////////////////////////////////////////////////////
843  m_lights.Clear();
844 
845  // This will work as the front camera light.
846  const float light_camera_intensity = 0.20;
847  const float light_top_bottom = 0.25;
848  const float light_directional_intensity = ( 1.0f - ( light_camera_intensity +
849  light_top_bottom * 0.5f ) ) / 4.0f;
850 
851  m_camera_light = new CDIRECTIONALLIGHT( SFVEC3F( 0.0f, 0.0f, 0.0f ),
852  SFVEC3F( light_camera_intensity ) );
853  m_camera_light->SetCastShadows( false );
855 
856  // Option 1 - using Point Lights
857 
858  const SFVEC3F &boarCenter = m_settings.GetBBox3DU().GetCenter();
859 
860  m_lights.Add( new CPOINTLIGHT( SFVEC3F( boarCenter.x, boarCenter.y, +RANGE_SCALE_3D * 2.0f ),
861  SFVEC3F( light_top_bottom ) ) );
862 
863  m_lights.Add( new CPOINTLIGHT( SFVEC3F( boarCenter.x, boarCenter.y, -RANGE_SCALE_3D * 2.0f ),
864  SFVEC3F( light_top_bottom ) ) );
865 
866 
867  // http://www.flashandmath.com/mathlets/multicalc/coords/shilmay23fin.html
868 
869  // Option 2 - Top/Bottom direction lights
870  /*
871  m_lights.Add( new CDIRECTIONALLIGHT( SphericalToCartesian( glm::pi<float>() * 0.03f,
872  glm::pi<float>() * 0.25f ),
873  SFVEC3F( light_top_bottom ) ) );
874 
875  m_lights.Add( new CDIRECTIONALLIGHT( SphericalToCartesian( glm::pi<float>() * 0.97f,
876  glm::pi<float>() * 1.25f ),
877  SFVEC3F( light_top_bottom ) ) );
878  */
879 
880  m_lights.Add( new CDIRECTIONALLIGHT( SphericalToCartesian( glm::pi<float>() * 1.0f / 8.0f,
881  glm::pi<float>() * 1 / 4.0f ),
882  SFVEC3F( light_directional_intensity ) ) );
883  m_lights.Add( new CDIRECTIONALLIGHT( SphericalToCartesian( glm::pi<float>() * 1.0f / 8.0f,
884  glm::pi<float>() * 3 / 4.0f ),
885  SFVEC3F( light_directional_intensity ) ) );
886  m_lights.Add( new CDIRECTIONALLIGHT( SphericalToCartesian( glm::pi<float>() * 1.0f / 8.0f,
887  glm::pi<float>() * 5 / 4.0f ),
888  SFVEC3F( light_directional_intensity ) ) );
889  m_lights.Add( new CDIRECTIONALLIGHT( SphericalToCartesian( glm::pi<float>() * 1.0f / 8.0f,
890  glm::pi<float>() * 7 / 4.0f ),
891  SFVEC3F( light_directional_intensity ) ) );
892 
893 
894  m_lights.Add( new CDIRECTIONALLIGHT( SphericalToCartesian( glm::pi<float>() * 7.0f / 8.0f,
895  glm::pi<float>() * 1 / 4.0f ),
896  SFVEC3F( light_directional_intensity ) ) );
897  m_lights.Add( new CDIRECTIONALLIGHT( SphericalToCartesian( glm::pi<float>() * 7.0f / 8.0f,
898  glm::pi<float>() * 3 / 4.0f ),
899  SFVEC3F( light_directional_intensity ) ) );
900  m_lights.Add( new CDIRECTIONALLIGHT( SphericalToCartesian( glm::pi<float>() * 7.0f / 8.0f,
901  glm::pi<float>() * 5 / 4.0f ),
902  SFVEC3F( light_directional_intensity ) ) );
903  m_lights.Add( new CDIRECTIONALLIGHT( SphericalToCartesian( glm::pi<float>() * 7.0f / 8.0f,
904  glm::pi<float>() * 7 / 4.0f ),
905  SFVEC3F( light_directional_intensity ) ) );
906 
907 
908  // Create an accelerator
909  // /////////////////////////////////////////////////////////////////////////
910 
911 #ifdef PRINT_STATISTICS_3D_VIEWER
912  unsigned stats_startAcceleratorTime = GetRunningMicroSecs();
913 #endif
914 
915  if( m_accelerator )
916  {
917  delete m_accelerator;
918  }
919  m_accelerator = 0;
920 
922 
923 #ifdef PRINT_STATISTICS_3D_VIEWER
924  unsigned stats_endAcceleratorTime = GetRunningMicroSecs();
925 #endif
926 
927  setupMaterials();
928 
929 #ifdef PRINT_STATISTICS_3D_VIEWER
930  printf( "C3D_RENDER_RAYTRACING::reload times:\n" );
931  printf( " Reload board: %.3f ms\n", (float)( stats_endReloadTime -
932  stats_startReloadTime ) /
933 
934  1000.0f );
935  printf( " Convert to 3D objects: %.3f ms\n", (float)( stats_endConvertTime -
936  stats_startConvertTime ) /
937  1000.0f );
938  printf( " Accelerator construction: %.3f ms\n", (float)( stats_endAcceleratorTime -
939  stats_startAcceleratorTime ) /
940  1000.0f );
941  printf( " Load and add 3D models: %.3f ms\n", (float)( stats_endLoad3DmodelsTime -
942  stats_startLoad3DmodelsTime ) /
943  1000.0f );
944  printf( "Optimizations\n" );
945 
946  printf( " m_stats_converted_dummy_to_plane: %u\n",
948 
949  printf( " m_stats_converted_roundsegment2d_to_roundsegment: %u\n",
951 
954 #endif
955 
956  if( aStatusTextReporter )
957  {
958  // Calculation time in seconds
959  const double calculation_time = (double)( GetRunningMicroSecs() -
960  stats_startReloadTime ) / 1e6;
961 
962  aStatusTextReporter->Report( wxString::Format( _( "Reload time %.3f s" ),
963  calculation_time ) );
964  }
965 }
966 
967 
968 
969 // Based on draw3DViaHole from
970 // 3d_draw_helper_functions.cpp
972 {
973  PCB_LAYER_ID top_layer, bottom_layer;
974  int radiusBUI = (aVia->GetDrillValue() / 2);
975 
976  aVia->LayerPair( &top_layer, &bottom_layer );
977 
978  float topZ = m_settings.GetLayerBottomZpos3DU( top_layer ) +
980 
981  float botZ = m_settings.GetLayerBottomZpos3DU( bottom_layer ) -
983 
984  const SFVEC2F center = SFVEC2F( aVia->GetStart().x * m_settings.BiuTo3Dunits(),
985  -aVia->GetStart().y * m_settings.BiuTo3Dunits() );
986 
987  CRING2D *ring = new CRING2D( center,
988  radiusBUI * m_settings.BiuTo3Dunits(),
989  ( radiusBUI + m_settings.GetCopperThicknessBIU() ) *
991  *aVia );
992 
994 
995 
996  CLAYERITEM *objPtr = new CLAYERITEM( ring, topZ, botZ );
997 
998  objPtr->SetMaterial( &m_materials.m_Copper );
999 
1002  else
1004 
1005  m_object_container.Add( objPtr );
1006 }
1007 
1008 
1009 // Based on draw3DPadHole from
1010 // 3d_draw_helper_functions.cpp
1012 {
1013  const COBJECT2D *object2d_A = NULL;
1014 
1015  SFVEC3F objColor;
1016 
1018  objColor = (SFVEC3F)m_settings.m_CopperColor;
1019  else
1020  objColor = m_settings.GetItemColor( LAYER_PADS_TH );
1021 
1022  const wxSize drillsize = aPad->GetDrillSize();
1023  const bool hasHole = drillsize.x && drillsize.y;
1024 
1025  if( !hasHole )
1026  return;
1027 
1028  const float topZ = m_settings.GetLayerBottomZpos3DU( F_Cu ) +
1030 
1031  const float botZ = m_settings.GetLayerBottomZpos3DU( B_Cu ) -
1033 
1034  if( drillsize.x == drillsize.y ) // usual round hole
1035  {
1036  SFVEC2F center = SFVEC2F( aPad->GetPosition().x * m_settings.BiuTo3Dunits(),
1037  -aPad->GetPosition().y * m_settings.BiuTo3Dunits() );
1038 
1039  CRING2D *ring = new CRING2D( center,
1040  ( drillsize.x / 2 ) * m_settings.BiuTo3Dunits(),
1041  ( ( drillsize.x / 2 ) +
1044  *aPad );
1045 
1047 
1048  object2d_A = ring;
1049  }
1050  else // Oblong hole
1051  {
1052  wxPoint ends_offset;
1053  int width;
1054 
1055  if( drillsize.x > drillsize.y ) // Horizontal oval
1056  {
1057  ends_offset.x = ( drillsize.x - drillsize.y ) / 2;
1058  width = drillsize.y;
1059  }
1060  else // Vertical oval
1061  {
1062  ends_offset.y = ( drillsize.y - drillsize.x ) / 2;
1063  width = drillsize.x;
1064  }
1065 
1066  RotatePoint( &ends_offset, aPad->GetOrientation() );
1067 
1068  wxPoint start = aPad->GetPosition() + ends_offset;
1069  wxPoint end = aPad->GetPosition() - ends_offset;
1070 
1071  CROUNDSEGMENT2D *innerSeg = new CROUNDSEGMENT2D(
1072  SFVEC2F( start.x * m_settings.BiuTo3Dunits(),
1073  -start.y * m_settings.BiuTo3Dunits() ),
1074  SFVEC2F( end.x * m_settings.BiuTo3Dunits(),
1075  -end.y * m_settings.BiuTo3Dunits() ),
1076  width * m_settings.BiuTo3Dunits(),
1077  *aPad );
1078 
1079  CROUNDSEGMENT2D *outterSeg = new CROUNDSEGMENT2D(
1080  SFVEC2F( start.x * m_settings.BiuTo3Dunits(),
1081  -start.y * m_settings.BiuTo3Dunits() ),
1082  SFVEC2F( end.x * m_settings.BiuTo3Dunits(),
1083  -end.y * m_settings.BiuTo3Dunits() ),
1084  ( width + m_settings.GetCopperThicknessBIU() * 2 ) *
1086  *aPad );
1087 
1088  // NOTE: the round segment width is the "diameter", so we double the thickness
1089 
1090  std::vector<const COBJECT2D *> *object2d_B = new std::vector<const COBJECT2D *>();
1091  object2d_B->push_back( innerSeg );
1092 
1093  CITEMLAYERCSG2D *itemCSG2d = new CITEMLAYERCSG2D( outterSeg,
1094  object2d_B,
1095  CSGITEM_FULL,
1096  *aPad );
1097 
1098  m_containerWithObjectsToDelete.Add( itemCSG2d );
1099  m_containerWithObjectsToDelete.Add( innerSeg );
1100  m_containerWithObjectsToDelete.Add( outterSeg );
1101 
1102  object2d_A = itemCSG2d;
1103  }
1104 
1105 
1106  if( object2d_A )
1107  {
1108  std::vector<const COBJECT2D *> *object2d_B = new std::vector<const COBJECT2D *>();
1109 
1110  // Check if there are any other THT that intersects this hole
1111  // It will use the non inflated holes
1112  if( !m_settings.GetThroughHole_Inner().GetList().empty() )
1113  {
1114 
1115  CONST_LIST_OBJECT2D intersectionList;
1117  intersectionList );
1118 
1119  if( !intersectionList.empty() )
1120  {
1121  for( CONST_LIST_OBJECT2D::const_iterator hole = intersectionList.begin();
1122  hole != intersectionList.end();
1123  ++hole )
1124  {
1125  const COBJECT2D *hole2d = static_cast<const COBJECT2D *>(*hole);
1126 
1127  if( object2d_A->Intersects( hole2d->GetBBox() ) )
1128  //if( object2d_A->GetBBox().Intersects( hole2d->GetBBox() ) )
1129  object2d_B->push_back( hole2d );
1130  }
1131  }
1132  }
1133 
1134  if( object2d_B->empty() )
1135  {
1136  delete object2d_B;
1137  object2d_B = CSGITEM_EMPTY;
1138  }
1139 
1140  if( object2d_B == CSGITEM_EMPTY )
1141  {
1142  CLAYERITEM *objPtr = new CLAYERITEM( object2d_A, topZ, botZ );
1143 
1144  objPtr->SetMaterial( &m_materials.m_Copper );
1145  objPtr->SetColor( ConvertSRGBToLinear( objColor ) );
1146  m_object_container.Add( objPtr );
1147  }
1148  else
1149  {
1150  CITEMLAYERCSG2D *itemCSG2d = new CITEMLAYERCSG2D( object2d_A,
1151  object2d_B,
1152  CSGITEM_FULL,
1153  (const BOARD_ITEM &)*aPad );
1154 
1155  m_containerWithObjectsToDelete.Add( itemCSG2d );
1156 
1157  CLAYERITEM *objPtr = new CLAYERITEM( itemCSG2d, topZ, botZ );
1158 
1159  objPtr->SetMaterial( &m_materials.m_Copper );
1160  objPtr->SetColor( ConvertSRGBToLinear( objColor ) );
1161 
1162  m_object_container.Add( objPtr );
1163  }
1164  }
1165 }
1166 
1167 
1169 {
1170  // Insert plated vertical holes inside the board
1171  // /////////////////////////////////////////////////////////////////////////
1172 
1173  // Insert vias holes (vertical cylinders)
1174  for( const TRACK* track = m_settings.GetBoard()->m_Track;
1175  track;
1176  track = track->Next() )
1177  {
1178  if( track->Type() == PCB_VIA_T )
1179  {
1180  const VIA *via = static_cast<const VIA*>(track);
1181  insert3DViaHole( via );
1182  }
1183  }
1184 
1185  // Insert pads holes (vertical cylinders)
1186  for( const MODULE* module = m_settings.GetBoard()->m_Modules;
1187  module;
1188  module = module->Next() )
1189  {
1190  for( const D_PAD* pad = module->PadsList(); pad; pad = pad->Next() )
1191  if( pad->GetAttribute () != PAD_ATTRIB_HOLE_NOT_PLATED )
1192  {
1193  insert3DPadHole( pad );
1194  }
1195  }
1196 }
1197 
1198 
1200 {
1201  // Go for all modules
1202  for( const MODULE* module = m_settings.GetBoard()->m_Modules;
1203  module;
1204  module = module->Next() )
1205  {
1206  if( (!module->Models().empty() ) &&
1207  m_settings.ShouldModuleBeDisplayed( (MODULE_ATTR_T)module->GetAttributes() ) )
1208  {
1209  double zpos = m_settings.GetModulesZcoord3DIU( module->IsFlipped() );
1210 
1211  wxPoint pos = module->GetPosition();
1212 
1213  glm::mat4 moduleMatrix = glm::mat4( 1.0f );
1214 
1215  moduleMatrix = glm::translate( moduleMatrix,
1216  SFVEC3F( pos.x * m_settings.BiuTo3Dunits(),
1217  -pos.y * m_settings.BiuTo3Dunits(),
1218  zpos ) );
1219 
1220  if( module->GetOrientation() )
1221  {
1222  moduleMatrix = glm::rotate( moduleMatrix,
1223  ( (float)(module->GetOrientation() / 10.0f) / 180.0f ) *
1224  glm::pi<float>(),
1225  SFVEC3F( 0.0f, 0.0f, 1.0f ) );
1226  }
1227 
1228 
1229  if( module->IsFlipped() )
1230  {
1231  moduleMatrix = glm::rotate( moduleMatrix,
1232  glm::pi<float>(),
1233  SFVEC3F( 0.0f, 1.0f, 0.0f ) );
1234 
1235  moduleMatrix = glm::rotate( moduleMatrix,
1236  glm::pi<float>(),
1237  SFVEC3F( 0.0f, 0.0f, 1.0f ) );
1238  }
1239 
1240  const double modelunit_to_3d_units_factor = m_settings.BiuTo3Dunits() *
1242 
1243  moduleMatrix = glm::scale( moduleMatrix,
1244  SFVEC3F( modelunit_to_3d_units_factor,
1245  modelunit_to_3d_units_factor,
1246  modelunit_to_3d_units_factor ) );
1247 
1248 
1249  // Get the list of model files for this model
1250  auto sM = module->Models().begin();
1251  auto eM = module->Models().end();
1252 
1253  while( sM != eM )
1254  {
1255  // get it from cache
1256  const S3DMODEL *modelPtr =
1257  m_settings.Get3DCacheManager()->GetModel( sM->m_Filename );
1258 
1259  // only add it if the return is not NULL
1260  if( modelPtr )
1261  {
1262  glm::mat4 modelMatrix = moduleMatrix;
1263 
1264  modelMatrix = glm::translate( modelMatrix,
1265  SFVEC3F( sM->m_Offset.x,
1266  sM->m_Offset.y,
1267  sM->m_Offset.z ) );
1268 
1269  modelMatrix = glm::rotate( modelMatrix,
1270  (float)-( sM->m_Rotation.z / 180.0f ) *
1271  glm::pi<float>(),
1272  SFVEC3F( 0.0f, 0.0f, 1.0f ) );
1273 
1274  modelMatrix = glm::rotate( modelMatrix,
1275  (float)-( sM->m_Rotation.y / 180.0f ) *
1276  glm::pi<float>(),
1277  SFVEC3F( 0.0f, 1.0f, 0.0f ) );
1278 
1279  modelMatrix = glm::rotate( modelMatrix,
1280  (float)-( sM->m_Rotation.x / 180.0f ) *
1281  glm::pi<float>(),
1282  SFVEC3F( 1.0f, 0.0f, 0.0f ) );
1283 
1284  modelMatrix = glm::scale( modelMatrix,
1285  SFVEC3F( sM->m_Scale.x,
1286  sM->m_Scale.y,
1287  sM->m_Scale.z ) );
1288 
1289  add_3D_models( modelPtr, modelMatrix );
1290  }
1291 
1292  ++sM;
1293  }
1294  }
1295  }
1296 }
1297 
1298 
1300  const glm::mat4 &aModelMatrix )
1301 {
1302 
1303  // Validate a3DModel pointers
1304  wxASSERT( a3DModel != NULL );
1305 
1306  if( a3DModel == NULL )
1307  return;
1308 
1309  wxASSERT( a3DModel->m_Materials != NULL );
1310  wxASSERT( a3DModel->m_Meshes != NULL );
1311  wxASSERT( a3DModel->m_MaterialsSize > 0 );
1312  wxASSERT( a3DModel->m_MeshesSize > 0 );
1313 
1314  if( (a3DModel->m_Materials != NULL) && (a3DModel->m_Meshes != NULL) &&
1315  (a3DModel->m_MaterialsSize > 0) && (a3DModel->m_MeshesSize > 0) )
1316  {
1317 
1318  MODEL_MATERIALS *materialVector;
1319 
1320  // Try find if the materials already exists in the map list
1321  if( m_model_materials.find( a3DModel ) != m_model_materials.end() )
1322  {
1323  // Found it, so get the pointer
1324  materialVector = &m_model_materials[a3DModel];
1325  }
1326  else
1327  {
1328  // Materials was not found in the map, so it will create a new for
1329  // this model.
1330 
1331  m_model_materials[a3DModel] = MODEL_MATERIALS();
1332  materialVector = &m_model_materials[a3DModel];
1333 
1334  materialVector->resize( a3DModel->m_MaterialsSize );
1335 
1336  for( unsigned int imat = 0;
1337  imat < a3DModel->m_MaterialsSize;
1338  ++imat )
1339  {
1341  {
1342  const SMATERIAL &material = a3DModel->m_Materials[imat];
1343 
1344  // http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiJtaW4oc3FydCh4LTAuMzUpKjAuNDAtMC4wNSwxLjApIiwiY29sb3IiOiIjMDAwMDAwIn0seyJ0eXBlIjoxMDAwLCJ3aW5kb3ciOlsiMC4wNzA3NzM2NzMyMzY1OTAxMiIsIjEuNTY5NTcxNjI5MjI1NDY5OCIsIi0wLjI3NDYzNTMyMTc1OTkyOTMiLCIwLjY0NzcwMTg4MTkyNTUzNjIiXSwic2l6ZSI6WzY0NCwzOTRdfV0-
1345 
1346  float reflectionFactor = 0.0f;
1347 
1348  if( (material.m_Shininess - 0.35f) > FLT_EPSILON )
1349  {
1350  reflectionFactor = glm::clamp( glm::sqrt( (material.m_Shininess - 0.35f) ) *
1351  0.40f - 0.05f,
1352  0.0f,
1353  0.5f );
1354  }
1355 
1356  CBLINN_PHONG_MATERIAL &blinnMaterial = (*materialVector)[imat];
1357 
1358  SFVEC3F ambient;
1359 
1361  {
1362  // apply a gain to the (dark) ambient colors
1363 
1364  // http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIoKHgrMC4yMCleKDEvMi4wMCkpLTAuMzUiLCJjb2xvciI6IiMwMDAwMDAifSx7InR5cGUiOjAsImVxIjoieCIsImNvbG9yIjoiIzAwMDAwMCJ9LHsidHlwZSI6MTAwMCwid2luZG93IjpbIi0xLjI0OTUwNTMzOTIyMzYyIiwiMS42Nzc4MzQ0MTg1NjcxODQzIiwiLTAuNDM1NTA0NjQyODEwOTMwMjYiLCIxLjM2NTkzNTIwODEzNzI1OCJdLCJzaXplIjpbNjQ5LDM5OV19XQ--
1365  // ambient = glm::max( (glm::pow((material.m_Ambient + 0.20f), SFVEC3F(1.0f / 2.00f)) - SFVEC3F(0.35f)), material.m_Ambient );
1366 
1367  // http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIoKHgrMC4yMCleKDEvMS41OCkpLTAuMzUiLCJjb2xvciI6IiMwMDAwMDAifSx7InR5cGUiOjAsImVxIjoieCIsImNvbG9yIjoiIzAwMDAwMCJ9LHsidHlwZSI6MTAwMCwid2luZG93IjpbIi0xLjI0OTUwNTMzOTIyMzYyIiwiMS42Nzc4MzQ0MTg1NjcxODQzIiwiLTAuNDM1NTA0NjQyODEwOTMwMjYiLCIxLjM2NTkzNTIwODEzNzI1OCJdLCJzaXplIjpbNjQ5LDM5OV19XQ--
1368  //ambient = glm::max( (glm::pow((material.m_Ambient + 0.20f), SFVEC3F(1.0f / 1.58f)) - SFVEC3F(0.35f)), material.m_Ambient );
1369 
1370  // http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIoKHgrMC4yMCleKDEvMS41NCkpLTAuMzQiLCJjb2xvciI6IiMwMDAwMDAifSx7InR5cGUiOjAsImVxIjoieCIsImNvbG9yIjoiIzAwMDAwMCJ9LHsidHlwZSI6MTAwMCwid2luZG93IjpbIi0yLjcyMTA5NTg0MjA1MDYwNSIsIjEuODUyODcyNTI5NDk3NTIyMyIsIi0xLjQyMTM3NjAxOTkyOTA4MDYiLCIxLjM5MzM3Mzc0NzE3NzQ2MTIiXSwic2l6ZSI6WzY0OSwzOTldfV0-
1371  ambient = ConvertSRGBToLinear(
1372  glm::pow((material.m_Ambient + 0.30f), SFVEC3F(1.0f / 1.54f)) - SFVEC3F(0.34f) );
1373  }
1374  else
1375  {
1376  ambient = ConvertSRGBToLinear( material.m_Ambient );
1377  }
1378 
1379 
1380  blinnMaterial = CBLINN_PHONG_MATERIAL(
1381  ambient,
1382  ConvertSRGBToLinear( material.m_Emissive ),
1383  ConvertSRGBToLinear( material.m_Specular ),
1384  material.m_Shininess * 180.0f,
1385  material.m_Transparency,
1386  reflectionFactor );
1387 
1389  {
1390  // Guess material type and apply a normal perturbator
1391 
1392  if( ( RGBtoGray(material.m_Diffuse) < 0.3f ) &&
1393  ( material.m_Shininess < 0.36f ) &&
1394  ( material.m_Transparency == 0.0f ) &&
1395  ( (glm::abs( material.m_Diffuse.r - material.m_Diffuse.g ) < 0.15f) &&
1396  (glm::abs( material.m_Diffuse.b - material.m_Diffuse.g ) < 0.15f) &&
1397  (glm::abs( material.m_Diffuse.r - material.m_Diffuse.b ) < 0.15f) ) )
1398  {
1399  // This may be a black plastic..
1400 
1401  if( material.m_Shininess < 0.26f )
1403  else
1405  }
1406  else
1407  {
1408  if( ( RGBtoGray(material.m_Diffuse) > 0.3f ) &&
1409  ( material.m_Shininess < 0.30f ) &&
1410  ( material.m_Transparency == 0.0f ) &&
1411  ( (glm::abs( material.m_Diffuse.r - material.m_Diffuse.g ) > 0.25f) ||
1412  (glm::abs( material.m_Diffuse.b - material.m_Diffuse.g ) > 0.25f) ||
1413  (glm::abs( material.m_Diffuse.r - material.m_Diffuse.b ) > 0.25f) ) )
1414  {
1415  // This may be a color plastic ...
1417  }
1418  else
1419  {
1420  if( ( RGBtoGray(material.m_Diffuse) > 0.6f ) &&
1421  ( material.m_Shininess > 0.35f ) &&
1422  ( material.m_Transparency == 0.0f ) &&
1423  ( (glm::abs( material.m_Diffuse.r - material.m_Diffuse.g ) < 0.40f) &&
1424  (glm::abs( material.m_Diffuse.b - material.m_Diffuse.g ) < 0.40f) &&
1425  (glm::abs( material.m_Diffuse.r - material.m_Diffuse.b ) < 0.40f) ) )
1426  {
1427  // This may be a brushed metal
1429  }
1430  }
1431  }
1432  }
1433  }
1434  else
1435  {
1436  (*materialVector)[imat] = CBLINN_PHONG_MATERIAL( SFVEC3F( 0.2f ),
1437  SFVEC3F( 0.0f ),
1438  SFVEC3F( 0.0f ),
1439  0.0f,
1440  0.0f,
1441  0.0f );
1442  }
1443  }
1444  }
1445 
1446  const glm::mat3 normalMatrix = glm::transpose( glm::inverse( glm::mat3( aModelMatrix ) ) );
1447 
1448  for( unsigned int mesh_i = 0;
1449  mesh_i < a3DModel->m_MeshesSize;
1450  ++mesh_i )
1451  {
1452  const SMESH &mesh = a3DModel->m_Meshes[mesh_i];
1453 
1454  // Validate the mesh pointers
1455  wxASSERT( mesh.m_Positions != NULL );
1456  wxASSERT( mesh.m_FaceIdx != NULL );
1457  wxASSERT( mesh.m_Normals != NULL );
1458  wxASSERT( mesh.m_FaceIdxSize > 0 );
1459  wxASSERT( (mesh.m_FaceIdxSize % 3) == 0 );
1460 
1461 
1462  if( (mesh.m_Positions != NULL) &&
1463  (mesh.m_Normals != NULL) &&
1464  (mesh.m_FaceIdx != NULL) &&
1465  (mesh.m_FaceIdxSize > 0) &&
1466  (mesh.m_VertexSize > 0) &&
1467  ((mesh.m_FaceIdxSize % 3) == 0) &&
1468  (mesh.m_MaterialIdx < a3DModel->m_MaterialsSize) )
1469  {
1470  const CBLINN_PHONG_MATERIAL &blinn_material = (*materialVector)[mesh.m_MaterialIdx];
1471 
1472  // Add all face triangles
1473  for( unsigned int faceIdx = 0;
1474  faceIdx < mesh.m_FaceIdxSize;
1475  faceIdx += 3 )
1476  {
1477  const unsigned int idx0 = mesh.m_FaceIdx[faceIdx + 0];
1478  const unsigned int idx1 = mesh.m_FaceIdx[faceIdx + 1];
1479  const unsigned int idx2 = mesh.m_FaceIdx[faceIdx + 2];
1480 
1481  wxASSERT( idx0 < mesh.m_VertexSize );
1482  wxASSERT( idx1 < mesh.m_VertexSize );
1483  wxASSERT( idx2 < mesh.m_VertexSize );
1484 
1485  if( ( idx0 < mesh.m_VertexSize ) &&
1486  ( idx1 < mesh.m_VertexSize ) &&
1487  ( idx2 < mesh.m_VertexSize ) )
1488  {
1489  const SFVEC3F &v0 = mesh.m_Positions[idx0];
1490  const SFVEC3F &v1 = mesh.m_Positions[idx1];
1491  const SFVEC3F &v2 = mesh.m_Positions[idx2];
1492 
1493  const SFVEC3F &n0 = mesh.m_Normals[idx0];
1494  const SFVEC3F &n1 = mesh.m_Normals[idx1];
1495  const SFVEC3F &n2 = mesh.m_Normals[idx2];
1496 
1497  // Transform vertex with the model matrix
1498  const SFVEC3F vt0 = SFVEC3F( aModelMatrix * glm::vec4( v0, 1.0f) );
1499  const SFVEC3F vt1 = SFVEC3F( aModelMatrix * glm::vec4( v1, 1.0f) );
1500  const SFVEC3F vt2 = SFVEC3F( aModelMatrix * glm::vec4( v2, 1.0f) );
1501 
1502  const SFVEC3F nt0 = glm::normalize( SFVEC3F( normalMatrix * n0 ) );
1503  const SFVEC3F nt1 = glm::normalize( SFVEC3F( normalMatrix * n1 ) );
1504  const SFVEC3F nt2 = glm::normalize( SFVEC3F( normalMatrix * n2 ) );
1505 
1506  CTRIANGLE *newTriangle = new CTRIANGLE( vt0, vt2, vt1,
1507  nt0, nt2, nt1 );
1508 
1509 
1510 
1511  m_object_container.Add( newTriangle );
1512  newTriangle->SetMaterial( (const CMATERIAL *)&blinn_material );
1513 
1514  if( mesh.m_Color == NULL )
1515  {
1516  const SFVEC3F diffuseColor =
1517  a3DModel->m_Materials[mesh.m_MaterialIdx].m_Diffuse;
1518 
1520  newTriangle->SetColor( ConvertSRGBToLinear( MaterialDiffuseToColorCAD( diffuseColor ) ) );
1521  else
1522  newTriangle->SetColor( ConvertSRGBToLinear( diffuseColor ) );
1523  }
1524  else
1525  {
1527  newTriangle->SetColor( ConvertSRGBToLinear( MaterialDiffuseToColorCAD( mesh.m_Color[idx0] ) ),
1530  else
1531  newTriangle->SetColor( ConvertSRGBToLinear( mesh.m_Color[idx0] ),
1532  ConvertSRGBToLinear( mesh.m_Color[idx1] ),
1533  ConvertSRGBToLinear( mesh.m_Color[idx2] ) );
1534  }
1535  }
1536  }
1537  }
1538  }
1539  }
1540 }
std::map< PCB_LAYER_ID, CBVHCONTAINER2D * > MAP_CONTAINER_2D
A type that stores a container of 2d objects for each layer id.
Definition: cinfo3d_visu.h:55
D_PAD * Next() const
Definition: class_pad.h:160
void GetListObjectsIntersects(const CBBOX2D &aBBox, CONST_LIST_OBJECT2D &aOutList) const override
GetListObjectsIntersects - Get a list of objects that intersects a bbox.
SFVEC3F * m_Normals
Vertex normals array.
Definition: c3dmodel.h:80
struct C3D_RENDER_RAYTRACING::@37 m_materials
void LayerPair(PCB_LAYER_ID *top_layer, PCB_LAYER_ID *bottom_layer) const
Function LayerPair Return the 2 layers used by the via (the via actually uses all layers between thes...
float RGBtoGray(const SFVEC3F &aColor)
Definition: 3d_math.h:147
const CBBOX & GetBBox() const
Definition: ccontainer.h:67
SFVEC3F m_Ambient
Definition: c3dmodel.h:39
unsigned int GetStats_Nr_Holes() const
GetStats_Nr_Holes - Get statistics of the nr of holes.
Definition: cinfo3d_visu.h:368
Defines math related functions.
CPLASTICNORMAL m_plastic_normal_perturbator
SFVEC3F ConvertSRGBToLinear(const SFVEC3F &aSRGBcolor)
OBJECT2D_TYPE GetObjectType() const
Definition: cobject2d.h:125
const LIST_OBJECT & GetList() const
Definition: ccontainer.h:63
float GetStats_Med_Via_Hole_Diameter3DU() const
GetStats_Med_Via_Hole_Diameter3DU - Average diameter of the via holes.
Definition: cinfo3d_visu.h:374
CBOARDNORMAL m_board_normal_perturbator
Directional light - a light based only on a direction vector.
Definition: clight.h:114
like PAD_STANDARD, but not plated mechanical use only, no connection allowed
Definition: pad_shapes.h:65
multilayer pads, usually with holes
void PrintStats()
Definition: cobject2d.cpp:60
Implementation of conversion functions that require both schematic and board internal units...
Class BOARD_ITEM is a base class for any item which can be embedded within the BOARD container class...
const SFVEC2F & Min() const
Function Min return the minimun vertex pointer.
Definition: cbbox2d.h:176
A base material class that can be used to derive a material implementation.
Definition: cmaterial.h:167
SFVEC3D m_CopperColor
in realistic mode: copper color
Definition: cinfo3d_visu.h:509
const wxPoint & GetStart() const
Definition: class_track.h:126
CCOPPERNORMAL m_copper_normal_perturbator
const MAP_CONTAINER_2D & GetMapLayers() const
GetMapLayers - Get the map of container that have the objects per layer.
Definition: cinfo3d_visu.h:293
Class BOARD to handle a board.
void create_3d_object_from(CCONTAINER &aDstContainer, const COBJECT2D *aObject2D, float aZMin, float aZMax, const CMATERIAL *aMaterial, const SFVEC3F &aObjColor)
Function create_3d_object_from.
std::list< const COBJECT2D * > CONST_LIST_OBJECT2D
Definition: ccontainer2d.h:38
void SetMaterial(const CMATERIAL *aMaterial)
Definition: cobject.h:62
A dummy block is used to fill the polygons.
Definition: cdummyblock.h:39
const MAP_CONTAINER_2D & GetMapLayersHoles() const
GetMapLayersHoles -Get the map of container that have the holes per layer.
Definition: cinfo3d_visu.h:299
void insert3DViaHole(const VIA *aVia)
#define RANGE_SCALE_3D
This defines the range that all coord will have to be rendered.
Definition: cinfo3d_visu.h:63
CPLASTICSHINENORMAL m_plastic_shine_normal_perturbator
void SetColor(SFVEC3F aObjColor)
Definition: croundseg.h:48
float m_Transparency
1.0 is completely transparent, 0.0 completely opaque
Definition: c3dmodel.h:44
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:216
Class REPORTER is a pure virtual class used to derive REPORTER objects from.
Definition: reporter.h:61
void PrintStats()
Definition: cobject.cpp:57
void SetNormalPerturbator(const CPROCEDURALGENERATOR *aPerturbator)
Definition: cmaterial.h:220
SFVEC3F * m_Positions
Vertex position array.
Definition: c3dmodel.h:79
CMETALBRUSHEDNORMAL m_brushed_metal_normal_perturbator
CINFO3D_VISU & m_settings
settings refrence in use for this render
#define abs(a)
Definition: auxiliary.h:84
#define UNITS3D_TO_UNITSPCB
Scale convertion from 3d model units to pcb units.
SFVEC3D m_BgColorTop
background top color
Definition: cinfo3d_visu.h:504
Per-vertex normal/color/texcoors structure.
Definition: c3dmodel.h:76
SMESH * m_Meshes
The meshes list of this model.
Definition: c3dmodel.h:93
SFVEC3F GetLayerColor(PCB_LAYER_ID aLayerId) const
GetLayerColor - get the technical color of a layer.
float GetLayerBottomZpos3DU(PCB_LAYER_ID aLayerId) const
GetLayerBottomZpos3DU - Get the bottom z position.
Definition: cinfo3d_visu.h:287
bool GetFlag(DISPLAY3D_FLG aFlag) const
GetFlag - get a configuration status of a flag.
A plane that is parallel to XY plane.
Definition: cplane.h:38
SFVEC3D m_BoardBodyColor
in realistic mode: FR4 board color
Definition: cinfo3d_visu.h:505
unsigned int m_stats_converted_dummy_to_plane
double BiuTo3Dunits() const
BiuTo3Dunits - Board integer units To 3D units.
Definition: cinfo3d_visu.h:141
S3DMODEL * GetModel(const wxString &aModelFileName)
Function GetModel attempts to load the scene data for a model and to translate it into an S3D_MODEL s...
Definition: 3d_cache.cpp:725
const SFVEC3F & GetBoardCenter3DU() const
GetBoardCenter - the board center position in 3d units.
Definition: cinfo3d_visu.h:189
unsigned int m_FaceIdxSize
Number of elements of the m_FaceIdx array.
Definition: c3dmodel.h:83
SFVEC3F GetItemColor(int aItemId) const
GetItemColor - get the technical color of a layer.
#define CSGITEM_EMPTY
This class is used to make constructive solig geometry for items objects on layers.
const SHAPE_POLY_SET & GetBoardPoly() const
GetBoardPoly - Get the current polygon of the epoxy board.
Definition: cinfo3d_visu.h:252
MATERIAL_MODE MaterialModeGet() const
MaterialModeGet.
Definition: cinfo3d_visu.h:246
std::vector< CBLINN_PHONG_MATERIAL > MODEL_MATERIALS
Vector of materials.
SFVEC3F GetCenter() const
Function GetCenter return the center point of the bounding box.
Definition: cbbox.cpp:135
CGENERICACCELERATOR * m_accelerator
const BOARD * GetBoard() const
GetBoard - Get current board to be rendered.
Definition: cinfo3d_visu.h:128
void SetColor(const SFVEC3F &aColor)
Definition: ctriangle.cpp:161
unsigned int m_VertexSize
Number of vertex in the arrays.
Definition: c3dmodel.h:78
const BOARD_ITEM & GetBoardItem() const
Definition: cobject2d.h:75
PCB_LAYER_ID
A quick note on layer IDs:
void SetColor(SFVEC3F aObjColor)
Definition: ccylinder.h:51
void SetColor(SFVEC3F aObjColor)
Definition: cplane.h:52
CCAMERA & CameraGet() const
CameraGet - get current camera in use.
Definition: cinfo3d_visu.h:210
glm::vec2 SFVEC2F
Definition: xv3d_types.h:45
int GetCopperThicknessBIU() const
GetCopperThicknessBIU - Get the current copper layer thickness.
float NextFloatDown(float v)
Definition: 3d_fastmath.h:157
int GetDrillValue() const
Function GetDrillValue "calculates" the drill value for vias (m-Drill if > 0, or default drill value ...
Class SHAPE_POLY_SET.
S3D_CACHE * Get3DCacheManager() const
Get3DCacheManager - Return the 3d cache manager pointer.
Definition: cinfo3d_visu.h:88
unsigned int GetStats_Nr_Vias() const
GetStats_Nr_Vias - Get statistics of the nr of vias.
Definition: cinfo3d_visu.h:362
Blinn Phong based material https://en.wikipedia.org/wiki/Blinn%E2%80%93Phong_shading_model.
Definition: cmaterial.h:248
const CBBOX & GetBBox3DU() const
GetBBox3DU - Get the bbox of the pcb board.
Definition: cinfo3d_visu.h:147
SFVEC3F * m_Color
Vertex color array, can be NULL.
Definition: c3dmodel.h:82
Use a gray shading based on diffuse material.
Definition: 3d_enums.h:94
VIATYPE_T GetViaType() const
Definition: class_track.h:461
CCONTAINER2D m_containerWithObjectsToDelete
This will store the list of created objects special for RT, that will be clear in the end...
void Add(CLIGHT *aLight)
Add - Add a light to the container.
Definition: clight.h:186
Point light based on: http://ogldev.atspace.co.uk/www/tutorial20/tutorial20.html. ...
Definition: clight.h:67
MODULE_ATTR_T
Enum MODULE_ATTR_T is the set of attributes allowed within a MODULE, using MODULE::SetAttributes() an...
Definition: class_module.h:73
float GetLayerTopZpos3DU(PCB_LAYER_ID aLayerId) const
GetLayerTopZpos3DU - Get the top z position.
Definition: cinfo3d_visu.h:280
unsigned int m_stats_converted_roundsegment2d_to_roundsegment
float m_Shininess
Definition: c3dmodel.h:43
const SFVEC2F & Max() const
Function Max return the maximum vertex pointer.
Definition: cbbox2d.h:183
#define CSGITEM_FULL
void SetColor(SFVEC3F aObjColor)
Definition: clayeritem.h:46
unsigned int m_MaterialsSize
Number of materials in the material array.
Definition: c3dmodel.h:95
SFVEC3D m_SolderPasteColor
in realistic mode: solder paste color
Definition: cinfo3d_visu.h:507
A triangle object.
Definition: ctriangle.h:42
CDIRECTIONALLIGHT * m_camera_light
void Add(COBJECT *aObject)
Definition: ccontainer.h:52
SFVEC3D m_SolderMaskColor
in realistic mode: solder mask color
Definition: cinfo3d_visu.h:506
void Fracture(POLYGON_MODE aFastMode)
Converts a set of polygons with holes to a singe outline with "slits"/"fractures" connecting the oute...
static COBJECT2D_STATS & Instance()
Definition: cobject2d.h:146
void Scale(float aScale)
Function Scale scales a bounding box by its center.
Definition: cbbox.cpp:194
A vertical cylinder.
Definition: ccylinder.h:38
const SFVEC3F & Min() const
Function Min return the minimun vertex pointer.
Definition: cbbox.h:205
const CBVHCONTAINER2D & GetThroughHole_Inner() const
GetThroughHole_Inner - Get the ThroughHole container.
Definition: cinfo3d_visu.h:350
void add_3D_models(const S3DMODEL *a3DModel, const glm::mat4 &aModelMatrix)
const CBVHCONTAINER2D & GetThroughHole_Outer() const
GetThroughHole_Outer - Get the inflated ThroughHole container.
Definition: cinfo3d_visu.h:305
void ResetStats()
Definition: cobject.h:106
void Add(COBJECT2D *aObject)
Definition: ccontainer2d.h:52
Use all material properties from model file.
Definition: 3d_enums.h:92
SFVEC3D m_SilkScreenColor
in realistic mode: SilkScreen color
Definition: cinfo3d_visu.h:508
Implements a triangle ray intersection based on article http://www.flipcode.com/archives/Raytracing_T...
CSOLDERMASKNORMAL m_solder_mask_normal_perturbator
const int scale
TRACK * Next() const
Definition: class_track.h:103
SFVEC2F GetExtent() const
Function GetExtent.
Definition: cbbox2d.cpp:127
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
bool m_reloadRequested
!TODO: this must be reviewed in order to flag change types
SFVEC3F MaterialDiffuseToColorCAD(const SFVEC3F &aDiffuseColor)
Definition: 3d_math.h:154
std::list< COBJECT2D * > LIST_OBJECT2D
Definition: ccontainer2d.h:37
DLIST< MODULE > m_Modules
Definition: class_board.h:249
unsigned GetRunningMicroSecs()
Function GetRunningMicroSecs An alternate way to calculate an elapset time (in microsecondes) to clas...
SFVEC3F m_Emissive
Definition: c3dmodel.h:41
glm::vec3 SFVEC3F
Definition: xv3d_types.h:47
double GetOrientation() const
Function GetOrientation returns the rotation angle of the pad in tenths of degrees, but soon degrees.
Definition: class_pad.h:389
float GetCopperThickness3DU() const
GetCopperThickness3DU - Get the current copper layer thickness.
Definition: cinfo3d_visu.h:165
unsigned int m_MaterialIdx
Material Index to be used in this mesh (must be < m_MaterialsSize )
Definition: c3dmodel.h:85
float NextFloatUp(float v)
Definition: 3d_fastmath.h:136
void SetBoardLookAtPos(const SFVEC3F &aBoardPos)
Definition: ccamera.h:115
static COBJECT3D_STATS & Instance()
Definition: cobject.h:116
SMATERIAL * m_Materials
The materials list of this model.
Definition: c3dmodel.h:96
void SetCastShadows(bool aCastShadow)
Definition: clight.h:57
const wxSize & GetDrillSize() const
Definition: class_pad.h:275
SFVEC3F SphericalToCartesian(float aInclination, float aAzimuth)
SphericalToCartesian.
Definition: 3d_math.h:43
void ResetStats()
Definition: cobject2d.h:135
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_UNDEFINED)=0
Function Report is a pure virtual function to override in the derived object.
Defines math related functions.
SFVEC3F m_Diffuse
Default diffuse color if m_Color is NULL.
Definition: c3dmodel.h:40
MODULE * Next() const
Definition: class_module.h:122
CCONTAINER2D * m_outlineBoard2dObjects
const SFVEC2F & GetCentroid() const
Definition: cobject2d.h:123
const CBBOX2D & GetBBox() const
Definition: cobject2d.h:121
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:96
Store the a model based on meshes and materials.
Definition: c3dmodel.h:90
DLIST< TRACK > m_Track
Definition: class_board.h:250
Module description (excepted pads)
unsigned int * m_FaceIdx
Triangle Face Indexes.
Definition: c3dmodel.h:84
void insert3DPadHole(const D_PAD *aPad)
bool ShouldModuleBeDisplayed(MODULE_ATTR_T aModuleAttributs) const
ShouldModuleBeDisplayed - Test if module should be displayed in relation to attributs and the flags...
const wxPoint GetPosition() const override
Definition: class_pad.h:220
const LIST_OBJECT2D & GetList() const
Definition: ccontainer2d.h:64
void Clear()
Clear - Remove all lights from the container.
Definition: clight.h:165
unsigned int m_MeshesSize
Number of meshes in the array.
Definition: c3dmodel.h:92
virtual bool Intersects(const CBBOX2D &aBBox) const =0
Function Intersects.
Class CBBOX manages a bounding box defined by two SFVEC3F min max points.
Definition: cbbox.h:40
MAP_MODEL_MATERIALS m_model_materials
Stores materials of the 3D models.
float GetModulesZcoord3DIU(bool aIsFlipped) const
GetModulesZcoord3DIU - Get the position of the module in 3d integer units considering if it is flippe...
float GetStats_Med_Hole_Diameter3DU() const
GetStats_Med_Hole_Diameter3DU - Average diameter of holes.
Definition: cinfo3d_visu.h:380
This BVH implementation is based on the source code implementation from the book "Physically Based Re...
bool IsInitialized() const
Function IsInitialized check if this bounding box is already initialized.
Definition: cbbox.cpp:87
SFVEC3F m_Specular
Definition: c3dmodel.h:42
#define min(a, b)
Definition: auxiliary.h:85
void InitSettings(REPORTER *aStatusTextReporter)
InitSettings - Function to be called by the render when it need to reload the settings for the board...
void Convert_path_polygon_to_polygon_blocks_and_dummy_blocks(const SHAPE_POLY_SET &aMainPath, CGENERICCONTAINER2D &aDstContainer, float aBiuTo3DunitsScale, float aDivFactor, const BOARD_ITEM &aBoardItem)
Convert_path_polygon_to_polygon_blocks_and_dummy_blocks This function will use a polygon in the forma...
Definition: cpolygon2d.cpp:406
void reload(REPORTER *aStatusTextReporter)