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 an other 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 
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 
921  //m_accelerator = new CGRID( m_object_container );
923 
924 #ifdef PRINT_STATISTICS_3D_VIEWER
925  unsigned stats_endAcceleratorTime = GetRunningMicroSecs();
926 #endif
927 
928  setupMaterials();
929 
930 #ifdef PRINT_STATISTICS_3D_VIEWER
931  printf( "C3D_RENDER_RAYTRACING::reload times:\n" );
932  printf( " Reload board: %.3f ms\n", (float)( stats_endReloadTime -
933  stats_startReloadTime ) /
934 
935  1000.0f );
936  printf( " Convert to 3D objects: %.3f ms\n", (float)( stats_endConvertTime -
937  stats_startConvertTime ) /
938  1000.0f );
939  printf( " Accelerator construction: %.3f ms\n", (float)( stats_endAcceleratorTime -
940  stats_startAcceleratorTime ) /
941  1000.0f );
942  printf( " Load and add 3D models: %.3f ms\n", (float)( stats_endLoad3DmodelsTime -
943  stats_startLoad3DmodelsTime ) /
944  1000.0f );
945  printf( "Optimizations\n" );
946 
947  printf( " m_stats_converted_dummy_to_plane: %u\n",
949 
950  printf( " m_stats_converted_roundsegment2d_to_roundsegment: %u\n",
952 
955 #endif
956 
957  if( aStatusTextReporter )
958  {
959  // Calculation time in seconds
960  const double calculation_time = (double)( GetRunningMicroSecs() -
961  stats_startReloadTime ) / 1e6;
962 
963  aStatusTextReporter->Report( wxString::Format( _( "Reload time %.3f s" ),
964  calculation_time ) );
965  }
966 }
967 
968 
969 
970 // Based on draw3DViaHole from
971 // 3d_draw_helper_functions.cpp
973 {
974  PCB_LAYER_ID top_layer, bottom_layer;
975  int radiusBUI = (aVia->GetDrillValue() / 2);
976 
977  aVia->LayerPair( &top_layer, &bottom_layer );
978 
979  float topZ = m_settings.GetLayerBottomZpos3DU( top_layer ) +
981 
982  float botZ = m_settings.GetLayerBottomZpos3DU( bottom_layer ) -
984 
985  const SFVEC2F center = SFVEC2F( aVia->GetStart().x * m_settings.BiuTo3Dunits(),
986  -aVia->GetStart().y * m_settings.BiuTo3Dunits() );
987 
988  CRING2D *ring = new CRING2D( center,
989  radiusBUI * m_settings.BiuTo3Dunits(),
990  ( radiusBUI + m_settings.GetCopperThicknessBIU() ) *
992  *aVia );
993 
995 
996 
997  CLAYERITEM *objPtr = new CLAYERITEM( ring, topZ, botZ );
998 
999  objPtr->SetMaterial( &m_materials.m_Copper );
1000 
1003  else
1005 
1006  m_object_container.Add( objPtr );
1007 }
1008 
1009 
1010 // Based on draw3DPadHole from
1011 // 3d_draw_helper_functions.cpp
1013 {
1014  const COBJECT2D *object2d_A = NULL;
1015 
1016  SFVEC3F objColor;
1017 
1019  objColor = (SFVEC3F)m_settings.m_CopperColor;
1020  else
1021  objColor = m_settings.GetItemColor( LAYER_PADS );
1022 
1023  const wxSize drillsize = aPad->GetDrillSize();
1024  const bool hasHole = drillsize.x && drillsize.y;
1025 
1026  if( !hasHole )
1027  return;
1028 
1029  const float topZ = m_settings.GetLayerBottomZpos3DU( F_Cu ) +
1031 
1032  const float botZ = m_settings.GetLayerBottomZpos3DU( B_Cu ) -
1034 
1035  if( drillsize.x == drillsize.y ) // usual round hole
1036  {
1037  SFVEC2F center = SFVEC2F( aPad->GetPosition().x * m_settings.BiuTo3Dunits(),
1038  -aPad->GetPosition().y * m_settings.BiuTo3Dunits() );
1039 
1040  CRING2D *ring = new CRING2D( center,
1041  ( drillsize.x / 2 ) * m_settings.BiuTo3Dunits(),
1042  ( ( drillsize.x / 2 ) +
1045  *aPad );
1046 
1048 
1049  object2d_A = ring;
1050  }
1051  else // Oblong hole
1052  {
1053  wxPoint ends_offset;
1054  int width;
1055 
1056  if( drillsize.x > drillsize.y ) // Horizontal oval
1057  {
1058  ends_offset.x = ( drillsize.x - drillsize.y ) / 2;
1059  width = drillsize.y;
1060  }
1061  else // Vertical oval
1062  {
1063  ends_offset.y = ( drillsize.y - drillsize.x ) / 2;
1064  width = drillsize.x;
1065  }
1066 
1067  RotatePoint( &ends_offset, aPad->GetOrientation() );
1068 
1069  wxPoint start = aPad->GetPosition() + ends_offset;
1070  wxPoint end = aPad->GetPosition() - ends_offset;
1071 
1072  CROUNDSEGMENT2D *innerSeg = new CROUNDSEGMENT2D(
1073  SFVEC2F( start.x * m_settings.BiuTo3Dunits(),
1074  -start.y * m_settings.BiuTo3Dunits() ),
1075  SFVEC2F( end.x * m_settings.BiuTo3Dunits(),
1076  -end.y * m_settings.BiuTo3Dunits() ),
1077  width * m_settings.BiuTo3Dunits(),
1078  *aPad );
1079 
1080  CROUNDSEGMENT2D *outterSeg = new CROUNDSEGMENT2D(
1081  SFVEC2F( start.x * m_settings.BiuTo3Dunits(),
1082  -start.y * m_settings.BiuTo3Dunits() ),
1083  SFVEC2F( end.x * m_settings.BiuTo3Dunits(),
1084  -end.y * m_settings.BiuTo3Dunits() ),
1085  ( width + m_settings.GetCopperThicknessBIU() * 2 ) *
1087  *aPad );
1088 
1089  // NOTE: the round segment width is the "diameter", so we double the thickness
1090 
1091  std::vector<const COBJECT2D *> *object2d_B = new std::vector<const COBJECT2D *>();
1092  object2d_B->push_back( innerSeg );
1093 
1094  CITEMLAYERCSG2D *itemCSG2d = new CITEMLAYERCSG2D( outterSeg,
1095  object2d_B,
1096  CSGITEM_FULL,
1097  *aPad );
1098 
1099  m_containerWithObjectsToDelete.Add( itemCSG2d );
1100  m_containerWithObjectsToDelete.Add( innerSeg );
1101  m_containerWithObjectsToDelete.Add( outterSeg );
1102 
1103  object2d_A = itemCSG2d;
1104  }
1105 
1106 
1107  if( object2d_A )
1108  {
1109  std::vector<const COBJECT2D *> *object2d_B = new std::vector<const COBJECT2D *>();
1110 
1111  // Check if there are any other THT that intersects this hole
1112  // It will use the non inflated holes
1113  if( !m_settings.GetThroughHole_Inner().GetList().empty() )
1114  {
1115 
1116  CONST_LIST_OBJECT2D intersectionList;
1118  intersectionList );
1119 
1120  if( !intersectionList.empty() )
1121  {
1122  for( CONST_LIST_OBJECT2D::const_iterator hole = intersectionList.begin();
1123  hole != intersectionList.end();
1124  ++hole )
1125  {
1126  const COBJECT2D *hole2d = static_cast<const COBJECT2D *>(*hole);
1127 
1128  if( object2d_A->Intersects( hole2d->GetBBox() ) )
1129  //if( object2d_A->GetBBox().Intersects( hole2d->GetBBox() ) )
1130  object2d_B->push_back( hole2d );
1131  }
1132  }
1133  }
1134 
1135  if( object2d_B->empty() )
1136  {
1137  delete object2d_B;
1138  object2d_B = CSGITEM_EMPTY;
1139  }
1140 
1141  if( object2d_B == CSGITEM_EMPTY )
1142  {
1143  CLAYERITEM *objPtr = new CLAYERITEM( object2d_A, topZ, botZ );
1144 
1145  objPtr->SetMaterial( &m_materials.m_Copper );
1146  objPtr->SetColor( ConvertSRGBToLinear( objColor ) );
1147  m_object_container.Add( objPtr );
1148  }
1149  else
1150  {
1151  CITEMLAYERCSG2D *itemCSG2d = new CITEMLAYERCSG2D( object2d_A,
1152  object2d_B,
1153  CSGITEM_FULL,
1154  (const BOARD_ITEM &)*aPad );
1155 
1156  m_containerWithObjectsToDelete.Add( itemCSG2d );
1157 
1158  CLAYERITEM *objPtr = new CLAYERITEM( itemCSG2d, topZ, botZ );
1159 
1160  objPtr->SetMaterial( &m_materials.m_Copper );
1161  objPtr->SetColor( ConvertSRGBToLinear( objColor ) );
1162 
1163  m_object_container.Add( objPtr );
1164  }
1165  }
1166 }
1167 
1168 
1170 {
1171  // Insert plated vertical holes inside the board
1172  // /////////////////////////////////////////////////////////////////////////
1173 
1174  // Insert vias holes (vertical cylinders)
1175  for( const TRACK* track = m_settings.GetBoard()->m_Track;
1176  track;
1177  track = track->Next() )
1178  {
1179  if( track->Type() == PCB_VIA_T )
1180  {
1181  const VIA *via = static_cast<const VIA*>(track);
1182  insert3DViaHole( via );
1183  }
1184  }
1185 
1186  // Insert pads holes (vertical cylinders)
1187  for( const MODULE* module = m_settings.GetBoard()->m_Modules;
1188  module;
1189  module = module->Next() )
1190  {
1191  for( const D_PAD* pad = module->PadsList(); pad; pad = pad->Next() )
1192  if( pad->GetAttribute () != PAD_ATTRIB_HOLE_NOT_PLATED )
1193  {
1194  insert3DPadHole( pad );
1195  }
1196  }
1197 }
1198 
1199 
1201 {
1202  // Go for all modules
1203  for( const MODULE* module = m_settings.GetBoard()->m_Modules;
1204  module;
1205  module = module->Next() )
1206  {
1207  if( (!module->Models().empty() ) &&
1208  m_settings.ShouldModuleBeDisplayed( (MODULE_ATTR_T)module->GetAttributes() ) )
1209  {
1210  double zpos = m_settings.GetModulesZcoord3DIU( module->IsFlipped() );
1211 
1212  wxPoint pos = module->GetPosition();
1213 
1214  glm::mat4 moduleMatrix = glm::mat4();
1215 
1216  moduleMatrix = glm::translate( moduleMatrix,
1217  SFVEC3F( pos.x * m_settings.BiuTo3Dunits(),
1218  -pos.y * m_settings.BiuTo3Dunits(),
1219  zpos ) );
1220 
1221  if( module->GetOrientation() )
1222  {
1223  moduleMatrix = glm::rotate( moduleMatrix,
1224  ( (float)(module->GetOrientation() / 10.0f) / 180.0f ) *
1225  glm::pi<float>(),
1226  SFVEC3F( 0.0f, 0.0f, 1.0f ) );
1227  }
1228 
1229 
1230  if( module->IsFlipped() )
1231  {
1232  moduleMatrix = glm::rotate( moduleMatrix,
1233  glm::pi<float>(),
1234  SFVEC3F( 0.0f, 1.0f, 0.0f ) );
1235 
1236  moduleMatrix = glm::rotate( moduleMatrix,
1237  glm::pi<float>(),
1238  SFVEC3F( 0.0f, 0.0f, 1.0f ) );
1239  }
1240 
1241  const double modelunit_to_3d_units_factor = m_settings.BiuTo3Dunits() *
1243 
1244  moduleMatrix = glm::scale( moduleMatrix,
1245  SFVEC3F( modelunit_to_3d_units_factor,
1246  modelunit_to_3d_units_factor,
1247  modelunit_to_3d_units_factor ) );
1248 
1249 
1250  // Get the list of model files for this model
1251  std::list<S3D_INFO>::const_iterator sM = module->Models().begin();
1252  std::list<S3D_INFO>::const_iterator eM = module->Models().end();
1253 
1254  while( sM != eM )
1255  {
1256  // get it from cache
1257  const S3DMODEL *modelPtr =
1258  m_settings.Get3DCacheManager()->GetModel( sM->m_Filename );
1259 
1260  // only add it if the return is not NULL
1261  if( modelPtr )
1262  {
1263  glm::mat4 modelMatrix = moduleMatrix;
1264 
1265  modelMatrix = glm::translate( modelMatrix,
1266  SFVEC3F( sM->m_Offset.x * 25.4f,
1267  sM->m_Offset.y * 25.4f,
1268  sM->m_Offset.z * 25.4f ) );
1269 
1270  modelMatrix = glm::rotate( modelMatrix,
1271  (float)-( sM->m_Rotation.z / 180.0f ) *
1272  glm::pi<float>(),
1273  SFVEC3F( 0.0f, 0.0f, 1.0f ) );
1274 
1275  modelMatrix = glm::rotate( modelMatrix,
1276  (float)-( sM->m_Rotation.y / 180.0f ) *
1277  glm::pi<float>(),
1278  SFVEC3F( 0.0f, 1.0f, 0.0f ) );
1279 
1280  modelMatrix = glm::rotate( modelMatrix,
1281  (float)-( sM->m_Rotation.x / 180.0f ) *
1282  glm::pi<float>(),
1283  SFVEC3F( 1.0f, 0.0f, 0.0f ) );
1284 
1285  modelMatrix = glm::scale( modelMatrix,
1286  SFVEC3F( sM->m_Scale.x,
1287  sM->m_Scale.y,
1288  sM->m_Scale.z ) );
1289 
1290  add_3D_models( modelPtr, modelMatrix );
1291  }
1292 
1293  ++sM;
1294  }
1295  }
1296  }
1297 }
1298 
1299 
1301  const glm::mat4 &aModelMatrix )
1302 {
1303 
1304  // Validate a3DModel pointers
1305  wxASSERT( a3DModel != NULL );
1306 
1307  if( a3DModel == NULL )
1308  return;
1309 
1310  wxASSERT( a3DModel->m_Materials != NULL );
1311  wxASSERT( a3DModel->m_Meshes != NULL );
1312  wxASSERT( a3DModel->m_MaterialsSize > 0 );
1313  wxASSERT( a3DModel->m_MeshesSize > 0 );
1314 
1315  if( (a3DModel->m_Materials != NULL) && (a3DModel->m_Meshes != NULL) &&
1316  (a3DModel->m_MaterialsSize > 0) && (a3DModel->m_MeshesSize > 0) )
1317  {
1318 
1319  MODEL_MATERIALS *materialVector;
1320 
1321  // Try find if the materials already exists in the map list
1322  if( m_model_materials.find( a3DModel ) != m_model_materials.end() )
1323  {
1324  // Found it, so get the pointer
1325  materialVector = &m_model_materials[a3DModel];
1326  }
1327  else
1328  {
1329  // Materials was not found in the map, so it will create a new for
1330  // this model.
1331 
1332  m_model_materials[a3DModel] = MODEL_MATERIALS();
1333  materialVector = &m_model_materials[a3DModel];
1334 
1335  materialVector->resize( a3DModel->m_MaterialsSize );
1336 
1337  for( unsigned int imat = 0;
1338  imat < a3DModel->m_MaterialsSize;
1339  ++imat )
1340  {
1342  {
1343  const SMATERIAL &material = a3DModel->m_Materials[imat];
1344 
1345  // http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiJtaW4oc3FydCh4LTAuMzUpKjAuNDAtMC4wNSwxLjApIiwiY29sb3IiOiIjMDAwMDAwIn0seyJ0eXBlIjoxMDAwLCJ3aW5kb3ciOlsiMC4wNzA3NzM2NzMyMzY1OTAxMiIsIjEuNTY5NTcxNjI5MjI1NDY5OCIsIi0wLjI3NDYzNTMyMTc1OTkyOTMiLCIwLjY0NzcwMTg4MTkyNTUzNjIiXSwic2l6ZSI6WzY0NCwzOTRdfV0-
1346 
1347  float reflectionFactor = 0.0f;
1348 
1349  if( (material.m_Shininess - 0.35f) > FLT_EPSILON )
1350  {
1351  reflectionFactor = glm::clamp( glm::sqrt( (material.m_Shininess - 0.35f) ) *
1352  0.40f - 0.05f,
1353  0.0f,
1354  0.5f );
1355  }
1356 
1357  CBLINN_PHONG_MATERIAL &blinnMaterial = (*materialVector)[imat];
1358 
1359  SFVEC3F ambient;
1360 
1362  {
1363  // apply a gain to the (dark) ambient colors
1364 
1365  // http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIoKHgrMC4yMCleKDEvMi4wMCkpLTAuMzUiLCJjb2xvciI6IiMwMDAwMDAifSx7InR5cGUiOjAsImVxIjoieCIsImNvbG9yIjoiIzAwMDAwMCJ9LHsidHlwZSI6MTAwMCwid2luZG93IjpbIi0xLjI0OTUwNTMzOTIyMzYyIiwiMS42Nzc4MzQ0MTg1NjcxODQzIiwiLTAuNDM1NTA0NjQyODEwOTMwMjYiLCIxLjM2NTkzNTIwODEzNzI1OCJdLCJzaXplIjpbNjQ5LDM5OV19XQ--
1366  // ambient = glm::max( (glm::pow((material.m_Ambient + 0.20f), SFVEC3F(1.0f / 2.00f)) - SFVEC3F(0.35f)), material.m_Ambient );
1367 
1368  // http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIoKHgrMC4yMCleKDEvMS41OCkpLTAuMzUiLCJjb2xvciI6IiMwMDAwMDAifSx7InR5cGUiOjAsImVxIjoieCIsImNvbG9yIjoiIzAwMDAwMCJ9LHsidHlwZSI6MTAwMCwid2luZG93IjpbIi0xLjI0OTUwNTMzOTIyMzYyIiwiMS42Nzc4MzQ0MTg1NjcxODQzIiwiLTAuNDM1NTA0NjQyODEwOTMwMjYiLCIxLjM2NTkzNTIwODEzNzI1OCJdLCJzaXplIjpbNjQ5LDM5OV19XQ--
1369  //ambient = glm::max( (glm::pow((material.m_Ambient + 0.20f), SFVEC3F(1.0f / 1.58f)) - SFVEC3F(0.35f)), material.m_Ambient );
1370 
1371  // http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIoKHgrMC4yMCleKDEvMS41NCkpLTAuMzQiLCJjb2xvciI6IiMwMDAwMDAifSx7InR5cGUiOjAsImVxIjoieCIsImNvbG9yIjoiIzAwMDAwMCJ9LHsidHlwZSI6MTAwMCwid2luZG93IjpbIi0yLjcyMTA5NTg0MjA1MDYwNSIsIjEuODUyODcyNTI5NDk3NTIyMyIsIi0xLjQyMTM3NjAxOTkyOTA4MDYiLCIxLjM5MzM3Mzc0NzE3NzQ2MTIiXSwic2l6ZSI6WzY0OSwzOTldfV0-
1372  ambient = ConvertSRGBToLinear(
1373  glm::pow((material.m_Ambient + 0.30f), SFVEC3F(1.0f / 1.54f)) - SFVEC3F(0.34f) );
1374  }
1375  else
1376  {
1377  ambient = ConvertSRGBToLinear( material.m_Ambient );
1378  }
1379 
1380 
1381  blinnMaterial = CBLINN_PHONG_MATERIAL(
1382  ambient,
1383  ConvertSRGBToLinear( material.m_Emissive ),
1384  ConvertSRGBToLinear( material.m_Specular ),
1385  material.m_Shininess * 180.0f,
1386  material.m_Transparency,
1387  reflectionFactor );
1388 
1390  {
1391  // Guess material type and apply a normal perturbator
1392 
1393  if( ( RGBtoGray(material.m_Diffuse) < 0.3f ) &&
1394  ( material.m_Shininess < 0.36f ) &&
1395  ( material.m_Transparency == 0.0f ) &&
1396  ( (glm::abs( material.m_Diffuse.r - material.m_Diffuse.g ) < 0.15f) &&
1397  (glm::abs( material.m_Diffuse.b - material.m_Diffuse.g ) < 0.15f) &&
1398  (glm::abs( material.m_Diffuse.r - material.m_Diffuse.b ) < 0.15f) ) )
1399  {
1400  // This may be a black plastic..
1401 
1402  if( material.m_Shininess < 0.26f )
1404  else
1406  }
1407  else
1408  {
1409  if( ( RGBtoGray(material.m_Diffuse) > 0.3f ) &&
1410  ( material.m_Shininess < 0.30f ) &&
1411  ( material.m_Transparency == 0.0f ) &&
1412  ( (glm::abs( material.m_Diffuse.r - material.m_Diffuse.g ) > 0.25f) ||
1413  (glm::abs( material.m_Diffuse.b - material.m_Diffuse.g ) > 0.25f) ||
1414  (glm::abs( material.m_Diffuse.r - material.m_Diffuse.b ) > 0.25f) ) )
1415  {
1416  // This may be a color plastic ...
1418  }
1419  else
1420  {
1421  if( ( RGBtoGray(material.m_Diffuse) > 0.6f ) &&
1422  ( material.m_Shininess > 0.35f ) &&
1423  ( material.m_Transparency == 0.0f ) &&
1424  ( (glm::abs( material.m_Diffuse.r - material.m_Diffuse.g ) < 0.40f) &&
1425  (glm::abs( material.m_Diffuse.b - material.m_Diffuse.g ) < 0.40f) &&
1426  (glm::abs( material.m_Diffuse.r - material.m_Diffuse.b ) < 0.40f) ) )
1427  {
1428  // This may be a brushed metal
1430  }
1431  }
1432  }
1433  }
1434  }
1435  else
1436  {
1437  (*materialVector)[imat] = CBLINN_PHONG_MATERIAL( SFVEC3F( 0.2f ),
1438  SFVEC3F( 0.0f ),
1439  SFVEC3F( 0.0f ),
1440  0.0f,
1441  0.0f,
1442  0.0f );
1443  }
1444  }
1445  }
1446 
1447  const glm::mat3 normalMatrix = glm::transpose( glm::inverse( glm::mat3( aModelMatrix ) ) );
1448 
1449  for( unsigned int mesh_i = 0;
1450  mesh_i < a3DModel->m_MeshesSize;
1451  ++mesh_i )
1452  {
1453  const SMESH &mesh = a3DModel->m_Meshes[mesh_i];
1454 
1455  // Validate the mesh pointers
1456  wxASSERT( mesh.m_Positions != NULL );
1457  wxASSERT( mesh.m_FaceIdx != NULL );
1458  wxASSERT( mesh.m_Normals != NULL );
1459  wxASSERT( mesh.m_FaceIdxSize > 0 );
1460  wxASSERT( (mesh.m_FaceIdxSize % 3) == 0 );
1461 
1462 
1463  if( (mesh.m_Positions != NULL) &&
1464  (mesh.m_Normals != NULL) &&
1465  (mesh.m_FaceIdx != NULL) &&
1466  (mesh.m_FaceIdxSize > 0) &&
1467  (mesh.m_VertexSize > 0) &&
1468  ((mesh.m_FaceIdxSize % 3) == 0) &&
1469  (mesh.m_MaterialIdx < a3DModel->m_MaterialsSize) )
1470  {
1471  const CBLINN_PHONG_MATERIAL &blinn_material = (*materialVector)[mesh.m_MaterialIdx];
1472 
1473  // Add all face triangles
1474  for( unsigned int faceIdx = 0;
1475  faceIdx < mesh.m_FaceIdxSize;
1476  faceIdx += 3 )
1477  {
1478  const unsigned int idx0 = mesh.m_FaceIdx[faceIdx + 0];
1479  const unsigned int idx1 = mesh.m_FaceIdx[faceIdx + 1];
1480  const unsigned int idx2 = mesh.m_FaceIdx[faceIdx + 2];
1481 
1482  wxASSERT( idx0 < mesh.m_VertexSize );
1483  wxASSERT( idx1 < mesh.m_VertexSize );
1484  wxASSERT( idx2 < mesh.m_VertexSize );
1485 
1486  if( ( idx0 < mesh.m_VertexSize ) &&
1487  ( idx1 < mesh.m_VertexSize ) &&
1488  ( idx2 < mesh.m_VertexSize ) )
1489  {
1490  const SFVEC3F &v0 = mesh.m_Positions[idx0];
1491  const SFVEC3F &v1 = mesh.m_Positions[idx1];
1492  const SFVEC3F &v2 = mesh.m_Positions[idx2];
1493 
1494  const SFVEC3F &n0 = mesh.m_Normals[idx0];
1495  const SFVEC3F &n1 = mesh.m_Normals[idx1];
1496  const SFVEC3F &n2 = mesh.m_Normals[idx2];
1497 
1498  // Transform vertex with the model matrix
1499  const SFVEC3F vt0 = SFVEC3F( aModelMatrix * glm::vec4( v0, 1.0f) );
1500  const SFVEC3F vt1 = SFVEC3F( aModelMatrix * glm::vec4( v1, 1.0f) );
1501  const SFVEC3F vt2 = SFVEC3F( aModelMatrix * glm::vec4( v2, 1.0f) );
1502 
1503  const SFVEC3F nt0 = glm::normalize( SFVEC3F( normalMatrix * n0 ) );
1504  const SFVEC3F nt1 = glm::normalize( SFVEC3F( normalMatrix * n1 ) );
1505  const SFVEC3F nt2 = glm::normalize( SFVEC3F( normalMatrix * n2 ) );
1506 
1507  CTRIANGLE *newTriangle = new CTRIANGLE( vt0, vt2, vt1,
1508  nt0, nt2, nt1 );
1509 
1510 
1511 
1512  m_object_container.Add( newTriangle );
1513  newTriangle->SetMaterial( (const CMATERIAL *)&blinn_material );
1514 
1515  if( mesh.m_Color == NULL )
1516  {
1517  const SFVEC3F diffuseColor =
1518  a3DModel->m_Materials[mesh.m_MaterialIdx].m_Diffuse;
1519 
1521  newTriangle->SetColor( ConvertSRGBToLinear( MaterialDiffuseToColorCAD( diffuseColor ) ) );
1522  else
1523  newTriangle->SetColor( ConvertSRGBToLinear( diffuseColor ) );
1524  }
1525  else
1526  {
1528  newTriangle->SetColor( ConvertSRGBToLinear( MaterialDiffuseToColorCAD( mesh.m_Color[idx0] ) ),
1531  else
1532  newTriangle->SetColor( ConvertSRGBToLinear( mesh.m_Color[idx0] ),
1533  ConvertSRGBToLinear( mesh.m_Color[idx1] ),
1534  ConvertSRGBToLinear( mesh.m_Color[idx2] ) );
1535  }
1536  }
1537  }
1538  }
1539  }
1540  }
1541 }
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
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
const LIST_OBJECT2D & GetList() const
Definition: ccontainer2d.h:62
SFVEC3F GetLayerColor(PCB_LAYER_ID aLayerId) const
GetLayerColor - get the technical color of a layer.
float RGBtoGray(const SFVEC3F &aColor)
Definition: 3d_math.h:147
S3D_CACHE * Get3DCacheManager() const
Get3DCacheManager - Return the 3d cache manager pointer.
Definition: cinfo3d_visu.h:88
SFVEC3F m_Ambient
Definition: c3dmodel.h:39
Defines math related functions.
CPLASTICNORMAL m_plastic_normal_perturbator
SFVEC3F ConvertSRGBToLinear(const SFVEC3F &aSRGBcolor)
CBOARDNORMAL m_board_normal_perturbator
float GetCopperThickness3DU() const
GetCopperThickness3DU - Get the current copper layer thickness.
Definition: cinfo3d_visu.h:165
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:63
MATERIAL_MODE MaterialModeGet() const
MaterialModeGet.
Definition: cinfo3d_visu.h:246
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...
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 SHAPE_POLY_SET & GetBoardPoly() const
GetBoardPoly - Get the current polygon of the epoxy board.
Definition: cinfo3d_visu.h:252
SFVEC3F GetItemColor(int aItemId) const
GetItemColor - get the technical color of a layer.
CCOPPERNORMAL m_copper_normal_perturbator
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:37
MODULE * Next() const
Definition: class_module.h:100
const BOARD_ITEM & GetBoardItem() const
Definition: cobject2d.h:75
const SFVEC3F & Min() const
Function Min return the minimun vertex pointer.
Definition: cbbox.h:205
void SetMaterial(const CMATERIAL *aMaterial)
Definition: cobject.h:62
A dummy block is used to fill the polygons.
Definition: cdummyblock.h:39
bool IsInitialized() const
Function IsInitialized check if this bounding box is already initialized.
Definition: cbbox.cpp:87
int GetCopperThicknessBIU() const
GetCopperThicknessBIU - Get the current copper layer thickness.
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:317
const wxSize & GetDrillSize() const
Definition: class_pad.h:188
Class REPORTER is a pure virtual class used to derive REPORTER objects from.
Definition: reporter.h:61
float GetStats_Med_Via_Hole_Diameter3DU() const
GetStats_Med_Via_Hole_Diameter3DU - Average diameter of the via holes.
Definition: cinfo3d_visu.h:374
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.
float GetLayerTopZpos3DU(PCB_LAYER_ID aLayerId) const
GetLayerTopZpos3DU - Get the top z position.
Definition: cinfo3d_visu.h:280
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
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
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:781
unsigned int m_FaceIdxSize
Number of elements of the m_FaceIdx array.
Definition: c3dmodel.h:83
#define CSGITEM_EMPTY
This class is used to make constructive solig geometry for items objects on layers.
std::vector< CBLINN_PHONG_MATERIAL > MODEL_MATERIALS
Vector of materials.
CGENERICACCELERATOR * m_accelerator
void SetColor(const SFVEC3F &aColor)
Definition: ctriangle.cpp:161
const MAP_CONTAINER_2D & GetMapLayersHoles() const
GetMapLayersHoles -Get the map of container that have the holes per layer.
Definition: cinfo3d_visu.h:299
unsigned int m_VertexSize
Number of vertex in the arrays.
Definition: c3dmodel.h:78
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
glm::vec2 SFVEC2F
Definition: xv3d_types.h:45
const SFVEC3F & GetBoardCenter3DU() const
GetBoardCenter - the board center position in 3d units.
Definition: cinfo3d_visu.h:189
VIATYPE_T GetViaType() const
Definition: class_track.h:439
float NextFloatDown(float v)
Definition: 3d_fastmath.h:157
float GetLayerBottomZpos3DU(PCB_LAYER_ID aLayerId) const
GetLayerBottomZpos3DU - Get the bottom z position.
Definition: cinfo3d_visu.h:287
Class SHAPE_POLY_SET.
const wxPoint & GetStart() const
Definition: class_track.h:121
const wxPoint & GetPosition() const override
Definition: class_pad.h:170
multilayer pads, usually with holes
Blinn Phong based material https://en.wikipedia.org/wiki/Blinn%E2%80%93Phong_shading_model.
Definition: cmaterial.h:248
D_PAD * Next() const
Definition: class_pad.h:106
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:95
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
OBJECT2D_TYPE GetObjectType() const
Definition: cobject2d.h:125
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:74
unsigned int m_stats_converted_roundsegment2d_to_roundsegment
float m_Shininess
Definition: c3dmodel.h:43
#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
const CBBOX & GetBBox() const
Definition: ccontainer.h:67
const CBVHCONTAINER2D & GetThroughHole_Inner() const
GetThroughHole_Inner - Get the ThroughHole container.
Definition: cinfo3d_visu.h:350
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
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...
SFVEC3F GetCenter() const
Function GetCenter return the center point of the bounding box.
Definition: cbbox.cpp:135
void add_3D_models(const S3DMODEL *a3DModel, const glm::mat4 &aModelMatrix)
struct C3D_RENDER_RAYTRACING::@35 m_materials
float GetModulesZcoord3DIU(bool aIsFlipped) const
GetModulesZcoord3DIU - Get the position of the module in 3d integer units considering if it is flippe...
void ResetStats()
Definition: cobject.h:106
void Add(COBJECT2D *aObject)
Definition: ccontainer2d.h:51
Use all material properties from model file.
Definition: 3d_enums.h:93
bool GetFlag(DISPLAY3D_FLG aFlag) const
GetFlag - get a configuration status of a flag.
const SFVEC2F & GetCentroid() const
Definition: cobject2d.h:123
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:98
bool ShouldModuleBeDisplayed(MODULE_ATTR_T aModuleAttributs) const
ShouldModuleBeDisplayed - Test if module should be displayed in relation to attributs and the flags...
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
int GetDrillValue() const
Function GetDrillValue "calculates" the drill value for vias (m-Drill if > 0, or default drill value ...
SFVEC3F MaterialDiffuseToColorCAD(const SFVEC3F &aDiffuseColor)
Definition: 3d_math.h:154
std::list< COBJECT2D * > LIST_OBJECT2D
Definition: ccontainer2d.h:36
DLIST< MODULE > m_Modules
Definition: class_board.h:245
CCAMERA & CameraGet() const
CameraGet - get current camera in use.
Definition: cinfo3d_visu.h:210
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
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
double GetOrientation() const
Function GetOrientation returns the rotation angle of the pad in tenths of degrees, but soon degrees.
Definition: class_pad.h:214
SFVEC3F SphericalToCartesian(float aInclination, float aAzimuth)
SphericalToCartesian.
Definition: 3d_math.h:43
void ResetStats()
Definition: cobject2d.h:135
unsigned int GetStats_Nr_Vias() const
GetStats_Nr_Vias - Get statistics of the nr of vias.
Definition: cinfo3d_visu.h:362
const CBBOX2D & GetBBox() const
Definition: cobject2d.h:121
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
CCONTAINER2D * m_outlineBoard2dObjects
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:108
Store the a model based on meshes and materials.
Definition: c3dmodel.h:90
DLIST< TRACK > m_Track
Definition: class_board.h:246
Module description (excepted pads)
const CBVHCONTAINER2D & GetThroughHole_Outer() const
GetThroughHole_Outer - Get the inflated ThroughHole container.
Definition: cinfo3d_visu.h:305
unsigned int * m_FaceIdx
Triangle Face Indexes.
Definition: c3dmodel.h:84
void insert3DPadHole(const D_PAD *aPad)
const SFVEC2F & Min() const
Function Min return the minimun vertex pointer.
Definition: cbbox2d.h:176
float GetStats_Med_Hole_Diameter3DU() const
GetStats_Med_Hole_Diameter3DU - Average diameter of holes.
Definition: cinfo3d_visu.h:380
void Clear()
Clear - Remove all lights from the container.
Definition: clight.h:165
SFVEC2F GetExtent() const
Function GetExtent.
Definition: cbbox2d.cpp:127
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.
const BOARD * GetBoard() const
GetBoard - Get current board to be rendered.
Definition: cinfo3d_visu.h:128
This BVH implementation is based on the source code implementation from the book "Physically Based Re...
const SFVEC2F & Max() const
Function Max return the maximum vertex pointer.
Definition: cbbox2d.h:183
double BiuTo3Dunits() const
BiuTo3Dunits - Board integer units To 3D units.
Definition: cinfo3d_visu.h:141
const LIST_OBJECT & GetList() const
Definition: ccontainer.h:63
SFVEC3F m_Specular
Definition: c3dmodel.h:42
const MAP_CONTAINER_2D & GetMapLayers() const
GetMapLayers - Get the map of container that have the objects per layer.
Definition: cinfo3d_visu.h:293
#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
unsigned int GetStats_Nr_Holes() const
GetStats_Nr_Holes - Get statistics of the nr of holes.
Definition: cinfo3d_visu.h:368
const CBBOX & GetBBox3DU() const
GetBBox3DU - Get the bbox of the pcb board.
Definition: cinfo3d_visu.h:147
void reload(REPORTER *aStatusTextReporter)