KiCad PCB EDA Suite
RENDER_3D_RAYTRACE Class Reference

#include <render_3d_raytrace.h>

Inheritance diagram for RENDER_3D_RAYTRACE:
RENDER_3D_BASE

Public Member Functions

 RENDER_3D_RAYTRACE (EDA_3D_CANVAS *aCanvas, BOARD_ADAPTER &aAdapter, CAMERA &aCamera)
 
 ~RENDER_3D_RAYTRACE ()
 
void SetCurWindowSize (const wxSize &aSize) override
 Before each render, the canvas will tell the render what is the size of its windows, so render can take actions if it changed. More...
 
bool Redraw (bool aIsMoving, REPORTER *aStatusReporter, REPORTER *aWarningReporter) override
 Redraw the view. More...
 
int GetWaitForEditingTimeOut () override
 Give the interface the time (in ms) that it should wait for editing or movements before (this works for display preview mode). More...
 
void Reload (REPORTER *aStatusReporter, REPORTER *aWarningReporter, bool aOnlyLoadCopperAndShapes)
 
BOARD_ITEMIntersectBoardItem (const RAY &aRay)
 
void ReloadRequest ()
 
bool IsReloadRequestPending () const
 Query if there is a pending reload request. More...
 
void SetBusyIndicatorFactory (BUSY_INDICATOR::FACTORY aNewFactory)
 Set a new busy indicator factory. More...
 

Static Public Attributes

static constexpr float MIN_DISTANCE_IU = 4 * PCB_IU_PER_MM
 

Protected Member Functions

std::unique_ptr< BUSY_INDICATORCreateBusyIndicator () const
 Return a created busy indicator, if a factory has been set, else a null pointer. More...
 

Protected Attributes

EDA_3D_CANVASm_canvas
 Settings reference in use for this render. More...
 
BOARD_ADAPTERm_boardAdapter
 
CAMERAm_camera
 Flag if the opengl specific for this render was already initialized. More...
 
bool m_is_opengl_initialized
 
bool m_reloadRequested
 The window size that this camera is working. More...
 
wxSize m_windowSize
 

Static Protected Attributes

static const wxChar * m_logTrace = wxT( "KI_TRACE_3D_RENDER" )
 Trace mask used to enable or disable the trace output of this class. More...
 

Private Member Functions

bool initializeOpenGL ()
 
void initializeNewWindowSize ()
 
void initPbo ()
 
void deletePbo ()
 
void createItemsFromContainer (const BVH_CONTAINER_2D *aContainer2d, PCB_LAYER_ID aLayer_id, const MATERIAL *aMaterialLayer, const SFVEC3F &aLayerColor, float aLayerZOffset)
 
void restartRenderState ()
 
void renderTracing (GLubyte *ptrPBO, REPORTER *aStatusReporter)
 
void postProcessShading (GLubyte *ptrPBO, REPORTER *aStatusReporter)
 
void postProcessBlurFinish (GLubyte *ptrPBO, REPORTER *aStatusReporter)
 
void renderBlockTracing (GLubyte *ptrPBO, signed int iBlock)
 
void renderFinalColor (GLubyte *ptrPBO, const SFVEC3F &rgbColor, bool applyColorSpaceConversion)
 
void renderRayPackets (const SFVEC3F *bgColorY, const RAY *aRayPkt, HITINFO_PACKET *aHitPacket, bool is_testShadow, SFVEC3F *aOutHitColor)
 
void renderAntiAliasPackets (const SFVEC3F *aBgColorY, const HITINFO_PACKET *aHitPck_X0Y0, const HITINFO_PACKET *aHitPck_AA_X1Y1, const RAY *aRayPck, SFVEC3F *aOutHitColor)
 
void setupMaterials ()
 
SFVEC3F shadeHit (const SFVEC3F &aBgColor, const RAY &aRay, HITINFO &aHitInfo, bool aIsInsideObject, unsigned int aRecursiveLevel, bool is_testShadow) const
 
void createObject (CONTAINER_3D &aDstContainer, const OBJECT_2D *aObject2D, float aZMin, float aZMax, const MATERIAL *aMaterial, const SFVEC3F &aObjColor)
 Create one or more 3D objects form a 2D object and Z positions. More...
 
void addPadsAndVias ()
 
void insertHole (const PCB_VIA *aVia)
 
void insertHole (const PAD *aPad)
 
void load3DModels (CONTAINER_3D &aDstContainer, bool aSkipMaterialInformation)
 
void addModels (CONTAINER_3D &aDstContainer, const S3DMODEL *a3DModel, const glm::mat4 &aModelMatrix, float aFPOpacity, bool aSkipMaterialInformation, BOARD_ITEM *aBoardItem)
 
MODEL_MATERIALSgetModelMaterial (const S3DMODEL *a3DModel)
 
void initializeBlockPositions ()
 
void render (GLubyte *ptrPBO, REPORTER *aStatusReporter)
 
void renderPreview (GLubyte *ptrPBO)
 

Private Attributes

struct {
   BLINN_PHONG_MATERIAL   m_Paste
 
   BLINN_PHONG_MATERIAL   m_SilkS
 
   BLINN_PHONG_MATERIAL   m_SolderMask
 
   BLINN_PHONG_MATERIAL   m_EpoxyBoard
 
   BLINN_PHONG_MATERIAL   m_Copper
 
   BLINN_PHONG_MATERIAL   m_NonPlatedCopper
 
   BLINN_PHONG_MATERIAL   m_Floor
 
m_materials
 
BOARD_NORMAL m_boardMaterial
 
COPPER_NORMAL m_copperMaterial
 
PLATED_COPPER_NORMAL m_platedCopperMaterial
 
SOLDER_MASK_NORMAL m_solderMaskMaterial
 
PLASTIC_NORMAL m_plasticMaterial
 
PLASTIC_SHINE_NORMAL m_shinyPlasticMaterial
 
BRUSHED_METAL_NORMAL m_brushedMetalMaterial
 
SILK_SCREEN_NORMAL m_silkScreenMaterial
 
bool m_isPreview
 
RT_RENDER_STATE m_renderState
 State used on quality render. More...
 
unsigned long int m_renderStartTime
 Time that the render starts. More...
 
size_t m_blockRenderProgressCount
 Save the number of blocks progress of the render. More...
 
POST_SHADER_SSAO m_postShaderSsao
 
std::list< LIGHT * > m_lights
 
DIRECTIONAL_LIGHTm_cameraLight
 
bool m_openglSupportsVertexBufferObjects
 
GLuint m_pboId
 
GLuint m_pboDataSize
 
CONTAINER_3D m_objectContainer
 Store the list of created objects special for RT that will be clear in the end. More...
 
CONTAINER_2D m_containerWithObjectsToDelete
 
CONTAINER_2Dm_outlineBoard2dObjects
 
BVH_CONTAINER_2Dm_antioutlineBoard2dObjects
 
ACCELERATOR_3Dm_accelerator
 
SFVEC3F m_backgroundColorTop
 
SFVEC3F m_backgroundColorBottom
 Used to see if the windows size changed. More...
 
wxSize m_oldWindowsSize
 Encode Morton code positions. More...
 
std::vector< SFVEC2UIm_blockPositions
 Flag if a position was already processed (cleared each new render). More...
 
std::vector< int > m_blockPositionsWasProcessed
 Encode the Morton code positions (on fast preview mode). More...
 
std::vector< SFVEC2UIm_blockPositionsFast
 
SFVEC2UI m_realBufferSize
 
SFVEC2UI m_fastPreviewModeSize
 
HITINFO_PACKETm_firstHitinfo
 
SFVEC3Fm_shaderBuffer
 
unsigned int m_xoffset
 
unsigned int m_yoffset
 
MAP_MODEL_MATERIALS m_modelMaterialMap
 Stores materials of the 3D models. More...
 
unsigned int m_convertedDummyBlockCount
 
unsigned int m_converted2dRoundSegmentCount
 
BUSY_INDICATOR::FACTORY m_busyIndicatorFactory
 < Factory that returns a suitable busy indicator for the context. More...
 

Detailed Description

Definition at line 55 of file render_3d_raytrace.h.

Constructor & Destructor Documentation

◆ RENDER_3D_RAYTRACE()

RENDER_3D_RAYTRACE::RENDER_3D_RAYTRACE ( EDA_3D_CANVAS aCanvas,
BOARD_ADAPTER aAdapter,
CAMERA aCamera 
)
explicit

Definition at line 43 of file render_3d_raytrace.cpp.

43 :
44 RENDER_3D_BASE( aCanvas, aAdapter, aCamera ),
45 m_postShaderSsao( aCamera )
46{
47 wxLogTrace( m_logTrace, wxT( "RENDER_3D_RAYTRACE::RENDER_3D_RAYTRACE" ) );
48
50 m_pboId = GL_NONE;
51 m_pboDataSize = 0;
52 m_accelerator = nullptr;
55 m_oldWindowsSize.x = 0;
56 m_oldWindowsSize.y = 0;
59 m_firstHitinfo = nullptr;
60 m_shaderBuffer = nullptr;
61 m_cameraLight = nullptr;
62
63 m_xoffset = 0;
64 m_yoffset = 0;
65
66 m_isPreview = false;
67 m_renderState = RT_RENDER_STATE_MAX; // Set to an initial invalid state
70}
RENDER_3D_BASE(EDA_3D_CANVAS *aCanvas, BOARD_ADAPTER &aBoardAdapter, CAMERA &aCamera)
DIRECTIONAL_LIGHT * m_cameraLight
unsigned int m_converted2dRoundSegmentCount
HITINFO_PACKET * m_firstHitinfo
POST_SHADER_SSAO m_postShaderSsao
unsigned long int m_renderStartTime
Time that the render starts.
CONTAINER_2D * m_outlineBoard2dObjects
wxSize m_oldWindowsSize
Encode Morton code positions.
ACCELERATOR_3D * m_accelerator
unsigned int m_convertedDummyBlockCount
size_t m_blockRenderProgressCount
Save the number of blocks progress of the render.
RT_RENDER_STATE m_renderState
State used on quality render.
BVH_CONTAINER_2D * m_antioutlineBoard2dObjects
static const wxChar * m_logTrace
Trace mask used to enable or disable the trace output of this class.
@ RT_RENDER_STATE_MAX

References m_accelerator, m_antioutlineBoard2dObjects, m_blockRenderProgressCount, m_cameraLight, m_converted2dRoundSegmentCount, m_convertedDummyBlockCount, m_firstHitinfo, m_isPreview, RENDER_3D_BASE::m_logTrace, m_oldWindowsSize, m_openglSupportsVertexBufferObjects, m_outlineBoard2dObjects, m_pboDataSize, m_pboId, m_renderStartTime, m_renderState, m_shaderBuffer, m_xoffset, m_yoffset, and RT_RENDER_STATE_MAX.

◆ ~RENDER_3D_RAYTRACE()

RENDER_3D_RAYTRACE::~RENDER_3D_RAYTRACE ( )

Definition at line 73 of file render_3d_raytrace.cpp.

74{
75 wxLogTrace( m_logTrace, wxT( "RENDER_3D_RAYTRACE::~RENDER_3D_RAYTRACE" ) );
76
77 delete m_accelerator;
78 m_accelerator = nullptr;
79
82
85
86 delete[] m_shaderBuffer;
87 m_shaderBuffer = nullptr;
88
89 deletePbo();
90}

References deletePbo(), m_accelerator, m_antioutlineBoard2dObjects, RENDER_3D_BASE::m_logTrace, m_outlineBoard2dObjects, and m_shaderBuffer.

Member Function Documentation

◆ addModels()

void RENDER_3D_RAYTRACE::addModels ( CONTAINER_3D aDstContainer,
const S3DMODEL a3DModel,
const glm::mat4 &  aModelMatrix,
float  aFPOpacity,
bool  aSkipMaterialInformation,
BOARD_ITEM aBoardItem 
)
private

Definition at line 1424 of file raytracing/create_scene.cpp.

1427{
1428 // Validate a3DModel pointers
1429 wxASSERT( a3DModel != nullptr );
1430
1431 if( a3DModel == nullptr )
1432 return;
1433
1434 wxASSERT( a3DModel->m_Materials != nullptr );
1435 wxASSERT( a3DModel->m_Meshes != nullptr );
1436 wxASSERT( a3DModel->m_MaterialsSize > 0 );
1437 wxASSERT( a3DModel->m_MeshesSize > 0 );
1438 wxASSERT( aFPOpacity > 0.0f );
1439 wxASSERT( aFPOpacity <= 1.0f );
1440
1441 if( aFPOpacity > 1.0f )
1442 {
1443 aFPOpacity = 1.0f;
1444 }
1445
1446 if( ( a3DModel->m_Materials != nullptr ) && ( a3DModel->m_Meshes != nullptr )
1447 && ( a3DModel->m_MaterialsSize > 0 ) && ( a3DModel->m_MeshesSize > 0 ) )
1448 {
1449 MODEL_MATERIALS* materialVector = nullptr;
1450
1451 if( !aSkipMaterialInformation )
1452 {
1453 materialVector = getModelMaterial( a3DModel );
1454 }
1455
1456 const glm::mat3 normalMatrix = glm::transpose( glm::inverse( glm::mat3( aModelMatrix ) ) );
1457
1458 for( unsigned int mesh_i = 0; mesh_i < a3DModel->m_MeshesSize; ++mesh_i )
1459 {
1460 const SMESH& mesh = a3DModel->m_Meshes[mesh_i];
1461
1462 // Validate the mesh pointers
1463 wxASSERT( mesh.m_Positions != nullptr );
1464 wxASSERT( mesh.m_FaceIdx != nullptr );
1465 wxASSERT( mesh.m_Normals != nullptr );
1466 wxASSERT( mesh.m_FaceIdxSize > 0 );
1467 wxASSERT( ( mesh.m_FaceIdxSize % 3 ) == 0 );
1468
1469
1470 if( ( mesh.m_Positions != nullptr ) && ( mesh.m_Normals != nullptr )
1471 && ( mesh.m_FaceIdx != nullptr ) && ( mesh.m_FaceIdxSize > 0 )
1472 && ( mesh.m_VertexSize > 0 ) && ( ( mesh.m_FaceIdxSize % 3 ) == 0 )
1473 && ( mesh.m_MaterialIdx < a3DModel->m_MaterialsSize ) )
1474 {
1475 float fpTransparency;
1476 const BLINN_PHONG_MATERIAL* blinn_material;
1477
1478 if( !aSkipMaterialInformation )
1479 {
1480 blinn_material = &( *materialVector )[mesh.m_MaterialIdx];
1481
1482 fpTransparency =
1483 1.0f - ( ( 1.0f - blinn_material->GetTransparency() ) * aFPOpacity );
1484 }
1485
1486 // Add all face triangles
1487 for( unsigned int faceIdx = 0; faceIdx < mesh.m_FaceIdxSize; faceIdx += 3 )
1488 {
1489 const unsigned int idx0 = mesh.m_FaceIdx[faceIdx + 0];
1490 const unsigned int idx1 = mesh.m_FaceIdx[faceIdx + 1];
1491 const unsigned int idx2 = mesh.m_FaceIdx[faceIdx + 2];
1492
1493 wxASSERT( idx0 < mesh.m_VertexSize );
1494 wxASSERT( idx1 < mesh.m_VertexSize );
1495 wxASSERT( idx2 < mesh.m_VertexSize );
1496
1497 if( ( idx0 < mesh.m_VertexSize ) && ( idx1 < mesh.m_VertexSize )
1498 && ( idx2 < mesh.m_VertexSize ) )
1499 {
1500 const SFVEC3F& v0 = mesh.m_Positions[idx0];
1501 const SFVEC3F& v1 = mesh.m_Positions[idx1];
1502 const SFVEC3F& v2 = mesh.m_Positions[idx2];
1503
1504 const SFVEC3F& n0 = mesh.m_Normals[idx0];
1505 const SFVEC3F& n1 = mesh.m_Normals[idx1];
1506 const SFVEC3F& n2 = mesh.m_Normals[idx2];
1507
1508 // Transform vertex with the model matrix
1509 const SFVEC3F vt0 = SFVEC3F( aModelMatrix * glm::vec4( v0, 1.0f ) );
1510 const SFVEC3F vt1 = SFVEC3F( aModelMatrix * glm::vec4( v1, 1.0f ) );
1511 const SFVEC3F vt2 = SFVEC3F( aModelMatrix * glm::vec4( v2, 1.0f ) );
1512
1513 const SFVEC3F nt0 = glm::normalize( SFVEC3F( normalMatrix * n0 ) );
1514 const SFVEC3F nt1 = glm::normalize( SFVEC3F( normalMatrix * n1 ) );
1515 const SFVEC3F nt2 = glm::normalize( SFVEC3F( normalMatrix * n2 ) );
1516
1517 TRIANGLE* newTriangle = new TRIANGLE( vt0, vt2, vt1, nt0, nt2, nt1 );
1518
1519 newTriangle->SetBoardItem( aBoardItem );
1520
1521 aDstContainer.Add( newTriangle );
1522
1523 if( !aSkipMaterialInformation )
1524 {
1525 newTriangle->SetMaterial( blinn_material );
1526 newTriangle->SetModelTransparency( fpTransparency );
1527
1528 if( mesh.m_Color == nullptr )
1529 {
1530 const SFVEC3F diffuseColor =
1531 a3DModel->m_Materials[mesh.m_MaterialIdx].m_Diffuse;
1532
1534 newTriangle->SetColor( ConvertSRGBToLinear(
1535 MaterialDiffuseToColorCAD( diffuseColor ) ) );
1536 else
1537 newTriangle->SetColor( ConvertSRGBToLinear( diffuseColor ) );
1538 }
1539 else
1540 {
1542 {
1543 newTriangle->SetColor(
1545 mesh.m_Color[idx0] ) ),
1547 mesh.m_Color[idx1] ) ),
1549 mesh.m_Color[idx2] ) ) );
1550 }
1551 else
1552 {
1553 newTriangle->SetColor(
1554 ConvertSRGBToLinear( mesh.m_Color[idx0] ),
1555 ConvertSRGBToLinear( mesh.m_Color[idx1] ),
1556 ConvertSRGBToLinear( mesh.m_Color[idx2] ) );
1557 }
1558 }
1559 }
1560 }
1561 }
1562 }
1563 }
1564 }
1565}
@ CAD_MODE
Use a gray shading based on diffuse material.
SFVEC3F MaterialDiffuseToColorCAD(const SFVEC3F &aDiffuseColor)
Definition: 3d_math.h:147
Blinn Phong based material https://en.wikipedia.org/wiki/Blinn%E2%80%93Phong_shading_model.
Definition: material.h:379
EDA_3D_VIEWER_SETTINGS * m_Cfg
void Add(OBJECT_3D *aObject)
Definition: container_3d.h:48
float GetTransparency() const
Definition: material.h:273
void SetMaterial(const MATERIAL *aMaterial)
Definition: object_3d.h:58
const void SetBoardItem(BOARD_ITEM *aBoardItem)
Definition: object_3d.h:55
void SetModelTransparency(float aModelTransparency)
Definition: object_3d.h:66
BOARD_ADAPTER & m_boardAdapter
MODEL_MATERIALS * getModelMaterial(const S3DMODEL *a3DModel)
A triangle object.
Definition: triangle_3d.h:43
void SetColor(const SFVEC3F &aColor)
SFVEC3F ConvertSRGBToLinear(const SFVEC3F &aSRGBcolor)
std::vector< BLINN_PHONG_MATERIAL > MODEL_MATERIALS
Vector of materials.
SMATERIAL * m_Materials
The materials list of this model.
Definition: c3dmodel.h:96
unsigned int m_MeshesSize
Number of meshes in the array.
Definition: c3dmodel.h:92
SMESH * m_Meshes
The meshes list of this model.
Definition: c3dmodel.h:93
unsigned int m_MaterialsSize
Number of materials in the material array.
Definition: c3dmodel.h:95
SFVEC3F m_Diffuse
Default diffuse color if m_Color is NULL.
Definition: c3dmodel.h:40
Per-vertex normal/color/texcoors structure.
Definition: c3dmodel.h:77
unsigned int * m_FaceIdx
Triangle Face Indexes.
Definition: c3dmodel.h:84
SFVEC3F * m_Normals
Vertex normals array.
Definition: c3dmodel.h:80
unsigned int m_MaterialIdx
Material Index to be used in this mesh (must be < m_MaterialsSize )
Definition: c3dmodel.h:85
unsigned int m_VertexSize
Number of vertex in the arrays.
Definition: c3dmodel.h:78
unsigned int m_FaceIdxSize
Number of elements of the m_FaceIdx array.
Definition: c3dmodel.h:83
SFVEC3F * m_Color
Vertex color array, can be NULL.
Definition: c3dmodel.h:82
SFVEC3F * m_Positions
Vertex position array.
Definition: c3dmodel.h:79
VECTOR3I v1(5, 5, 5)
VECTOR2I v2(1, 0)
Test suite for KiCad math code.
glm::vec3 SFVEC3F
Definition: xv3d_types.h:44

References CONTAINER_3D_BASE::Add(), CAD_MODE, ConvertSRGBToLinear(), getModelMaterial(), MATERIAL::GetTransparency(), RENDER_3D_BASE::m_boardAdapter, BOARD_ADAPTER::m_Cfg, SMESH::m_Color, SMATERIAL::m_Diffuse, SMESH::m_FaceIdx, SMESH::m_FaceIdxSize, SMESH::m_MaterialIdx, S3DMODEL::m_Materials, S3DMODEL::m_MaterialsSize, S3DMODEL::m_Meshes, S3DMODEL::m_MeshesSize, SMESH::m_Normals, SMESH::m_Positions, EDA_3D_VIEWER_SETTINGS::m_Render, SMESH::m_VertexSize, EDA_3D_VIEWER_SETTINGS::RENDER_SETTINGS::material_mode, MaterialDiffuseToColorCAD(), OBJECT_3D::SetBoardItem(), TRIANGLE::SetColor(), OBJECT_3D::SetMaterial(), OBJECT_3D::SetModelTransparency(), TRIANGLE, v1, and v2.

Referenced by load3DModels().

◆ addPadsAndVias()

void RENDER_3D_RAYTRACE::addPadsAndVias ( )
private

Definition at line 1171 of file raytracing/create_scene.cpp.

1172{
1173 if( !m_boardAdapter.GetBoard() )
1174 return;
1175
1176 // Insert plated vertical holes inside the board
1177
1178 // Insert vias holes (vertical cylinders)
1179 for( PCB_TRACK* track : m_boardAdapter.GetBoard()->Tracks() )
1180 {
1181 if( track->Type() == PCB_VIA_T )
1182 {
1183 const PCB_VIA* via = static_cast<const PCB_VIA*>( track );
1184 insertHole( via );
1185 }
1186 }
1187
1188 // Insert pads holes (vertical cylinders)
1189 for( FOOTPRINT* footprint : m_boardAdapter.GetBoard()->Footprints() )
1190 {
1191 for( PAD* pad : footprint->Pads() )
1192 {
1193 if( pad->GetAttribute() != PAD_ATTRIB::NPTH )
1194 insertHole( pad );
1195 }
1196 }
1197}
const BOARD * GetBoard() const noexcept
FOOTPRINTS & Footprints()
Definition: board.h:307
TRACKS & Tracks()
Definition: board.h:304
Definition: pad.h:59
void insertHole(const PCB_VIA *aVia)
@ NPTH
like PAD_PTH, but not plated
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:102

References BOARD::Footprints(), BOARD_ADAPTER::GetBoard(), insertHole(), RENDER_3D_BASE::m_boardAdapter, NPTH, pad, PCB_VIA_T, BOARD::Tracks(), and via.

Referenced by Reload().

◆ CreateBusyIndicator()

std::unique_ptr< BUSY_INDICATOR > RENDER_3D_BASE::CreateBusyIndicator ( ) const
protectedinherited

Return a created busy indicator, if a factory has been set, else a null pointer.

the canvas to display the scene

Definition at line 70 of file render_3d_base.cpp.

71{
72 std::unique_ptr<BUSY_INDICATOR> busy;
73
76
77 return busy;
78}
BUSY_INDICATOR::FACTORY m_busyIndicatorFactory
< Factory that returns a suitable busy indicator for the context.

References RENDER_3D_BASE::m_busyIndicatorFactory.

Referenced by RENDER_3D_OPENGL::Redraw(), and Redraw().

◆ createItemsFromContainer()

void RENDER_3D_RAYTRACE::createItemsFromContainer ( const BVH_CONTAINER_2D aContainer2d,
PCB_LAYER_ID  aLayer_id,
const MATERIAL aMaterialLayer,
const SFVEC3F aLayerColor,
float  aLayerZOffset 
)
private

Definition at line 228 of file raytracing/create_scene.cpp.

233{
234 if( aContainer2d == nullptr )
235 return;
236
237 const LIST_OBJECT2D& listObject2d = aContainer2d->GetList();
238
239 if( listObject2d.size() == 0 )
240 return;
241
242 for( const OBJECT_2D* object2d_A : listObject2d )
243 {
244 // not yet used / implemented (can be used in future to clip the objects in the
245 // board borders
246 OBJECT_2D* object2d_C = CSGITEM_FULL;
247
248 std::vector<const OBJECT_2D*>* object2d_B = CSGITEM_EMPTY;
249
250 object2d_B = new std::vector<const OBJECT_2D*>();
251
252 // Subtract holes but not in SolderPaste
253 // (can be added as an option in future)
254 if( !( aLayer_id == B_Paste || aLayer_id == F_Paste ) )
255 {
256 // Check if there are any layerhole that intersects this object
257 // Eg: a segment is cut by a via hole or THT hole.
259
260 if( layerHolesMap.find( aLayer_id ) != layerHolesMap.end() )
261 {
262 const BVH_CONTAINER_2D* holes2d = layerHolesMap.at( aLayer_id );
263
264 CONST_LIST_OBJECT2D intersecting;
265
266 holes2d->GetIntersectingObjects( object2d_A->GetBBox(), intersecting );
267
268 for( const OBJECT_2D* hole2d : intersecting )
269 object2d_B->push_back( hole2d );
270 }
271
272 // Check if there are any THT that intersects this object. If we're processing a silk
273 // layer and the flag is set, then clip the silk at the outer edge of the annular ring,
274 // rather than the at the outer edge of the copper plating.
275 const BVH_CONTAINER_2D& throughHoleOuter =
278 && ( aLayer_id == B_SilkS || aLayer_id == F_SilkS ) ?
281
282 if( !throughHoleOuter.GetList().empty() )
283 {
284 CONST_LIST_OBJECT2D intersecting;
285
286 throughHoleOuter.GetIntersectingObjects( object2d_A->GetBBox(), intersecting );
287
288 for( const OBJECT_2D* hole2d : intersecting )
289 object2d_B->push_back( hole2d );
290 }
291 }
292
293 if( !m_antioutlineBoard2dObjects->GetList().empty() )
294 {
295 CONST_LIST_OBJECT2D intersecting;
296
298 intersecting );
299
300 for( const OBJECT_2D* obj : intersecting )
301 object2d_B->push_back( obj );
302 }
303
305
308 && ( ( aLayer_id == B_SilkS && mapLayers.find( B_Mask ) != mapLayers.end() )
309 || ( aLayer_id == F_SilkS && mapLayers.find( F_Mask ) != mapLayers.end() ) ) )
310 {
311 const PCB_LAYER_ID layerMask_id = ( aLayer_id == B_SilkS ) ? B_Mask : F_Mask;
312
313 const BVH_CONTAINER_2D* containerMaskLayer2d = mapLayers.at( layerMask_id );
314
315 CONST_LIST_OBJECT2D intersecting;
316
317 if( containerMaskLayer2d ) // can be null if B_Mask or F_Mask is not shown
318 containerMaskLayer2d->GetIntersectingObjects( object2d_A->GetBBox(), intersecting );
319
320 for( const OBJECT_2D* obj2d : intersecting )
321 object2d_B->push_back( obj2d );
322 }
323
324 if( object2d_B->empty() )
325 {
326 delete object2d_B;
327 object2d_B = CSGITEM_EMPTY;
328 }
329
330 if( ( object2d_B == CSGITEM_EMPTY ) && ( object2d_C == CSGITEM_FULL ) )
331 {
332 LAYER_ITEM* objPtr = new LAYER_ITEM( object2d_A,
333 m_boardAdapter.GetLayerBottomZPos( aLayer_id ) - aLayerZOffset,
334 m_boardAdapter.GetLayerTopZPos( aLayer_id ) + aLayerZOffset );
335 objPtr->SetMaterial( aMaterialLayer );
336 objPtr->SetColor( ConvertSRGBToLinear( aLayerColor ) );
337 m_objectContainer.Add( objPtr );
338 }
339 else
340 {
341 LAYER_ITEM_2D* itemCSG2d = new LAYER_ITEM_2D( object2d_A, object2d_B, object2d_C,
342 object2d_A->GetBoardItem() );
344
345 LAYER_ITEM* objPtr = new LAYER_ITEM( itemCSG2d,
346 m_boardAdapter.GetLayerBottomZPos( aLayer_id ) - aLayerZOffset,
347 m_boardAdapter.GetLayerTopZPos( aLayer_id ) + aLayerZOffset );
348
349 objPtr->SetMaterial( aMaterialLayer );
350 objPtr->SetColor( ConvertSRGBToLinear( aLayerColor ) );
351
352 m_objectContainer.Add( objPtr );
353 }
354 }
355}
std::map< PCB_LAYER_ID, BVH_CONTAINER_2D * > MAP_CONTAINER_2D_BASE
A type that stores a container of 2d objects for each layer id.
Definition: board_adapter.h:54
const MAP_CONTAINER_2D_BASE & GetLayerHoleMap() const noexcept
float GetLayerBottomZPos(PCB_LAYER_ID aLayerId) const noexcept
Get the bottom z position.
float GetLayerTopZPos(PCB_LAYER_ID aLayerId) const noexcept
Get the top z position.
const MAP_CONTAINER_2D_BASE & GetLayerMap() const noexcept
Get the map of containers that have the objects per layer.
const BVH_CONTAINER_2D & GetThroughHoleAnnularRings() const noexcept
const BVH_CONTAINER_2D & GetThroughHoleOds() const noexcept
void GetIntersectingObjects(const BBOX_2D &aBBox, CONST_LIST_OBJECT2D &aOutList) const override
Get a list of objects that intersects a bounding box.
void Add(OBJECT_2D *aObject)
Definition: container_2d.h:49
const LIST_OBJECT2D & GetList() const
Definition: container_2d.h:66
Make solid geometry for objects on layers.
Definition: layer_item_2d.h:80
void SetColor(SFVEC3F aObjColor)
Definition: layer_item_3d.h:37
CONTAINER_3D m_objectContainer
Store the list of created objects special for RT that will be clear in the end.
CONTAINER_2D m_containerWithObjectsToDelete
std::list< OBJECT_2D * > LIST_OBJECT2D
Definition: container_2d.h:38
std::list< const OBJECT_2D * > CONST_LIST_OBJECT2D
Definition: container_2d.h:39
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:59
@ F_Paste
Definition: layer_ids.h:101
@ B_Mask
Definition: layer_ids.h:106
@ F_Mask
Definition: layer_ids.h:107
@ B_Paste
Definition: layer_ids.h:100
@ F_SilkS
Definition: layer_ids.h:104
@ B_SilkS
Definition: layer_ids.h:103
#define CSGITEM_EMPTY
Definition: layer_item_2d.h:38
#define CSGITEM_FULL
Definition: layer_item_2d.h:39

References CONTAINER_2D_BASE::Add(), CONTAINER_3D_BASE::Add(), B_Mask, B_Paste, B_SilkS, EDA_3D_VIEWER_SETTINGS::RENDER_SETTINGS::clip_silk_on_via_annulus, ConvertSRGBToLinear(), CSGITEM_EMPTY, CSGITEM_FULL, F_Mask, F_Paste, F_SilkS, OBJECT_2D::GetBoardItem(), BVH_CONTAINER_2D::GetIntersectingObjects(), BOARD_ADAPTER::GetLayerBottomZPos(), BOARD_ADAPTER::GetLayerHoleMap(), BOARD_ADAPTER::GetLayerMap(), BOARD_ADAPTER::GetLayerTopZPos(), CONTAINER_2D_BASE::GetList(), BOARD_ADAPTER::GetThroughHoleAnnularRings(), BOARD_ADAPTER::GetThroughHoleOds(), m_antioutlineBoard2dObjects, RENDER_3D_BASE::m_boardAdapter, BOARD_ADAPTER::m_Cfg, m_containerWithObjectsToDelete, m_objectContainer, EDA_3D_VIEWER_SETTINGS::m_Render, EDA_3D_VIEWER_SETTINGS::RENDER_SETTINGS::realistic, LAYER_ITEM::SetColor(), OBJECT_3D::SetMaterial(), and EDA_3D_VIEWER_SETTINGS::RENDER_SETTINGS::subtract_mask_from_silk.

Referenced by Reload().

◆ createObject()

void RENDER_3D_RAYTRACE::createObject ( CONTAINER_3D aDstContainer,
const OBJECT_2D aObject2D,
float  aZMin,
float  aZMax,
const MATERIAL aMaterial,
const SFVEC3F aObjColor 
)
private

Create one or more 3D objects form a 2D object and Z positions.

It tries to optimize some types of objects that will be faster to trace than the LAYER_ITEM object.

Definition at line 177 of file raytracing/create_scene.cpp.

180{
181 switch( aObject2D->GetObjectType() )
182 {
184 {
186
187 XY_PLANE* objPtr;
188 objPtr = new XY_PLANE( BBOX_3D(
189 SFVEC3F( aObject2D->GetBBox().Min().x, aObject2D->GetBBox().Min().y, aZMin ),
190 SFVEC3F( aObject2D->GetBBox().Max().x, aObject2D->GetBBox().Max().y, aZMin ) ) );
191 objPtr->SetMaterial( aMaterial );
192 objPtr->SetColor( ConvertSRGBToLinear( aObjColor ) );
193 aDstContainer.Add( objPtr );
194
195 objPtr = new XY_PLANE( BBOX_3D(
196 SFVEC3F( aObject2D->GetBBox().Min().x, aObject2D->GetBBox().Min().y, aZMax ),
197 SFVEC3F( aObject2D->GetBBox().Max().x, aObject2D->GetBBox().Max().y, aZMax ) ) );
198 objPtr->SetMaterial( aMaterial );
199 objPtr->SetColor( ConvertSRGBToLinear( aObjColor ) );
200 aDstContainer.Add( objPtr );
201 break;
202 }
203
205 {
207
208 const ROUND_SEGMENT_2D* aRoundSeg2D = static_cast<const ROUND_SEGMENT_2D*>( aObject2D );
209 ROUND_SEGMENT* objPtr = new ROUND_SEGMENT( *aRoundSeg2D, aZMin, aZMax );
210 objPtr->SetMaterial( aMaterial );
211 objPtr->SetColor( ConvertSRGBToLinear( aObjColor ) );
212 aDstContainer.Add( objPtr );
213 break;
214 }
215
216 default:
217 {
218 LAYER_ITEM* objPtr = new LAYER_ITEM( aObject2D, aZMin, aZMax );
219 objPtr->SetMaterial( aMaterial );
220 objPtr->SetColor( ConvertSRGBToLinear( aObjColor ) );
221 aDstContainer.Add( objPtr );
222 break;
223 }
224 }
225}
const BBOX_2D & GetBBox() const
Definition: object_2d.h:103
OBJECT_2D_TYPE GetObjectType() const
Definition: object_2d.h:107
void SetColor(SFVEC3F aObjColor)
A plane that is parallel to XY plane.
Definition: plane_3d.h:38
void SetColor(SFVEC3F aObjColor)
Definition: plane_3d.h:49
const SFVEC2F & Min() const
Definition: bbox_2d.h:167
const SFVEC2F & Max() const
Definition: bbox_2d.h:172
Manage a bounding box defined by two SFVEC3F min max points.
Definition: bbox_3d.h:42

References CONTAINER_3D_BASE::Add(), ConvertSRGBToLinear(), DUMMYBLOCK, OBJECT_2D::GetBBox(), OBJECT_2D::GetObjectType(), m_converted2dRoundSegmentCount, m_convertedDummyBlockCount, BBOX_2D::Max(), BBOX_2D::Min(), ROUNDSEG, LAYER_ITEM::SetColor(), XY_PLANE::SetColor(), ROUND_SEGMENT::SetColor(), and OBJECT_3D::SetMaterial().

Referenced by Reload().

◆ deletePbo()

void RENDER_3D_RAYTRACE::deletePbo ( )
private

Definition at line 99 of file render_3d_raytrace.cpp.

100{
101 // Delete PBO if it was created
103 {
104 if( glIsBufferARB( m_pboId ) )
105 glDeleteBuffers( 1, &m_pboId );
106
107 m_pboId = GL_NONE;
108 }
109}

References m_openglSupportsVertexBufferObjects, and m_pboId.

Referenced by initPbo(), and ~RENDER_3D_RAYTRACE().

◆ getModelMaterial()

MODEL_MATERIALS * RENDER_3D_RAYTRACE::getModelMaterial ( const S3DMODEL a3DModel)
private

Definition at line 1321 of file raytracing/create_scene.cpp.

1322{
1323 MODEL_MATERIALS* materialVector;
1324
1325 // Try find if the materials already exists in the map list
1326 if( m_modelMaterialMap.find( a3DModel ) != m_modelMaterialMap.end() )
1327 {
1328 // Found it, so get the pointer
1329 materialVector = &m_modelMaterialMap[a3DModel];
1330 }
1331 else
1332 {
1333 // Materials was not found in the map, so it will create a new for
1334 // this model.
1335
1336 m_modelMaterialMap[a3DModel] = MODEL_MATERIALS();
1337 materialVector = &m_modelMaterialMap[a3DModel];
1338
1339 materialVector->resize( a3DModel->m_MaterialsSize );
1340
1341 for( unsigned int imat = 0; imat < a3DModel->m_MaterialsSize; ++imat )
1342 {
1344 {
1345 const SMATERIAL& material = a3DModel->m_Materials[imat];
1346
1347 // http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiJtaW4oc3FydCh4LTAuMzUpKjAuNDAtMC4wNSwxLjApIiwiY29sb3IiOiIjMDAwMDAwIn0seyJ0eXBlIjoxMDAwLCJ3aW5kb3ciOlsiMC4wNzA3NzM2NzMyMzY1OTAxMiIsIjEuNTY5NTcxNjI5MjI1NDY5OCIsIi0wLjI3NDYzNTMyMTc1OTkyOTMiLCIwLjY0NzcwMTg4MTkyNTUzNjIiXSwic2l6ZSI6WzY0NCwzOTRdfV0-
1348
1349 float reflectionFactor = 0.0f;
1350
1351 if( ( material.m_Shininess - 0.35f ) > FLT_EPSILON )
1352 {
1353 reflectionFactor = glm::clamp(
1354 glm::sqrt( ( material.m_Shininess - 0.35f ) ) * 0.40f - 0.05f, 0.0f,
1355 0.5f );
1356 }
1357
1358 BLINN_PHONG_MATERIAL& blinnMaterial = ( *materialVector )[imat];
1359
1360 blinnMaterial = BLINN_PHONG_MATERIAL( ConvertSRGBToLinear( material.m_Ambient ),
1361 ConvertSRGBToLinear( material.m_Emissive ),
1362 ConvertSRGBToLinear( material.m_Specular ), material.m_Shininess * 180.0f,
1363 material.m_Transparency, reflectionFactor );
1364
1366 {
1367 // Guess material type and apply a normal perturbator
1368 if( ( RGBtoGray( material.m_Diffuse ) < 0.3f )
1369 && ( material.m_Shininess < 0.36f )
1370 && ( material.m_Transparency == 0.0f )
1371 && ( ( glm::abs( material.m_Diffuse.r - material.m_Diffuse.g ) < 0.15f )
1372 && ( glm::abs( material.m_Diffuse.b - material.m_Diffuse.g )
1373 < 0.15f )
1374 && ( glm::abs( material.m_Diffuse.r - material.m_Diffuse.b )
1375 < 0.15f ) ) )
1376 {
1377 // This may be a black plastic..
1378 blinnMaterial.SetGenerator( &m_plasticMaterial );
1379 }
1380 else
1381 {
1382 if( ( RGBtoGray( material.m_Diffuse ) > 0.3f )
1383 && ( material.m_Shininess < 0.30f )
1384 && ( material.m_Transparency == 0.0f )
1385 && ( ( glm::abs( material.m_Diffuse.r - material.m_Diffuse.g ) > 0.25f )
1386 || ( glm::abs( material.m_Diffuse.b - material.m_Diffuse.g ) > 0.25f )
1387 || ( glm::abs( material.m_Diffuse.r - material.m_Diffuse.b )
1388 > 0.25f ) ) )
1389 {
1390 // This may be a color plastic ...
1391 blinnMaterial.SetGenerator( &m_shinyPlasticMaterial );
1392 }
1393 else
1394 {
1395 if( ( RGBtoGray( material.m_Diffuse ) > 0.6f )
1396 && ( material.m_Shininess > 0.35f )
1397 && ( material.m_Transparency == 0.0f )
1398 && ( ( glm::abs( material.m_Diffuse.r - material.m_Diffuse.g )
1399 < 0.40f )
1400 && ( glm::abs( material.m_Diffuse.b - material.m_Diffuse.g )
1401 < 0.40f )
1402 && ( glm::abs( material.m_Diffuse.r - material.m_Diffuse.b )
1403 < 0.40f ) ) )
1404 {
1405 // This may be a brushed metal
1406 blinnMaterial.SetGenerator( &m_brushedMetalMaterial );
1407 }
1408 }
1409 }
1410 }
1411 }
1412 else
1413 {
1414 ( *materialVector )[imat] = BLINN_PHONG_MATERIAL(
1415 SFVEC3F( 0.2f ), SFVEC3F( 0.0f ), SFVEC3F( 0.0f ), 0.0f, 0.0f, 0.0f );
1416 }
1417 }
1418 }
1419
1420 return materialVector;
1421}
@ NORMAL
Use all material properties from model file.
float RGBtoGray(const SFVEC3F &aColor)
Definition: 3d_math.h:140
void SetGenerator(const MATERIAL_GENERATOR *aGenerator)
Definition: material.h:328
BRUSHED_METAL_NORMAL m_brushedMetalMaterial
PLASTIC_SHINE_NORMAL m_shinyPlasticMaterial
PLASTIC_NORMAL m_plasticMaterial
MAP_MODEL_MATERIALS m_modelMaterialMap
Stores materials of the 3D models.
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition: eda_angle.h:401
float m_Shininess
Definition: c3dmodel.h:43
SFVEC3F m_Specular
Definition: c3dmodel.h:42
SFVEC3F m_Ambient
Definition: c3dmodel.h:39
float m_Transparency
1.0 is completely transparent, 0.0 completely opaque
Definition: c3dmodel.h:44
SFVEC3F m_Emissive
Definition: c3dmodel.h:41

References std::abs(), ConvertSRGBToLinear(), SMATERIAL::m_Ambient, RENDER_3D_BASE::m_boardAdapter, m_brushedMetalMaterial, BOARD_ADAPTER::m_Cfg, SMATERIAL::m_Diffuse, SMATERIAL::m_Emissive, S3DMODEL::m_Materials, S3DMODEL::m_MaterialsSize, m_modelMaterialMap, m_plasticMaterial, EDA_3D_VIEWER_SETTINGS::m_Render, SMATERIAL::m_Shininess, m_shinyPlasticMaterial, SMATERIAL::m_Specular, SMATERIAL::m_Transparency, EDA_3D_VIEWER_SETTINGS::RENDER_SETTINGS::material_mode, NORMAL, EDA_3D_VIEWER_SETTINGS::RENDER_SETTINGS::raytrace_procedural_textures, RGBtoGray(), and MATERIAL::SetGenerator().

Referenced by addModels().

◆ GetWaitForEditingTimeOut()

int RENDER_3D_RAYTRACE::GetWaitForEditingTimeOut ( )
overridevirtual

Give the interface the time (in ms) that it should wait for editing or movements before (this works for display preview mode).

Returns
a value in milliseconds

Implements RENDER_3D_BASE.

Definition at line 93 of file render_3d_raytrace.cpp.

94{
95 return 1000; // ms
96}

◆ initializeBlockPositions()

void RENDER_3D_RAYTRACE::initializeBlockPositions ( )
private

Definition at line 1854 of file render_3d_raytrace.cpp.

1855{
1857
1858 // Calc block positions for fast preview mode
1859 m_blockPositionsFast.clear();
1860
1861 unsigned int i = 0;
1862
1863 while(1)
1864 {
1865 const unsigned int mX = DecodeMorton2X(i);
1866 const unsigned int mY = DecodeMorton2Y(i);
1867
1868 i++;
1869
1870 const SFVEC2UI blockPos( mX * 4 * RAYPACKET_DIM - mX * 4,
1871 mY * 4 * RAYPACKET_DIM - mY * 4 );
1872
1873 if( ( blockPos.x >= ( (unsigned int)m_windowSize.x - ( 4 * RAYPACKET_DIM + 4 ) ) ) &&
1874 ( blockPos.y >= ( (unsigned int)m_windowSize.y - ( 4 * RAYPACKET_DIM + 4 ) ) ) )
1875 break;
1876
1877 if( ( blockPos.x < ( (unsigned int)m_windowSize.x - ( 4 * RAYPACKET_DIM + 4 ) ) ) &&
1878 ( blockPos.y < ( (unsigned int)m_windowSize.y - ( 4 * RAYPACKET_DIM + 4 ) ) ) )
1879 {
1880 m_blockPositionsFast.push_back( blockPos );
1881
1882 if( blockPos.x > m_realBufferSize.x )
1883 m_realBufferSize.x = blockPos.x;
1884
1885 if( blockPos.y > m_realBufferSize.y )
1886 m_realBufferSize.y = blockPos.y;
1887 }
1888 }
1889
1891
1894
1895 m_xoffset = ( m_windowSize.x - m_realBufferSize.x ) / 2;
1896 m_yoffset = ( m_windowSize.y - m_realBufferSize.y ) / 2;
1897
1899
1900 // Calc block positions for regular rendering. Choose an 'inside out' style of rendering.
1901 m_blockPositions.clear();
1902 const int blocks_x = m_realBufferSize.x / RAYPACKET_DIM;
1903 const int blocks_y = m_realBufferSize.y / RAYPACKET_DIM;
1904 m_blockPositions.reserve( blocks_x * blocks_y );
1905
1906 for( int x = 0; x < blocks_x; ++x )
1907 {
1908 for( int y = 0; y < blocks_y; ++y )
1909 m_blockPositions.emplace_back( x * RAYPACKET_DIM, y * RAYPACKET_DIM );
1910 }
1911
1912 const SFVEC2UI center( m_realBufferSize.x / 2, m_realBufferSize.y / 2 );
1913 std::sort( m_blockPositions.begin(), m_blockPositions.end(),
1914 [&]( const SFVEC2UI& a, const SFVEC2UI& b ) {
1915 // Sort order: inside out.
1916 return distance( a, center ) < distance( b, center );
1917 } );
1918
1919 // Create m_shader buffer
1920 delete[] m_shaderBuffer;
1922
1923 initPbo();
1924}
void UpdateSize(const SFVEC2UI &aSize)
Definition: post_shader.cpp:73
std::vector< SFVEC2UI > m_blockPositionsFast
std::vector< SFVEC2UI > m_blockPositions
Flag if a position was already processed (cleared each new render).
uint32_t DecodeMorton2Y(uint32_t code)
uint32_t DecodeMorton2X(uint32_t code)
Definition: mortoncodes.cpp:98
#define RAYPACKET_INVMASK
Definition: raypacket.h:34
#define RAYPACKET_DIM
Definition: raypacket.h:32
glm::uvec2 SFVEC2UI
Definition: xv3d_types.h:38

References DecodeMorton2X(), DecodeMorton2Y(), initPbo(), m_blockPositions, m_blockPositionsFast, m_fastPreviewModeSize, m_postShaderSsao, m_realBufferSize, m_shaderBuffer, RENDER_3D_BASE::m_windowSize, m_xoffset, m_yoffset, RAYPACKET_DIM, RAYPACKET_INVMASK, and POST_SHADER::UpdateSize().

Referenced by Redraw().

◆ initializeNewWindowSize()

void RENDER_3D_RAYTRACE::initializeNewWindowSize ( )
private

Definition at line 1803 of file render_3d_raytrace.cpp.

1804{
1805 initPbo();
1806}

References initPbo().

Referenced by SetCurWindowSize().

◆ initializeOpenGL()

bool RENDER_3D_RAYTRACE::initializeOpenGL ( )
private

Definition at line 1838 of file render_3d_raytrace.cpp.

1839{
1841
1842 return true;
1843}
bool m_is_opengl_initialized

References RENDER_3D_BASE::m_is_opengl_initialized.

Referenced by Redraw().

◆ initPbo()

void RENDER_3D_RAYTRACE::initPbo ( )
private

Definition at line 1809 of file render_3d_raytrace.cpp.

1810{
1811 if( GLEW_ARB_pixel_buffer_object )
1812 {
1814
1815 // Try to delete vbo if it was already initialized
1816 deletePbo();
1817
1818 // Learn about Pixel buffer objects at:
1819 // http://www.songho.ca/opengl/gl_pbo.html
1820 // http://web.eecs.umich.edu/~sugih/courses/eecs487/lectures/25-PBO+Mipmapping.pdf
1821 // "create 2 pixel buffer objects, you need to delete them when program exits.
1822 // glBufferDataARB with NULL pointer reserves only memory space."
1823
1824 // This sets the number of RGBA pixels
1826
1827 glGenBuffersARB( 1, &m_pboId );
1828 glBindBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB, m_pboId );
1829 glBufferDataARB( GL_PIXEL_UNPACK_BUFFER_ARB, m_pboDataSize, 0, GL_STREAM_DRAW_ARB );
1830 glBindBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB, 0 );
1831
1832 wxLogTrace( m_logTrace,
1833 wxT( "RENDER_3D_RAYTRACE:: GLEW_ARB_pixel_buffer_object is supported" ) );
1834 }
1835}

References deletePbo(), RENDER_3D_BASE::m_logTrace, m_openglSupportsVertexBufferObjects, m_pboDataSize, m_pboId, and m_realBufferSize.

Referenced by initializeBlockPositions(), and initializeNewWindowSize().

◆ insertHole() [1/2]

void RENDER_3D_RAYTRACE::insertHole ( const PAD aPad)
private

Definition at line 993 of file raytracing/create_scene.cpp.

994{
995 const OBJECT_2D* object2d_A = nullptr;
996
997 SFVEC3F objColor;
998
1000 objColor = m_boardAdapter.m_CopperColor;
1001 else
1003
1004 const VECTOR2I drillsize = aPad->GetDrillSize();
1005 const bool hasHole = drillsize.x && drillsize.y;
1006
1007 if( !hasHole )
1008 return;
1009
1010 CONST_LIST_OBJECT2D antiOutlineIntersectionList;
1011
1012 const float topZ = m_boardAdapter.GetLayerBottomZPos( F_Cu )
1014
1015 const float botZ = m_boardAdapter.GetLayerBottomZPos( B_Cu )
1017
1018 if( drillsize.x == drillsize.y ) // usual round hole
1019 {
1022
1023 int innerRadius = drillsize.x / 2;
1024 int outerRadius = innerRadius + m_boardAdapter.GetHolePlatingThickness();
1025
1026 RING_2D* ring = new RING_2D( center, innerRadius * m_boardAdapter.BiuTo3dUnits(),
1027 outerRadius * m_boardAdapter.BiuTo3dUnits(), *aPad );
1028
1030
1031 object2d_A = ring;
1032
1033 // If the object (ring) is intersected by an antioutline board,
1034 // it will use instead a CSG of two circles.
1035 if( object2d_A && !m_antioutlineBoard2dObjects->GetList().empty() )
1036 {
1038 antiOutlineIntersectionList );
1039 }
1040
1041 if( !antiOutlineIntersectionList.empty() )
1042 {
1043 FILLED_CIRCLE_2D* innerCircle = new FILLED_CIRCLE_2D(
1044 center, innerRadius * m_boardAdapter.BiuTo3dUnits(), *aPad );
1045
1046 FILLED_CIRCLE_2D* outterCircle = new FILLED_CIRCLE_2D(
1047 center, outerRadius * m_boardAdapter.BiuTo3dUnits(), *aPad );
1048 std::vector<const OBJECT_2D*>* object2d_B = new std::vector<const OBJECT_2D*>();
1049 object2d_B->push_back( innerCircle );
1050
1051 LAYER_ITEM_2D* itemCSG2d = new LAYER_ITEM_2D( outterCircle, object2d_B, CSGITEM_FULL,
1052 *aPad );
1053
1055 m_containerWithObjectsToDelete.Add( innerCircle );
1056 m_containerWithObjectsToDelete.Add( outterCircle );
1057
1058 object2d_A = itemCSG2d;
1059 }
1060 }
1061 else // Oblong hole
1062 {
1063 VECTOR2I ends_offset;
1064 int width;
1065
1066 if( drillsize.x > drillsize.y ) // Horizontal oval
1067 {
1068 ends_offset.x = ( drillsize.x - drillsize.y ) / 2;
1069 width = drillsize.y;
1070 }
1071 else // Vertical oval
1072 {
1073 ends_offset.y = ( drillsize.y - drillsize.x ) / 2;
1074 width = drillsize.x;
1075 }
1076
1077 RotatePoint( ends_offset, aPad->GetOrientation() );
1078
1079 VECTOR2I start = VECTOR2I( aPad->GetPosition() ) + ends_offset;
1080 VECTOR2I end = VECTOR2I( aPad->GetPosition() ) - ends_offset;
1081
1082 ROUND_SEGMENT_2D* innerSeg =
1084 -start.y * m_boardAdapter.BiuTo3dUnits() ),
1086 -end.y * m_boardAdapter.BiuTo3dUnits() ),
1087 width * m_boardAdapter.BiuTo3dUnits(), *aPad );
1088
1089 ROUND_SEGMENT_2D* outerSeg =
1091 -start.y * m_boardAdapter.BiuTo3dUnits() ),
1093 -end.y * m_boardAdapter.BiuTo3dUnits() ),
1094 ( width + m_boardAdapter.GetHolePlatingThickness() * 2 )
1095 * m_boardAdapter.BiuTo3dUnits(), *aPad );
1096
1097 // NOTE: the round segment width is the "diameter", so we double the thickness
1098 std::vector<const OBJECT_2D*>* object2d_B = new std::vector<const OBJECT_2D*>();
1099 object2d_B->push_back( innerSeg );
1100
1101 LAYER_ITEM_2D* itemCSG2d = new LAYER_ITEM_2D( outerSeg, object2d_B, CSGITEM_FULL, *aPad );
1102
1106
1107 object2d_A = itemCSG2d;
1108
1109 if( object2d_A && !m_antioutlineBoard2dObjects->GetList().empty() )
1110 {
1112 antiOutlineIntersectionList );
1113 }
1114 }
1115
1116 if( object2d_A )
1117 {
1118 std::vector<const OBJECT_2D*>* object2d_B = new std::vector<const OBJECT_2D*>();
1119
1120 // Check if there are any other THT that intersects this hole
1121 // It will use the non inflated holes
1122 if( !m_boardAdapter.GetThroughHoleIds().GetList().empty() )
1123 {
1124 CONST_LIST_OBJECT2D intersecting;
1125
1127 intersecting );
1128
1129 for( const OBJECT_2D* hole2d : intersecting )
1130 {
1131 if( object2d_A->Intersects( hole2d->GetBBox() ) )
1132 object2d_B->push_back( hole2d );
1133 }
1134 }
1135
1136 for( const OBJECT_2D* obj : antiOutlineIntersectionList )
1137 object2d_B->push_back( obj );
1138
1139 if( object2d_B->empty() )
1140 {
1141 delete object2d_B;
1142 object2d_B = CSGITEM_EMPTY;
1143 }
1144
1145 if( object2d_B == CSGITEM_EMPTY )
1146 {
1147 LAYER_ITEM* objPtr = new LAYER_ITEM( object2d_A, topZ, botZ );
1148
1149 objPtr->SetMaterial( &m_materials.m_Copper );
1150 objPtr->SetColor( ConvertSRGBToLinear( objColor ) );
1151 m_objectContainer.Add( objPtr );
1152 }
1153 else
1154 {
1155 LAYER_ITEM_2D* itemCSG2d = new LAYER_ITEM_2D( object2d_A, object2d_B, CSGITEM_FULL,
1156 *aPad );
1157
1159
1160 LAYER_ITEM* objPtr = new LAYER_ITEM( itemCSG2d, topZ, botZ );
1161
1162 objPtr->SetMaterial( &m_materials.m_Copper );
1163 objPtr->SetColor( ConvertSRGBToLinear( objColor ) );
1164
1165 m_objectContainer.Add( objPtr );
1166 }
1167 }
1168}
double BiuTo3dUnits() const noexcept
Board integer units To 3D units.
const BVH_CONTAINER_2D & GetThroughHoleIds() const noexcept
int GetHolePlatingThickness() const noexcept
Get the hole plating thickness (NB: in BOARD UNITS!).
float GetBackCopperThickness() const noexcept
SFVEC4F m_CopperColor
in realistic mode: copper color
SFVEC4F GetItemColor(int aItemId) const
Get the technical color of a layer.
float GetFrontCopperThickness() const noexcept
Get the copper layer thicknesses (in 3D units).
virtual bool Intersects(const BBOX_2D &aBBox) const =0
a.Intersects(b) ⇔ !a.Disjoint(b) ⇔ !(a ∩ b = ∅)
const VECTOR2I & GetDrillSize() const
Definition: pad.h:267
VECTOR2I GetPosition() const override
Definition: pad.h:202
EDA_ANGLE GetOrientation() const
Return the rotation angle of the pad.
Definition: pad.h:370
struct RENDER_3D_RAYTRACE::@5 m_materials
@ LAYER_PADS_TH
multilayer pads, usually with holes
Definition: layer_ids.h:213
@ B_Cu
Definition: layer_ids.h:95
@ F_Cu
Definition: layer_ids.h:64
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Definition: trigo.cpp:183
VECTOR2< int > VECTOR2I
Definition: vector2d.h:618
glm::vec2 SFVEC2F
Definition: xv3d_types.h:42

References CONTAINER_2D_BASE::Add(), CONTAINER_3D_BASE::Add(), B_Cu, BOARD_ADAPTER::BiuTo3dUnits(), ConvertSRGBToLinear(), CSGITEM_EMPTY, CSGITEM_FULL, F_Cu, BOARD_ADAPTER::GetBackCopperThickness(), OBJECT_2D::GetBBox(), PAD::GetDrillSize(), BOARD_ADAPTER::GetFrontCopperThickness(), BOARD_ADAPTER::GetHolePlatingThickness(), BVH_CONTAINER_2D::GetIntersectingObjects(), BOARD_ADAPTER::GetItemColor(), BOARD_ADAPTER::GetLayerBottomZPos(), CONTAINER_2D_BASE::GetList(), PAD::GetOrientation(), PAD::GetPosition(), BOARD_ADAPTER::GetThroughHoleIds(), OBJECT_2D::Intersects(), LAYER_PADS_TH, m_antioutlineBoard2dObjects, RENDER_3D_BASE::m_boardAdapter, BOARD_ADAPTER::m_Cfg, m_containerWithObjectsToDelete, BOARD_ADAPTER::m_CopperColor, m_materials, m_objectContainer, EDA_3D_VIEWER_SETTINGS::m_Render, EDA_3D_VIEWER_SETTINGS::RENDER_SETTINGS::realistic, RotatePoint(), LAYER_ITEM::SetColor(), OBJECT_3D::SetMaterial(), VECTOR2< T >::x, and VECTOR2< T >::y.

◆ insertHole() [2/2]

void RENDER_3D_RAYTRACE::insertHole ( const PCB_VIA aVia)
private

Definition at line 954 of file raytracing/create_scene.cpp.

955{
956 PCB_LAYER_ID top_layer, bottom_layer;
957 int radiusBUI = ( aVia->GetDrillValue() / 2 );
958
959 aVia->LayerPair( &top_layer, &bottom_layer );
960
961 float topZ = m_boardAdapter.GetLayerBottomZPos( top_layer )
963
964 float botZ = m_boardAdapter.GetLayerBottomZPos( bottom_layer )
966
967 const SFVEC2F center = SFVEC2F( aVia->GetStart().x * m_boardAdapter.BiuTo3dUnits(),
968 -aVia->GetStart().y * m_boardAdapter.BiuTo3dUnits() );
969
970 RING_2D* ring = new RING_2D( center, radiusBUI * m_boardAdapter.BiuTo3dUnits(),
972 * m_boardAdapter.BiuTo3dUnits(), *aVia );
973
975
976 LAYER_ITEM* objPtr = new LAYER_ITEM( ring, topZ, botZ );
977
978 objPtr->SetMaterial( &m_materials.m_Copper );
979
982 else if( aVia->GetViaType() == VIATYPE::MICROVIA )
984 else if( aVia->GetViaType() == VIATYPE::BLIND_BURIED )
986 else
988
989 m_objectContainer.Add( objPtr );
990}
const VECTOR2I & GetStart() const
Definition: pcb_track.h:113
int GetDrillValue() const
Function GetDrillValue "calculates" the drill value for vias (m-Drill if > 0, or default drill value ...
Definition: pcb_track.cpp:222
VIATYPE GetViaType() const
Definition: pcb_track.h:393
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...
Definition: pcb_track.cpp:572
@ LAYER_VIA_MICROVIA
to draw micro vias
Definition: layer_ids.h:194
@ LAYER_VIAS
Meta control for all vias opacity/visibility.
Definition: layer_ids.h:193
@ LAYER_VIA_BBLIND
to draw blind/buried vias
Definition: layer_ids.h:195
@ BLIND_BURIED

References CONTAINER_2D_BASE::Add(), CONTAINER_3D_BASE::Add(), BOARD_ADAPTER::BiuTo3dUnits(), BLIND_BURIED, ConvertSRGBToLinear(), BOARD_ADAPTER::GetBackCopperThickness(), PCB_VIA::GetDrillValue(), BOARD_ADAPTER::GetFrontCopperThickness(), BOARD_ADAPTER::GetHolePlatingThickness(), BOARD_ADAPTER::GetItemColor(), BOARD_ADAPTER::GetLayerBottomZPos(), PCB_TRACK::GetStart(), PCB_VIA::GetViaType(), LAYER_VIA_BBLIND, LAYER_VIA_MICROVIA, LAYER_VIAS, PCB_VIA::LayerPair(), RENDER_3D_BASE::m_boardAdapter, BOARD_ADAPTER::m_Cfg, m_containerWithObjectsToDelete, BOARD_ADAPTER::m_CopperColor, m_materials, m_objectContainer, EDA_3D_VIEWER_SETTINGS::m_Render, MICROVIA, EDA_3D_VIEWER_SETTINGS::RENDER_SETTINGS::realistic, LAYER_ITEM::SetColor(), OBJECT_3D::SetMaterial(), VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by addPadsAndVias().

◆ IntersectBoardItem()

BOARD_ITEM * RENDER_3D_RAYTRACE::IntersectBoardItem ( const RAY aRay)

Definition at line 1927 of file render_3d_raytrace.cpp.

1928{
1929 HITINFO hitInfo;
1930 hitInfo.m_tHit = std::numeric_limits<float>::infinity();
1931
1932 if( m_accelerator )
1933 {
1934 if( m_accelerator->Intersect( aRay, hitInfo ) )
1935 {
1936 if( hitInfo.pHitObject )
1937 return hitInfo.pHitObject->GetBoardItem();
1938 }
1939 }
1940
1941 return nullptr;
1942}
virtual bool Intersect(const RAY &aRay, HITINFO &aHitInfo) const =0
BOARD_ITEM * GetBoardItem() const
Definition: object_3d.h:56
Stores the hit information of a ray with a point on the surface of a object.
Definition: hitinfo.h:36
float m_tHit
( 4) distance
Definition: hitinfo.h:38
const OBJECT_3D * pHitObject
( 4) Object that was hitted
Definition: hitinfo.h:40

References OBJECT_3D::GetBoardItem(), ACCELERATOR_3D::Intersect(), m_accelerator, HITINFO::m_tHit, and HITINFO::pHitObject.

Referenced by EDA_3D_CANVAS::OnLeftDown(), and EDA_3D_CANVAS::OnMouseMove().

◆ IsReloadRequestPending()

bool RENDER_3D_BASE::IsReloadRequestPending ( ) const
inlineinherited

Query if there is a pending reload request.

Returns
true if it wants to reload, false if there is no reload pending

Definition at line 77 of file render_3d_base.h.

77{ return m_reloadRequested; }
bool m_reloadRequested
The window size that this camera is working.

References RENDER_3D_BASE::m_reloadRequested.

Referenced by EDA_3D_CANVAS::DoRePaint(), and EDA_3D_CANVAS::IsReloadRequestPending().

◆ load3DModels()

void RENDER_3D_RAYTRACE::load3DModels ( CONTAINER_3D aDstContainer,
bool  aSkipMaterialInformation 
)
private

Definition at line 1200 of file raytracing/create_scene.cpp.

1201{
1202 if( !m_boardAdapter.GetBoard() )
1203 return;
1204
1208 {
1209 return;
1210 }
1211
1212 // Go for all footprints
1214 {
1215 if( !fp->Models().empty()
1216 && m_boardAdapter.IsFootprintShown( (FOOTPRINT_ATTR_T) fp->GetAttributes() ) )
1217 {
1218 double zpos = m_boardAdapter.GetFootprintZPos( fp->IsFlipped() );
1219
1220 VECTOR2I pos = fp->GetPosition();
1221
1222 glm::mat4 fpMatrix = glm::mat4( 1.0f );
1223
1224 fpMatrix = glm::translate( fpMatrix,
1226 -pos.y * m_boardAdapter.BiuTo3dUnits(),
1227 zpos ) );
1228
1229 if( !fp->GetOrientation().IsZero() )
1230 {
1231 fpMatrix = glm::rotate( fpMatrix, (float) fp->GetOrientation().AsRadians(),
1232 SFVEC3F( 0.0f, 0.0f, 1.0f ) );
1233 }
1234
1235 if( fp->IsFlipped() )
1236 {
1237 fpMatrix = glm::rotate( fpMatrix, glm::pi<float>(), SFVEC3F( 0.0f, 1.0f, 0.0f ) );
1238
1239 fpMatrix = glm::rotate( fpMatrix, glm::pi<float>(), SFVEC3F( 0.0f, 0.0f, 1.0f ) );
1240 }
1241
1242 const double modelunit_to_3d_units_factor =
1244
1245 fpMatrix = glm::scale(
1246 fpMatrix, SFVEC3F( modelunit_to_3d_units_factor, modelunit_to_3d_units_factor,
1247 modelunit_to_3d_units_factor ) );
1248
1249 BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( fp );
1250
1251 // Get the list of model files for this model
1253 auto sM = fp->Models().begin();
1254 auto eM = fp->Models().end();
1255
1256 wxString libraryName = fp->GetFPID().GetLibNickname();
1257
1258 wxString footprintBasePath = wxEmptyString;
1260 {
1261 try
1262 {
1263 // FindRow() can throw an exception
1264 const FP_LIB_TABLE_ROW* fpRow =
1266 libraryName, false );
1267
1268 if( fpRow )
1269 footprintBasePath = fpRow->GetFullURI( true );
1270 }
1271 catch( ... )
1272 {
1273 // Do nothing if the libraryName is not found in lib table
1274 }
1275 }
1276
1277 while( sM != eM )
1278 {
1279 if( ( static_cast<float>( sM->m_Opacity ) > FLT_EPSILON )
1280 && ( sM->m_Show && !sM->m_Filename.empty() ) )
1281 {
1282 // get it from cache
1283 const S3DMODEL* modelPtr =
1284 cacheMgr->GetModel( sM->m_Filename, footprintBasePath );
1285
1286 // only add it if the return is not NULL.
1287 if( modelPtr )
1288 {
1289 glm::mat4 modelMatrix = fpMatrix;
1290
1291 modelMatrix = glm::translate( modelMatrix,
1292 SFVEC3F( sM->m_Offset.x, sM->m_Offset.y, sM->m_Offset.z ) );
1293
1294 modelMatrix = glm::rotate( modelMatrix,
1295 (float) -( sM->m_Rotation.z / 180.0f ) * glm::pi<float>(),
1296 SFVEC3F( 0.0f, 0.0f, 1.0f ) );
1297
1298 modelMatrix = glm::rotate( modelMatrix,
1299 (float) -( sM->m_Rotation.y / 180.0f ) * glm::pi<float>(),
1300 SFVEC3F( 0.0f, 1.0f, 0.0f ) );
1301
1302 modelMatrix = glm::rotate( modelMatrix,
1303 (float) -( sM->m_Rotation.x / 180.0f ) * glm::pi<float>(),
1304 SFVEC3F( 1.0f, 0.0f, 0.0f ) );
1305
1306 modelMatrix = glm::scale( modelMatrix,
1307 SFVEC3F( sM->m_Scale.x, sM->m_Scale.y, sM->m_Scale.z ) );
1308
1309 addModels( aDstContainer, modelPtr, modelMatrix, (float) sM->m_Opacity,
1310 aSkipMaterialInformation, boardItem );
1311 }
1312 }
1313
1314 ++sM;
1315 }
1316 }
1317 }
1318}
bool IsFootprintShown(FOOTPRINT_ATTR_T aFPAttributes) const
Test if footprint should be displayed in relation to attributes and the flags.
float GetFootprintZPos(bool aIsFlipped) const
Get the position of the footprint in 3d integer units considering if it is flipped or not.
S3D_CACHE * Get3dCacheManager() const noexcept
Definition: board_adapter.h:81
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:58
PROJECT * GetProject() const
Definition: board.h:440
Hold a record identifying a library accessed by the appropriate footprint library PLUGIN object in th...
Definition: fp_lib_table.h:41
const FP_LIB_TABLE_ROW * FindRow(const wxString &aNickName, bool aCheckIfEnabled=false)
Return an FP_LIB_TABLE_ROW if aNickName is found in this table or in any chained fall back table frag...
const wxString GetFullURI(bool aSubstituted=false) const
Return the full location specifying URI for the LIB, either in original UI form or in environment var...
virtual FP_LIB_TABLE * PcbFootprintLibs(KIWAY &aKiway)
Return the table of footprint libraries.
Definition: project.cpp:324
void addModels(CONTAINER_3D &aDstContainer, const S3DMODEL *a3DModel, const glm::mat4 &aModelMatrix, float aFPOpacity, bool aSkipMaterialInformation, BOARD_ITEM *aBoardItem)
Cache for storing the 3D shapes.
Definition: 3d_cache.h:53
S3DMODEL * GetModel(const wxString &aModelFileName, const wxString &aBasePath)
Attempt to load the scene data for a model and to translate it into an S3D_MODEL structure for displa...
Definition: 3d_cache.cpp:635
FOOTPRINT_ATTR_T
The set of attributes allowed within a FOOTPRINT, using FOOTPRINT::SetAttributes() and FOOTPRINT::Get...
Definition: footprint.h:67
#define UNITS3D_TO_UNITSPCB
Scale conversion from 3d model units to pcb units.
const int scale
Store the a model based on meshes and materials.
Definition: c3dmodel.h:91

References addModels(), BOARD_ADAPTER::BiuTo3dUnits(), FP_LIB_TABLE::FindRow(), BOARD::Footprints(), BOARD_ADAPTER::Get3dCacheManager(), BOARD_ADAPTER::GetBoard(), BOARD_ADAPTER::GetFootprintZPos(), LIB_TABLE_ROW::GetFullURI(), S3D_CACHE::GetModel(), BOARD::GetProject(), BOARD_ADAPTER::IsFootprintShown(), RENDER_3D_BASE::m_boardAdapter, BOARD_ADAPTER::m_Cfg, EDA_3D_VIEWER_SETTINGS::m_Render, PROJECT::PcbFootprintLibs(), scale, EDA_3D_VIEWER_SETTINGS::RENDER_SETTINGS::show_footprints_insert, EDA_3D_VIEWER_SETTINGS::RENDER_SETTINGS::show_footprints_normal, EDA_3D_VIEWER_SETTINGS::RENDER_SETTINGS::show_footprints_virtual, UNITS3D_TO_UNITSPCB, VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by Reload().

◆ postProcessBlurFinish()

void RENDER_3D_RAYTRACE::postProcessBlurFinish ( GLubyte *  ptrPBO,
REPORTER aStatusReporter 
)
private

Definition at line 889 of file render_3d_raytrace.cpp.

890{
892 {
893 // Now blurs the shader result and compute the final color
894 std::atomic<size_t> nextBlock( 0 );
895 std::atomic<size_t> threadsFinished( 0 );
896
897 size_t parallelThreadCount = std::max<size_t>( std::thread::hardware_concurrency(), 2 );
898
899 for( size_t ii = 0; ii < parallelThreadCount; ++ii )
900 {
901 std::thread t = std::thread( [&]()
902 {
903 for( size_t y = nextBlock.fetch_add( 1 ); y < m_realBufferSize.y;
904 y = nextBlock.fetch_add( 1 ) )
905 {
906 GLubyte* ptr = &ptrPBO[ y * m_realBufferSize.x * 4 ];
907
908 for( signed int x = 0; x < (int)m_realBufferSize.x; ++x )
909 {
910 const SFVEC3F bluredShadeColor = m_postShaderSsao.Blur( SFVEC2I( x, y ) );
911
912#ifdef USE_SRGB_SPACE
913 const SFVEC3F originColor = convertLinearToSRGB(
914 m_postShaderSsao.GetColorAtNotProtected( SFVEC2I( x, y ) ) );
915#else
916 const SFVEC3F originColor =
917 m_postShaderSsao.GetColorAtNotProtected( SFVEC2I( x, y ) );
918#endif
919 const SFVEC3F shadedColor = m_postShaderSsao.ApplyShadeColor(
920 SFVEC2I( x, y ), originColor, bluredShadeColor );
921
922 renderFinalColor( ptr, shadedColor, false );
923
924 ptr += 4;
925 }
926 }
927
928 threadsFinished++;
929 } );
930
931 t.detach();
932 }
933
934 while( threadsFinished < parallelThreadCount )
935 std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) );
936
937 // Debug code
938 //m_postShaderSsao.DebugBuffersOutputAsImages();
939 }
940
941 // End rendering
943}
@ RT_RENDER_STATE_FINISH

References RENDER_3D_BASE::m_boardAdapter, BOARD_ADAPTER::m_Cfg, m_realBufferSize, EDA_3D_VIEWER_SETTINGS::m_Render, and EDA_3D_VIEWER_SETTINGS::RENDER_SETTINGS::raytrace_post_processing.

Referenced by render().

◆ postProcessShading()

void RENDER_3D_RAYTRACE::postProcessShading ( GLubyte *  ptrPBO,
REPORTER aStatusReporter 
)
private

Definition at line 837 of file render_3d_raytrace.cpp.

838{
840 {
841 if( aStatusReporter )
842 aStatusReporter->Report( _( "Rendering: Post processing shader" ) );
843
845
846 std::atomic<size_t> nextBlock( 0 );
847 std::atomic<size_t> threadsFinished( 0 );
848
849 size_t parallelThreadCount = std::max<size_t>( std::thread::hardware_concurrency(), 2 );
850
851 for( size_t ii = 0; ii < parallelThreadCount; ++ii )
852 {
853 std::thread t = std::thread( [&]()
854 {
855 for( size_t y = nextBlock.fetch_add( 1 ); y < m_realBufferSize.y;
856 y = nextBlock.fetch_add( 1 ) )
857 {
858 SFVEC3F* ptr = &m_shaderBuffer[ y * m_realBufferSize.x ];
859
860 for( signed int x = 0; x < (int)m_realBufferSize.x; ++x )
861 {
862 *ptr = m_postShaderSsao.Shade( SFVEC2I( x, y ) );
863 ptr++;
864 }
865 }
866
867 threadsFinished++;
868 } );
869
870 t.detach();
871 }
872
873 while( threadsFinished < parallelThreadCount )
874 std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) );
875
877
878 // Set next state
880 }
881 else
882 {
883 // As this was an invalid state, set to finish
885 }
886}
void SetShadedBuffer(SFVEC3F *aShadedBuffer)
void SetShadowsEnabled(bool aIsShadowsEnabled)
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)=0
Report a string with a given severity.
#define _(s)
@ RT_RENDER_STATE_POST_PROCESS_BLUR_AND_FINISH

References _, RENDER_3D_BASE::m_boardAdapter, BOARD_ADAPTER::m_Cfg, m_postShaderSsao, m_realBufferSize, EDA_3D_VIEWER_SETTINGS::m_Render, m_renderState, m_shaderBuffer, EDA_3D_VIEWER_SETTINGS::RENDER_SETTINGS::raytrace_post_processing, EDA_3D_VIEWER_SETTINGS::RENDER_SETTINGS::raytrace_shadows, REPORTER::Report(), RT_RENDER_STATE_POST_PROCESS_BLUR_AND_FINISH, POST_SHADER_SSAO::SetShadedBuffer(), and POST_SHADER_SSAO::SetShadowsEnabled().

Referenced by render().

◆ Redraw()

bool RENDER_3D_RAYTRACE::Redraw ( bool  aIsMoving,
REPORTER aStatusReporter,
REPORTER aWarningReporter 
)
overridevirtual

Redraw the view.

Parameters
aIsMovingif the user is moving the scene, it should be render in preview mode.
aStatusReportera pointer to the status progress reporter.
Returns
true if the render would like to redraw again.

Implements RENDER_3D_BASE.

Definition at line 149 of file render_3d_raytrace.cpp.

151{
152 bool requestRedraw = false;
153
154 // Initialize openGL if need
156 {
157 if( !initializeOpenGL() )
158 return false;
159
160 //aIsMoving = true;
161 requestRedraw = true;
162
163 // It will assign the first time the windows size, so it will now
164 // revert to preview mode the first time the Redraw is called
167 }
168
169 std::unique_ptr<BUSY_INDICATOR> busy = CreateBusyIndicator();
170
171 // Reload board if it was requested
173 {
174 if( aStatusReporter )
175 aStatusReporter->Report( _( "Loading..." ) );
176
177 //aIsMoving = true;
178 requestRedraw = true;
179 Reload( aStatusReporter, aWarningReporter, false );
180 }
181
182
183 // Recalculate constants if windows size was changed
185 {
187 aIsMoving = true;
188 requestRedraw = true;
189
191 }
192
193
194 // Clear buffers
195 glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
196 glClearDepth( 1.0f );
197 glClearStencil( 0x00 );
198 glClear( GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
199
200 // 4-byte pixel alignment
201 glPixelStorei( GL_UNPACK_ALIGNMENT, 4 );
202
203 glDisable( GL_STENCIL_TEST );
204 glDisable( GL_LIGHTING );
205 glDisable( GL_COLOR_MATERIAL );
206 glDisable( GL_DEPTH_TEST );
207 glDisable( GL_TEXTURE_2D );
208 glDisable( GL_BLEND );
209 glDisable( GL_MULTISAMPLE );
210
211 const bool was_camera_changed = m_camera.ParametersChanged();
212
213 if( requestRedraw || aIsMoving || was_camera_changed )
214 m_renderState = RT_RENDER_STATE_MAX; // Set to an invalid state,
215 // so it will restart again latter
216
217 // This will only render if need, otherwise it will redraw the PBO on the screen again
218 if( aIsMoving || was_camera_changed )
219 {
220 // Set head light (camera view light) with the opposite direction of the camera
221 if( m_cameraLight )
223
226
227 // Bind PBO
228 glBindBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB, m_pboId );
229
230 // Get the PBO pixel pointer to write the data
231 GLubyte* ptrPBO = (GLubyte *)glMapBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB,
232 GL_WRITE_ONLY_ARB );
233
234 if( ptrPBO )
235 {
236 renderPreview( ptrPBO );
237
238 // release pointer to mapping buffer, this initialize the coping to PBO
239 glUnmapBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB );
240 }
241
242 glWindowPos2i( m_xoffset, m_yoffset );
243 }
244 else
245 {
246 // Bind PBO
247 glBindBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB, m_pboId );
248
250 {
251 // Get the PBO pixel pointer to write the data
252 GLubyte* ptrPBO = (GLubyte *)glMapBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB,
253 GL_WRITE_ONLY_ARB );
254
255 if( ptrPBO )
256 {
257 render( ptrPBO, aStatusReporter );
258
260 requestRedraw = true;
261
262 // release pointer to mapping buffer, this initialize the coping to PBO
263 glUnmapBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB );
264 }
265 }
266
268 {
269 glClear( GL_COLOR_BUFFER_BIT );
270 }
271
272 glWindowPos2i( m_xoffset, m_yoffset );
273 }
274
275 // This way it will blend the progress rendering with the last buffer. eg:
276 // if it was called after a openGL.
277 glEnable( GL_BLEND );
278 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
279 glEnable( GL_ALPHA_TEST );
280 glDrawPixels( m_realBufferSize.x, m_realBufferSize.y, GL_RGBA, GL_UNSIGNED_BYTE, 0 );
281 glBindBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB, 0 );
282
283 return requestRedraw;
284}
SFVEC4F m_BgColorTop
background top color
SFVEC4F m_BgColorBot
background bottom color
const SFVEC3F & GetDir() const
Definition: camera.h:109
bool ParametersChanged()
Definition: camera.cpp:662
void SetDirection(const SFVEC3F &aDir)
Set directional light orientation.
Definition: light.h:131
CAMERA & m_camera
Flag if the opengl specific for this render was already initialized.
std::unique_ptr< BUSY_INDICATOR > CreateBusyIndicator() const
Return a created busy indicator, if a factory has been set, else a null pointer.
void render(GLubyte *ptrPBO, REPORTER *aStatusReporter)
void renderPreview(GLubyte *ptrPBO)
void Reload(REPORTER *aStatusReporter, REPORTER *aWarningReporter, bool aOnlyLoadCopperAndShapes)
void OglDrawBackground(const SFVEC3F &aTopColor, const SFVEC3F &aBotColor)
Definition: ogl_utils.cpp:160

References _, RENDER_3D_BASE::CreateBusyIndicator(), CAMERA::GetDir(), initializeBlockPositions(), initializeOpenGL(), BOARD_ADAPTER::m_BgColorBot, BOARD_ADAPTER::m_BgColorTop, RENDER_3D_BASE::m_boardAdapter, RENDER_3D_BASE::m_camera, m_cameraLight, RENDER_3D_BASE::m_is_opengl_initialized, m_oldWindowsSize, m_pboId, m_realBufferSize, RENDER_3D_BASE::m_reloadRequested, m_renderState, RENDER_3D_BASE::m_windowSize, m_xoffset, m_yoffset, OglDrawBackground(), CAMERA::ParametersChanged(), Reload(), render(), renderPreview(), REPORTER::Report(), RT_RENDER_STATE_FINISH, RT_RENDER_STATE_MAX, and DIRECTIONAL_LIGHT::SetDirection().

◆ Reload()

void RENDER_3D_RAYTRACE::Reload ( REPORTER aStatusReporter,
REPORTER aWarningReporter,
bool  aOnlyLoadCopperAndShapes 
)

Definition at line 361 of file raytracing/create_scene.cpp.

363{
364 m_reloadRequested = false;
365
366 m_modelMaterialMap.clear();
367
370
371 unsigned stats_startReloadTime = GetRunningMicroSecs();
372
373 if( !aOnlyLoadCopperAndShapes )
374 {
375 m_boardAdapter.InitSettings( aStatusReporter, aWarningReporter );
376
378 m_camera.SetBoardLookAtPos( camera_pos );
379 }
380
383
385
386 if( aStatusReporter )
387 aStatusReporter->Report( _( "Load Raytracing: board" ) );
388
389 // Create and add the outline board
392
395
396 if( !aOnlyLoadCopperAndShapes )
397 {
398 const int outlineCount = m_boardAdapter.GetBoardPoly().OutlineCount();
399
400 if( outlineCount > 0 )
401 {
402 float divFactor = 0.0f;
403
405 divFactor = m_boardAdapter.GetAverageViaHoleDiameter() * 18.0f;
406 else if( m_boardAdapter.GetHoleCount() )
407 divFactor = m_boardAdapter.GetAverageHoleDiameter() * 8.0f;
408
410
411 // Calculate an antiboard outline
412 SHAPE_POLY_SET antiboardPoly;
413
415
416 antiboardPoly.BooleanSubtract( boardPolyCopy, SHAPE_POLY_SET::PM_FAST );
417 antiboardPoly.Fracture( SHAPE_POLY_SET::PM_FAST );
418
419 for( int ii = 0; ii < antiboardPoly.OutlineCount(); ii++ )
420 {
423 *m_boardAdapter.GetBoard(), ii );
424 }
425
427
428 boardPolyCopy.Fracture( SHAPE_POLY_SET::PM_FAST );
429
430 for( int ii = 0; ii < outlineCount; ii++ )
431 {
433 m_boardAdapter.BiuTo3dUnits(), divFactor,
434 *m_boardAdapter.GetBoard(), ii );
435 }
436
438 {
439 const LIST_OBJECT2D& listObjects = m_outlineBoard2dObjects->GetList();
440
441 for( const OBJECT_2D* object2d_A : listObjects )
442 {
443 std::vector<const OBJECT_2D*>* object2d_B = new std::vector<const OBJECT_2D*>();
444
445 // Check if there are any THT that intersects this outline object part
446 if( !m_boardAdapter.GetThroughHoleOds().GetList().empty() )
447 {
448 const BVH_CONTAINER_2D& throughHoles = m_boardAdapter.GetThroughHoleOds();
449 CONST_LIST_OBJECT2D intersecting;
450
451 throughHoles.GetIntersectingObjects( object2d_A->GetBBox(), intersecting );
452
453 for( const OBJECT_2D* hole : intersecting )
454 {
455 if( object2d_A->Intersects( hole->GetBBox() ) )
456 object2d_B->push_back( hole );
457 }
458 }
459
460 if( !m_antioutlineBoard2dObjects->GetList().empty() )
461 {
462 CONST_LIST_OBJECT2D intersecting;
463
465 intersecting );
466
467 for( const OBJECT_2D* obj : intersecting )
468 object2d_B->push_back( obj );
469 }
470
471 if( object2d_B->empty() )
472 {
473 delete object2d_B;
474 object2d_B = CSGITEM_EMPTY;
475 }
476
477 if( object2d_B == CSGITEM_EMPTY )
478 {
479 LAYER_ITEM* objPtr = new LAYER_ITEM( object2d_A,
482
483 objPtr->SetMaterial( &m_materials.m_EpoxyBoard );
485 m_objectContainer.Add( objPtr );
486 }
487 else
488 {
489
490 LAYER_ITEM_2D* itemCSG2d = new LAYER_ITEM_2D( object2d_A, object2d_B,
493
495
496 LAYER_ITEM* objPtr = new LAYER_ITEM( itemCSG2d,
499
500 objPtr->SetMaterial( &m_materials.m_EpoxyBoard );
502 m_objectContainer.Add( objPtr );
503 }
504 }
505
506 // Add cylinders of the board body to container
507 // Note: This is actually a workaround for the holes in the board.
508 // The issue is because if a hole is in a border of a divided polygon ( ex
509 // a polygon or dummy block) it will cut also the render of the hole.
510 // So this will add a full hole.
511 // In fact, that is not need if the hole have copper.
512 if( !m_boardAdapter.GetThroughHoleOds().GetList().empty() )
513 {
515
516 for( const OBJECT_2D* hole2d : holeList )
517 {
518 if( !m_antioutlineBoard2dObjects->GetList().empty() )
519 {
520 CONST_LIST_OBJECT2D intersecting;
521
523 intersecting );
524
525 // Do not add cylinder if it intersects the edge of the board
526 if( !intersecting.empty() )
527 continue;
528 }
529
530 switch( hole2d->GetObjectType() )
531 {
533 {
534 const float radius = hole2d->GetBBox().GetExtent().x * 0.5f * 0.999f;
535
536 CYLINDER* objPtr = new CYLINDER( hole2d->GetCentroid(),
539 radius );
540
541 objPtr->SetMaterial( &m_materials.m_EpoxyBoard );
543
544 m_objectContainer.Add( objPtr );
545 }
546 break;
547
548 default:
549 break;
550 }
551 }
552 }
553 }
554 }
555 }
556
557 if( aStatusReporter )
558 aStatusReporter->Report( _( "Load Raytracing: layers" ) );
559
560 // Add layers maps (except B_Mask and F_Mask)
561 for( const std::pair<const PCB_LAYER_ID, BVH_CONTAINER_2D*>& entry : m_boardAdapter.GetLayerMap() )
562 {
563 const PCB_LAYER_ID layer_id = entry.first;
564 const BVH_CONTAINER_2D* container2d = entry.second;
565
566 // Only process layers that exist
567 if( !container2d )
568 continue;
569
570 if( aOnlyLoadCopperAndShapes && !IsCopperLayer( layer_id ) )
571 continue;
572
573 // Mask layers are not processed here because they are a special case
574 if( layer_id == B_Mask || layer_id == F_Mask )
575 continue;
576
577 MATERIAL* materialLayer = &m_materials.m_SilkS;
578 SFVEC3F layerColor = SFVEC3F( 0.0f, 0.0f, 0.0f );
579
580 switch( layer_id )
581 {
582 case B_Adhes:
583 case F_Adhes:
584 break;
585
586 case B_Paste:
587 case F_Paste:
588 materialLayer = &m_materials.m_Paste;
589
592 else
593 layerColor = m_boardAdapter.GetLayerColor( layer_id );
594
595 break;
596
597 case B_SilkS:
598 materialLayer = &m_materials.m_SilkS;
599
602 else
603 layerColor = m_boardAdapter.GetLayerColor( layer_id );
604
605 break;
606
607 case F_SilkS:
608 materialLayer = &m_materials.m_SilkS;
609
612 else
613 layerColor = m_boardAdapter.GetLayerColor( layer_id );
614
615 break;
616
617 case Dwgs_User:
618 case Cmts_User:
619 case Eco1_User:
620 case Eco2_User:
621 case Edge_Cuts:
622 case Margin:
623 break;
624
625 case B_CrtYd:
626 case F_CrtYd:
627 break;
628
629 case B_Fab:
630 case F_Fab:
631 break;
632
633 default:
635 {
637 {
638 layerColor = SFVEC3F( 184.0f / 255.0f, 115.0f / 255.0f, 50.0f / 255.0f );
639 materialLayer = &m_materials.m_NonPlatedCopper;
640 }
641 else
642 {
643 layerColor = m_boardAdapter.m_CopperColor;
644 materialLayer = &m_materials.m_Copper;
645 }
646 }
647 else
648 {
649 layerColor = m_boardAdapter.GetLayerColor( layer_id );
650 }
651
652 break;
653 }
654
655 createItemsFromContainer( container2d, layer_id, materialLayer, layerColor, 0.0f );
656 } // for each layer on map
657
658 // Create plated copper
661 {
665
669 }
670
671 if( !aOnlyLoadCopperAndShapes )
672 {
673 // Add Mask layer
674 // Solder mask layers are "negative" layers so the elements that we have in the container
675 // should remove the board outline. We will check for all objects in the outline if it
676 // intersects any object in the layer container and also any hole.
678 && !m_outlineBoard2dObjects->GetList().empty() )
679 {
680 const MATERIAL* materialLayer = &m_materials.m_SolderMask;
681
682 for( const std::pair<const PCB_LAYER_ID, BVH_CONTAINER_2D*>& entry : m_boardAdapter.GetLayerMap() )
683 {
684 const PCB_LAYER_ID layer_id = entry.first;
685 const BVH_CONTAINER_2D* container2d = entry.second;
686
687 // Only process layers that exist
688 if( !container2d )
689 continue;
690
691 // Only get the Solder mask layers (and only if the board has them)
692 if( !( layer_id == B_Mask || layer_id == F_Mask ) )
693 continue;
694
695 SFVEC3F layerColor;
696
698 {
699 if( layer_id == B_Mask )
701 else
703 }
704 else
705 {
706 layerColor = m_boardAdapter.GetLayerColor( layer_id );
707 }
708
709 const float zLayerMin = m_boardAdapter.GetLayerBottomZPos( layer_id );
710 const float zLayerMax = m_boardAdapter.GetLayerTopZPos( layer_id );
711
712 // Get the outline board objects
713 for( const OBJECT_2D* object2d_A : m_outlineBoard2dObjects->GetList() )
714 {
715 std::vector<const OBJECT_2D*>* object2d_B = new std::vector<const OBJECT_2D*>();
716
717 // Check if there are any THT that intersects this outline object part
718 if( !m_boardAdapter.GetThroughHoleOds().GetList().empty() )
719 {
720 const BVH_CONTAINER_2D& throughHoles = m_boardAdapter.GetThroughHoleOds();
721 CONST_LIST_OBJECT2D intersecting;
722
723 throughHoles.GetIntersectingObjects( object2d_A->GetBBox(), intersecting );
724
725 for( const OBJECT_2D* hole : intersecting )
726 {
727 if( object2d_A->Intersects( hole->GetBBox() ) )
728 object2d_B->push_back( hole );
729 }
730 }
731
732 // Check if there are any objects in the layer to subtract with the current
733 // object
734 if( !container2d->GetList().empty() )
735 {
736 CONST_LIST_OBJECT2D intersecting;
737
738 container2d->GetIntersectingObjects( object2d_A->GetBBox(), intersecting );
739
740 for( const OBJECT_2D* obj : intersecting )
741 object2d_B->push_back( obj );
742 }
743
744 if( object2d_B->empty() )
745 {
746 delete object2d_B;
747 object2d_B = CSGITEM_EMPTY;
748 }
749
750 if( object2d_B == CSGITEM_EMPTY )
751 {
752#if 0
753 createObject( m_objectContainer, object2d_A, zLayerMin, zLayerMax,
754 materialLayer, layerColor );
755#else
756 LAYER_ITEM* objPtr = new LAYER_ITEM( object2d_A, zLayerMin, zLayerMax );
757
758 objPtr->SetMaterial( materialLayer );
759 objPtr->SetColor( ConvertSRGBToLinear( layerColor ) );
760
761 m_objectContainer.Add( objPtr );
762#endif
763 }
764 else
765 {
766 LAYER_ITEM_2D* itemCSG2d = new LAYER_ITEM_2D( object2d_A, object2d_B,
768 object2d_A->GetBoardItem() );
769
771
772 LAYER_ITEM* objPtr = new LAYER_ITEM( itemCSG2d, zLayerMin, zLayerMax );
773 objPtr->SetMaterial( materialLayer );
774 objPtr->SetColor( ConvertSRGBToLinear( layerColor ) );
775
776 m_objectContainer.Add( objPtr );
777 }
778 }
779 }
780 }
781
783 }
784
785#ifdef PRINT_STATISTICS_3D_VIEWER
786 unsigned stats_endConvertTime = GetRunningMicroSecs();
787 unsigned stats_startLoad3DmodelsTime = stats_endConvertTime;
788#endif
789
790 if( aStatusReporter )
791 aStatusReporter->Report( _( "Loading 3D models..." ) );
792
793 load3DModels( m_objectContainer, aOnlyLoadCopperAndShapes );
794
795#ifdef PRINT_STATISTICS_3D_VIEWER
796 unsigned stats_endLoad3DmodelsTime = GetRunningMicroSecs();
797#endif
798
799 if( !aOnlyLoadCopperAndShapes )
800 {
801 // Add floor
803 {
804 BBOX_3D boardBBox = m_boardAdapter.GetBBox();
805
806 if( boardBBox.IsInitialized() )
807 {
808 boardBBox.Scale( 3.0f );
809
810 if( m_objectContainer.GetList().size() > 0 )
811 {
812 BBOX_3D containerBBox = m_objectContainer.GetBBox();
813
814 containerBBox.Scale( 1.3f );
815
816 const SFVEC3F centerBBox = containerBBox.GetCenter();
817
818 // Floor triangles
819 const float minZ = glm::min( containerBBox.Min().z, boardBBox.Min().z );
820
821 const SFVEC3F v1 =
822 SFVEC3F( -RANGE_SCALE_3D * 4.0f, -RANGE_SCALE_3D * 4.0f, minZ )
823 + SFVEC3F( centerBBox.x, centerBBox.y, 0.0f );
824
825 const SFVEC3F v3 =
826 SFVEC3F( +RANGE_SCALE_3D * 4.0f, +RANGE_SCALE_3D * 4.0f, minZ )
827 + SFVEC3F( centerBBox.x, centerBBox.y, 0.0f );
828
829 const SFVEC3F v2 = SFVEC3F( v1.x, v3.y, v1.z );
830 const SFVEC3F v4 = SFVEC3F( v3.x, v1.y, v1.z );
831
833
834 TRIANGLE* newTriangle1 = new TRIANGLE( v1, v2, v3 );
835 TRIANGLE* newTriangle2 = new TRIANGLE( v3, v4, v1 );
836
837 m_objectContainer.Add( newTriangle1 );
838 m_objectContainer.Add( newTriangle2 );
839
840 newTriangle1->SetMaterial( &m_materials.m_Floor );
841 newTriangle2->SetMaterial( &m_materials.m_Floor );
842
843 newTriangle1->SetColor( backgroundColor );
844 newTriangle2->SetColor( backgroundColor );
845
846 // Ceiling triangles
847 const float maxZ = glm::max( containerBBox.Max().z, boardBBox.Max().z );
848
849 const SFVEC3F v5 = SFVEC3F( v1.x, v1.y, maxZ );
850 const SFVEC3F v6 = SFVEC3F( v2.x, v2.y, maxZ );
851 const SFVEC3F v7 = SFVEC3F( v3.x, v3.y, maxZ );
852 const SFVEC3F v8 = SFVEC3F( v4.x, v4.y, maxZ );
853
854 TRIANGLE* newTriangle3 = new TRIANGLE( v7, v6, v5 );
855 TRIANGLE* newTriangle4 = new TRIANGLE( v5, v8, v7 );
856
857 m_objectContainer.Add( newTriangle3 );
858 m_objectContainer.Add( newTriangle4 );
859
860 newTriangle3->SetMaterial( &m_materials.m_Floor );
861 newTriangle4->SetMaterial( &m_materials.m_Floor );
862
863 newTriangle3->SetColor( backgroundColor );
864 newTriangle4->SetColor( backgroundColor );
865 }
866 }
867 }
868
869 // Init initial lights
870 for( LIGHT* light : m_lights )
871 delete light;
872
873 m_lights.clear();
874
875 auto IsColorZero =
876 []( const SFVEC3F& aSource )
877 {
878 return ( ( aSource.r < ( 1.0f / 255.0f ) ) && ( aSource.g < ( 1.0f / 255.0f ) )
879 && ( aSource.b < ( 1.0f / 255.0f ) ) );
880 };
881
882 SFVEC3F cameraLightColor =
884 SFVEC3F topLightColor =
886 SFVEC3F bottomLightColor =
888
889 m_cameraLight = new DIRECTIONAL_LIGHT( SFVEC3F( 0.0f, 0.0f, 0.0f ), cameraLightColor );
891
892 if( !IsColorZero( cameraLightColor ) )
893 m_lights.push_back( m_cameraLight );
894
895 const SFVEC3F& boardCenter = m_boardAdapter.GetBBox().GetCenter();
896
897 if( !IsColorZero( topLightColor ) )
898 {
899 m_lights.push_back( new POINT_LIGHT( SFVEC3F( boardCenter.x, boardCenter.y,
900 +RANGE_SCALE_3D * 2.0f ),
901 topLightColor ) );
902 }
903
904 if( !IsColorZero( bottomLightColor ) )
905 {
906 m_lights.push_back( new POINT_LIGHT( SFVEC3F( boardCenter.x, boardCenter.y,
907 -RANGE_SCALE_3D * 2.0f ),
908 bottomLightColor ) );
909 }
910
911 for( size_t i = 0; i < m_boardAdapter.m_Cfg->m_Render.raytrace_lightColor.size(); ++i )
912 {
913 SFVEC3F lightColor =
915
916 if( !IsColorZero( lightColor ) )
917 {
919
920 m_lights.push_back( new DIRECTIONAL_LIGHT(
921 SphericalToCartesian( glm::pi<float>() * sc.x, glm::pi<float>() * sc.y ),
922 lightColor ) );
923 }
924 }
925 }
926
927 // Set min. and max. zoom range. This doesn't really fit here, but moving this outside of this
928 // class would require reimplementing bounding box calculation (feel free to do this if you
929 // have time and patience).
930 if( m_objectContainer.GetList().size() > 0 )
931 {
932 float ratio =
935
937 / -m_camera.GetCameraInitPos().z ) );
938 }
939
940 // Create an accelerator
941 delete m_accelerator;
943
944 if( aStatusReporter )
945 {
946 // Calculation time in seconds
947 double calculation_time = (double) GetRunningMicroSecs() - stats_startReloadTime / 1e6;
948
949 aStatusReporter->Report( wxString::Format( _( "Reload time %.3f s" ), calculation_time ) );
950 }
951}
float NextFloatDown(float v)
Definition: 3d_fastmath.h:157
float NextFloatUp(float v)
Definition: 3d_fastmath.h:136
SFVEC3F SphericalToCartesian(float aInclination, float aAzimuth)
https://en.wikipedia.org/wiki/Spherical_coordinate_system
Definition: 3d_math.h:43
#define RANGE_SCALE_3D
This defines the range that all coord will have to be rendered.
Definition: board_adapter.h:62
SFVEC4F m_SolderPasteColor
in realistic mode: solder paste color
const SHAPE_POLY_SET & GetBoardPoly() const noexcept
Get the current polygon of the epoxy board.
const BBOX_3D & GetBBox() const noexcept
Get the board outling bounding box.
SFVEC4F m_SolderMaskColorBot
in realistic mode: solder mask color ( bot )
void InitSettings(REPORTER *aStatusReporter, REPORTER *aWarningReporter)
Function to be called by the render when it need to reload the settings for the board.
SFVEC4F m_SolderMaskColorTop
in realistic mode: solder mask color ( top )
SFVEC4F GetColor(const COLOR4D &aColor) const
const BVH_CONTAINER_2D * GetPlatedPadsBack() const noexcept
float GetAverageViaHoleDiameter() const noexcept
SFVEC2F GetSphericalCoord(int i) const
unsigned int GetViaCount() const noexcept
const SFVEC3F & GetBoardCenter() const noexcept
The board center position in 3D units.
SFVEC4F m_SilkScreenColorTop
in realistic mode: SilkScreen color ( top )
unsigned int GetHoleCount() const noexcept
SFVEC4F m_SilkScreenColorBot
in realistic mode: SilkScreen color ( bot )
const BVH_CONTAINER_2D * GetPlatedPadsFront() const noexcept
SFVEC4F m_BoardBodyColor
in realistic mode: FR4 board color
float GetAverageHoleDiameter() const noexcept
SFVEC4F GetLayerColor(PCB_LAYER_ID aLayerId) const
Get the technical color of a layer.
void SetMinZoom(float minZoom)
Definition: camera.h:198
void SetBoardLookAtPos(const SFVEC3F &aBoardPos)
Definition: camera.cpp:123
static const float DEFAULT_MAX_ZOOM
Definition: camera.h:81
void SetMaxZoom(float maxZoom)
Definition: camera.h:205
const SFVEC3F & GetCameraInitPos() const
Definition: camera.h:144
virtual void Clear()
const BBOX_3D & GetBBox() const
Definition: container_3d.h:63
const LIST_OBJECT & GetList() const
Definition: container_3d.h:59
A vertical cylinder.
Definition: cylinder_3d.h:38
void SetColor(SFVEC3F aObjColor)
Definition: cylinder_3d.h:48
A light source based only on a directional vector.
Definition: light.h:116
A base light class to derive to implement other light classes.
Definition: light.h:41
void SetCastShadows(bool aCastShadow)
Definition: light.h:59
Base material class that can be used to derive other material implementations.
Definition: material.h:240
static OBJECT_2D_STATS & Instance()
Definition: object_2d.h:137
void ResetStats()
Definition: object_2d.h:122
static OBJECT_3D_STATS & Instance()
Definition: object_3d.h:132
void ResetStats()
Definition: object_3d.h:115
Point light source based on http://ogldev.atspace.co.uk/www/tutorial20/tutorial20....
Definition: light.h:71
void load3DModels(CONTAINER_3D &aDstContainer, bool aSkipMaterialInformation)
void createItemsFromContainer(const BVH_CONTAINER_2D *aContainer2d, PCB_LAYER_ID aLayer_id, const MATERIAL *aMaterialLayer, const SFVEC3F &aLayerColor, float aLayerZOffset)
void createObject(CONTAINER_3D &aDstContainer, const OBJECT_2D *aObject2D, float aZMin, float aZMax, const MATERIAL *aMaterial, const SFVEC3F &aObjColor)
Create one or more 3D objects form a 2D object and Z positions.
std::list< LIGHT * > m_lights
static constexpr float MIN_DISTANCE_IU
Represent a set of closed polygons.
void BooleanSubtract(const SHAPE_POLY_SET &b, POLYGON_MODE aFastMode)
Perform boolean polyset intersection For aFastMode meaning, see function booleanOp.
void Fracture(POLYGON_MODE aFastMode)
Convert a single outline slitted ("fractured") polygon into a set ouf outlines with holes.
int OutlineCount() const
Return the number of vertices in a given outline/hole.
T y
Definition: vector3.h:62
T z
Definition: vector3.h:63
T x
Definition: vector3.h:61
bool IsCopperLayer(int aLayerId)
Tests whether a layer is a copper layer.
Definition: layer_ids.h:825
@ F_CrtYd
Definition: layer_ids.h:117
@ B_Adhes
Definition: layer_ids.h:97
@ Edge_Cuts
Definition: layer_ids.h:113
@ Dwgs_User
Definition: layer_ids.h:109
@ Cmts_User
Definition: layer_ids.h:110
@ F_Adhes
Definition: layer_ids.h:98
@ Eco1_User
Definition: layer_ids.h:111
@ F_Fab
Definition: layer_ids.h:120
@ Margin
Definition: layer_ids.h:114
@ B_CrtYd
Definition: layer_ids.h:116
@ Eco2_User
Definition: layer_ids.h:112
@ B_Fab
Definition: layer_ids.h:119
void ConvertPolygonToBlocks(const SHAPE_POLY_SET &aMainPath, CONTAINER_2D_BASE &aDstContainer, float aBiuTo3dUnitsScale, float aDivFactor, const BOARD_ITEM &aBoardItem, int aPolyIndex)
Use a polygon in the format of the ClipperLib::Path and process it and create multiple 2d objects (PO...
Definition: polygon_2d.cpp:378
unsigned GetRunningMicroSecs()
An alternate way to calculate an elapsed time (in microsecondes) to class PROF_COUNTER.
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
void buildBoardBoundingBoxPoly(const BOARD *aBoard, SHAPE_POLY_SET &aOutline)
Get the complete bounding box of the board (including all items).
SFVEC3F GetCenter() const
Return the center point of the bounding box.
Definition: bbox_3d.cpp:132
const SFVEC3F & Min() const
Return the minimum vertex pointer.
Definition: bbox_3d.h:183
const SFVEC3F & Max() const
Return the maximum vertex pointer.
Definition: bbox_3d.h:190
float GetMaxDimension() const
Definition: bbox_3d.cpp:167
bool IsInitialized() const
Check if this bounding box is already initialized.
Definition: bbox_3d.cpp:88
void Scale(float aScale)
Scales a bounding box by its center.
Definition: bbox_3d.cpp:182
std::vector< KIGFX::COLOR4D > raytrace_lightColor
VECTOR3I v3(1, 1, 1)

References _, CONTAINER_2D_BASE::Add(), CONTAINER_3D_BASE::Add(), addPadsAndVias(), B_Adhes, B_CrtYd, B_Cu, B_Fab, B_Mask, B_Paste, B_SilkS, BOARD_ADAPTER::BiuTo3dUnits(), SHAPE_POLY_SET::BooleanSubtract(), buildBoardBoundingBoxPoly(), BVH_CONTAINER_2D::BuildBVH(), CONTAINER_2D_BASE::Clear(), CONTAINER_3D_BASE::Clear(), Cmts_User, ConvertPolygonToBlocks(), ConvertSRGBToLinear(), createItemsFromContainer(), createObject(), CSGITEM_EMPTY, CSGITEM_FULL, CYLINDER, CAMERA::DEFAULT_MAX_ZOOM, Dwgs_User, Eco1_User, Eco2_User, Edge_Cuts, F_Adhes, F_CrtYd, F_Cu, F_Fab, F_Mask, F_Paste, F_SilkS, FILLED_CIRCLE, Format(), SHAPE_POLY_SET::Fracture(), BOARD_ADAPTER::GetAverageHoleDiameter(), BOARD_ADAPTER::GetAverageViaHoleDiameter(), BOARD_ADAPTER::GetBackCopperThickness(), CONTAINER_3D_BASE::GetBBox(), BOARD_ADAPTER::GetBBox(), BOARD_ADAPTER::GetBoard(), BOARD_ADAPTER::GetBoardCenter(), BOARD_ADAPTER::GetBoardPoly(), CAMERA::GetCameraInitPos(), BBOX_3D::GetCenter(), BOARD_ADAPTER::GetColor(), BOARD_ADAPTER::GetFrontCopperThickness(), BOARD_ADAPTER::GetHoleCount(), BVH_CONTAINER_2D::GetIntersectingObjects(), BOARD_ADAPTER::GetLayerBottomZPos(), BOARD_ADAPTER::GetLayerColor(), BOARD_ADAPTER::GetLayerMap(), BOARD_ADAPTER::GetLayerTopZPos(), CONTAINER_2D_BASE::GetList(), CONTAINER_3D_BASE::GetList(), BBOX_3D::GetMaxDimension(), BOARD_ADAPTER::GetPlatedPadsBack(), BOARD_ADAPTER::GetPlatedPadsFront(), GetRunningMicroSecs(), BOARD_ADAPTER::GetSphericalCoord(), BOARD_ADAPTER::GetThroughHoleOds(), BOARD_ADAPTER::GetViaCount(), BOARD_ADAPTER::InitSettings(), OBJECT_2D_STATS::Instance(), OBJECT_3D_STATS::Instance(), IsCopperLayer(), BBOX_3D::IsInitialized(), load3DModels(), m_accelerator, m_antioutlineBoard2dObjects, BOARD_ADAPTER::m_BgColorTop, RENDER_3D_BASE::m_boardAdapter, BOARD_ADAPTER::m_BoardBodyColor, RENDER_3D_BASE::m_camera, m_cameraLight, BOARD_ADAPTER::m_Cfg, m_containerWithObjectsToDelete, BOARD_ADAPTER::m_CopperColor, m_lights, m_materials, m_modelMaterialMap, m_objectContainer, m_outlineBoard2dObjects, RENDER_3D_BASE::m_reloadRequested, EDA_3D_VIEWER_SETTINGS::m_Render, BOARD_ADAPTER::m_SilkScreenColorBot, BOARD_ADAPTER::m_SilkScreenColorTop, BOARD_ADAPTER::m_SolderMaskColorBot, BOARD_ADAPTER::m_SolderMaskColorTop, BOARD_ADAPTER::m_SolderPasteColor, Margin, BBOX_3D::Max(), MIDDLE, BBOX_3D::Min(), MIN_DISTANCE_IU, NextFloatDown(), NextFloatUp(), SHAPE_POLY_SET::OutlineCount(), SHAPE_POLY_SET::PM_FAST, RANGE_SCALE_3D, EDA_3D_VIEWER_SETTINGS::RENDER_SETTINGS::raytrace_backfloor, EDA_3D_VIEWER_SETTINGS::RENDER_SETTINGS::raytrace_lightColor, EDA_3D_VIEWER_SETTINGS::RENDER_SETTINGS::raytrace_lightColorBottom, EDA_3D_VIEWER_SETTINGS::RENDER_SETTINGS::raytrace_lightColorCamera, EDA_3D_VIEWER_SETTINGS::RENDER_SETTINGS::raytrace_lightColorTop, EDA_3D_VIEWER_SETTINGS::RENDER_SETTINGS::realistic, EDA_3D_VIEWER_SETTINGS::RENDER_SETTINGS::renderPlatedPadsAsPlated, REPORTER::Report(), OBJECT_2D_STATS::ResetStats(), OBJECT_3D_STATS::ResetStats(), BBOX_3D::Scale(), CAMERA::SetBoardLookAtPos(), LIGHT::SetCastShadows(), TRIANGLE::SetColor(), CYLINDER::SetColor(), LAYER_ITEM::SetColor(), OBJECT_3D::SetMaterial(), CAMERA::SetMaxZoom(), CAMERA::SetMinZoom(), setupMaterials(), EDA_3D_VIEWER_SETTINGS::RENDER_SETTINGS::show_board_body, EDA_3D_VIEWER_SETTINGS::RENDER_SETTINGS::show_soldermask, SphericalToCartesian(), TRIANGLE, v1, v2, v3, VECTOR2< T >::x, VECTOR3< T >::x, VECTOR2< T >::y, VECTOR3< T >::y, and VECTOR3< T >::z.

Referenced by EDA_3D_CANVAS::DoRePaint(), and Redraw().

◆ ReloadRequest()

void RENDER_3D_BASE::ReloadRequest ( )
inlineinherited
Todo:
This must be reviewed to add flags to improve specific render.

Definition at line 70 of file render_3d_base.h.

70{ m_reloadRequested = true; }

References RENDER_3D_BASE::m_reloadRequested.

Referenced by EDA_3D_CANVAS::ReloadRequest(), EDA_3D_CANVAS::RenderEngineChanged(), and EDA_3D_CANVAS::RenderRaytracingRequest().

◆ render()

void RENDER_3D_RAYTRACE::render ( GLubyte *  ptrPBO,
REPORTER aStatusReporter 
)
private

Definition at line 287 of file render_3d_raytrace.cpp.

288{
290 {
292
293 if( m_cameraLight )
295
297 {
298 // Set all pixels of PBO transparent (Alpha to 0)
299 // This way it will draw the full buffer but only shows the updated (
300 // already calculated) squares
301 unsigned int nPixels = m_realBufferSize.x * m_realBufferSize.y;
302 GLubyte* tmp_ptrPBO = ptrPBO + 3; // PBO is RGBA
303
304 for( unsigned int i = 0; i < nPixels; ++i )
305 {
306 *tmp_ptrPBO = 0;
307 tmp_ptrPBO += 4; // PBO is RGBA
308 }
309 }
310
313 }
314
315 switch( m_renderState )
316 {
318 renderTracing( ptrPBO, aStatusReporter );
319 break;
320
322 postProcessShading( ptrPBO, aStatusReporter );
323 break;
324
326 postProcessBlurFinish( ptrPBO, aStatusReporter );
327 break;
328
329 default:
330 wxASSERT_MSG( false, wxT( "Invalid state on m_renderState" ) );
332 break;
333 }
334
335 if( aStatusReporter && ( m_renderState == RT_RENDER_STATE_FINISH ) )
336 {
337 // Calculation time in seconds
338 const double elapsed_time = (double)( GetRunningMicroSecs() - m_renderStartTime ) / 1e6;
339
340 aStatusReporter->Report( wxString::Format( _( "Rendering time %.3f s" ), elapsed_time ) );
341 }
342}
void postProcessShading(GLubyte *ptrPBO, REPORTER *aStatusReporter)
void renderTracing(GLubyte *ptrPBO, REPORTER *aStatusReporter)
void postProcessBlurFinish(GLubyte *ptrPBO, REPORTER *aStatusReporter)
SFVEC3F m_backgroundColorBottom
Used to see if the windows size changed.
@ RT_RENDER_STATE_POST_PROCESS_SHADE
@ RT_RENDER_STATE_TRACING

References _, ConvertSRGBToLinear(), EDA_3D_VIEWER_SETTINGS::RENDER_SETTINGS::engine, Format(), CAMERA::GetDir(), GetRunningMicroSecs(), m_backgroundColorBottom, m_backgroundColorTop, BOARD_ADAPTER::m_BgColorBot, BOARD_ADAPTER::m_BgColorTop, RENDER_3D_BASE::m_boardAdapter, RENDER_3D_BASE::m_camera, m_cameraLight, BOARD_ADAPTER::m_Cfg, m_realBufferSize, EDA_3D_VIEWER_SETTINGS::m_Render, m_renderStartTime, m_renderState, OPENGL, postProcessBlurFinish(), postProcessShading(), renderTracing(), REPORTER::Report(), restartRenderState(), RT_RENDER_STATE_FINISH, RT_RENDER_STATE_MAX, RT_RENDER_STATE_POST_PROCESS_BLUR_AND_FINISH, RT_RENDER_STATE_POST_PROCESS_SHADE, RT_RENDER_STATE_TRACING, and DIRECTIONAL_LIGHT::SetDirection().

Referenced by Redraw().

◆ renderAntiAliasPackets()

void RENDER_3D_RAYTRACE::renderAntiAliasPackets ( const SFVEC3F aBgColorY,
const HITINFO_PACKET aHitPck_X0Y0,
const HITINFO_PACKET aHitPck_AA_X1Y1,
const RAY aRayPck,
SFVEC3F aOutHitColor 
)
private
Todo:
Either get rid of the if statement above or do something with the commented out code below.

Definition at line 502 of file render_3d_raytrace.cpp.

506{
507 const bool is_testShadow = m_boardAdapter.m_Cfg->m_Render.raytrace_shadows;
508
509 for( unsigned int y = 0, i = 0; y < RAYPACKET_DIM; ++y )
510 {
511 for( unsigned int x = 0; x < RAYPACKET_DIM; ++x, ++i )
512 {
513 const RAY& rayAA = aRayPck[i];
514
515 HITINFO hitAA;
516 hitAA.m_tHit = std::numeric_limits<float>::infinity();
517 hitAA.m_acc_node_info = 0;
518
519 bool hitted = false;
520
521 const unsigned int idx0y1 = ( x + 0 ) + RAYPACKET_DIM * ( y + 1 );
522 const unsigned int idx1y1 = ( x + 1 ) + RAYPACKET_DIM * ( y + 1 );
523
524 // Gets the node info from the hit.
525 const unsigned int nodex0y0 = aHitPck_X0Y0[ i ].m_HitInfo.m_acc_node_info;
526 const unsigned int node_AA_x0y0 = aHitPck_AA_X1Y1[ i ].m_HitInfo.m_acc_node_info;
527
528 unsigned int nodex1y0 = 0;
529
530 if( x < (RAYPACKET_DIM - 1) )
531 nodex1y0 = aHitPck_X0Y0[ i + 1 ].m_HitInfo.m_acc_node_info;
532
533 unsigned int nodex0y1 = 0;
534
535 if( y < ( RAYPACKET_DIM - 1 ) && idx0y1 < RAYPACKET_RAYS_PER_PACKET )
536 nodex0y1 = aHitPck_X0Y0[idx0y1].m_HitInfo.m_acc_node_info;
537
538 unsigned int nodex1y1 = 0;
539
540 if( ( x < ( RAYPACKET_DIM - 1 ) ) && ( y < ( RAYPACKET_DIM - 1 ) )
541 && idx1y1 < RAYPACKET_RAYS_PER_PACKET )
542 nodex1y1 = aHitPck_X0Y0[idx1y1].m_HitInfo.m_acc_node_info;
543
544 // If all notes are equal we assume there was no change on the object hits.
545 if( ( ( nodex0y0 == nodex1y0 ) || ( nodex1y0 == 0 ) )
546 && ( ( nodex0y0 == nodex0y1 ) || ( nodex0y1 == 0 ) )
547 && ( ( nodex0y0 == nodex1y1 ) || ( nodex1y1 == 0 ) )
548 && ( nodex0y0 == node_AA_x0y0 ) )
549 {
552 // Option 1
553 // This option will give a very good quality on reflections (slow)
554 /*
555 if( m_accelerator->Intersect( rayAA, hitAA, nodex0y0 ) )
556 {
557 aOutHitColor[i] += shadeHit( aBgColorY[y], rayAA, hitAA, false, 0 );
558 }
559 else
560 {
561 if( m_accelerator->Intersect( rayAA, hitAA ) )
562 aOutHitColor[i] += shadeHit( aBgColorY[y], rayAA, hitAA, false, 0 );
563 else
564 aOutHitColor[i] += hitColor[i];
565 }
566 */
567
568 // Option 2
569 // Trace again with the same node,
570 // then if miss just give the same color as before
571 //if( m_accelerator->Intersect( rayAA, hitAA, nodex0y0 ) )
572 // aOutHitColor[i] += shadeHit( aBgColorY[y], rayAA, hitAA, false, 0 );
573
574 // Option 3
575 // Use same color
576 }
577 else
578 {
579 // Try to intersect the different nodes
580 // It tests the possible combination of hitted or not hitted points
581 // This will try to get the best hit for this ray
582
583 if( nodex0y0 != 0 )
584 hitted |= m_accelerator->Intersect( rayAA, hitAA, nodex0y0 );
585
586 if( ( nodex1y0 != 0 ) && ( nodex0y0 != nodex1y0 ) )
587 hitted |= m_accelerator->Intersect( rayAA, hitAA, nodex1y0 );
588
589 if( ( nodex0y1 != 0 ) && ( nodex0y0 != nodex0y1 ) && ( nodex1y0 != nodex0y1 ) )
590 hitted |= m_accelerator->Intersect( rayAA, hitAA, nodex0y1 );
591
592 if( ( nodex1y1 != 0 ) && ( nodex0y0 != nodex1y1 ) && ( nodex0y1 != nodex1y1 ) &&
593 ( nodex1y0 != nodex1y1 ) )
594 hitted |= m_accelerator->Intersect( rayAA, hitAA, nodex1y1 );
595
596 if( (node_AA_x0y0 != 0 ) && ( nodex0y0 != node_AA_x0y0 ) &&
597 ( nodex0y1 != node_AA_x0y0 ) && ( nodex1y0 != node_AA_x0y0 ) &&
598 ( nodex1y1 != node_AA_x0y0 ) )
599 hitted |= m_accelerator->Intersect( rayAA, hitAA, node_AA_x0y0 );
600
601 if( hitted )
602 {
603 // If we got any result, shade it
604 aOutHitColor[i] = shadeHit( aBgColorY[y], rayAA, hitAA, false, 0,
605 is_testShadow );
606 }
607 else
608 {
609 // Note: There are very few cases that will end on this situation
610 // so it is not so expensive to trace a single ray from the beginning
611
612 // It was missed the 'last nodes' so, trace a ray from the beginning
613 if( m_accelerator->Intersect( rayAA, hitAA ) )
614 aOutHitColor[i] = shadeHit( aBgColorY[y], rayAA, hitAA, false, 0,
615 is_testShadow );
616 }
617 }
618 }
619 }
620}
SFVEC3F shadeHit(const SFVEC3F &aBgColor, const RAY &aRay, HITINFO &aHitInfo, bool aIsInsideObject, unsigned int aRecursiveLevel, bool is_testShadow) const
#define RAYPACKET_RAYS_PER_PACKET
Definition: raypacket.h:35
HITINFO m_HitInfo
Definition: hitinfo.h:58
unsigned int m_acc_node_info
( 4) The acc stores here the node that it hits
Definition: hitinfo.h:42
Definition: ray.h:63

References ACCELERATOR_3D::Intersect(), HITINFO::m_acc_node_info, m_accelerator, RENDER_3D_BASE::m_boardAdapter, BOARD_ADAPTER::m_Cfg, HITINFO_PACKET::m_HitInfo, EDA_3D_VIEWER_SETTINGS::m_Render, HITINFO::m_tHit, RAYPACKET_DIM, RAYPACKET_RAYS_PER_PACKET, EDA_3D_VIEWER_SETTINGS::RENDER_SETTINGS::raytrace_shadows, and shadeHit().

Referenced by renderBlockTracing().

◆ renderBlockTracing()

void RENDER_3D_RAYTRACE::renderBlockTracing ( GLubyte *  ptrPBO,
signed int  iBlock 
)
private

Definition at line 626 of file render_3d_raytrace.cpp.

627{
628 // Initialize ray packets
629 const SFVEC2UI& blockPos = m_blockPositions[iBlock];
630 const SFVEC2I blockPosI = SFVEC2I( blockPos.x + m_xoffset, blockPos.y + m_yoffset );
631
632 RAYPACKET blockPacket( m_camera, (SFVEC2F) blockPosI + SFVEC2F( DISP_FACTOR, DISP_FACTOR ),
633 SFVEC2F( DISP_FACTOR, DISP_FACTOR ) /* Displacement random factor */ );
634
635
637
638 HITINFO_PACKET_init( hitPacket_X0Y0 );
639
640 // Calculate background gradient color
641 SFVEC3F bgColor[RAYPACKET_DIM];// Store a vertical gradient color
642
643 for( unsigned int y = 0; y < RAYPACKET_DIM; ++y )
644 {
645 const float posYfactor = (float) ( blockPosI.y + y ) / (float) m_windowSize.y;
646
647 bgColor[y] = m_backgroundColorTop * SFVEC3F(posYfactor) +
648 m_backgroundColorBottom * ( SFVEC3F(1.0f) - SFVEC3F(posYfactor) );
649 }
650
651 // Intersect ray packets (calculate the intersection with rays and objects)
652 if( !m_accelerator->Intersect( blockPacket, hitPacket_X0Y0 ) )
653 {
654 // If block is empty then set shades and continue
656 {
657 for( unsigned int y = 0; y < RAYPACKET_DIM; ++y )
658 {
659 const SFVEC3F& outColor = bgColor[y];
660
661 const unsigned int yBlockPos = blockPos.y + y;
662
663 for( unsigned int x = 0; x < RAYPACKET_DIM; ++x )
664 {
665 m_postShaderSsao.SetPixelData( blockPos.x + x, yBlockPos,
666 SFVEC3F( 0.0f ), outColor,
667 SFVEC3F( 0.0f ), 0, 1.0f );
668 }
669 }
670 }
671
672 // This will set the output color to be displayed
673 // If post processing is enabled, it will not reflect the final result (as the final
674 // color will be computed on post processing) but it is used for report progress
675 const bool isFinalColor = !m_boardAdapter.m_Cfg->m_Render.raytrace_post_processing;
676
677 for( unsigned int y = 0; y < RAYPACKET_DIM; ++y )
678 {
679 const SFVEC3F& outColor = bgColor[y];
680
681 const unsigned int yConst = blockPos.x + ( ( y + blockPos.y ) * m_realBufferSize.x );
682
683 for( unsigned int x = 0; x < RAYPACKET_DIM; ++x )
684 {
685 GLubyte* ptr = &ptrPBO[( yConst + x ) * 4];
686
687 renderFinalColor( ptr, outColor, isFinalColor );
688 }
689 }
690
691 // There is nothing more here to do.. there are no hits ..
692 // just background so continue
693 return;
694 }
695
696 SFVEC3F hitColor_X0Y0[RAYPACKET_RAYS_PER_PACKET];
697
698 // Shade original (0, 0) hits ("paint" the intersected objects)
699 renderRayPackets( bgColor, blockPacket.m_ray, hitPacket_X0Y0,
701
703 {
704 SFVEC3F hitColor_AA_X1Y1[RAYPACKET_RAYS_PER_PACKET];
705
706 // Intersect one blockPosI + (0.5, 0.5) used for anti aliasing calculation
707 HITINFO_PACKET hitPacket_AA_X1Y1[RAYPACKET_RAYS_PER_PACKET];
708 HITINFO_PACKET_init( hitPacket_AA_X1Y1 );
709
710 RAYPACKET blockPacket_AA_X1Y1( m_camera, (SFVEC2F) blockPosI + SFVEC2F( 0.5f, 0.5f ),
712
713 if( !m_accelerator->Intersect( blockPacket_AA_X1Y1, hitPacket_AA_X1Y1 ) )
714 {
715 // Missed all the package
716 for( unsigned int y = 0, i = 0; y < RAYPACKET_DIM; ++y )
717 {
718 const SFVEC3F& outColor = bgColor[y];
719
720 for( unsigned int x = 0; x < RAYPACKET_DIM; ++x, ++i )
721 hitColor_AA_X1Y1[i] = outColor;
722 }
723 }
724 else
725 {
726 renderRayPackets( bgColor, blockPacket_AA_X1Y1.m_ray, hitPacket_AA_X1Y1,
727 m_boardAdapter.m_Cfg->m_Render.raytrace_shadows, hitColor_AA_X1Y1 );
728 }
729
730 SFVEC3F hitColor_AA_X1Y0[RAYPACKET_RAYS_PER_PACKET];
731 SFVEC3F hitColor_AA_X0Y1[RAYPACKET_RAYS_PER_PACKET];
732 SFVEC3F hitColor_AA_X0Y1_half[RAYPACKET_RAYS_PER_PACKET];
733
734 for( unsigned int i = 0; i < RAYPACKET_RAYS_PER_PACKET; ++i )
735 {
736 SFVEC3F color_average = ( hitColor_X0Y0[i] + hitColor_AA_X1Y1[i] ) * SFVEC3F( 0.5f );
737
738 hitColor_AA_X1Y0[i] = color_average;
739 hitColor_AA_X0Y1[i] = color_average;
740 hitColor_AA_X0Y1_half[i] = color_average;
741 }
742
743 RAY blockRayPck_AA_X1Y0[RAYPACKET_RAYS_PER_PACKET];
744 RAY blockRayPck_AA_X0Y1[RAYPACKET_RAYS_PER_PACKET];
745 RAY blockRayPck_AA_X1Y1_half[RAYPACKET_RAYS_PER_PACKET];
746
748 m_camera, (SFVEC2F) blockPosI + SFVEC2F( 0.5f - DISP_FACTOR, DISP_FACTOR ),
749 SFVEC2F( DISP_FACTOR, DISP_FACTOR ), blockRayPck_AA_X1Y0 );
750
752 m_camera, (SFVEC2F) blockPosI + SFVEC2F( DISP_FACTOR, 0.5f - DISP_FACTOR ),
753 SFVEC2F( DISP_FACTOR, DISP_FACTOR ), blockRayPck_AA_X0Y1 );
754
756 m_camera, (SFVEC2F) blockPosI + SFVEC2F( 0.25f - DISP_FACTOR, 0.25f - DISP_FACTOR ),
757 SFVEC2F( DISP_FACTOR, DISP_FACTOR ), blockRayPck_AA_X1Y1_half );
758
759 renderAntiAliasPackets( bgColor, hitPacket_X0Y0, hitPacket_AA_X1Y1, blockRayPck_AA_X1Y0,
760 hitColor_AA_X1Y0 );
761
762 renderAntiAliasPackets( bgColor, hitPacket_X0Y0, hitPacket_AA_X1Y1, blockRayPck_AA_X0Y1,
763 hitColor_AA_X0Y1 );
764
765 renderAntiAliasPackets( bgColor, hitPacket_X0Y0, hitPacket_AA_X1Y1,
766 blockRayPck_AA_X1Y1_half, hitColor_AA_X0Y1_half );
767
768 // Average the result
769 for( unsigned int i = 0; i < RAYPACKET_RAYS_PER_PACKET; ++i )
770 {
771 hitColor_X0Y0[i] = ( hitColor_X0Y0[i] + hitColor_AA_X1Y1[i] + hitColor_AA_X1Y0[i] +
772 hitColor_AA_X0Y1[i] + hitColor_AA_X0Y1_half[i] ) *
773 SFVEC3F( 1.0f / 5.0f );
774 }
775 }
776
777 // Copy results to the next stage
778 GLubyte* ptr = &ptrPBO[( blockPos.x + ( blockPos.y * m_realBufferSize.x ) ) * 4];
779
780 const uint32_t ptrInc = ( m_realBufferSize.x - RAYPACKET_DIM ) * 4;
781
783 {
784 SFVEC2I bPos;
785 bPos.y = blockPos.y;
786
787 for( unsigned int y = 0, i = 0; y < RAYPACKET_DIM; ++y )
788 {
789 bPos.x = blockPos.x;
790
791 for( unsigned int x = 0; x < RAYPACKET_DIM; ++x, ++i )
792 {
793 const SFVEC3F& hColor = hitColor_X0Y0[i];
794
795 if( hitPacket_X0Y0[i].m_hitresult == true )
796 {
797 m_postShaderSsao.SetPixelData( bPos.x, bPos.y,
798 hitPacket_X0Y0[i].m_HitInfo.m_HitNormal,
799 hColor,
800 blockPacket.m_ray[i].at(
801 hitPacket_X0Y0[i].m_HitInfo.m_tHit ),
802 hitPacket_X0Y0[i].m_HitInfo.m_tHit,
803 hitPacket_X0Y0[i].m_HitInfo.m_ShadowFactor );
804 }
805 else
806 {
807 m_postShaderSsao.SetPixelData( bPos.x, bPos.y, SFVEC3F( 0.0f ), hColor,
808 SFVEC3F( 0.0f ), 0, 1.0f );
809 }
810
811 renderFinalColor( ptr, hColor, false );
812
813 bPos.x++;
814 ptr += 4;
815 }
816
817 ptr += ptrInc;
818 bPos.y++;
819 }
820 }
821 else
822 {
823 for( unsigned int y = 0, i = 0; y < RAYPACKET_DIM; ++y )
824 {
825 for( unsigned int x = 0; x < RAYPACKET_DIM; ++x, ++i )
826 {
827 renderFinalColor( ptr, hitColor_X0Y0[i], true );
828 ptr += 4;
829 }
830
831 ptr += ptrInc;
832 }
833 }
834}
void SetPixelData(unsigned int x, unsigned int y, const SFVEC3F &aNormal, const SFVEC3F &aColor, const SFVEC3F &aHitPosition, float aDepth, float aShadowAttFactor)
Definition: post_shader.cpp:79
void renderFinalColor(GLubyte *ptrPBO, const SFVEC3F &rgbColor, bool applyColorSpaceConversion)
void renderRayPackets(const SFVEC3F *bgColorY, const RAY *aRayPkt, HITINFO_PACKET *aHitPacket, bool is_testShadow, SFVEC3F *aOutHitColor)
void renderAntiAliasPackets(const SFVEC3F *aBgColorY, const HITINFO_PACKET *aHitPck_X0Y0, const HITINFO_PACKET *aHitPck_AA_X1Y1, const RAY *aRayPck, SFVEC3F *aOutHitColor)
void RAYPACKET_InitRays_with2DDisplacement(const CAMERA &aCamera, const SFVEC2F &aWindowsPosition, const SFVEC2F &a2DWindowsPosDisplacementFactor, RAY *aRayPck)
Definition: raypacket.cpp:162
static void HITINFO_PACKET_init(HITINFO_PACKET *aHitPacket)
#define DISP_FACTOR
float m_ShadowFactor
( 4) Shadow attenuation (1.0 no shadow, 0.0f darkness)
Definition: hitinfo.h:45
glm::ivec2 SFVEC2I
Definition: xv3d_types.h:39

References RAY::at(), DISP_FACTOR, HITINFO_PACKET_init(), ACCELERATOR_3D::Intersect(), m_accelerator, m_backgroundColorBottom, m_backgroundColorTop, m_blockPositions, RENDER_3D_BASE::m_boardAdapter, RENDER_3D_BASE::m_camera, BOARD_ADAPTER::m_Cfg, HITINFO_PACKET::m_HitInfo, HITINFO::m_HitNormal, m_postShaderSsao, RAYPACKET::m_ray, m_realBufferSize, EDA_3D_VIEWER_SETTINGS::m_Render, HITINFO::m_ShadowFactor, HITINFO::m_tHit, RENDER_3D_BASE::m_windowSize, m_xoffset, m_yoffset, RAYPACKET_DIM, RAYPACKET_InitRays_with2DDisplacement(), RAYPACKET_RAYS_PER_PACKET, EDA_3D_VIEWER_SETTINGS::RENDER_SETTINGS::raytrace_anti_aliasing, EDA_3D_VIEWER_SETTINGS::RENDER_SETTINGS::raytrace_post_processing, EDA_3D_VIEWER_SETTINGS::RENDER_SETTINGS::raytrace_shadows, renderAntiAliasPackets(), renderFinalColor(), renderRayPackets(), and POST_SHADER::SetPixelData().

◆ renderFinalColor()

void RENDER_3D_RAYTRACE::renderFinalColor ( GLubyte *  ptrPBO,
const SFVEC3F rgbColor,
bool  applyColorSpaceConversion 
)
private
Note
This should be used in future when the KiCad support a greater version of glm lib.

Definition at line 445 of file render_3d_raytrace.cpp.

447{
448 SFVEC3F color = rgbColor;
449
450#ifdef USE_SRGB_SPACE
452 // if( applyColorSpaceConversion )
453 // rgbColor = glm::convertLinearToSRGB( rgbColor );
454
455 if( applyColorSpaceConversion )
456 color = convertLinearToSRGB( rgbColor );
457#endif
458
459 ptrPBO[0] = (unsigned int) glm::clamp( (int) ( color.r * 255 ), 0, 255 );
460 ptrPBO[1] = (unsigned int) glm::clamp( (int) ( color.g * 255 ), 0, 255 );
461 ptrPBO[2] = (unsigned int) glm::clamp( (int) ( color.b * 255 ), 0, 255 );
462 ptrPBO[3] = 255;
463}
int color
Definition: DXF_plotter.cpp:57
static SFVEC3F convertLinearToSRGB(const SFVEC3F &aRGBcolor)

References color, and convertLinearToSRGB().

Referenced by renderBlockTracing().

◆ renderPreview()

void RENDER_3D_RAYTRACE::renderPreview ( GLubyte *  ptrPBO)
private

Definition at line 946 of file render_3d_raytrace.cpp.

947{
948 m_isPreview = true;
949
950 std::atomic<size_t> nextBlock( 0 );
951 std::atomic<size_t> threadsFinished( 0 );
952
953 size_t parallelThreadCount = std::min<size_t>(
954 std::max<size_t>( std::thread::hardware_concurrency(), 2 ),
955 m_blockPositions.size() );
956
957 for( size_t ii = 0; ii < parallelThreadCount; ++ii )
958 {
959 std::thread t = std::thread( [&]()
960 {
961 for( size_t iBlock = nextBlock.fetch_add( 1 ); iBlock < m_blockPositionsFast.size();
962 iBlock = nextBlock.fetch_add( 1 ) )
963 {
964 const SFVEC2UI& windowPosUI = m_blockPositionsFast[ iBlock ];
965 const SFVEC2I windowsPos = SFVEC2I( windowPosUI.x + m_xoffset,
966 windowPosUI.y + m_yoffset );
967
968 RAYPACKET blockPacket( m_camera, windowsPos, 4 );
969
970 HITINFO_PACKET hitPacket[RAYPACKET_RAYS_PER_PACKET];
971
972 // Initialize hitPacket with a "not hit" information
973 for( HITINFO_PACKET& packet : hitPacket )
974 {
975 packet.m_HitInfo.m_tHit = std::numeric_limits<float>::infinity();
976 packet.m_HitInfo.m_acc_node_info = 0;
977 packet.m_hitresult = false;
978 }
979
980 // Intersect packet block
981 m_accelerator->Intersect( blockPacket, hitPacket );
982
983 // Calculate background gradient color
984 SFVEC3F bgColor[RAYPACKET_DIM];
985
986 for( unsigned int y = 0; y < RAYPACKET_DIM; ++y )
987 {
988 const float posYfactor =
989 (float) ( windowsPos.y + y * 4.0f ) / (float) m_windowSize.y;
990
991 bgColor[y] = (SFVEC3F) m_boardAdapter.m_BgColorTop * SFVEC3F( posYfactor )
992 + (SFVEC3F) m_boardAdapter.m_BgColorBot
993 * ( SFVEC3F( 1.0f ) - SFVEC3F( posYfactor ) );
994 }
995
996 COLOR_RGB hitColorShading[RAYPACKET_RAYS_PER_PACKET];
997
998 for( unsigned int i = 0; i < RAYPACKET_RAYS_PER_PACKET; ++i )
999 {
1000 const SFVEC3F bhColorY = bgColor[i / RAYPACKET_DIM];
1001
1002 if( hitPacket[i].m_hitresult == true )
1003 {
1004 const SFVEC3F hitColor = shadeHit( bhColorY, blockPacket.m_ray[i],
1005 hitPacket[i].m_HitInfo, false,
1006 0, false );
1007
1008 hitColorShading[i] = COLOR_RGB( hitColor );
1009 }
1010 else
1011 hitColorShading[i] = bhColorY;
1012 }
1013
1014 COLOR_RGB cLRB_old[(RAYPACKET_DIM - 1)];
1015
1016 for( unsigned int y = 0; y < (RAYPACKET_DIM - 1); ++y )
1017 {
1018 const SFVEC3F bgColorY = bgColor[y];
1019 const COLOR_RGB bgColorYRGB = COLOR_RGB( bgColorY );
1020
1021 // This stores cRTB from the last block to be reused next time in a cLTB pixel
1022 COLOR_RGB cRTB_old;
1023
1024 //RAY cRTB_ray;
1025 //HITINFO cRTB_hitInfo;
1026
1027 for( unsigned int x = 0; x < ( RAYPACKET_DIM - 1 ); ++x )
1028 {
1029 // pxl 0 pxl 1 pxl 2 pxl 3 pxl 4
1030 // x0 x1 ...
1031 // .---------------------------.
1032 // y0 | cLT | cxxx | cLRT | cxxx | cRT |
1033 // | cxxx | cLTC | cxxx | cRTC | cxxx |
1034 // | cLTB | cxxx | cC | cxxx | cRTB |
1035 // | cxxx | cLBC | cxxx | cRBC | cxxx |
1036 // '---------------------------'
1037 // y1 | cLB | cxxx | cLRB | cxxx | cRB |
1038
1039 const unsigned int iLT = ( ( x + 0 ) + RAYPACKET_DIM * ( y + 0 ) );
1040 const unsigned int iRT = ( ( x + 1 ) + RAYPACKET_DIM * ( y + 0 ) );
1041 const unsigned int iLB = ( ( x + 0 ) + RAYPACKET_DIM * ( y + 1 ) );
1042 const unsigned int iRB = ( ( x + 1 ) + RAYPACKET_DIM * ( y + 1 ) );
1043
1044 // !TODO: skip when there are no hits
1045 const COLOR_RGB& cLT = hitColorShading[ iLT ];
1046 const COLOR_RGB& cRT = hitColorShading[ iRT ];
1047 const COLOR_RGB& cLB = hitColorShading[ iLB ];
1048 const COLOR_RGB& cRB = hitColorShading[ iRB ];
1049
1050 // Trace and shade cC
1051 COLOR_RGB cC = bgColorYRGB;
1052
1053 const SFVEC3F& oriLT = blockPacket.m_ray[ iLT ].m_Origin;
1054 const SFVEC3F& oriRB = blockPacket.m_ray[ iRB ].m_Origin;
1055
1056 const SFVEC3F& dirLT = blockPacket.m_ray[ iLT ].m_Dir;
1057 const SFVEC3F& dirRB = blockPacket.m_ray[ iRB ].m_Dir;
1058
1059 SFVEC3F oriC;
1060 SFVEC3F dirC;
1061
1062 HITINFO centerHitInfo;
1063 centerHitInfo.m_tHit = std::numeric_limits<float>::infinity();
1064
1065 bool hittedC = false;
1066
1067 if( ( hitPacket[iLT].m_hitresult == true )
1068 || ( hitPacket[iRT].m_hitresult == true )
1069 || ( hitPacket[iLB].m_hitresult == true )
1070 || ( hitPacket[iRB].m_hitresult == true ) )
1071 {
1072 oriC = ( oriLT + oriRB ) * 0.5f;
1073 dirC = glm::normalize( ( dirLT + dirRB ) * 0.5f );
1074
1075 // Trace the center ray
1076 RAY centerRay;
1077 centerRay.Init( oriC, dirC );
1078
1079 const unsigned int nodeLT = hitPacket[ iLT ].m_HitInfo.m_acc_node_info;
1080 const unsigned int nodeRT = hitPacket[ iRT ].m_HitInfo.m_acc_node_info;
1081 const unsigned int nodeLB = hitPacket[ iLB ].m_HitInfo.m_acc_node_info;
1082 const unsigned int nodeRB = hitPacket[ iRB ].m_HitInfo.m_acc_node_info;
1083
1084 if( nodeLT != 0 )
1085 hittedC |= m_accelerator->Intersect( centerRay, centerHitInfo,
1086 nodeLT );
1087
1088 if( ( nodeRT != 0 ) && ( nodeRT != nodeLT ) )
1089 hittedC |= m_accelerator->Intersect( centerRay, centerHitInfo,
1090 nodeRT );
1091
1092 if( ( nodeLB != 0 ) && ( nodeLB != nodeLT ) && ( nodeLB != nodeRT ) )
1093 hittedC |= m_accelerator->Intersect( centerRay, centerHitInfo,
1094 nodeLB );
1095
1096 if( ( nodeRB != 0 ) && ( nodeRB != nodeLB ) && ( nodeRB != nodeLT )
1097 && ( nodeRB != nodeRT ) )
1098 hittedC |= m_accelerator->Intersect( centerRay, centerHitInfo,
1099 nodeRB );
1100
1101 if( hittedC )
1102 {
1103 cC = COLOR_RGB( shadeHit( bgColorY, centerRay, centerHitInfo,
1104 false, 0, false ) );
1105 }
1106 else
1107 {
1108 centerHitInfo.m_tHit = std::numeric_limits<float>::infinity();
1109 hittedC = m_accelerator->Intersect( centerRay, centerHitInfo );
1110
1111 if( hittedC )
1112 cC = COLOR_RGB( shadeHit( bgColorY, centerRay, centerHitInfo,
1113 false, 0, false ) );
1114 }
1115 }
1116
1117 // Trace and shade cLRT
1118 COLOR_RGB cLRT = bgColorYRGB;
1119
1120 const SFVEC3F& oriRT = blockPacket.m_ray[ iRT ].m_Origin;
1121 const SFVEC3F& dirRT = blockPacket.m_ray[ iRT ].m_Dir;
1122
1123 if( y == 0 )
1124 {
1125 // Trace the center ray
1126 RAY rayLRT;
1127 rayLRT.Init( ( oriLT + oriRT ) * 0.5f,
1128 glm::normalize( ( dirLT + dirRT ) * 0.5f ) );
1129
1130 HITINFO hitInfoLRT;
1131 hitInfoLRT.m_tHit = std::numeric_limits<float>::infinity();
1132
1133 if( hitPacket[iLT].m_hitresult && hitPacket[iRT].m_hitresult
1134 && ( hitPacket[iLT].m_HitInfo.pHitObject
1135 == hitPacket[iRT].m_HitInfo.pHitObject ) )
1136 {
1137 hitInfoLRT.pHitObject = hitPacket[ iLT ].m_HitInfo.pHitObject;
1138 hitInfoLRT.m_tHit = ( hitPacket[ iLT ].m_HitInfo.m_tHit +
1139 hitPacket[ iRT ].m_HitInfo.m_tHit ) * 0.5f;
1140 hitInfoLRT.m_HitNormal =
1141 glm::normalize( ( hitPacket[ iLT ].m_HitInfo.m_HitNormal +
1142 hitPacket[ iRT ].m_HitInfo.m_HitNormal ) * 0.5f );
1143
1144 cLRT = COLOR_RGB( shadeHit( bgColorY, rayLRT, hitInfoLRT, false,
1145 0, false ) );
1146 cLRT = BlendColor( cLRT, BlendColor( cLT, cRT ) );
1147 }
1148 else
1149 {
1150 // If any hits
1151 if( hitPacket[ iLT ].m_hitresult || hitPacket[ iRT ].m_hitresult )
1152 {
1153 const unsigned int nodeLT =
1154 hitPacket[ iLT ].m_HitInfo.m_acc_node_info;
1155 const unsigned int nodeRT =
1156 hitPacket[ iRT ].m_HitInfo.m_acc_node_info;
1157
1158 bool hittedLRT = false;
1159
1160 if( nodeLT != 0 )
1161 hittedLRT |= m_accelerator->Intersect( rayLRT, hitInfoLRT,
1162 nodeLT );
1163
1164 if( ( nodeRT != 0 ) && ( nodeRT != nodeLT ) )
1165 hittedLRT |= m_accelerator->Intersect( rayLRT, hitInfoLRT,
1166 nodeRT );
1167
1168 if( hittedLRT )
1169 cLRT = COLOR_RGB( shadeHit( bgColorY, rayLRT, hitInfoLRT,
1170 false, 0, false ) );
1171 else
1172 {
1173 hitInfoLRT.m_tHit = std::numeric_limits<float>::infinity();
1174
1175 if( m_accelerator->Intersect( rayLRT,hitInfoLRT ) )
1176 cLRT = COLOR_RGB( shadeHit( bgColorY, rayLRT,
1177 hitInfoLRT, false,
1178 0, false ) );
1179 }
1180 }
1181 }
1182 }
1183 else
1184 {
1185 cLRT = cLRB_old[x];
1186 }
1187
1188 // Trace and shade cLTB
1189 COLOR_RGB cLTB = bgColorYRGB;
1190
1191 if( x == 0 )
1192 {
1193 const SFVEC3F &oriLB = blockPacket.m_ray[ iLB ].m_Origin;
1194 const SFVEC3F& dirLB = blockPacket.m_ray[ iLB ].m_Dir;
1195
1196 // Trace the center ray
1197 RAY rayLTB;
1198 rayLTB.Init( ( oriLT + oriLB ) * 0.5f,
1199 glm::normalize( ( dirLT + dirLB ) * 0.5f ) );
1200
1201 HITINFO hitInfoLTB;
1202 hitInfoLTB.m_tHit = std::numeric_limits<float>::infinity();
1203
1204 if( hitPacket[ iLT ].m_hitresult && hitPacket[ iLB ].m_hitresult
1205 && ( hitPacket[ iLT ].m_HitInfo.pHitObject ==
1206 hitPacket[ iLB ].m_HitInfo.pHitObject ) )
1207 {
1208 hitInfoLTB.pHitObject = hitPacket[ iLT ].m_HitInfo.pHitObject;
1209 hitInfoLTB.m_tHit = ( hitPacket[ iLT ].m_HitInfo.m_tHit +
1210 hitPacket[ iLB ].m_HitInfo.m_tHit ) * 0.5f;
1211 hitInfoLTB.m_HitNormal =
1212 glm::normalize( ( hitPacket[ iLT ].m_HitInfo.m_HitNormal +
1213 hitPacket[ iLB ].m_HitInfo.m_HitNormal ) * 0.5f );
1214 cLTB = COLOR_RGB( shadeHit( bgColorY, rayLTB, hitInfoLTB, false,
1215 0, false ) );
1216 cLTB = BlendColor( cLTB, BlendColor( cLT, cLB) );
1217 }
1218 else
1219 {
1220 // If any hits
1221 if( hitPacket[ iLT ].m_hitresult || hitPacket[ iLB ].m_hitresult )
1222 {
1223 const unsigned int nodeLT =
1224 hitPacket[ iLT ].m_HitInfo.m_acc_node_info;
1225 const unsigned int nodeLB =
1226 hitPacket[ iLB ].m_HitInfo.m_acc_node_info;
1227
1228 bool hittedLTB = false;
1229
1230 if( nodeLT != 0 )
1231 hittedLTB |= m_accelerator->Intersect( rayLTB, hitInfoLTB,
1232 nodeLT );
1233
1234 if( ( nodeLB != 0 ) && ( nodeLB != nodeLT ) )
1235 hittedLTB |= m_accelerator->Intersect( rayLTB, hitInfoLTB,
1236 nodeLB );
1237
1238 if( hittedLTB )
1239 cLTB = COLOR_RGB( shadeHit( bgColorY, rayLTB, hitInfoLTB,
1240 false, 0, false ) );
1241 else
1242 {
1243 hitInfoLTB.m_tHit = std::numeric_limits<float>::infinity();
1244
1245 if( m_accelerator->Intersect( rayLTB, hitInfoLTB ) )
1246 cLTB = COLOR_RGB( shadeHit( bgColorY, rayLTB,
1247 hitInfoLTB, false,
1248 0, false ) );
1249 }
1250 }
1251 }
1252 }
1253 else
1254 {
1255 cLTB = cRTB_old;
1256 }
1257
1258 // Trace and shade cRTB
1259 COLOR_RGB cRTB = bgColorYRGB;
1260
1261 // Trace the center ray
1262 RAY rayRTB;
1263 rayRTB.Init( ( oriRT + oriRB ) * 0.5f,
1264 glm::normalize( ( dirRT + dirRB ) * 0.5f ) );
1265
1266 HITINFO hitInfoRTB;
1267 hitInfoRTB.m_tHit = std::numeric_limits<float>::infinity();
1268
1269 if( hitPacket[ iRT ].m_hitresult && hitPacket[ iRB ].m_hitresult
1270 && ( hitPacket[ iRT ].m_HitInfo.pHitObject ==
1271 hitPacket[ iRB ].m_HitInfo.pHitObject ) )
1272 {
1273 hitInfoRTB.pHitObject = hitPacket[ iRT ].m_HitInfo.pHitObject;
1274
1275 hitInfoRTB.m_tHit = ( hitPacket[ iRT ].m_HitInfo.m_tHit +
1276 hitPacket[ iRB ].m_HitInfo.m_tHit ) * 0.5f;
1277
1278 hitInfoRTB.m_HitNormal =
1279 glm::normalize( ( hitPacket[ iRT ].m_HitInfo.m_HitNormal +
1280 hitPacket[ iRB ].m_HitInfo.m_HitNormal ) * 0.5f );
1281
1282 cRTB = COLOR_RGB( shadeHit( bgColorY, rayRTB, hitInfoRTB, false, 0,
1283 false ) );
1284 cRTB = BlendColor( cRTB, BlendColor( cRT, cRB ) );
1285 }
1286 else
1287 {
1288 // If any hits
1289 if( hitPacket[ iRT ].m_hitresult || hitPacket[ iRB ].m_hitresult )
1290 {
1291 const unsigned int nodeRT =
1292 hitPacket[ iRT ].m_HitInfo.m_acc_node_info;
1293 const unsigned int nodeRB =
1294 hitPacket[ iRB ].m_HitInfo.m_acc_node_info;
1295
1296 bool hittedRTB = false;
1297
1298 if( nodeRT != 0 )
1299 hittedRTB |= m_accelerator->Intersect( rayRTB, hitInfoRTB,
1300 nodeRT );
1301
1302 if( ( nodeRB != 0 ) && ( nodeRB != nodeRT ) )
1303 hittedRTB |= m_accelerator->Intersect( rayRTB, hitInfoRTB,
1304 nodeRB );
1305
1306 if( hittedRTB )
1307 {
1308 cRTB = COLOR_RGB( shadeHit( bgColorY, rayRTB, hitInfoRTB,
1309 false, 0, false) );
1310 }
1311 else
1312 {
1313 hitInfoRTB.m_tHit = std::numeric_limits<float>::infinity();
1314
1315 if( m_accelerator->Intersect( rayRTB, hitInfoRTB ) )
1316 cRTB = COLOR_RGB( shadeHit( bgColorY, rayRTB, hitInfoRTB,
1317 false, 0, false ) );
1318 }
1319 }
1320 }
1321
1322 cRTB_old = cRTB;
1323
1324 // Trace and shade cLRB
1325 COLOR_RGB cLRB = bgColorYRGB;
1326
1327 const SFVEC3F& oriLB = blockPacket.m_ray[ iLB ].m_Origin;
1328 const SFVEC3F& dirLB = blockPacket.m_ray[ iLB ].m_Dir;
1329
1330 // Trace the center ray
1331 RAY rayLRB;
1332 rayLRB.Init( ( oriLB + oriRB ) * 0.5f,
1333 glm::normalize( ( dirLB + dirRB ) * 0.5f ) );
1334
1335 HITINFO hitInfoLRB;
1336 hitInfoLRB.m_tHit = std::numeric_limits<float>::infinity();
1337
1338 if( hitPacket[iLB].m_hitresult && hitPacket[iRB].m_hitresult
1339 && ( hitPacket[iLB].m_HitInfo.pHitObject ==
1340 hitPacket[iRB].m_HitInfo.pHitObject ) )
1341 {
1342 hitInfoLRB.pHitObject = hitPacket[ iLB ].m_HitInfo.pHitObject;
1343
1344 hitInfoLRB.m_tHit = ( hitPacket[ iLB ].m_HitInfo.m_tHit +
1345 hitPacket[ iRB ].m_HitInfo.m_tHit ) * 0.5f;
1346
1347 hitInfoLRB.m_HitNormal =
1348 glm::normalize( ( hitPacket[ iLB ].m_HitInfo.m_HitNormal +
1349 hitPacket[ iRB ].m_HitInfo.m_HitNormal ) * 0.5f );
1350
1351 cLRB = COLOR_RGB( shadeHit( bgColorY, rayLRB, hitInfoLRB, false, 0,
1352 false ) );
1353 cLRB = BlendColor( cLRB, BlendColor( cLB, cRB ) );
1354 }
1355 else
1356 {
1357 // If any hits
1358 if( hitPacket[ iLB ].m_hitresult || hitPacket[ iRB ].m_hitresult )
1359 {
1360 const unsigned int nodeLB =
1361 hitPacket[ iLB ].m_HitInfo.m_acc_node_info;
1362 const unsigned int nodeRB =
1363 hitPacket[ iRB ].m_HitInfo.m_acc_node_info;
1364
1365 bool hittedLRB = false;
1366
1367 if( nodeLB != 0 )
1368 hittedLRB |= m_accelerator->Intersect( rayLRB, hitInfoLRB,
1369 nodeLB );
1370
1371 if( ( nodeRB != 0 ) && ( nodeRB != nodeLB ) )
1372 hittedLRB |= m_accelerator->Intersect( rayLRB, hitInfoLRB,
1373 nodeRB );
1374
1375 if( hittedLRB )
1376 {
1377 cLRB = COLOR_RGB( shadeHit( bgColorY, rayLRB, hitInfoLRB,
1378 false, 0, false ) );
1379 }
1380 else
1381 {
1382 hitInfoLRB.m_tHit = std::numeric_limits<float>::infinity();
1383
1384 if( m_accelerator->Intersect( rayLRB, hitInfoLRB ) )
1385 cLRB = COLOR_RGB( shadeHit( bgColorY, rayLRB, hitInfoLRB,
1386 false, 0, false ) );
1387 }
1388 }
1389 }
1390
1391 cLRB_old[x] = cLRB;
1392
1393 // Trace and shade cLTC
1394 COLOR_RGB cLTC = BlendColor( cLT , cC );
1395
1396 if( hitPacket[ iLT ].m_hitresult || hittedC )
1397 {
1398 // Trace the center ray
1399 RAY rayLTC;
1400 rayLTC.Init( ( oriLT + oriC ) * 0.5f,
1401 glm::normalize( ( dirLT + dirC ) * 0.5f ) );
1402
1403 HITINFO hitInfoLTC;
1404 hitInfoLTC.m_tHit = std::numeric_limits<float>::infinity();
1405
1406 bool hitted = false;
1407
1408 if( hittedC )
1409 hitted = centerHitInfo.pHitObject->Intersect( rayLTC, hitInfoLTC );
1410 else if( hitPacket[ iLT ].m_hitresult )
1411 hitted = hitPacket[ iLT ].m_HitInfo.pHitObject->Intersect(
1412 rayLTC,
1413 hitInfoLTC );
1414
1415 if( hitted )
1416 cLTC = COLOR_RGB( shadeHit( bgColorY, rayLTC, hitInfoLTC, false,
1417 0, false ) );
1418 }
1419
1420 // Trace and shade cRTC
1421 COLOR_RGB cRTC = BlendColor( cRT , cC );
1422
1423 if( hitPacket[ iRT ].m_hitresult || hittedC )
1424 {
1425 // Trace the center ray
1426 RAY rayRTC;
1427 rayRTC.Init( ( oriRT + oriC ) * 0.5f,
1428 glm::normalize( ( dirRT + dirC ) * 0.5f ) );
1429
1430 HITINFO hitInfoRTC;
1431 hitInfoRTC.m_tHit = std::numeric_limits<float>::infinity();
1432
1433 bool hitted = false;
1434
1435 if( hittedC )
1436 hitted = centerHitInfo.pHitObject->Intersect( rayRTC, hitInfoRTC );
1437 else if( hitPacket[ iRT ].m_hitresult )
1438 hitted = hitPacket[ iRT ].m_HitInfo.pHitObject->Intersect( rayRTC,
1439 hitInfoRTC );
1440
1441 if( hitted )
1442 cRTC = COLOR_RGB( shadeHit( bgColorY, rayRTC, hitInfoRTC, false,
1443 0, false ) );
1444 }
1445
1446 // Trace and shade cLBC
1447 COLOR_RGB cLBC = BlendColor( cLB , cC );
1448
1449 if( hitPacket[ iLB ].m_hitresult || hittedC )
1450 {
1451 // Trace the center ray
1452 RAY rayLBC;
1453 rayLBC.Init( ( oriLB + oriC ) * 0.5f,
1454 glm::normalize( ( dirLB + dirC ) * 0.5f ) );
1455
1456 HITINFO hitInfoLBC;
1457 hitInfoLBC.m_tHit = std::numeric_limits<float>::infinity();
1458
1459 bool hitted = false;
1460
1461 if( hittedC )
1462 hitted = centerHitInfo.pHitObject->Intersect( rayLBC, hitInfoLBC );
1463 else if( hitPacket[ iLB ].m_hitresult )
1464 hitted = hitPacket[ iLB ].m_HitInfo.pHitObject->Intersect( rayLBC,
1465 hitInfoLBC );
1466
1467 if( hitted )
1468 cLBC = COLOR_RGB( shadeHit( bgColorY, rayLBC, hitInfoLBC, false,
1469 0, false ) );
1470 }
1471
1472 // Trace and shade cRBC
1473 COLOR_RGB cRBC = BlendColor( cRB , cC );
1474
1475 if( hitPacket[ iRB ].m_hitresult || hittedC )
1476 {
1477 // Trace the center ray
1478 RAY rayRBC;
1479 rayRBC.Init( ( oriRB + oriC ) * 0.5f,
1480 glm::normalize( ( dirRB + dirC ) * 0.5f ) );
1481
1482 HITINFO hitInfoRBC;
1483 hitInfoRBC.m_tHit = std::numeric_limits<float>::infinity();
1484
1485 bool hitted = false;
1486
1487 if( hittedC )
1488 hitted = centerHitInfo.pHitObject->Intersect( rayRBC, hitInfoRBC );
1489 else if( hitPacket[ iRB ].m_hitresult )
1490 hitted = hitPacket[ iRB ].m_HitInfo.pHitObject->Intersect( rayRBC,
1491 hitInfoRBC );
1492
1493 if( hitted )
1494 cRBC = COLOR_RGB( shadeHit( bgColorY, rayRBC, hitInfoRBC, false,
1495 0, false ) );
1496 }
1497
1498 // Set pixel colors
1499 GLubyte* ptr =
1500 &ptrPBO[( 4 * x + m_blockPositionsFast[iBlock].x
1502 * ( m_blockPositionsFast[iBlock].y + 4 * y ) ) * 4];
1503 SetPixel( ptr + 0, cLT );
1504 SetPixel( ptr + 4, BlendColor( cLT, cLRT, cLTC ) );
1505 SetPixel( ptr + 8, cLRT );
1506 SetPixel( ptr + 12, BlendColor( cLRT, cRT, cRTC ) );
1507
1508 ptr += m_realBufferSize.x * 4;
1509 SetPixel( ptr + 0, BlendColor( cLT , cLTB, cLTC ) );
1510 SetPixel( ptr + 4, BlendColor( cLTC, BlendColor( cLT , cC ) ) );
1511 SetPixel( ptr + 8, BlendColor( cC, BlendColor( cLRT, cLTC, cRTC ) ) );
1512 SetPixel( ptr + 12, BlendColor( cRTC, BlendColor( cRT , cC ) ) );
1513
1514 ptr += m_realBufferSize.x * 4;
1515 SetPixel( ptr + 0, cLTB );
1516 SetPixel( ptr + 4, BlendColor( cC, BlendColor( cLTB, cLTC, cLBC ) ) );
1517 SetPixel( ptr + 8, cC );
1518 SetPixel( ptr + 12, BlendColor( cC, BlendColor( cRTB, cRTC, cRBC ) ) );
1519
1520 ptr += m_realBufferSize.x * 4;
1521 SetPixel( ptr + 0, BlendColor( cLB , cLTB, cLBC ) );
1522 SetPixel( ptr + 4, BlendColor( cLBC, BlendColor( cLB , cC ) ) );
1523 SetPixel( ptr + 8, BlendColor( cC, BlendColor( cLRB, cLBC, cRBC ) ) );
1524 SetPixel( ptr + 12, BlendColor( cRBC, BlendColor( cRB , cC ) ) );
1525 }
1526 }
1527 }
1528
1529 threadsFinished++;
1530 } );
1531
1532 t.detach();
1533 }
1534
1535 while( threadsFinished < parallelThreadCount )
1536 std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) );
1537}
virtual bool Intersect(const RAY &aRay, HITINFO &aHitInfo) const =0
COLOR_RGB BlendColor(const COLOR_RGB &aC1, const COLOR_RGB &aC2)
Definition: color_rgb.cpp:41
static void SetPixel(GLubyte *p, const COLOR_RGB &v)
SFVEC3F m_HitNormal
(12) normal at the hit point
Definition: hitinfo.h:37
void Init(const SFVEC3F &o, const SFVEC3F &d)
Definition: ray.cpp:35

References BlendColor(), RAY::Init(), ACCELERATOR_3D::Intersect(), OBJECT_3D::Intersect(), m_accelerator, m_blockPositions, m_blockPositionsFast, HITINFO::m_HitNormal, m_isPreview, m_realBufferSize, HITINFO::m_tHit, HITINFO::pHitObject, RAYPACKET_DIM, RAYPACKET_RAYS_PER_PACKET, SetPixel(), and shadeHit().

Referenced by Redraw().

◆ renderRayPackets()

void RENDER_3D_RAYTRACE::renderRayPackets ( const SFVEC3F bgColorY,
const RAY aRayPkt,
HITINFO_PACKET aHitPacket,
bool  is_testShadow,
SFVEC3F aOutHitColor 
)
private

Definition at line 480 of file render_3d_raytrace.cpp.

483{
484 for( unsigned int y = 0, i = 0; y < RAYPACKET_DIM; ++y )
485 {
486 for( unsigned int x = 0; x < RAYPACKET_DIM; ++x, ++i )
487 {
488 if( aHitPacket[i].m_hitresult == true )
489 {
490 aOutHitColor[i] = shadeHit( bgColorY[y], aRayPkt[i], aHitPacket[i].m_HitInfo,
491 false, 0, is_testShadow );
492 }
493 else
494 {
495 aOutHitColor[i] = bgColorY[y];
496 }
497 }
498 }
499}

References RAYPACKET_DIM, and shadeHit().

Referenced by renderBlockTracing().

◆ renderTracing()

void RENDER_3D_RAYTRACE::renderTracing ( GLubyte *  ptrPBO,
REPORTER aStatusReporter 
)
private

Definition at line 345 of file render_3d_raytrace.cpp.

346{
347 m_isPreview = false;
348
349 auto startTime = std::chrono::steady_clock::now();
350 bool breakLoop = false;
351
352 std::atomic<size_t> numBlocksRendered( 0 );
353 std::atomic<size_t> currentBlock( 0 );
354 std::atomic<size_t> threadsFinished( 0 );
355
356 size_t parallelThreadCount = std::min<size_t>(
357 std::max<size_t>( std::thread::hardware_concurrency(), 2 ),
358 m_blockPositions.size() );
359
360 for( size_t ii = 0; ii < parallelThreadCount; ++ii )
361 {
362 std::thread t = std::thread( [&]()
363 {
364 for( size_t iBlock = currentBlock.fetch_add( 1 );
365 iBlock < m_blockPositions.size() && !breakLoop;
366 iBlock = currentBlock.fetch_add( 1 ) )
367 {
368 if( !m_blockPositionsWasProcessed[iBlock] )
369 {
370 renderBlockTracing( ptrPBO, iBlock );
371 numBlocksRendered++;
372 m_blockPositionsWasProcessed[iBlock] = 1;
373
374 // Check if it spend already some time render and request to exit
375 // to display the progress
376 if( std::chrono::duration_cast<std::chrono::milliseconds>(
377 std::chrono::steady_clock::now() - startTime ).count() > 150 )
378 breakLoop = true;
379 }
380 }
381
382 threadsFinished++;
383 } );
384
385 t.detach();
386 }
387
388 while( threadsFinished < parallelThreadCount )
389 std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) );
390
391 m_blockRenderProgressCount += numBlocksRendered;
392
393 if( aStatusReporter )
394 aStatusReporter->Report( wxString::Format( _( "Rendering: %.0f %%" ),
395 (float) ( m_blockRenderProgressCount * 100 )
396 / (float) m_blockPositions.size() ) );
397
398 // Check if it finish the rendering and if should continue to a post processing
399 // or mark it as finished
401 {
404 else
406 }
407}

References m_blockPositions, and m_isPreview.

Referenced by render().

◆ restartRenderState()

void RENDER_3D_RAYTRACE::restartRenderState ( )
private

Definition at line 124 of file render_3d_raytrace.cpp.

125{
127
130
132
134
135 // Mark the blocks not processed yet
136 std::fill( m_blockPositionsWasProcessed.begin(), m_blockPositionsWasProcessed.end(), 0 );
137}
void InitFrame()
Definition: post_shader.h:56
std::vector< int > m_blockPositionsWasProcessed
Encode the Morton code positions (on fast preview mode).

References GetRunningMicroSecs(), POST_SHADER::InitFrame(), m_blockPositions, m_blockPositionsWasProcessed, m_blockRenderProgressCount, m_postShaderSsao, m_renderStartTime, m_renderState, and RT_RENDER_STATE_TRACING.

Referenced by render().

◆ SetBusyIndicatorFactory()

void RENDER_3D_BASE::SetBusyIndicatorFactory ( BUSY_INDICATOR::FACTORY  aNewFactory)
inherited

Set a new busy indicator factory.

When set, this factory will be used to generate busy indicators when suitable. If not set, no busy indicator will be used.

Definition at line 64 of file render_3d_base.cpp.

65{
66 m_busyIndicatorFactory = aNewFactory;
67}

References RENDER_3D_BASE::m_busyIndicatorFactory.

◆ SetCurWindowSize()

void RENDER_3D_RAYTRACE::SetCurWindowSize ( const wxSize &  aSize)
overridevirtual

Before each render, the canvas will tell the render what is the size of its windows, so render can take actions if it changed.

Parameters
aSizethe current size of the render window

Implements RENDER_3D_BASE.

Definition at line 112 of file render_3d_raytrace.cpp.

113{
114 if( m_windowSize != aSize )
115 {
116 m_windowSize = aSize;
117 glViewport( 0, 0, m_windowSize.x, m_windowSize.y );
118
120 }
121}

References initializeNewWindowSize(), and RENDER_3D_BASE::m_windowSize.

◆ setupMaterials()

void RENDER_3D_RAYTRACE::setupMaterials ( )
private

Definition at line 73 of file raytracing/create_scene.cpp.

74{
77
80
81 double mmTo3Dunits = pcbIUScale.IU_PER_MM * m_boardAdapter.BiuTo3dUnits();
82
84 {
85 m_boardMaterial = BOARD_NORMAL( 0.40f * mmTo3Dunits );
86 m_copperMaterial = COPPER_NORMAL( 4.0f * mmTo3Dunits, &m_boardMaterial );
87 m_platedCopperMaterial = PLATED_COPPER_NORMAL( 0.5f * mmTo3Dunits );
89 m_plasticMaterial = PLASTIC_NORMAL( 0.05f * mmTo3Dunits );
90 m_shinyPlasticMaterial = PLASTIC_SHINE_NORMAL( 0.1f * mmTo3Dunits );
91 m_brushedMetalMaterial = BRUSHED_METAL_NORMAL( 0.05f * mmTo3Dunits );
92 m_silkScreenMaterial = SILK_SCREEN_NORMAL( 0.25f * mmTo3Dunits );
93 }
94
95 // http://devernay.free.fr/cours/opengl/materials.html
96 // Copper
97 const SFVEC3F copperSpecularLinear =
98 ConvertSRGBToLinear( glm::clamp( (SFVEC3F) m_boardAdapter.m_CopperColor * 0.5f + 0.25f,
99 SFVEC3F( 0.0f ), SFVEC3F( 1.0f ) ) );
100
103 SFVEC3F( 0.0f ), copperSpecularLinear, 0.4f * 128.0f, 0.0f, 0.0f );
104
106 m_materials.m_Copper.SetGenerator( &m_platedCopperMaterial );
107
108 m_materials.m_NonPlatedCopper = BLINN_PHONG_MATERIAL(
109 ConvertSRGBToLinear( SFVEC3F( 0.191f, 0.073f, 0.022f ) ), SFVEC3F( 0.0f, 0.0f, 0.0f ),
110 SFVEC3F( 0.256f, 0.137f, 0.086f ), 0.15f * 128.0f, 0.0f, 0.0f );
111
113 m_materials.m_NonPlatedCopper.SetGenerator( &m_copperMaterial );
114
118 SFVEC3F( 0.0f, 0.0f, 0.0f ),
122 0.10f * 128.0f, 0.0f, 0.0f );
123
125 SFVEC3F( 0.0f, 0.0f, 0.0f ),
126 glm::clamp( ( ( SFVEC3F )( 1.0f ) - ConvertSRGBToLinear(
128 SFVEC3F( 0.0f ), SFVEC3F( 0.10f ) ), 0.078125f * 128.0f, 0.0f, 0.0f );
129
131 m_materials.m_SilkS.SetGenerator( &m_silkScreenMaterial );
132
133 // Assume that SolderMaskTop == SolderMaskBot
134 const float solderMask_gray =
137 / 3.0f;
138
139 const float solderMask_transparency = TransparencyControl( solderMask_gray,
141
142 m_materials.m_SolderMask = BLINN_PHONG_MATERIAL(
144 SFVEC3F( 0.0f, 0.0f, 0.0f ),
145 SFVEC3F( glm::clamp( solderMask_gray * 2.0f, 0.25f, 1.0f ) ), 0.85f * 128.0f,
146 solderMask_transparency, 0.16f );
147
148 m_materials.m_SolderMask.SetCastShadows( true );
149 m_materials.m_SolderMask.SetRefractionRayCount( 1 );
150
152 m_materials.m_SolderMask.SetGenerator( &m_solderMaskMaterial );
153
154 m_materials.m_EpoxyBoard =
155 BLINN_PHONG_MATERIAL( ConvertSRGBToLinear( SFVEC3F( 16.0f / 255.0f, 14.0f / 255.0f,
156 10.0f / 255.0f ) ),
157 SFVEC3F( 0.0f, 0.0f, 0.0f ),
158 ConvertSRGBToLinear( SFVEC3F( 10.0f / 255.0f, 8.0f / 255.0f,
159 10.0f / 255.0f ) ),
160 0.1f * 128.0f, 1.0f - m_boardAdapter.m_BoardBodyColor.a, 0.0f );
161
162 m_materials.m_EpoxyBoard.SetAbsorvance( 10.0f );
163
165 m_materials.m_EpoxyBoard.SetGenerator( &m_boardMaterial );
166
168
169 m_materials.m_Floor = BLINN_PHONG_MATERIAL( bgTop * 0.125f, SFVEC3F( 0.0f, 0.0f, 0.0f ),
170 ( SFVEC3F( 1.0f ) - bgTop ) / 3.0f,
171 0.10f * 128.0f, 0.0f, 0.50f );
172 m_materials.m_Floor.SetCastShadows( false );
173 m_materials.m_Floor.SetReflectionRecursionCount( 1 );
174}
constexpr EDA_IU_SCALE pcbIUScale
Definition: base_units.h:109
Procedural generation of the shiny brushed metal.
Definition: material.h:195
Procedural generation of the copper normals.
Definition: material.h:76
static void SetDefaultReflectionRayCount(unsigned int aCount)
Definition: material.h:247
static void SetDefaultRefractionRayCount(unsigned int aCount)
Definition: material.h:242
static void SetDefaultRefractionRecursionCount(unsigned int aCount)
Definition: material.h:252
static void SetDefaultReflectionRecursionCount(unsigned int aCount)
Definition: material.h:257
Procedural generation of the plastic normals.
Definition: material.h:146
Procedural generation of the shiny plastic normals.
Definition: material.h:170
PLATED_COPPER_NORMAL m_platedCopperMaterial
SOLDER_MASK_NORMAL m_solderMaskMaterial
SILK_SCREEN_NORMAL m_silkScreenMaterial
BOARD_NORMAL m_boardMaterial
COPPER_NORMAL m_copperMaterial
Procedural generation of the solder mask.
Definition: material.h:126
static float TransparencyControl(float aGrayColorValue, float aTransparency)
Perform an interpolation step to easy control the transparency based on the gray color value and tran...
const double IU_PER_MM
Definition: base_units.h:77

References BOARD_ADAPTER::BiuTo3dUnits(), ConvertSRGBToLinear(), EDA_IU_SCALE::IU_PER_MM, BOARD_ADAPTER::m_BgColorTop, RENDER_3D_BASE::m_boardAdapter, BOARD_ADAPTER::m_BoardBodyColor, m_boardMaterial, m_brushedMetalMaterial, BOARD_ADAPTER::m_Cfg, BOARD_ADAPTER::m_CopperColor, m_copperMaterial, m_materials, m_plasticMaterial, m_platedCopperMaterial, EDA_3D_VIEWER_SETTINGS::m_Render, m_shinyPlasticMaterial, BOARD_ADAPTER::m_SilkScreenColorTop, m_silkScreenMaterial, BOARD_ADAPTER::m_SolderMaskColorTop, m_solderMaskMaterial, BOARD_ADAPTER::m_SolderPasteColor, pcbIUScale, EDA_3D_VIEWER_SETTINGS::RENDER_SETTINGS::raytrace_nrsamples_reflections, EDA_3D_VIEWER_SETTINGS::RENDER_SETTINGS::raytrace_nrsamples_refractions, EDA_3D_VIEWER_SETTINGS::RENDER_SETTINGS::raytrace_procedural_textures, EDA_3D_VIEWER_SETTINGS::RENDER_SETTINGS::raytrace_recursivelevel_reflections, EDA_3D_VIEWER_SETTINGS::RENDER_SETTINGS::raytrace_recursivelevel_refractions, MATERIAL::SetDefaultReflectionRayCount(), MATERIAL::SetDefaultReflectionRecursionCount(), MATERIAL::SetDefaultRefractionRayCount(), MATERIAL::SetDefaultRefractionRecursionCount(), and TransparencyControl().

Referenced by Reload().

◆ shadeHit()

SFVEC3F RENDER_3D_RAYTRACE::shadeHit ( const SFVEC3F aBgColor,
const RAY aRay,
HITINFO aHitInfo,
bool  aIsInsideObject,
unsigned int  aRecursiveLevel,
bool  is_testShadow 
) const
private

Definition at line 1542 of file render_3d_raytrace.cpp.

1545{
1546 const MATERIAL* objMaterial = aHitInfo.pHitObject->GetMaterial();
1547 wxASSERT( objMaterial != nullptr );
1548
1549 SFVEC3F outColor = objMaterial->GetEmissiveColor() + objMaterial->GetAmbientColor();
1550
1551 if( aRecursiveLevel > 7 )
1552 return outColor;
1553
1554 SFVEC3F hitPoint = aHitInfo.m_HitPoint;
1555
1556 hitPoint += aHitInfo.m_HitNormal * m_boardAdapter.GetNonCopperLayerThickness() * 0.6f;
1557
1558 const SFVEC3F diffuseColorObj = aHitInfo.pHitObject->GetDiffuseColor( aHitInfo );
1559
1560#if USE_EXPERIMENTAL_SOFT_SHADOWS
1562#endif
1563
1564 float shadow_att_factor_sum = 0.0f;
1565
1566 unsigned int nr_lights_that_can_cast_shadows = 0;
1567
1568 for( const LIGHT* light : m_lights )
1569 {
1570 SFVEC3F vectorToLight;
1571 SFVEC3F colorOfLight;
1572 float distToLight;
1573
1574 light->GetLightParameters( hitPoint, vectorToLight, colorOfLight, distToLight );
1575
1576 if( m_isPreview )
1577 colorOfLight = SFVEC3F( 1.0f );
1578
1579 const float NdotL = glm::dot( aHitInfo.m_HitNormal, vectorToLight );
1580
1581 // Only calc shade if the normal is facing the direction of light,
1582 // otherwise it is in the shadow
1583 if( NdotL >= FLT_EPSILON )
1584 {
1585 float shadow_att_factor_light = 1.0f;
1586
1587 if( is_testShadow && light->GetCastShadows() )
1588 {
1589 nr_lights_that_can_cast_shadows++;
1590#if USE_EXPERIMENTAL_SOFT_SHADOWS
1591 // For rays that are recursive, just calculate one hit shadow
1592 if( aRecursiveLevel > 0 )
1593 {
1594#endif
1595 RAY rayToLight;
1596 rayToLight.Init( hitPoint, vectorToLight );
1597
1598 // Test if point is not in the shadow.
1599 // Test for any hit from the point in the direction of light
1600 if( m_accelerator->IntersectP( rayToLight, distToLight ) )
1601 shadow_att_factor_light = 0.0f;
1602
1603#if USE_EXPERIMENTAL_SOFT_SHADOWS
1604 }
1605 else // Experimental softshadow calculation
1606 {
1607 const unsigned int shadow_number_of_samples =
1609 const float shadow_inc_factor = 1.0f / (float) ( shadow_number_of_samples );
1610
1611 for( unsigned int i = 0; i < shadow_number_of_samples; ++i )
1612 {
1613 RAY rayToLight;
1614
1615 if( i == 0 )
1616 {
1617 rayToLight.Init( hitPoint, vectorToLight );
1618 }
1619 else
1620 {
1621 const SFVEC3F unifVector = UniformRandomHemisphereDirection();
1622 const SFVEC3F disturbed_vector_to_light =
1623 glm::normalize( vectorToLight + unifVector *
1625
1626 rayToLight.Init( hitPoint, disturbed_vector_to_light );
1627 }
1628
1629 // !TODO: there are multiple ways that this tests can be
1630 // optimized. Eg: by packing rays or to test against the
1631 // latest hit object.
1632 if( m_accelerator->IntersectP( rayToLight, distToLight ) )
1633 {
1634 shadow_att_factor_light -= shadow_inc_factor;
1635 }
1636 }
1637 }
1638#endif
1639 shadow_att_factor_sum += shadow_att_factor_light;
1640 }
1641
1642 outColor += objMaterial->Shade( aRay, aHitInfo, NdotL, diffuseColorObj, vectorToLight,
1643 colorOfLight, shadow_att_factor_light );
1644 }
1645
1646 // Only use the headlight for preview
1647 if( m_isPreview )
1648 break;
1649 }
1650
1651 // Improvement: this is not taking in account the lightcolor
1652 if( nr_lights_that_can_cast_shadows > 0 )
1653 {
1654 aHitInfo.m_ShadowFactor = glm::max(
1655 shadow_att_factor_sum / (float) ( nr_lights_that_can_cast_shadows * 1.0f ), 0.0f );
1656 }
1657 else
1658 {
1659 aHitInfo.m_ShadowFactor = 1.0f;
1660 }
1661
1662 // Clamp color to not be brighter than 1.0f
1663 outColor = glm::min( outColor, SFVEC3F( 1.0f ) );
1664
1665 if( !m_isPreview )
1666 {
1667 // Reflections
1668 if( ( objMaterial->GetReflection() > 0.0f )
1670 && ( aRecursiveLevel < objMaterial->GetReflectionRecursionCount() ) )
1671 {
1672 const unsigned int reflection_number_of_samples =
1673 objMaterial->GetReflectionRayCount();
1674
1675 SFVEC3F sum_color = SFVEC3F( 0.0f );
1676
1677 const SFVEC3F reflectVector = aRay.m_Dir - 2.0f *
1678 glm::dot( aRay.m_Dir, aHitInfo.m_HitNormal ) * aHitInfo.m_HitNormal;
1679
1680 for( unsigned int i = 0; i < reflection_number_of_samples; ++i )
1681 {
1682 RAY reflectedRay;
1683
1684 if( i == 0 )
1685 {
1686 reflectedRay.Init( hitPoint, reflectVector );
1687 }
1688 else
1689 {
1690 // Apply some randomize to the reflected vector
1691 const SFVEC3F random_reflectVector =
1692 glm::normalize( reflectVector +
1695
1696 reflectedRay.Init( hitPoint, random_reflectVector );
1697 }
1698
1699 HITINFO reflectedHit;
1700 reflectedHit.m_tHit = std::numeric_limits<float>::infinity();
1701
1702 if( m_accelerator->Intersect( reflectedRay, reflectedHit ) )
1703 {
1704 sum_color += ( diffuseColorObj + objMaterial->GetSpecularColor() ) *
1705 shadeHit( aBgColor, reflectedRay, reflectedHit, false,
1706 aRecursiveLevel + 1, is_testShadow ) *
1707 SFVEC3F( objMaterial->GetReflection() *
1708 // Falloff factor
1709 (1.0f / ( 1.0f + 0.75f * reflectedHit.m_tHit *
1710 reflectedHit.m_tHit) ) );
1711 }
1712 }
1713
1714 outColor += (sum_color / SFVEC3F( (float)reflection_number_of_samples) );
1715 }
1716
1717 // Refraction
1718 const float objTransparency = aHitInfo.pHitObject->GetModelTransparency();
1719
1720 if( ( objTransparency > 0.0f ) && m_boardAdapter.m_Cfg->m_Render.raytrace_refractions
1721 && ( aRecursiveLevel < objMaterial->GetRefractionRecursionCount() ) )
1722 {
1723 const float airIndex = 1.000293f;
1724 const float glassIndex = 1.49f;
1725 const float air_over_glass = airIndex / glassIndex;
1726 const float glass_over_air = glassIndex / airIndex;
1727
1728 const float refractionRatio = aIsInsideObject?glass_over_air:air_over_glass;
1729
1730 SFVEC3F refractedVector;
1731
1732 if( Refract( aRay.m_Dir, aHitInfo.m_HitNormal, refractionRatio, refractedVector ) )
1733 {
1734 // This increase the start point by a "fixed" factor so it will work the
1735 // same for all distances
1736 const SFVEC3F startPoint =
1738 0.25f );
1739
1740 const unsigned int refractions_number_of_samples =
1741 objMaterial->GetRefractionRayCount();
1742
1743 SFVEC3F sum_color = SFVEC3F(0.0f);
1744
1745 for( unsigned int i = 0; i < refractions_number_of_samples; ++i )
1746 {
1747 RAY refractedRay;
1748
1749 if( i == 0 )
1750 {
1751 refractedRay.Init( startPoint, refractedVector );
1752 }
1753 else
1754 {
1755 // apply some randomize to the refracted vector
1756 const SFVEC3F randomizeRefractedVector =
1757 glm::normalize( refractedVector +
1760
1761 refractedRay.Init( startPoint, randomizeRefractedVector );
1762 }
1763
1764 HITINFO refractedHit;
1765 refractedHit.m_tHit = std::numeric_limits<float>::infinity();
1766
1767 SFVEC3F refractedColor = aBgColor;
1768
1769 if( m_accelerator->Intersect( refractedRay, refractedHit ) )
1770 {
1771 refractedColor = shadeHit( aBgColor, refractedRay, refractedHit,
1772 !aIsInsideObject, aRecursiveLevel + 1, false );
1773
1774 const SFVEC3F absorbance = ( SFVEC3F(1.0f) - diffuseColorObj ) *
1775 (1.0f - objTransparency ) *
1776 objMaterial->GetAbsorvance() *
1777 refractedHit.m_tHit;
1778
1779 const SFVEC3F transparency = 1.0f / ( absorbance + 1.0f );
1780
1781 sum_color += refractedColor * transparency;
1782 }
1783 else
1784 {
1785 sum_color += refractedColor;
1786 }
1787 }
1788
1789 outColor = outColor * ( 1.0f - objTransparency ) + objTransparency * sum_color
1790 / SFVEC3F( (float) refractions_number_of_samples );
1791 }
1792 else
1793 {
1794 outColor = outColor * ( 1.0f - objTransparency ) + objTransparency * aBgColor;
1795 }
1796 }
1797 }
1798
1799 return outColor;
1800}
bool Refract(const SFVEC3F &aInVector, const SFVEC3F &aNormal, float aRin_over_Rout, SFVEC3F &aOutVector)
Based on: https://github.com/mmp/pbrt-v3/blob/master/src/core/reflection.h See also: http://www....
Definition: 3d_math.h:112
SFVEC3F UniformRandomHemisphereDirection()
Definition: 3d_math.h:55
virtual bool IntersectP(const RAY &aRay, float aMaxDistance) const =0
float GetNonCopperLayerThickness() const noexcept
Get the non copper layers thickness (in 3D units).
float GetAbsorvance() const
Definition: material.h:275
virtual SFVEC3F Shade(const RAY &aRay, const HITINFO &aHitInfo, float NdotL, const SFVEC3F &aDiffuseObjColor, const SFVEC3F &aDirToLight, const SFVEC3F &aLightColor, float aShadowAttenuationFactor) const =0
Shade an intersection point.
const SFVEC3F & GetAmbientColor() const
Definition: material.h:268
unsigned int GetRefractionRayCount() const
Definition: material.h:276
unsigned int GetRefractionRecursionCount() const
Definition: material.h:279
const SFVEC3F & GetSpecularColor() const
Definition: material.h:270
const SFVEC3F & GetEmissiveColor() const
Definition: material.h:269
float GetReflection() const
Definition: material.h:274
unsigned int GetReflectionRayCount() const
Definition: material.h:277
virtual SFVEC3F GetDiffuseColor(const HITINFO &aHitInfo) const =0
float GetModelTransparency() const
Definition: object_3d.h:65
const MATERIAL * GetMaterial() const
Definition: object_3d.h:64
SFVEC3F m_HitPoint
(12) hit position
Definition: hitinfo.h:44
SFVEC3F m_Dir
Definition: ray.h:67
SFVEC3F at(float t) const
Definition: ray.h:84

References RAY::at(), MATERIAL::GetAbsorvance(), MATERIAL::GetAmbientColor(), OBJECT_3D::GetDiffuseColor(), MATERIAL::GetEmissiveColor(), OBJECT_3D::GetMaterial(), OBJECT_3D::GetModelTransparency(), BOARD_ADAPTER::GetNonCopperLayerThickness(), MATERIAL::GetReflection(), MATERIAL::GetReflectionRayCount(), MATERIAL::GetRefractionRayCount(), MATERIAL::GetRefractionRecursionCount(), MATERIAL::GetSpecularColor(), RAY::Init(), ACCELERATOR_3D::Intersect(), ACCELERATOR_3D::IntersectP(), m_accelerator, RENDER_3D_BASE::m_boardAdapter, BOARD_ADAPTER::m_Cfg, RAY::m_Dir, HITINFO::m_HitNormal, HITINFO::m_HitPoint, m_isPreview, m_lights, EDA_3D_VIEWER_SETTINGS::m_Render, HITINFO::m_ShadowFactor, HITINFO::m_tHit, HITINFO::pHitObject, EDA_3D_VIEWER_SETTINGS::RENDER_SETTINGS::raytrace_anti_aliasing, EDA_3D_VIEWER_SETTINGS::RENDER_SETTINGS::raytrace_nrsamples_shadows, EDA_3D_VIEWER_SETTINGS::RENDER_SETTINGS::raytrace_reflections, EDA_3D_VIEWER_SETTINGS::RENDER_SETTINGS::raytrace_refractions, EDA_3D_VIEWER_SETTINGS::RENDER_SETTINGS::raytrace_spread_reflections, EDA_3D_VIEWER_SETTINGS::RENDER_SETTINGS::raytrace_spread_refractions, EDA_3D_VIEWER_SETTINGS::RENDER_SETTINGS::raytrace_spread_shadows, Refract(), MATERIAL::Shade(), shadeHit(), and UniformRandomHemisphereDirection().

Referenced by renderAntiAliasPackets(), renderPreview(), renderRayPackets(), and shadeHit().

Member Data Documentation

◆ m_accelerator

◆ m_antioutlineBoard2dObjects

BVH_CONTAINER_2D* RENDER_3D_RAYTRACE::m_antioutlineBoard2dObjects
private

◆ m_backgroundColorBottom

SFVEC3F RENDER_3D_RAYTRACE::m_backgroundColorBottom
private

Used to see if the windows size changed.

Definition at line 184 of file render_3d_raytrace.h.

Referenced by render(), and renderBlockTracing().

◆ m_backgroundColorTop

SFVEC3F RENDER_3D_RAYTRACE::m_backgroundColorTop
private

Definition at line 183 of file render_3d_raytrace.h.

Referenced by render(), and renderBlockTracing().

◆ m_blockPositions

std::vector< SFVEC2UI > RENDER_3D_RAYTRACE::m_blockPositions
private

Flag if a position was already processed (cleared each new render).

Definition at line 190 of file render_3d_raytrace.h.

Referenced by initializeBlockPositions(), renderBlockTracing(), renderPreview(), renderTracing(), and restartRenderState().

◆ m_blockPositionsFast

std::vector< SFVEC2UI > RENDER_3D_RAYTRACE::m_blockPositionsFast
private

Definition at line 196 of file render_3d_raytrace.h.

Referenced by initializeBlockPositions(), and renderPreview().

◆ m_blockPositionsWasProcessed

std::vector< int > RENDER_3D_RAYTRACE::m_blockPositionsWasProcessed
private

Encode the Morton code positions (on fast preview mode).

Definition at line 193 of file render_3d_raytrace.h.

Referenced by restartRenderState().

◆ m_blockRenderProgressCount

size_t RENDER_3D_RAYTRACE::m_blockRenderProgressCount
private

Save the number of blocks progress of the render.

Definition at line 160 of file render_3d_raytrace.h.

Referenced by RENDER_3D_RAYTRACE(), and restartRenderState().

◆ m_boardAdapter

◆ m_boardMaterial

BOARD_NORMAL RENDER_3D_RAYTRACE::m_boardMaterial
private

Definition at line 142 of file render_3d_raytrace.h.

Referenced by setupMaterials().

◆ m_brushedMetalMaterial

BRUSHED_METAL_NORMAL RENDER_3D_RAYTRACE::m_brushedMetalMaterial
private

Definition at line 148 of file render_3d_raytrace.h.

Referenced by getModelMaterial(), and setupMaterials().

◆ m_busyIndicatorFactory

BUSY_INDICATOR::FACTORY RENDER_3D_BASE::m_busyIndicatorFactory
privateinherited

< Factory that returns a suitable busy indicator for the context.

Definition at line 128 of file render_3d_base.h.

Referenced by RENDER_3D_BASE::CreateBusyIndicator(), and RENDER_3D_BASE::SetBusyIndicatorFactory().

◆ m_camera

CAMERA& RENDER_3D_BASE::m_camera
protectedinherited

Flag if the opengl specific for this render was already initialized.

Definition at line 107 of file render_3d_base.h.

Referenced by RENDER_3D_OPENGL::Redraw(), Redraw(), RENDER_3D_OPENGL::reload(), Reload(), render(), RENDER_3D_OPENGL::render3dArrows(), renderBlockTracing(), and RENDER_3D_OPENGL::renderSolderMaskLayer().

◆ m_cameraLight

DIRECTIONAL_LIGHT* RENDER_3D_RAYTRACE::m_cameraLight
private

Definition at line 166 of file render_3d_raytrace.h.

Referenced by Redraw(), Reload(), render(), and RENDER_3D_RAYTRACE().

◆ m_canvas

EDA_3D_CANVAS* RENDER_3D_BASE::m_canvas
protectedinherited

Settings reference in use for this render.

Definition at line 102 of file render_3d_base.h.

Referenced by RENDER_3D_OPENGL::Load3dModelsIfNeeded(), and RENDER_3D_BASE::RENDER_3D_BASE().

◆ m_containerWithObjectsToDelete

CONTAINER_2D RENDER_3D_RAYTRACE::m_containerWithObjectsToDelete
private

Definition at line 176 of file render_3d_raytrace.h.

Referenced by createItemsFromContainer(), insertHole(), and Reload().

◆ m_converted2dRoundSegmentCount

unsigned int RENDER_3D_RAYTRACE::m_converted2dRoundSegmentCount
private

Definition at line 214 of file render_3d_raytrace.h.

Referenced by createObject(), and RENDER_3D_RAYTRACE().

◆ m_convertedDummyBlockCount

unsigned int RENDER_3D_RAYTRACE::m_convertedDummyBlockCount
private

Definition at line 213 of file render_3d_raytrace.h.

Referenced by createObject(), and RENDER_3D_RAYTRACE().

◆ m_Copper

BLINN_PHONG_MATERIAL RENDER_3D_RAYTRACE::m_Copper

Definition at line 137 of file render_3d_raytrace.h.

◆ m_copperMaterial

COPPER_NORMAL RENDER_3D_RAYTRACE::m_copperMaterial
private

Definition at line 143 of file render_3d_raytrace.h.

Referenced by setupMaterials().

◆ m_EpoxyBoard

BLINN_PHONG_MATERIAL RENDER_3D_RAYTRACE::m_EpoxyBoard

Definition at line 136 of file render_3d_raytrace.h.

◆ m_fastPreviewModeSize

SFVEC2UI RENDER_3D_RAYTRACE::m_fastPreviewModeSize
private

Definition at line 199 of file render_3d_raytrace.h.

Referenced by initializeBlockPositions().

◆ m_firstHitinfo

HITINFO_PACKET* RENDER_3D_RAYTRACE::m_firstHitinfo
private

Definition at line 201 of file render_3d_raytrace.h.

Referenced by RENDER_3D_RAYTRACE().

◆ m_Floor

BLINN_PHONG_MATERIAL RENDER_3D_RAYTRACE::m_Floor

Definition at line 139 of file render_3d_raytrace.h.

◆ m_is_opengl_initialized

bool RENDER_3D_BASE::m_is_opengl_initialized
protectedinherited
Todo:
This must be reviewed in order to flag change types.

Definition at line 110 of file render_3d_base.h.

Referenced by RENDER_3D_OPENGL::initializeOpenGL(), initializeOpenGL(), RENDER_3D_OPENGL::Redraw(), Redraw(), and RENDER_3D_BASE::RENDER_3D_BASE().

◆ m_isPreview

bool RENDER_3D_RAYTRACE::m_isPreview
private

Definition at line 151 of file render_3d_raytrace.h.

Referenced by RENDER_3D_RAYTRACE(), renderPreview(), renderTracing(), and shadeHit().

◆ m_lights

std::list<LIGHT*> RENDER_3D_RAYTRACE::m_lights
private

Definition at line 164 of file render_3d_raytrace.h.

Referenced by Reload(), and shadeHit().

◆ 

struct { ... } RENDER_3D_RAYTRACE::m_materials

Referenced by insertHole(), Reload(), and setupMaterials().

◆ m_modelMaterialMap

MAP_MODEL_MATERIALS RENDER_3D_RAYTRACE::m_modelMaterialMap
private

Stores materials of the 3D models.

Definition at line 210 of file render_3d_raytrace.h.

Referenced by getModelMaterial(), and Reload().

◆ m_NonPlatedCopper

BLINN_PHONG_MATERIAL RENDER_3D_RAYTRACE::m_NonPlatedCopper

Definition at line 138 of file render_3d_raytrace.h.

◆ m_objectContainer

CONTAINER_3D RENDER_3D_RAYTRACE::m_objectContainer
private

Store the list of created objects special for RT that will be clear in the end.

Definition at line 173 of file render_3d_raytrace.h.

Referenced by createItemsFromContainer(), insertHole(), and Reload().

◆ m_oldWindowsSize

wxSize RENDER_3D_RAYTRACE::m_oldWindowsSize
private

Encode Morton code positions.

Definition at line 187 of file render_3d_raytrace.h.

Referenced by Redraw(), and RENDER_3D_RAYTRACE().

◆ m_openglSupportsVertexBufferObjects

bool RENDER_3D_RAYTRACE::m_openglSupportsVertexBufferObjects
private

Definition at line 168 of file render_3d_raytrace.h.

Referenced by deletePbo(), initPbo(), and RENDER_3D_RAYTRACE().

◆ m_outlineBoard2dObjects

CONTAINER_2D* RENDER_3D_RAYTRACE::m_outlineBoard2dObjects
private

Definition at line 178 of file render_3d_raytrace.h.

Referenced by Reload(), RENDER_3D_RAYTRACE(), and ~RENDER_3D_RAYTRACE().

◆ m_Paste

BLINN_PHONG_MATERIAL RENDER_3D_RAYTRACE::m_Paste

Definition at line 133 of file render_3d_raytrace.h.

◆ m_pboDataSize

GLuint RENDER_3D_RAYTRACE::m_pboDataSize
private

Definition at line 171 of file render_3d_raytrace.h.

Referenced by initPbo(), and RENDER_3D_RAYTRACE().

◆ m_pboId

GLuint RENDER_3D_RAYTRACE::m_pboId
private

Definition at line 170 of file render_3d_raytrace.h.

Referenced by deletePbo(), initPbo(), Redraw(), and RENDER_3D_RAYTRACE().

◆ m_plasticMaterial

PLASTIC_NORMAL RENDER_3D_RAYTRACE::m_plasticMaterial
private

Definition at line 146 of file render_3d_raytrace.h.

Referenced by getModelMaterial(), and setupMaterials().

◆ m_platedCopperMaterial

PLATED_COPPER_NORMAL RENDER_3D_RAYTRACE::m_platedCopperMaterial
private

Definition at line 144 of file render_3d_raytrace.h.

Referenced by setupMaterials().

◆ m_postShaderSsao

POST_SHADER_SSAO RENDER_3D_RAYTRACE::m_postShaderSsao
private

◆ m_realBufferSize

SFVEC2UI RENDER_3D_RAYTRACE::m_realBufferSize
private

◆ m_reloadRequested

bool RENDER_3D_BASE::m_reloadRequested
protectedinherited

◆ m_renderStartTime

unsigned long int RENDER_3D_RAYTRACE::m_renderStartTime
private

Time that the render starts.

Definition at line 157 of file render_3d_raytrace.h.

Referenced by render(), RENDER_3D_RAYTRACE(), and restartRenderState().

◆ m_renderState

RT_RENDER_STATE RENDER_3D_RAYTRACE::m_renderState
private

State used on quality render.

Definition at line 154 of file render_3d_raytrace.h.

Referenced by postProcessShading(), Redraw(), render(), RENDER_3D_RAYTRACE(), and restartRenderState().

◆ m_shaderBuffer

SFVEC3F* RENDER_3D_RAYTRACE::m_shaderBuffer
private

◆ m_shinyPlasticMaterial

PLASTIC_SHINE_NORMAL RENDER_3D_RAYTRACE::m_shinyPlasticMaterial
private

Definition at line 147 of file render_3d_raytrace.h.

Referenced by getModelMaterial(), and setupMaterials().

◆ m_SilkS

BLINN_PHONG_MATERIAL RENDER_3D_RAYTRACE::m_SilkS

Definition at line 134 of file render_3d_raytrace.h.

◆ m_silkScreenMaterial

SILK_SCREEN_NORMAL RENDER_3D_RAYTRACE::m_silkScreenMaterial
private

Definition at line 149 of file render_3d_raytrace.h.

Referenced by setupMaterials().

◆ m_SolderMask

BLINN_PHONG_MATERIAL RENDER_3D_RAYTRACE::m_SolderMask

Definition at line 135 of file render_3d_raytrace.h.

◆ m_solderMaskMaterial

SOLDER_MASK_NORMAL RENDER_3D_RAYTRACE::m_solderMaskMaterial
private

Definition at line 145 of file render_3d_raytrace.h.

Referenced by setupMaterials().

◆ m_windowSize

◆ m_xoffset

unsigned int RENDER_3D_RAYTRACE::m_xoffset
private

◆ m_yoffset

unsigned int RENDER_3D_RAYTRACE::m_yoffset
private

◆ MIN_DISTANCE_IU

constexpr float RENDER_3D_RAYTRACE::MIN_DISTANCE_IU = 4 * PCB_IU_PER_MM
staticconstexpr

Definition at line 60 of file render_3d_raytrace.h.

Referenced by Reload().


The documentation for this class was generated from the following files: