61 const float aaa = aTransparency * aTransparency * aTransparency;
64 float ca = 1.0f - aTransparency;
65 ca = 1.00f - 1.05f * ca * ca * ca;
69 return glm::max( glm::min( aGrayColorValue * aGrayColorValue * ca + aaa, 1.0f ), 0.0f );
75#define UNITS3D_TO_UNITSPCB ( pcbIUScale.IU_PER_MM )
86 m_boardAdapter.m_Cfg->m_Render.raytrace_recursivelevel_refractions );
88 m_boardAdapter.m_Cfg->m_Render.raytrace_recursivelevel_reflections );
106 const SFVEC3F copperSpecularLinear =
112 SFVEC3F( 0.0f ), copperSpecularLinear, 0.4f * 128.0f, 0.0f, 0.0f );
119 SFVEC3F( 0.256f, 0.137f, 0.086f ), 0.15f * 128.0f, 0.0f, 0.0f );
131 0.10f * 128.0f, 0.0f, 0.0f );
137 SFVEC3F( 0.0f ),
SFVEC3F( 0.10f ) ), 0.078125f * 128.0f, 0.0f, 0.0f );
143 const float solderMask_gray =
153 const float minSolderMaskShininess = 0.85f * 128.0f;
154 const float maxSolderMaskShininess = 512.0f;
155 const float solderMaskShininess = minSolderMaskShininess
156 + ( maxSolderMaskShininess - minSolderMaskShininess ) * ( 1.0f - solderMask_gray );
159 const float solderMaskReflection = glm::clamp( solderMask_gray * 0.3f, 0.02f, 0.16f );
164 SFVEC3F( glm::clamp( solderMask_gray * 2.0f, 0.30f, 1.0f ) ), solderMaskShininess,
165 solderMask_transparency, solderMaskReflection );
168 m_materials.m_SolderMask.SetRefractionRayCount( 1 );
189 (
SFVEC3F( 1.0f ) - bgTop ) / 3.0f,
190 0.10f * 128.0f, 1.0f, 0.50f );
192 m_materials.m_Floor.SetReflectionRecursionCount( 1 );
197 float aZMin,
float aZMax,
const MATERIAL* aMaterial,
212 aDstContainer.
Add( objPtr );
219 aDstContainer.
Add( objPtr );
231 aDstContainer.
Add( objPtr );
240 aDstContainer.
Add( objPtr );
251 float aLayerZOffset )
253 if( aContainer2d ==
nullptr )
260 if( listObject2d.size() == 0 )
263 for(
const OBJECT_2D* object2d_A : listObject2d )
271 object2d_B =
new std::vector<const OBJECT_2D*>();
281 if( layerHolesMap.find( aLayer_id ) != layerHolesMap.end() )
289 for(
const OBJECT_2D* hole2d : intersecting )
290 object2d_B->push_back( hole2d );
300 if( !throughHoleOuter.
GetList().empty() )
306 for(
const OBJECT_2D* hole2d : intersecting )
307 object2d_B->push_back( hole2d );
312 auto clipCutouts = [
this, &object2d_A, &object2d_B](
const BVH_CONTAINER_2D& cutouts )
314 if( !cutouts.GetList().empty() )
317 cutouts.GetIntersectingObjects( object2d_A->GetBBox(), intersecting );
319 for(
const OBJECT_2D* cutout : intersecting )
320 object2d_B->push_back( cutout );
324 if( aLayer_id ==
F_Cu )
330 else if( aLayer_id ==
B_Cu )
345 for(
const OBJECT_2D* obj : intersecting )
346 object2d_B->push_back( obj );
352 && ( ( aLayer_id ==
B_SilkS && mapLayers.find(
B_Mask ) != mapLayers.end() )
353 || ( aLayer_id ==
F_SilkS && mapLayers.find(
F_Mask ) != mapLayers.end() ) ) )
361 if( containerMaskLayer2d )
364 for(
const OBJECT_2D* obj2d : intersecting )
365 object2d_B->push_back( obj2d );
368 if( object2d_B->empty() )
406 bool aOnlyLoadCopperAndShapes )
417 if( !aOnlyLoadCopperAndShapes )
422 m_camera.SetBoardLookAtPos( camera_pos );
430 if( aStatusReporter )
431 aStatusReporter->
Report(
_(
"Load Raytracing: board" ) );
440 std::bitset<LAYER_3D_END> layerFlags =
m_boardAdapter.GetVisibleLayers();
442 if( !aOnlyLoadCopperAndShapes )
444 const int outlineCount =
m_boardAdapter.GetBoardPoly().OutlineCount();
446 if( outlineCount > 0 )
448 float divFactor = 0.0f;
465 for(
int ii = 0; ii < antiboardPoly.
OutlineCount(); ii++ )
476 for(
int ii = 0; ii < boardPolyCopy.
OutlineCount(); ii++ )
487 for(
const OBJECT_2D* object2d_A : listObjects )
489 std::vector<const OBJECT_2D*>* object2d_B =
new std::vector<const OBJECT_2D*>();
499 for(
const OBJECT_2D* hole : intersecting )
501 if( object2d_A->Intersects( hole->GetBBox() ) )
502 object2d_B->push_back( hole );
507 auto addCutoutsFromContainer =
510 if( !aContainer.GetList().empty() )
513 aContainer.GetIntersectingObjects( object2d_A->GetBBox(),
516 for(
const OBJECT_2D* cutout : intersecting )
518 if( object2d_A->Intersects( cutout->GetBBox() ) )
519 object2d_B->push_back( cutout );
524 addCutoutsFromContainer(
m_boardAdapter.GetFrontCounterboreCutouts() );
525 addCutoutsFromContainer(
m_boardAdapter.GetBackCounterboreCutouts() );
526 addCutoutsFromContainer(
m_boardAdapter.GetFrontCountersinkCutouts() );
527 addCutoutsFromContainer(
m_boardAdapter.GetBackCountersinkCutouts() );
532 if( layerHolesMap.find(
F_Cu ) != layerHolesMap.end() )
539 for(
const OBJECT_2D* hole2d : intersecting )
541 if( object2d_A->Intersects( hole2d->GetBBox() ) )
542 object2d_B->push_back( hole2d );
546 if( layerHolesMap.find(
B_Cu ) != layerHolesMap.end() )
553 for(
const OBJECT_2D* hole2d : intersecting )
555 if( object2d_A->Intersects( hole2d->GetBBox() ) )
556 object2d_B->push_back( hole2d );
567 for(
const OBJECT_2D* obj : intersecting )
568 object2d_B->push_back( obj );
571 if( object2d_B->empty() )
616 for(
const OBJECT_2D* hole2d : holeList )
626 if( !intersecting.empty() )
630 switch( hole2d->GetObjectType() )
634 const float radius = hole2d->GetBBox().GetExtent().x * 0.5f * 0.999f;
661 if( aStatusReporter )
662 aStatusReporter->
Report(
_(
"Load Raytracing: layers" ) );
665 for(
const std::pair<const PCB_LAYER_ID, BVH_CONTAINER_2D*>& entry :
740 else if(
m_boardAdapter.m_Cfg->m_Render.differentiate_plated_copper )
742 layerColor =
SFVEC3F( 184.0f / 255.0f, 115.0f / 255.0f, 50.0f / 255.0f );
770 if( !aOnlyLoadCopperAndShapes )
782 for(
const std::pair<const PCB_LAYER_ID, BVH_CONTAINER_2D*>& entry :
810 const float zLayerMin =
m_boardAdapter.GetLayerBottomZPos( layer_id );
811 const float zLayerMax =
m_boardAdapter.GetLayerTopZPos( layer_id );
816 std::vector<const OBJECT_2D*>* object2d_B =
new std::vector<const OBJECT_2D*>();
826 for(
const OBJECT_2D* hole : intersecting )
828 if( object2d_A->Intersects( hole->GetBBox() ) )
829 object2d_B->push_back( hole );
835 if( !container2d->
GetList().empty() )
841 for(
const OBJECT_2D* obj : intersecting )
842 object2d_B->push_back( obj );
845 if( object2d_B->empty() )
855 materialLayer, layerColor );
869 object2d_A->GetBoardItem() );
886#ifdef PRINT_STATISTICS_3D_VIEWER
888 int64_t stats_startLoad3DmodelsTime = stats_endConvertTime;
891 if( aStatusReporter )
892 aStatusReporter->
Report(
_(
"Loading 3D models..." ) );
896#ifdef PRINT_STATISTICS_3D_VIEWER
900 if( !aOnlyLoadCopperAndShapes )
909 boardBBox.
Scale( 3.0f );
915 containerBBox.
Scale( 1.3f );
920 const float minZ = glm::min( containerBBox.
Min().z, boardBBox.
Min().z );
924 +
SFVEC3F( centerBBox.x, centerBBox.y, 0.0f );
928 +
SFVEC3F( centerBBox.x, centerBBox.y, 0.0f );
944 newTriangle1->
SetColor( floorColor );
945 newTriangle2->
SetColor( floorColor );
948 const float maxZ = glm::max( containerBBox.
Max().z, boardBBox.
Max().z );
964 newTriangle3->
SetColor( floorColor );
965 newTriangle4->
SetColor( floorColor );
979 return ( ( aSource.r < ( 1.0f / 255.0f ) ) && ( aSource.g < ( 1.0f / 255.0f ) )
980 && ( aSource.b < ( 1.0f / 255.0f ) ) );
993 if( !IsColorZero( cameraLightColor ) )
998 if( !IsColorZero( topLightColor ) )
1005 if( !IsColorZero( bottomLightColor ) )
1009 bottomLightColor ) );
1012 for(
size_t i = 0; i <
m_boardAdapter.m_Cfg->m_Render.raytrace_lightColor.size(); ++i )
1017 if( !IsColorZero( lightColor ) )
1038 / -
m_camera.GetCameraInitPos().z );
1040 if( min_zoom > max_zoom )
1041 std::swap( min_zoom, max_zoom );
1043 float zoom_ratio = max_zoom / min_zoom;
1047 steps -=
static_cast<int>( ceil( log( zoom_ratio ) / log( 1.26f ) ) );
1048 steps = std::max( steps, 0 );
1051 float increased_zoom = pow( 1.26f, steps / 2 );
1052 max_zoom *= increased_zoom;
1053 min_zoom /= increased_zoom;
1058 min_zoom = std::min( min_zoom, 1.0f );
1068 if( aStatusReporter )
1071 double calculation_time = (double) (
GetRunningMicroSecs() - stats_startReloadTime ) / 1e6;
1073 aStatusReporter->
Report( wxString::Format(
_(
"Reload time %.3f s" ), calculation_time ) );
1080 float aInnerRadius,
float aDepth,
1081 float aSurfaceZ,
bool aIsFront )
1083 const float platingThickness =
m_boardAdapter.GetHolePlatingThickness()
1086 if( platingThickness <= 0.0f || aInnerRadius <= 0.0f || aDepth <= 0.0f )
1089 const float outerRadius = aInnerRadius + platingThickness;
1090 const float zOther = aIsFront ? ( aSurfaceZ - aDepth ) : ( aSurfaceZ + aDepth );
1091 const float zMin = std::min( aSurfaceZ, zOther );
1092 const float zMax = std::max( aSurfaceZ, zOther );
1094 RING_2D* ring =
new RING_2D( aCenter, aInnerRadius, outerRadius, aSource );
1106 float aTopInnerRadius,
1107 float aBottomInnerRadius,
1108 float aSurfaceZ,
float aDepth,
1111 const float platingThickness =
m_boardAdapter.GetHolePlatingThickness()
1114 if( platingThickness <= 0.0f || aTopInnerRadius <= 0.0f || aBottomInnerRadius <= 0.0f
1120 const float topOuterRadius = aTopInnerRadius + platingThickness;
1121 const float bottomOuterRadius = aBottomInnerRadius + platingThickness;
1123 const float zOther = aIsFront ? ( aSurfaceZ - aDepth ) : ( aSurfaceZ + aDepth );
1124 const float zTop = std::max( aSurfaceZ, zOther );
1125 const float zBot = std::min( aSurfaceZ, zOther );
1127 if( topOuterRadius <= 0.0f || bottomOuterRadius <= 0.0f )
1130 const float largestDiameter = 2.0f * std::max( aTopInnerRadius, aBottomInnerRadius );
1131 unsigned int segments = std::max( 12u,
m_boardAdapter.GetCircleSegmentCount( largestDiameter ) );
1150 auto makePoint = [&](
float radius,
float angle,
float z )
1153 aCenter.y + sinf( angle ) *
radius,
1157 const float step = 2.0f * glm::pi<float>() / (float) segments;
1159 SFVEC3F innerTopPrev = makePoint( aTopInnerRadius, 0.0f, zTop );
1160 SFVEC3F innerBotPrev = makePoint( aBottomInnerRadius, 0.0f, zBot );
1161 SFVEC3F outerTopPrev = makePoint( topOuterRadius, 0.0f, zTop );
1162 SFVEC3F outerBotPrev = makePoint( bottomOuterRadius, 0.0f, zBot );
1164 const SFVEC3F innerTopFirst = innerTopPrev;
1165 const SFVEC3F innerBotFirst = innerBotPrev;
1166 const SFVEC3F outerTopFirst = outerTopPrev;
1167 const SFVEC3F outerBotFirst = outerBotPrev;
1169 for(
unsigned int i = 1; i <= segments; ++i )
1171 const float angle = ( i == segments ) ? 0.0f : step * i;
1173 const SFVEC3F innerTopCurr = ( i == segments ) ? innerTopFirst
1174 : makePoint( aTopInnerRadius, angle, zTop );
1175 const SFVEC3F innerBotCurr = ( i == segments ) ? innerBotFirst
1176 : makePoint( aBottomInnerRadius, angle, zBot );
1177 const SFVEC3F outerTopCurr = ( i == segments ) ? outerTopFirst
1178 : makePoint( topOuterRadius, angle, zTop );
1179 const SFVEC3F outerBotCurr = ( i == segments ) ? outerBotFirst
1180 : makePoint( bottomOuterRadius, angle, zBot );
1183 addQuad( innerTopPrev, innerTopCurr, innerBotCurr, innerBotPrev );
1186 addQuad( outerTopPrev, outerBotPrev, outerBotCurr, outerTopCurr );
1189 addQuad( outerTopPrev, outerTopCurr, innerTopCurr, innerTopPrev );
1192 addQuad( outerBotPrev, innerBotPrev, innerBotCurr, outerBotCurr );
1194 innerTopPrev = innerTopCurr;
1195 innerBotPrev = innerBotCurr;
1196 outerTopPrev = outerTopCurr;
1197 outerBotPrev = outerBotCurr;
1208 const int platingThickness =
m_boardAdapter.GetHolePlatingThickness();
1209 const float platingThickness3d = platingThickness * unitScale;
1223 const float holeDiameter =
via->GetDrillValue() * unitScale;
1224 const float holeInnerRadius = holeDiameter / 2.0f;
1225 const float holeOuterRadius = holeInnerRadius + platingThickness3d;
1229 via->LayerPair( &topLayer, &bottomLayer );
1231 const float viaZTop =
m_boardAdapter.GetLayerBottomZPos( topLayer );
1232 const float viaZBot =
m_boardAdapter.GetLayerBottomZPos( bottomLayer );
1235 const auto secondaryDrillSize =
via->GetSecondaryDrillSize();
1237 if( secondaryDrillSize.has_value() && secondaryDrillSize.value() > 0 )
1239 const float backdrillRadius = secondaryDrillSize.value() * 0.5f * unitScale;
1241 if( backdrillRadius > holeOuterRadius )
1247 const float secEndZ =
m_boardAdapter.GetLayerBottomZPos( secEnd );
1249 float plugZTop, plugZBot;
1251 if( secStart ==
F_Cu )
1264 if( plugZTop > plugZBot )
1279 const auto frontMode =
via->GetFrontPostMachining();
1281 if( frontMode.has_value()
1285 const float frontRadius =
via->GetFrontPostMachiningSize() * 0.5f * unitScale;
1286 const float frontDepth =
via->GetFrontPostMachiningDepth() * unitScale;
1288 if( frontRadius > holeOuterRadius && frontDepth > 0 )
1291 const float pmBottomZ = viaZTop - frontDepth;
1292 const float plugZBot = viaZBot;
1294 if( pmBottomZ > plugZBot )
1301 if( angleRad < 0.01f )
1304 float radialDiff = frontRadius - holeOuterRadius;
1305 float innerHeight = radialDiff / tanf( angleRad );
1306 float totalHeight = pmBottomZ - plugZBot;
1308 if( innerHeight > totalHeight )
1309 innerHeight = totalHeight;
1311 float zInnerTop = plugZBot + innerHeight;
1315 holeOuterRadius, frontRadius );
1321 if( zInnerTop > plugZBot )
1347 const auto backMode =
via->GetBackPostMachining();
1349 if( backMode.has_value()
1353 const float backRadius =
via->GetBackPostMachiningSize() * 0.5f * unitScale;
1354 const float backDepth =
via->GetBackPostMachiningDepth() * unitScale;
1356 if( backRadius > holeOuterRadius && backDepth > 0 )
1359 const float plugZTop = viaZTop;
1360 const float pmTopZ = viaZBot + backDepth;
1362 if( plugZTop > pmTopZ )
1369 if( angleRad < 0.01f )
1372 float radialDiff = backRadius - holeOuterRadius;
1373 float innerHeight = radialDiff / tanf( angleRad );
1374 float totalHeight = plugZTop - pmTopZ;
1376 if( innerHeight > totalHeight )
1377 innerHeight = totalHeight;
1379 float zInnerBot = plugZTop - innerHeight;
1383 backRadius, holeOuterRadius );
1389 if( zInnerBot < plugZTop )
1418 for(
const PAD*
pad : footprint->Pads() )
1423 if( !
pad->HasHole() )
1429 const SFVEC2F padCenter(
pad->GetPosition().x * unitScale,
1430 -
pad->GetPosition().y * unitScale );
1431 const float holeInnerRadius =
pad->GetDrillSize().x * 0.5f * unitScale;
1432 const float holeOuterRadius = holeInnerRadius + platingThickness3d;
1434 const float padZTop = boardZTop;
1435 const float padZBot = boardZBot;
1438 const auto frontMode =
pad->GetFrontPostMachining();
1440 if( frontMode.has_value()
1444 const float frontRadius =
pad->GetFrontPostMachiningSize() * 0.5f * unitScale;
1445 const float frontDepth =
pad->GetFrontPostMachiningDepth() * unitScale;
1447 if( frontRadius > holeOuterRadius && frontDepth > 0 )
1449 const float pmBottomZ = padZTop - frontDepth;
1450 const float plugZBot = padZBot;
1452 if( pmBottomZ > plugZBot )
1459 if( angleRad < 0.01f )
1462 float radialDiff = frontRadius - holeOuterRadius;
1463 float innerHeight = radialDiff / tanf( angleRad );
1464 float totalHeight = pmBottomZ - plugZBot;
1466 if( innerHeight > totalHeight )
1467 innerHeight = totalHeight;
1469 float zInnerTop = plugZBot + innerHeight;
1473 holeOuterRadius, frontRadius );
1479 if( zInnerTop > plugZBot )
1505 const auto backMode =
pad->GetBackPostMachining();
1507 if( backMode.has_value()
1511 const float backRadius =
pad->GetBackPostMachiningSize() * 0.5f * unitScale;
1512 const float backDepth =
pad->GetBackPostMachiningDepth() * unitScale;
1514 if( backRadius > holeOuterRadius && backDepth > 0 )
1516 const float plugZTop = padZTop;
1517 const float pmTopZ = padZBot + backDepth;
1519 if( plugZTop > pmTopZ )
1526 if( angleRad < 0.01f )
1529 float radialDiff = backRadius - holeOuterRadius;
1530 float innerHeight = radialDiff / tanf( angleRad );
1531 float totalHeight = plugZTop - pmTopZ;
1533 if( innerHeight > totalHeight )
1534 innerHeight = totalHeight;
1536 float zInnerBot = plugZTop - innerHeight;
1540 backRadius, holeOuterRadius );
1546 if( zInnerBot < plugZTop )
1580 aVia->
LayerPair( &top_layer, &bottom_layer );
1582 float frontDepth = 0.0f;
1583 float backDepth = 0.0f;
1601 ( radiusBUI +
m_boardAdapter.GetHolePlatingThickness() ) * unitScale, *aVia );
1612 const float holeInnerRadius = radiusBUI * unitScale;
1613 const float frontSurface = topZ + frontDepth;
1614 const float backSurface = botZ - backDepth;
1620 if( frontDepth > 0.0f && frontRadius > holeInnerRadius )
1637 if( backDepth > 0.0f && backRadius > holeInnerRadius )
1658 const bool hasHole = drillsize.
x && drillsize.
y;
1660 const bool isRoundHole = drillsize.
x == drillsize.
y;
1662 float holeInnerRadius = 0.0f;
1669 float frontDepth = 0.0f;
1670 float backDepth = 0.0f;
1689 int innerRadius = drillsize.
x / 2;
1690 int outerRadius = innerRadius +
m_boardAdapter.GetHolePlatingThickness();
1691 holeInnerRadius = innerRadius * unitScale;
1693 RING_2D* ring =
new RING_2D( holeCenter, innerRadius * unitScale,
1694 outerRadius * unitScale, *aPad );
1705 antiOutlineIntersectionList );
1708 if( !antiOutlineIntersectionList.empty() )
1711 holeCenter, innerRadius * unitScale, *aPad );
1714 holeCenter, outerRadius * unitScale, *aPad );
1715 std::vector<const OBJECT_2D*>* object2d_B =
new std::vector<const OBJECT_2D*>();
1716 object2d_B->push_back( innerCircle );
1725 object2d_A = itemCSG2d;
1733 if( drillsize.
x > drillsize.
y )
1735 ends_offset.
x = ( drillsize.
x - drillsize.
y ) / 2;
1736 width = drillsize.
y;
1740 ends_offset.
y = ( drillsize.
y - drillsize.
x ) / 2;
1741 width = drillsize.
x;
1751 -start.
y * unitScale ),
1753 -
end.y * unitScale ),
1754 width * unitScale, *aPad );
1758 -start.
y * unitScale ),
1760 -
end.y * unitScale ),
1762 * unitScale, *aPad );
1765 std::vector<const OBJECT_2D*>* object2d_B =
new std::vector<const OBJECT_2D*>();
1766 object2d_B->push_back( innerSeg );
1774 object2d_A = itemCSG2d;
1779 antiOutlineIntersectionList );
1785 std::vector<const OBJECT_2D*>* object2d_B =
new std::vector<const OBJECT_2D*>();
1795 for(
const OBJECT_2D* hole2d : intersecting )
1797 if( object2d_A->
Intersects( hole2d->GetBBox() ) )
1798 object2d_B->push_back( hole2d );
1802 for(
const OBJECT_2D* obj : antiOutlineIntersectionList )
1803 object2d_B->push_back( obj );
1805 if( object2d_B->empty() )
1835 if( object2d_A && isRoundHole )
1837 const float frontSurface = topZ + frontDepth;
1838 const float backSurface = botZ - backDepth;
1844 if( frontDepth > 0.0f && frontRadius > holeInnerRadius )
1862 if( backDepth > 0.0f && backRadius > holeInnerRadius )
1899 for(
PAD*
pad : footprint->Pads() )
1909 bool aSkipMaterialInformation )
1922 const wxString currentVariant =
m_boardAdapter.GetBoard()->GetCurrentVariant();
1927 if( !fp->Models().empty()
1931 if( fp->GetDNPForVariant( currentVariant ) )
1934 double zpos =
m_boardAdapter.GetFootprintZPos( fp->IsFlipped() );
1938 glm::mat4 fpMatrix = glm::mat4( 1.0f );
1940 fpMatrix = glm::translate( fpMatrix,
1945 if( !fp->GetOrientation().IsZero() )
1947 fpMatrix = glm::rotate( fpMatrix, (
float) fp->GetOrientation().AsRadians(),
1948 SFVEC3F( 0.0f, 0.0f, 1.0f ) );
1951 if( fp->IsFlipped() )
1953 fpMatrix = glm::rotate( fpMatrix, glm::pi<float>(),
SFVEC3F( 0.0f, 1.0f, 0.0f ) );
1955 fpMatrix = glm::rotate( fpMatrix, glm::pi<float>(),
SFVEC3F( 0.0f, 0.0f, 1.0f ) );
1958 const double modelunit_to_3d_units_factor =
1961 fpMatrix = glm::scale(
1962 fpMatrix,
SFVEC3F( modelunit_to_3d_units_factor, modelunit_to_3d_units_factor,
1963 modelunit_to_3d_units_factor ) );
1968 wxString libraryName = fp->GetFPID().GetLibNickname();
1970 wxString footprintBasePath = wxEmptyString;
1977 std::optional<LIBRARY_TABLE_ROW*> fpRow =
1992 if( !
model.m_Show ||
model.m_Filename.empty() )
1996 std::vector<const EMBEDDED_FILES*> embeddedFilesStack;
1997 embeddedFilesStack.push_back( fp->GetEmbeddedFiles() );
1998 embeddedFilesStack.push_back(
m_boardAdapter.GetBoard()->GetEmbeddedFiles() );
2001 std::move( embeddedFilesStack ) );
2006 glm::mat4 modelMatrix = fpMatrix;
2008 modelMatrix = glm::translate( modelMatrix,
2011 modelMatrix = glm::rotate( modelMatrix,
2012 (
float) -(
model.m_Rotation.z / 180.0f ) * glm::pi<float>(),
2013 SFVEC3F( 0.0f, 0.0f, 1.0f ) );
2015 modelMatrix = glm::rotate( modelMatrix,
2016 (
float) -(
model.m_Rotation.y / 180.0f ) * glm::pi<float>(),
2017 SFVEC3F( 0.0f, 1.0f, 0.0f ) );
2019 modelMatrix = glm::rotate( modelMatrix,
2020 (
float) -(
model.m_Rotation.x / 180.0f ) * glm::pi<float>(),
2021 SFVEC3F( 1.0f, 0.0f, 0.0f ) );
2023 modelMatrix = glm::scale( modelMatrix,
2026 addModels( aDstContainer, modelPtr, modelMatrix, (
float)
model.m_Opacity,
2027 aSkipMaterialInformation, fp );
2055 for(
unsigned int imat = 0; imat < a3DModel->
m_MaterialsSize; ++imat )
2063 float reflectionFactor = 0.0f;
2065 if( ( material.
m_Shininess - 0.35f ) > FLT_EPSILON )
2067 reflectionFactor = glm::clamp(
2068 glm::sqrt( ( material.
m_Shininess - 0.35f ) ) * 0.40f - 0.05f, 0.0f,
2079 if(
m_boardAdapter.m_Cfg->m_Render.raytrace_procedural_textures )
2134 return materialVector;
2139 const glm::mat4& aModelMatrix,
float aFPOpacity,
2140 bool aSkipMaterialInformation,
BOARD_ITEM* aBoardItem )
2143 wxASSERT( a3DModel !=
nullptr );
2145 if( a3DModel ==
nullptr )
2149 wxASSERT( a3DModel->
m_Meshes !=
nullptr );
2153 if( aFPOpacity > 1.0f )
2156 if( aFPOpacity < 0.0f )
2164 if( !aSkipMaterialInformation )
2169 const glm::mat3 normalMatrix = glm::transpose( glm::inverse( glm::mat3( aModelMatrix ) ) );
2171 for(
unsigned int mesh_i = 0; mesh_i < a3DModel->
m_MeshesSize; ++mesh_i )
2188 float fpTransparency;
2191 if( !aSkipMaterialInformation )
2200 for(
unsigned int faceIdx = 0; faceIdx < mesh.
m_FaceIdxSize; faceIdx += 3 )
2202 const unsigned int idx0 = mesh.
m_FaceIdx[faceIdx + 0];
2203 const unsigned int idx1 = mesh.
m_FaceIdx[faceIdx + 1];
2204 const unsigned int idx2 = mesh.
m_FaceIdx[faceIdx + 2];
2222 const SFVEC3F vt0 =
SFVEC3F( aModelMatrix * glm::vec4( v0, 1.0f ) );
2226 const SFVEC3F nt0 = glm::normalize(
SFVEC3F( normalMatrix * n0 ) );
2227 const SFVEC3F nt1 = glm::normalize(
SFVEC3F( normalMatrix * n1 ) );
2228 const SFVEC3F nt2 = glm::normalize(
SFVEC3F( normalMatrix * n2 ) );
2234 aDstContainer.
Add( newTriangle );
2236 if( !aSkipMaterialInformation )
@ NORMAL
Use all material properties from model file.
@ CAD_MODE
Use a gray shading based on diffuse material.
Defines math related functions.
float NextFloatDown(float v)
float NextFloatUp(float v)
Defines math related functions.
float RGBtoGray(const SFVEC3F &aColor)
SFVEC3F MaterialDiffuseToColorCAD(const SFVEC3F &aDiffuseColor)
SFVEC3F SphericalToCartesian(float aInclination, float aAzimuth)
https://en.wikipedia.org/wiki/Spherical_coordinate_system
constexpr EDA_IU_SCALE pcbIUScale
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.
#define RANGE_SCALE_3D
This defines the range that all coord will have to be rendered.
This BVH implementation is based on the source code implementation from the book "Physically Based Re...
Blinn Phong based material https://en.wikipedia.org/wiki/Blinn%E2%80%93Phong_shading_model.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Information pertinent to a Pcbnew printed circuit board.
void GetIntersectingObjects(const BBOX_2D &aBBox, CONST_LIST_OBJECT2D &aOutList) const override
Get a list of objects that intersects a bounding box.
static const float DEFAULT_MAX_ZOOM
const LIST_OBJECT2D & GetList() const
void Add(OBJECT_3D *aObject)
Procedural generation of the copper normals.
void SetColor(SFVEC3F aObjColor)
A light source based only on a directional vector.
Make solid geometry for objects on layers.
void SetColor(SFVEC3F aObjColor)
std::optional< LIBRARY_TABLE_ROW * > GetRow(const wxString &aNickname, LIBRARY_TABLE_SCOPE aScope=LIBRARY_TABLE_SCOPE::BOTH) const
Like LIBRARY_MANAGER::GetRow but filtered to the LIBRARY_TABLE_TYPE of this adapter.
std::optional< wxString > GetFullURI(LIBRARY_TABLE_TYPE aType, const wxString &aNickname, bool aSubstituted=false) const
Return the full location specifying URI for the LIB, either in original UI form or in environment var...
A base light class to derive to implement other light classes.
Base material class that can be used to derive other material implementations.
static void SetDefaultReflectionRayCount(unsigned int aCount)
static void SetDefaultRefractionRayCount(unsigned int aCount)
static void SetDefaultRefractionRecursionCount(unsigned int aCount)
void SetGenerator(const MATERIAL_GENERATOR *aGenerator)
float GetTransparency() const
static void SetDefaultReflectionRecursionCount(unsigned int aCount)
static OBJECT_2D_STATS & Instance()
virtual bool Intersects(const BBOX_2D &aBBox) const =0
a.Intersects(b) ⇔ !a.Disjoint(b) ⇔ !(a ∩ b = ∅)
const BBOX_2D & GetBBox() const
const BOARD_ITEM & GetBoardItem() const
OBJECT_2D_TYPE GetObjectType() const
static OBJECT_3D_STATS & Instance()
void SetMaterial(const MATERIAL *aMaterial)
void SetModelTransparency(float aModelTransparency)
void SetBoardItem(BOARD_ITEM *aBoardItem)
POST_MACHINING_PROPS & FrontPostMachining()
POST_MACHINING_PROPS & BackPostMachining()
int GetBackPostMachiningSize() const
const VECTOR2I & GetDrillSize() const
VECTOR2I GetPosition() const override
int GetFrontPostMachiningSize() const
int GetFrontPostMachiningDepth() const
std::optional< PAD_DRILL_POST_MACHINING_MODE > GetFrontPostMachining() const
EDA_ANGLE GetOrientation() const
Return the rotation angle of the pad.
std::optional< PAD_DRILL_POST_MACHINING_MODE > GetBackPostMachining() const
int GetBackPostMachiningDepth() const
const VECTOR2I & GetStart() const
int GetFrontPostMachiningSize() const
const PADSTACK & Padstack() const
std::optional< PAD_DRILL_POST_MACHINING_MODE > GetFrontPostMachining() const
int GetBackPostMachiningSize() const
int GetDrillValue() const
Calculate the drill value for vias (m_drill if > 0, or default drill value for the board).
std::optional< PAD_DRILL_POST_MACHINING_MODE > GetBackPostMachining() const
void LayerPair(PCB_LAYER_ID *top_layer, PCB_LAYER_ID *bottom_layer) const
Return the 2 layers used by the via (the via actually uses all layers between these 2 layers)
Procedural generation of the plastic normals.
Procedural generation of the shiny plastic normals.
Point light source based on http://ogldev.atspace.co.uk/www/tutorial20/tutorial20....
static FOOTPRINT_LIBRARY_ADAPTER * FootprintLibAdapter(PROJECT *aProject)
BOARD_ADAPTER & m_boardAdapter
Settings reference in use for this render.
SILK_SCREEN_NORMAL m_silkScreenMaterial
struct RENDER_3D_RAYTRACE_BASE::@013206213056006125230376122042346155134272177300 m_materials
void Reload(REPORTER *aStatusReporter, REPORTER *aWarningReporter, bool aOnlyLoadCopperAndShapes)
void addCountersinkPlating(const SFVEC2F &aCenter, float aTopInnerRadius, float aBottomInnerRadius, float aSurfaceZ, float aDepth, bool aIsFront)
BOARD_NORMAL m_boardMaterial
CONTAINER_3D m_objectContainer
COPPER_NORMAL m_copperMaterial
void load3DModels(CONTAINER_3D &aDstContainer, bool aSkipMaterialInformation)
void insertHole(const PCB_VIA *aVia)
BRUSHED_METAL_NORMAL m_brushedMetalMaterial
static constexpr float MIN_DISTANCE_IU
PLATED_COPPER_NORMAL m_platedCopperMaterial
PLASTIC_NORMAL m_plasticMaterial
ACCELERATOR_3D * m_accelerator
void createItemsFromContainer(const BVH_CONTAINER_2D *aContainer2d, PCB_LAYER_ID aLayer_id, const MATERIAL *aMaterialLayer, const SFVEC3F &aLayerColor, float aLayerZOffset)
DIRECTIONAL_LIGHT * m_cameraLight
PLASTIC_SHINE_NORMAL m_shinyPlasticMaterial
unsigned int m_convertedDummyBlockCount
void backfillPostMachine()
void addCounterborePlating(const BOARD_ITEM &aSource, const SFVEC2F &aCenter, float aInnerRadius, float aDepth, float aSurfaceZ, bool aIsFront)
CONTAINER_2D * m_outlineBoard2dObjects
BVH_CONTAINER_2D * m_antioutlineBoard2dObjects
CONTAINER_2D m_containerWithObjectsToDelete
Store the list of created objects special for RT that will be clear in the end.
MODEL_MATERIALS * getModelMaterial(const S3DMODEL *a3DModel)
SOLDER_MASK_NORMAL m_solderMaskMaterial
void addModels(CONTAINER_3D &aDstContainer, const S3DMODEL *a3DModel, const glm::mat4 &aModelMatrix, float aFPOpacity, bool aSkipMaterialInformation, BOARD_ITEM *aBoardItem)
std::list< LIGHT * > m_lights
MAP_MODEL_MATERIALS m_modelMaterialMap
Stores materials of the 3D models.
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.
unsigned int m_converted2dRoundSegmentCount
A pure virtual class used to derive REPORTER objects from.
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)
Report a string with a given severity.
void SetColor(SFVEC3F aObjColor)
Cache for storing the 3D shapes.
S3DMODEL * GetModel(const wxString &aModelFileName, const wxString &aBasePath, std::vector< const EMBEDDED_FILES * > aEmbeddedFilesStack)
Attempt to load the scene data for a model and to translate it into an S3D_MODEL structure for displa...
Represent a set of closed polygons.
void Fracture()
Convert a set of polygons with holes to a single outline with "slits"/"fractures" connecting the oute...
int OutlineCount() const
Return the number of outlines in the set.
void BooleanSubtract(const SHAPE_POLY_SET &b)
Perform boolean polyset difference.
Procedural generation of the solder mask.
void SetColor(const SFVEC3F &aColor)
A vertical truncated cone with different radii at top and bottom.
void SetColor(SFVEC3F aObjColor)
A plane that is parallel to XY plane.
void SetColor(SFVEC3F aObjColor)
std::list< OBJECT_2D * > LIST_OBJECT2D
std::list< const OBJECT_2D * > CONST_LIST_OBJECT2D
#define UNITS3D_TO_UNITSPCB
Implements a model viewer canvas.
Declaration of the eda_3d_viewer class.
A truncated cone for raytracing, used for countersink visualization.
int MapPCBLayerTo3DLayer(PCB_LAYER_ID aLayer)
@ LAYER_3D_SOLDERMASK_TOP
@ LAYER_3D_SOLDERMASK_BOTTOM
bool IsCopperLayer(int aLayerId)
Test whether a layer is a copper layer.
PCB_LAYER_ID
A quick note on layer IDs:
PAD_DRILL_POST_MACHINING_MODE
@ NPTH
like PAD_PTH, but not plated mechanical use only, no connection allowed
static wxColor copperColor(220, 180, 30)
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...
int64_t GetRunningMicroSecs()
An alternate way to calculate an elapsed time (in microsecondes) to class PROF_COUNTER.
void buildBoardBoundingBoxPoly(const BOARD *aBoard, SHAPE_POLY_SET &aOutline)
Get the complete bounding box of the board (including all items).
static float TransparencyControl(float aGrayColorValue, float aTransparency)
Perform an interpolation step to easy control the transparency based on the gray color value and tran...
static float TransparencyControl(float aGrayColorValue, float aTransparency)
Attempt to control the transparency based on the gray value of the color.
SFVEC3F ConvertSRGBToLinear(const SFVEC3F &aSRGBcolor)
std::vector< BLINN_PHONG_MATERIAL > MODEL_MATERIALS
Vector of materials.
const SFVEC2F & Min() const
const SFVEC2F & Max() const
Manage a bounding box defined by two SFVEC3F min max points.
SFVEC3F GetCenter() const
Return the center point of the bounding box.
const SFVEC3F & Min() const
Return the minimum vertex pointer.
const SFVEC3F & Max() const
Return the maximum vertex pointer.
bool IsInitialized() const
Check if this bounding box is already initialized.
void Scale(float aScale)
Scales a bounding box by its center.
bool clip_silk_on_via_annuli
bool subtract_mask_from_silk
std::optional< PAD_DRILL_POST_MACHINING_MODE > mode
Store the a model based on meshes and materials.
SMATERIAL * m_Materials
The materials list of this model.
unsigned int m_MeshesSize
Number of meshes in the array.
SMESH * m_Meshes
The meshes list of this model.
unsigned int m_MaterialsSize
Number of materials in the material array.
float m_Transparency
1.0 is completely transparent, 0.0 completely opaque
SFVEC3F m_Diffuse
Default diffuse color if m_Color is NULL.
Per-vertex normal/color/texcoors structure.
unsigned int * m_FaceIdx
Triangle Face Indexes.
SFVEC3F * m_Normals
Vertex normals array.
unsigned int m_MaterialIdx
Material Index to be used in this mesh (must be < m_MaterialsSize )
unsigned int m_VertexSize
Number of vertex in the arrays.
unsigned int m_FaceIdxSize
Number of elements of the m_FaceIdx array.
SFVEC3F * m_Color
Vertex color array, can be NULL.
SFVEC3F * m_Positions
Vertex position array.
Implement a triangle ray intersection based on article http://www.flipcode.com/archives/Raytracing_To...
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Calculate the new point of coord coord pX, pY, for a rotation center 0, 0.
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
VECTOR2< int32_t > VECTOR2I