61 const float aaa = aTransparency * aTransparency * aTransparency;
64 float ca = 1.0f - aTransparency;
65 ca = 1.00f - 1.05f * ca * ca * ca;
67 return glm::max( glm::min( aGrayColorValue * ca + aaa, 1.0f ), 0.0f );
73#define UNITS3D_TO_UNITSPCB ( pcbIUScale.IU_PER_MM )
84 m_boardAdapter.m_Cfg->m_Render.raytrace_recursivelevel_refractions );
86 m_boardAdapter.m_Cfg->m_Render.raytrace_recursivelevel_reflections );
104 const SFVEC3F copperSpecularLinear =
110 SFVEC3F( 0.0f ), copperSpecularLinear, 0.4f * 128.0f, 0.0f, 0.0f );
117 SFVEC3F( 0.256f, 0.137f, 0.086f ), 0.15f * 128.0f, 0.0f, 0.0f );
129 0.10f * 128.0f, 0.0f, 0.0f );
135 SFVEC3F( 0.0f ),
SFVEC3F( 0.10f ) ), 0.078125f * 128.0f, 0.0f, 0.0f );
141 const float solderMask_gray =
151 const float minSolderMaskShininess = 0.85f * 128.0f;
152 const float maxSolderMaskShininess = 512.0f;
153 const float solderMaskShininess = minSolderMaskShininess
154 + ( maxSolderMaskShininess - minSolderMaskShininess ) * ( 1.0f - solderMask_gray );
157 const float solderMaskReflection = glm::clamp( solderMask_gray * 0.3f, 0.02f, 0.16f );
162 SFVEC3F( glm::clamp( solderMask_gray * 2.0f, 0.30f, 1.0f ) ), solderMaskShininess,
163 solderMask_transparency, solderMaskReflection );
166 m_materials.m_SolderMask.SetRefractionRayCount( 1 );
187 (
SFVEC3F( 1.0f ) - bgTop ) / 3.0f,
188 0.10f * 128.0f, 1.0f, 0.50f );
190 m_materials.m_Floor.SetReflectionRecursionCount( 1 );
195 float aZMin,
float aZMax,
const MATERIAL* aMaterial,
210 aDstContainer.
Add( objPtr );
217 aDstContainer.
Add( objPtr );
229 aDstContainer.
Add( objPtr );
238 aDstContainer.
Add( objPtr );
249 float aLayerZOffset )
251 if( aContainer2d ==
nullptr )
258 if( listObject2d.size() == 0 )
261 for(
const OBJECT_2D* object2d_A : listObject2d )
269 object2d_B =
new std::vector<const OBJECT_2D*>();
279 if( layerHolesMap.find( aLayer_id ) != layerHolesMap.end() )
287 for(
const OBJECT_2D* hole2d : intersecting )
288 object2d_B->push_back( hole2d );
298 if( !throughHoleOuter.
GetList().empty() )
304 for(
const OBJECT_2D* hole2d : intersecting )
305 object2d_B->push_back( hole2d );
310 auto clipCutouts = [
this, &object2d_A, &object2d_B](
const BVH_CONTAINER_2D& cutouts )
312 if( !cutouts.GetList().empty() )
315 cutouts.GetIntersectingObjects( object2d_A->GetBBox(), intersecting );
317 for(
const OBJECT_2D* cutout : intersecting )
318 object2d_B->push_back( cutout );
322 if( aLayer_id ==
F_Cu )
328 else if( aLayer_id ==
B_Cu )
343 for(
const OBJECT_2D* obj : intersecting )
344 object2d_B->push_back( obj );
350 && ( ( aLayer_id ==
B_SilkS && mapLayers.find(
B_Mask ) != mapLayers.end() )
351 || ( aLayer_id ==
F_SilkS && mapLayers.find(
F_Mask ) != mapLayers.end() ) ) )
359 if( containerMaskLayer2d )
362 for(
const OBJECT_2D* obj2d : intersecting )
363 object2d_B->push_back( obj2d );
366 if( object2d_B->empty() )
404 bool aOnlyLoadCopperAndShapes )
415 if( !aOnlyLoadCopperAndShapes )
420 m_camera.SetBoardLookAtPos( camera_pos );
428 if( aStatusReporter )
429 aStatusReporter->
Report(
_(
"Load Raytracing: board" ) );
438 std::bitset<LAYER_3D_END> layerFlags =
m_boardAdapter.GetVisibleLayers();
440 if( !aOnlyLoadCopperAndShapes )
442 const int outlineCount =
m_boardAdapter.GetBoardPoly().OutlineCount();
444 if( outlineCount > 0 )
446 float divFactor = 0.0f;
463 for(
int ii = 0; ii < antiboardPoly.
OutlineCount(); ii++ )
474 for(
int ii = 0; ii < boardPolyCopy.
OutlineCount(); ii++ )
485 for(
const OBJECT_2D* object2d_A : listObjects )
487 std::vector<const OBJECT_2D*>* object2d_B =
new std::vector<const OBJECT_2D*>();
497 for(
const OBJECT_2D* hole : intersecting )
499 if( object2d_A->Intersects( hole->GetBBox() ) )
500 object2d_B->push_back( hole );
505 auto addCutoutsFromContainer =
508 if( !aContainer.GetList().empty() )
511 aContainer.GetIntersectingObjects( object2d_A->GetBBox(),
514 for(
const OBJECT_2D* cutout : intersecting )
516 if( object2d_A->Intersects( cutout->GetBBox() ) )
517 object2d_B->push_back( cutout );
522 addCutoutsFromContainer(
m_boardAdapter.GetFrontCounterboreCutouts() );
523 addCutoutsFromContainer(
m_boardAdapter.GetBackCounterboreCutouts() );
524 addCutoutsFromContainer(
m_boardAdapter.GetFrontCountersinkCutouts() );
525 addCutoutsFromContainer(
m_boardAdapter.GetBackCountersinkCutouts() );
530 if( layerHolesMap.find(
F_Cu ) != layerHolesMap.end() )
537 for(
const OBJECT_2D* hole2d : intersecting )
539 if( object2d_A->Intersects( hole2d->GetBBox() ) )
540 object2d_B->push_back( hole2d );
544 if( layerHolesMap.find(
B_Cu ) != layerHolesMap.end() )
551 for(
const OBJECT_2D* hole2d : intersecting )
553 if( object2d_A->Intersects( hole2d->GetBBox() ) )
554 object2d_B->push_back( hole2d );
565 for(
const OBJECT_2D* obj : intersecting )
566 object2d_B->push_back( obj );
569 if( object2d_B->empty() )
614 for(
const OBJECT_2D* hole2d : holeList )
624 if( !intersecting.empty() )
628 switch( hole2d->GetObjectType() )
632 const float radius = hole2d->GetBBox().GetExtent().x * 0.5f * 0.999f;
659 if( aStatusReporter )
660 aStatusReporter->
Report(
_(
"Load Raytracing: layers" ) );
663 for(
const std::pair<const PCB_LAYER_ID, BVH_CONTAINER_2D*>& entry :
738 else if(
m_boardAdapter.m_Cfg->m_Render.differentiate_plated_copper )
740 layerColor =
SFVEC3F( 184.0f / 255.0f, 115.0f / 255.0f, 50.0f / 255.0f );
768 if( !aOnlyLoadCopperAndShapes )
780 for(
const std::pair<const PCB_LAYER_ID, BVH_CONTAINER_2D*>& entry :
808 const float zLayerMin =
m_boardAdapter.GetLayerBottomZPos( layer_id );
809 const float zLayerMax =
m_boardAdapter.GetLayerTopZPos( layer_id );
814 std::vector<const OBJECT_2D*>* object2d_B =
new std::vector<const OBJECT_2D*>();
824 for(
const OBJECT_2D* hole : intersecting )
826 if( object2d_A->Intersects( hole->GetBBox() ) )
827 object2d_B->push_back( hole );
833 if( !container2d->
GetList().empty() )
839 for(
const OBJECT_2D* obj : intersecting )
840 object2d_B->push_back( obj );
843 if( object2d_B->empty() )
853 materialLayer, layerColor );
867 object2d_A->GetBoardItem() );
884#ifdef PRINT_STATISTICS_3D_VIEWER
886 int64_t stats_startLoad3DmodelsTime = stats_endConvertTime;
889 if( aStatusReporter )
890 aStatusReporter->
Report(
_(
"Loading 3D models..." ) );
894#ifdef PRINT_STATISTICS_3D_VIEWER
898 if( !aOnlyLoadCopperAndShapes )
907 boardBBox.
Scale( 3.0f );
913 containerBBox.
Scale( 1.3f );
918 const float minZ = glm::min( containerBBox.
Min().z, boardBBox.
Min().z );
922 +
SFVEC3F( centerBBox.x, centerBBox.y, 0.0f );
926 +
SFVEC3F( centerBBox.x, centerBBox.y, 0.0f );
942 newTriangle1->
SetColor( floorColor );
943 newTriangle2->
SetColor( floorColor );
946 const float maxZ = glm::max( containerBBox.
Max().z, boardBBox.
Max().z );
962 newTriangle3->
SetColor( floorColor );
963 newTriangle4->
SetColor( floorColor );
977 return ( ( aSource.r < ( 1.0f / 255.0f ) ) && ( aSource.g < ( 1.0f / 255.0f ) )
978 && ( aSource.b < ( 1.0f / 255.0f ) ) );
991 if( !IsColorZero( cameraLightColor ) )
996 if( !IsColorZero( topLightColor ) )
1003 if( !IsColorZero( bottomLightColor ) )
1007 bottomLightColor ) );
1010 for(
size_t i = 0; i <
m_boardAdapter.m_Cfg->m_Render.raytrace_lightColor.size(); ++i )
1015 if( !IsColorZero( lightColor ) )
1036 / -
m_camera.GetCameraInitPos().z );
1038 if( min_zoom > max_zoom )
1039 std::swap( min_zoom, max_zoom );
1041 float zoom_ratio = max_zoom / min_zoom;
1045 steps -=
static_cast<int>( ceil( log( zoom_ratio ) / log( 1.26f ) ) );
1046 steps = std::max( steps, 0 );
1049 float increased_zoom = pow( 1.26f, steps / 2 );
1050 max_zoom *= increased_zoom;
1051 min_zoom /= increased_zoom;
1056 min_zoom = std::min( min_zoom, 1.0f );
1066 if( aStatusReporter )
1069 double calculation_time = (double) (
GetRunningMicroSecs() - stats_startReloadTime ) / 1e6;
1071 aStatusReporter->
Report( wxString::Format(
_(
"Reload time %.3f s" ), calculation_time ) );
1078 float aInnerRadius,
float aDepth,
1079 float aSurfaceZ,
bool aIsFront )
1081 const float platingThickness =
m_boardAdapter.GetHolePlatingThickness()
1084 if( platingThickness <= 0.0f || aInnerRadius <= 0.0f || aDepth <= 0.0f )
1087 const float outerRadius = aInnerRadius + platingThickness;
1088 const float zOther = aIsFront ? ( aSurfaceZ - aDepth ) : ( aSurfaceZ + aDepth );
1089 const float zMin = std::min( aSurfaceZ, zOther );
1090 const float zMax = std::max( aSurfaceZ, zOther );
1092 RING_2D* ring =
new RING_2D( aCenter, aInnerRadius, outerRadius, aSource );
1104 float aTopInnerRadius,
1105 float aBottomInnerRadius,
1106 float aSurfaceZ,
float aDepth,
1109 const float platingThickness =
m_boardAdapter.GetHolePlatingThickness()
1112 if( platingThickness <= 0.0f || aTopInnerRadius <= 0.0f || aBottomInnerRadius <= 0.0f
1118 const float topOuterRadius = aTopInnerRadius + platingThickness;
1119 const float bottomOuterRadius = aBottomInnerRadius + platingThickness;
1121 const float zOther = aIsFront ? ( aSurfaceZ - aDepth ) : ( aSurfaceZ + aDepth );
1122 const float zTop = std::max( aSurfaceZ, zOther );
1123 const float zBot = std::min( aSurfaceZ, zOther );
1125 if( topOuterRadius <= 0.0f || bottomOuterRadius <= 0.0f )
1128 const float largestDiameter = 2.0f * std::max( aTopInnerRadius, aBottomInnerRadius );
1129 unsigned int segments = std::max( 12u,
m_boardAdapter.GetCircleSegmentCount( largestDiameter ) );
1148 auto makePoint = [&](
float radius,
float angle,
float z )
1151 aCenter.y + sinf( angle ) *
radius,
1155 const float step = 2.0f * glm::pi<float>() / (float) segments;
1157 SFVEC3F innerTopPrev = makePoint( aTopInnerRadius, 0.0f, zTop );
1158 SFVEC3F innerBotPrev = makePoint( aBottomInnerRadius, 0.0f, zBot );
1159 SFVEC3F outerTopPrev = makePoint( topOuterRadius, 0.0f, zTop );
1160 SFVEC3F outerBotPrev = makePoint( bottomOuterRadius, 0.0f, zBot );
1162 const SFVEC3F innerTopFirst = innerTopPrev;
1163 const SFVEC3F innerBotFirst = innerBotPrev;
1164 const SFVEC3F outerTopFirst = outerTopPrev;
1165 const SFVEC3F outerBotFirst = outerBotPrev;
1167 for(
unsigned int i = 1; i <= segments; ++i )
1169 const float angle = ( i == segments ) ? 0.0f : step * i;
1171 const SFVEC3F innerTopCurr = ( i == segments ) ? innerTopFirst
1172 : makePoint( aTopInnerRadius, angle, zTop );
1173 const SFVEC3F innerBotCurr = ( i == segments ) ? innerBotFirst
1174 : makePoint( aBottomInnerRadius, angle, zBot );
1175 const SFVEC3F outerTopCurr = ( i == segments ) ? outerTopFirst
1176 : makePoint( topOuterRadius, angle, zTop );
1177 const SFVEC3F outerBotCurr = ( i == segments ) ? outerBotFirst
1178 : makePoint( bottomOuterRadius, angle, zBot );
1181 addQuad( innerTopPrev, innerTopCurr, innerBotCurr, innerBotPrev );
1184 addQuad( outerTopPrev, outerBotPrev, outerBotCurr, outerTopCurr );
1187 addQuad( outerTopPrev, outerTopCurr, innerTopCurr, innerTopPrev );
1190 addQuad( outerBotPrev, innerBotPrev, innerBotCurr, outerBotCurr );
1192 innerTopPrev = innerTopCurr;
1193 innerBotPrev = innerBotCurr;
1194 outerTopPrev = outerTopCurr;
1195 outerBotPrev = outerBotCurr;
1206 const int platingThickness =
m_boardAdapter.GetHolePlatingThickness();
1207 const float platingThickness3d = platingThickness * unitScale;
1221 const float holeDiameter =
via->GetDrillValue() * unitScale;
1222 const float holeInnerRadius = holeDiameter / 2.0f;
1223 const float holeOuterRadius = holeInnerRadius + platingThickness3d;
1227 via->LayerPair( &topLayer, &bottomLayer );
1229 const float viaZTop =
m_boardAdapter.GetLayerBottomZPos( topLayer );
1230 const float viaZBot =
m_boardAdapter.GetLayerBottomZPos( bottomLayer );
1233 const auto secondaryDrillSize =
via->GetSecondaryDrillSize();
1235 if( secondaryDrillSize.has_value() && secondaryDrillSize.value() > 0 )
1237 const float backdrillRadius = secondaryDrillSize.value() * 0.5f * unitScale;
1239 if( backdrillRadius > holeOuterRadius )
1245 const float secEndZ =
m_boardAdapter.GetLayerBottomZPos( secEnd );
1247 float plugZTop, plugZBot;
1249 if( secStart ==
F_Cu )
1262 if( plugZTop > plugZBot )
1277 const auto frontMode =
via->GetFrontPostMachining();
1279 if( frontMode.has_value()
1283 const float frontRadius =
via->GetFrontPostMachiningSize() * 0.5f * unitScale;
1284 const float frontDepth =
via->GetFrontPostMachiningDepth() * unitScale;
1286 if( frontRadius > holeOuterRadius && frontDepth > 0 )
1289 const float pmBottomZ = viaZTop - frontDepth;
1290 const float plugZBot = viaZBot;
1292 if( pmBottomZ > plugZBot )
1299 if( angleRad < 0.01f )
1302 float radialDiff = frontRadius - holeOuterRadius;
1303 float innerHeight = radialDiff / tanf( angleRad );
1304 float totalHeight = pmBottomZ - plugZBot;
1306 if( innerHeight > totalHeight )
1307 innerHeight = totalHeight;
1309 float zInnerTop = plugZBot + innerHeight;
1313 holeOuterRadius, frontRadius );
1319 if( zInnerTop > plugZBot )
1345 const auto backMode =
via->GetBackPostMachining();
1347 if( backMode.has_value()
1351 const float backRadius =
via->GetBackPostMachiningSize() * 0.5f * unitScale;
1352 const float backDepth =
via->GetBackPostMachiningDepth() * unitScale;
1354 if( backRadius > holeOuterRadius && backDepth > 0 )
1357 const float plugZTop = viaZTop;
1358 const float pmTopZ = viaZBot + backDepth;
1360 if( plugZTop > pmTopZ )
1367 if( angleRad < 0.01f )
1370 float radialDiff = backRadius - holeOuterRadius;
1371 float innerHeight = radialDiff / tanf( angleRad );
1372 float totalHeight = plugZTop - pmTopZ;
1374 if( innerHeight > totalHeight )
1375 innerHeight = totalHeight;
1377 float zInnerBot = plugZTop - innerHeight;
1381 backRadius, holeOuterRadius );
1387 if( zInnerBot < plugZTop )
1416 for(
const PAD*
pad : footprint->Pads() )
1421 if( !
pad->HasHole() )
1427 const SFVEC2F padCenter(
pad->GetPosition().x * unitScale,
1428 -
pad->GetPosition().y * unitScale );
1429 const float holeInnerRadius =
pad->GetDrillSize().x * 0.5f * unitScale;
1430 const float holeOuterRadius = holeInnerRadius + platingThickness3d;
1432 const float padZTop = boardZTop;
1433 const float padZBot = boardZBot;
1436 const auto frontMode =
pad->GetFrontPostMachining();
1438 if( frontMode.has_value()
1442 const float frontRadius =
pad->GetFrontPostMachiningSize() * 0.5f * unitScale;
1443 const float frontDepth =
pad->GetFrontPostMachiningDepth() * unitScale;
1445 if( frontRadius > holeOuterRadius && frontDepth > 0 )
1447 const float pmBottomZ = padZTop - frontDepth;
1448 const float plugZBot = padZBot;
1450 if( pmBottomZ > plugZBot )
1457 if( angleRad < 0.01f )
1460 float radialDiff = frontRadius - holeOuterRadius;
1461 float innerHeight = radialDiff / tanf( angleRad );
1462 float totalHeight = pmBottomZ - plugZBot;
1464 if( innerHeight > totalHeight )
1465 innerHeight = totalHeight;
1467 float zInnerTop = plugZBot + innerHeight;
1471 holeOuterRadius, frontRadius );
1477 if( zInnerTop > plugZBot )
1503 const auto backMode =
pad->GetBackPostMachining();
1505 if( backMode.has_value()
1509 const float backRadius =
pad->GetBackPostMachiningSize() * 0.5f * unitScale;
1510 const float backDepth =
pad->GetBackPostMachiningDepth() * unitScale;
1512 if( backRadius > holeOuterRadius && backDepth > 0 )
1514 const float plugZTop = padZTop;
1515 const float pmTopZ = padZBot + backDepth;
1517 if( plugZTop > pmTopZ )
1524 if( angleRad < 0.01f )
1527 float radialDiff = backRadius - holeOuterRadius;
1528 float innerHeight = radialDiff / tanf( angleRad );
1529 float totalHeight = plugZTop - pmTopZ;
1531 if( innerHeight > totalHeight )
1532 innerHeight = totalHeight;
1534 float zInnerBot = plugZTop - innerHeight;
1538 backRadius, holeOuterRadius );
1544 if( zInnerBot < plugZTop )
1581 aVia->
LayerPair( &top_layer, &bottom_layer );
1583 float frontDepth = 0.0f;
1584 float backDepth = 0.0f;
1602 ( radiusBUI +
m_boardAdapter.GetHolePlatingThickness() ) * unitScale, *aVia );
1613 const float holeInnerRadius = radiusBUI * unitScale;
1614 const float frontSurface = topZ + frontDepth;
1615 const float backSurface = botZ - backDepth;
1621 if( frontDepth > 0.0f && frontRadius > holeInnerRadius )
1638 if( backDepth > 0.0f && backRadius > holeInnerRadius )
1662 const bool hasHole = drillsize.
x && drillsize.
y;
1664 const bool isRoundHole = drillsize.
x == drillsize.
y;
1666 float holeInnerRadius = 0.0f;
1673 float frontDepth = 0.0f;
1674 float backDepth = 0.0f;
1693 int innerRadius = drillsize.
x / 2;
1694 int outerRadius = innerRadius +
m_boardAdapter.GetHolePlatingThickness();
1695 holeInnerRadius = innerRadius * unitScale;
1697 RING_2D* ring =
new RING_2D( holeCenter, innerRadius * unitScale,
1698 outerRadius * unitScale, *aPad );
1709 antiOutlineIntersectionList );
1712 if( !antiOutlineIntersectionList.empty() )
1715 holeCenter, innerRadius * unitScale, *aPad );
1718 holeCenter, outerRadius * unitScale, *aPad );
1719 std::vector<const OBJECT_2D*>* object2d_B =
new std::vector<const OBJECT_2D*>();
1720 object2d_B->push_back( innerCircle );
1729 object2d_A = itemCSG2d;
1737 if( drillsize.
x > drillsize.
y )
1739 ends_offset.
x = ( drillsize.
x - drillsize.
y ) / 2;
1740 width = drillsize.
y;
1744 ends_offset.
y = ( drillsize.
y - drillsize.
x ) / 2;
1745 width = drillsize.
x;
1755 -start.
y * unitScale ),
1757 -
end.y * unitScale ),
1758 width * unitScale, *aPad );
1762 -start.
y * unitScale ),
1764 -
end.y * unitScale ),
1766 * unitScale, *aPad );
1769 std::vector<const OBJECT_2D*>* object2d_B =
new std::vector<const OBJECT_2D*>();
1770 object2d_B->push_back( innerSeg );
1778 object2d_A = itemCSG2d;
1783 antiOutlineIntersectionList );
1789 std::vector<const OBJECT_2D*>* object2d_B =
new std::vector<const OBJECT_2D*>();
1799 for(
const OBJECT_2D* hole2d : intersecting )
1801 if( object2d_A->
Intersects( hole2d->GetBBox() ) )
1802 object2d_B->push_back( hole2d );
1806 for(
const OBJECT_2D* obj : antiOutlineIntersectionList )
1807 object2d_B->push_back( obj );
1809 if( object2d_B->empty() )
1839 if( object2d_A && isRoundHole )
1841 const float frontSurface = topZ + frontDepth;
1842 const float backSurface = botZ - backDepth;
1848 if( frontDepth > 0.0f && frontRadius > holeInnerRadius )
1866 if( backDepth > 0.0f && backRadius > holeInnerRadius )
1903 for(
PAD*
pad : footprint->Pads() )
1913 bool aSkipMaterialInformation )
1926 const wxString currentVariant =
m_boardAdapter.GetBoard()->GetCurrentVariant();
1931 if( !fp->Models().empty()
1935 if( fp->GetDNPForVariant( currentVariant ) )
1938 double zpos =
m_boardAdapter.GetFootprintZPos( fp->IsFlipped() );
1942 glm::mat4 fpMatrix = glm::mat4( 1.0f );
1944 fpMatrix = glm::translate( fpMatrix,
1949 if( !fp->GetOrientation().IsZero() )
1951 fpMatrix = glm::rotate( fpMatrix, (
float) fp->GetOrientation().AsRadians(),
1952 SFVEC3F( 0.0f, 0.0f, 1.0f ) );
1955 if( fp->IsFlipped() )
1957 fpMatrix = glm::rotate( fpMatrix, glm::pi<float>(),
SFVEC3F( 0.0f, 1.0f, 0.0f ) );
1959 fpMatrix = glm::rotate( fpMatrix, glm::pi<float>(),
SFVEC3F( 0.0f, 0.0f, 1.0f ) );
1962 const double modelunit_to_3d_units_factor =
1965 fpMatrix = glm::scale(
1966 fpMatrix,
SFVEC3F( modelunit_to_3d_units_factor, modelunit_to_3d_units_factor,
1967 modelunit_to_3d_units_factor ) );
1972 wxString libraryName = fp->GetFPID().GetLibNickname();
1974 wxString footprintBasePath = wxEmptyString;
1981 std::optional<LIBRARY_TABLE_ROW*> fpRow =
1996 if( !
model.m_Show ||
model.m_Filename.empty() )
2000 std::vector<const EMBEDDED_FILES*> embeddedFilesStack;
2001 embeddedFilesStack.push_back( fp->GetEmbeddedFiles() );
2002 embeddedFilesStack.push_back(
m_boardAdapter.GetBoard()->GetEmbeddedFiles() );
2005 std::move( embeddedFilesStack ) );
2010 glm::mat4 modelMatrix = fpMatrix;
2012 modelMatrix = glm::translate( modelMatrix,
2015 modelMatrix = glm::rotate( modelMatrix,
2016 (
float) -(
model.m_Rotation.z / 180.0f ) * glm::pi<float>(),
2017 SFVEC3F( 0.0f, 0.0f, 1.0f ) );
2019 modelMatrix = glm::rotate( modelMatrix,
2020 (
float) -(
model.m_Rotation.y / 180.0f ) * glm::pi<float>(),
2021 SFVEC3F( 0.0f, 1.0f, 0.0f ) );
2023 modelMatrix = glm::rotate( modelMatrix,
2024 (
float) -(
model.m_Rotation.x / 180.0f ) * glm::pi<float>(),
2025 SFVEC3F( 1.0f, 0.0f, 0.0f ) );
2027 modelMatrix = glm::scale( modelMatrix,
2030 addModels( aDstContainer, modelPtr, modelMatrix, (
float)
model.m_Opacity,
2031 aSkipMaterialInformation, fp );
2059 for(
unsigned int imat = 0; imat < a3DModel->
m_MaterialsSize; ++imat )
2067 float reflectionFactor = 0.0f;
2069 if( ( material.
m_Shininess - 0.35f ) > FLT_EPSILON )
2071 reflectionFactor = glm::clamp(
2072 glm::sqrt( ( material.
m_Shininess - 0.35f ) ) * 0.40f - 0.05f, 0.0f,
2083 if(
m_boardAdapter.m_Cfg->m_Render.raytrace_procedural_textures )
2138 return materialVector;
2143 const glm::mat4& aModelMatrix,
float aFPOpacity,
2144 bool aSkipMaterialInformation,
BOARD_ITEM* aBoardItem )
2147 wxASSERT( a3DModel !=
nullptr );
2149 if( a3DModel ==
nullptr )
2153 wxASSERT( a3DModel->
m_Meshes !=
nullptr );
2157 if( aFPOpacity > 1.0f )
2160 if( aFPOpacity < 0.0f )
2168 if( !aSkipMaterialInformation )
2173 const glm::mat3 normalMatrix = glm::transpose( glm::inverse( glm::mat3( aModelMatrix ) ) );
2175 for(
unsigned int mesh_i = 0; mesh_i < a3DModel->
m_MeshesSize; ++mesh_i )
2192 float fpTransparency;
2195 if( !aSkipMaterialInformation )
2204 for(
unsigned int faceIdx = 0; faceIdx < mesh.
m_FaceIdxSize; faceIdx += 3 )
2206 const unsigned int idx0 = mesh.
m_FaceIdx[faceIdx + 0];
2207 const unsigned int idx1 = mesh.
m_FaceIdx[faceIdx + 1];
2208 const unsigned int idx2 = mesh.
m_FaceIdx[faceIdx + 2];
2226 const SFVEC3F vt0 =
SFVEC3F( aModelMatrix * glm::vec4( v0, 1.0f ) );
2230 const SFVEC3F nt0 = glm::normalize(
SFVEC3F( normalMatrix * n0 ) );
2231 const SFVEC3F nt1 = glm::normalize(
SFVEC3F( normalMatrix * n1 ) );
2232 const SFVEC3F nt2 = glm::normalize(
SFVEC3F( normalMatrix * n2 ) );
2238 aDstContainer.
Add( newTriangle );
2240 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.
int OutlineCount() const
Return the number of outlines in the set.
void Fracture(bool aSimplify=true)
Convert a set of polygons with holes to a single outline with "slits"/"fractures" connecting the oute...
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