51 const float f = ( sqrtf( 2.0f ) / 2.0f ) *
radius * texture_factor;
74 float aZtop,
float aZbot )
87 float aOuterRadius,
unsigned int aNr_sides_per_circle,
88 std::vector< SFVEC2F >& aInnerContourResult,
89 std::vector< SFVEC2F >& aOuterContourResult,
92 aInnerContourResult.clear();
93 aInnerContourResult.reserve( aNr_sides_per_circle + 2 );
95 aOuterContourResult.clear();
96 aOuterContourResult.reserve( aNr_sides_per_circle + 2 );
98 const int delta = 3600 / aNr_sides_per_circle;
100 for(
int ii = 0; ii < 3600; ii +=
delta )
102 float angle = (float)( aInvertOrder ? ( 3600 - ii ) : ii )
103 * 2.0f * glm::pi<float>() / 3600.0f;
106 aInnerContourResult.emplace_back( aCenter.x + rotatedDir.x * aInnerRadius,
107 aCenter.y + rotatedDir.y * aInnerRadius );
109 aOuterContourResult.emplace_back( aCenter.x + rotatedDir.x * aOuterRadius,
110 aCenter.y + rotatedDir.y * aOuterRadius );
113 aInnerContourResult.push_back( aInnerContourResult[0] );
114 aOuterContourResult.push_back( aOuterContourResult[0] );
116 wxASSERT( aInnerContourResult.size() == aOuterContourResult.size() );
121 float aZtop,
float aZbot )
127 std::vector< SFVEC2F > innerContour;
128 std::vector< SFVEC2F > outerContour;
131 innerContour, outerContour,
false );
134 for(
unsigned int i = 0; i < ( innerContour.size() - 1 ); ++i )
136 const SFVEC2F& vi0 = innerContour[i + 0];
137 const SFVEC2F& vi1 = innerContour[i + 1];
138 const SFVEC2F& vo0 = outerContour[i + 0];
139 const SFVEC2F& vo1 = outerContour[i + 1];
142 SFVEC3F( vi0.x, vi0.y, aZtop ),
143 SFVEC3F( vo0.x, vo0.y, aZtop ),
144 SFVEC3F( vo1.x, vo1.y, aZtop ) );
147 SFVEC3F( vo1.x, vo1.y, aZbot ),
148 SFVEC3F( vo0.x, vo0.y, aZbot ),
149 SFVEC3F( vi0.x, vi0.y, aZbot ) );
155 float aZtop,
float aZbot )
167 float aZtop,
float aZbot )
184 const float radius_of_the_square = sqrtf( aSeg->
GetRadiusSquared() * 2.0f );
185 const float radius_triangle_factor = ( radius_of_the_square -
radius ) /
radius;
188 rightDir.x *
radius * radius_triangle_factor );
191 leftDir.x *
radius * radius_triangle_factor );
195 SFVEC3F( rightEnd.x + texture_factor * factorS.x,
196 rightEnd.y + texture_factor * factorS.y,
198 SFVEC3F( leftStart.x + texture_factor * factorE.x,
199 leftStart.y + texture_factor * factorE.y,
201 SFVEC3F( start.x - texture_factorF * leftDir.x *
radius * sqrtf( 2.0f ),
202 start.y - texture_factorF * leftDir.y *
radius * sqrtf( 2.0f ),
206 SFVEC3F( leftEnd.x + texture_factor * factorE.x,
207 leftEnd.y + texture_factor * factorE.y, aZtop ),
208 SFVEC3F( rightStart.x + texture_factor * factorS.x,
209 rightStart.y + texture_factor * factorS.y, aZtop ),
211 end.y - texture_factorF * rightDir.y *
radius * sqrtf( 2.0f ),
216 SFVEC3F( leftStart.x + texture_factor * factorE.x,
217 leftStart.y + texture_factor * factorE.y,
219 SFVEC3F( rightEnd.x + texture_factor * factorS.x,
220 rightEnd.y + texture_factor * factorS.y,
222 SFVEC3F( start.x - texture_factorF * leftDir.x *
radius * sqrtf( 2.0f ),
223 start.y - texture_factorF * leftDir.y *
radius * sqrtf( 2.0f ),
227 SFVEC3F( rightStart.x + texture_factor * factorS.x,
228 rightStart.y + texture_factor * factorS.y, aZbot ),
229 SFVEC3F( leftEnd.x + texture_factor * factorE.x,
230 leftEnd.y + texture_factor * factorE.y, aZbot ),
232 end.y - texture_factorF * rightDir.y *
radius * sqrtf( 2.0f ),
237 SFVEC3F( rightEnd.x, rightEnd.y, aZtop ),
238 SFVEC3F( rightStart.x, rightStart.y, aZtop ),
239 SFVEC3F( leftEnd.x, leftEnd.y, aZtop ),
240 SFVEC3F( leftStart.x, leftStart.y, aZtop ) );
243 SFVEC3F( rightEnd.x, rightEnd.y, aZbot ),
244 SFVEC3F( leftStart.x, leftStart.y, aZbot ),
245 SFVEC3F( leftEnd.x, leftEnd.y, aZbot ),
246 SFVEC3F( rightStart.x, rightStart.y, aZbot ) );
254 if( aListHolesObject2d.size() == 0 )
261 for(
const OBJECT_2D* object2d : aListHolesObject2d )
263 switch( object2d->GetObjectType() )
274 wxFAIL_MSG( wxT(
"RENDER_3D_OPENGL::generateHoles: Object type not implemented" ) );
289 delete layerTriangles;
299 if( aContainer ==
nullptr )
304 if( listObject2d.size() == 0 )
313 unsigned int nrTrianglesEstimation = listObject2d.size() * 8;
321 for(
const OBJECT_2D* object2d : listObject2d )
323 switch( object2d->GetObjectType() )
346 wxFAIL_MSG( wxT(
"RENDER_3D_OPENGL: Object type is not implemented" ) );
364 float layer_z_bot = 0.0f;
365 float layer_z_top = 0.0f;
389 if( listBoardObject2d.size() > 0 )
393 const float layer_z_top = 1.0f;
394 const float layer_z_bot = 0.0f;
400 for(
const OBJECT_2D* itemOnLayer : listBoardObject2d )
402 const OBJECT_2D* object2d_A = itemOnLayer;
422 layer_z_top, layer_z_top );
425 delete layerTriangles;
437 const int copperLayerCount =
m_boardAdapter.GetBoard()->GetCopperLayerCount();
439 const int platingThickness =
m_boardAdapter.GetHolePlatingThickness();
440 const float boardBodyThickness =
m_boardAdapter.GetBoardBodyThickness();
443 const float boardZTop = 1.0f;
444 const float boardZBot = 0.0f;
447 auto normalizeZ = [&](
float absZ ) ->
float
451 float boardThick = boardTop - boardBot;
453 if( boardThick <= 0 )
457 return ( absZ - boardBot ) / boardThick;
471 const float holeDiameter =
via->GetDrillValue() * unitScale;
472 const float holeInnerRadius = holeDiameter / 2.0f;
473 const float holeOuterRadius = holeInnerRadius + platingThickness * unitScale;
475 const int nrSegments =
m_boardAdapter.GetCircleSegmentCount(
via->GetDrillValue() );
478 via->LayerPair( &topLayer, &bottomLayer );
480 float viaZTop, viaZBot,
dummy;
485 const float secondaryDrillRadius =
via->GetSecondaryDrillSize().value_or( 0 ) * 0.5f * unitScale;
486 const float tertiaryDrillRadius =
via->GetTertiaryDrillSize().value_or( 0 ) * 0.5f * unitScale;
488 if( secondaryDrillRadius > holeOuterRadius || tertiaryDrillRadius > holeOuterRadius )
494 if( secondaryDrillRadius > holeOuterRadius )
496 plug_end_layer =
via->GetSecondaryDrillEndLayer();
499 if( tertiaryDrillRadius > holeOuterRadius )
501 plug_start_layer =
via->GetTertiaryDrillStartLayer();
505 float plugZTop, plugZBot, temp;
511 plugZTop, plugZBot, nrSegments, plugTriangles );
515 const auto frontMode =
via->GetFrontPostMachining();
517 if( frontMode.has_value()
521 const float frontRadius =
via->GetFrontPostMachiningSize() * 0.5f * unitScale;
522 const float frontDepth =
via->GetFrontPostMachiningDepth() * unitScale;
524 if( frontRadius > holeOuterRadius && frontDepth > 0 )
527 float pmBottomZ = normalizeZ( viaZTop - frontDepth );
528 float plugZBot = normalizeZ( viaZBot );
530 if( pmBottomZ > plugZBot )
536 pmBottomZ, plugZBot, nrSegments, plugTriangles, angle );
541 pmBottomZ, plugZBot, nrSegments, plugTriangles );
548 const auto backMode =
via->GetBackPostMachining();
550 if( backMode.has_value()
554 const float backRadius =
via->GetBackPostMachiningSize() * 0.5f * unitScale;
555 const float backDepth =
via->GetBackPostMachiningDepth() * unitScale;
557 if( backRadius > holeOuterRadius && backDepth > 0 )
560 float plugZTop = normalizeZ( viaZTop );
561 float pmTopZ = normalizeZ( viaZBot + backDepth );
563 if( plugZTop > pmTopZ )
569 plugZTop, pmTopZ, nrSegments, plugTriangles, angle );
574 plugZTop, pmTopZ, nrSegments, plugTriangles );
584 for(
const PAD*
pad : footprint->Pads() )
586 if( !
pad->HasHole() )
592 const SFVEC2F padCenter(
pad->GetPosition().x * unitScale,
593 -
pad->GetPosition().y * unitScale );
594 const float holeInnerRadius =
pad->GetDrillSize().x * 0.5f * unitScale;
595 const float holeOuterRadius = holeInnerRadius + platingThickness * unitScale;
596 const int nrSegments =
m_boardAdapter.GetCircleSegmentCount(
pad->GetDrillSize().x );
598 float padZTop, padZBot, padDummy;
603 const auto frontMode =
pad->GetFrontPostMachining();
605 if( frontMode.has_value()
609 const float frontRadius =
pad->GetFrontPostMachiningSize() * 0.5f * unitScale;
610 const float frontDepth =
pad->GetFrontPostMachiningDepth() * unitScale;
612 if( frontRadius > holeOuterRadius && frontDepth > 0 )
614 float pmBottomZ = normalizeZ( padZTop - frontDepth );
615 float plugZBot = normalizeZ( padZBot );
617 if( pmBottomZ > plugZBot )
623 pmBottomZ, plugZBot, nrSegments, plugTriangles, angle );
628 pmBottomZ, plugZBot, nrSegments, plugTriangles );
635 const auto backMode =
pad->GetBackPostMachining();
637 if( backMode.has_value()
641 const float backRadius =
pad->GetBackPostMachiningSize() * 0.5f * unitScale;
642 const float backDepth =
pad->GetBackPostMachiningDepth() * unitScale;
644 if( backRadius > holeOuterRadius && backDepth > 0 )
646 float plugZTop = normalizeZ( padZTop );
647 float pmTopZ = normalizeZ( padZBot + backDepth );
649 if( plugZTop > pmTopZ )
655 plugZTop, pmTopZ, nrSegments, plugTriangles, angle );
660 plugZTop, pmTopZ, nrSegments, plugTriangles );
679 boardZTop, boardZTop );
683 delete plugTriangles;
701 m_camera.SetBoardLookAtPos( camera_pos );
703 if( aStatusReporter )
704 aStatusReporter->
Report(
_(
"Load OpenGL: board" ) );
724 if(
m_boardAdapter.GetFrontCounterborePolys().OutlineCount() > 0 )
730 if(
m_boardAdapter.GetFrontCountersinkPolys().OutlineCount() > 0 )
752 if( aStatusReporter )
753 aStatusReporter->
Report(
_(
"Load OpenGL: holes and vias" ) );
779 wxASSERT( innerMapHoles.size() == outerMapHoles.size() );
783 if( outerMapHoles.size() > 0 )
785 float layer_z_bot = 0.0f;
786 float layer_z_top = 0.0f;
788 for(
const auto& [ layer, poly ] : outerMapHoles )
793 layer_z_top, layer_z_bot,
false );
796 for(
const auto& [ layer, poly ] : innerMapHoles )
801 layer_z_top, layer_z_bot,
false );
809 if( aStatusReporter )
810 aStatusReporter->
Report(
_(
"Load OpenGL: layers" ) );
812 std::bitset<LAYER_3D_END> visibilityFlags =
m_boardAdapter.GetVisibleLayers();
816 for(
const auto& [ layer, container2d ] :
m_boardAdapter.GetLayerMap() )
821 if( aStatusReporter )
824 aStatusReporter->
Report( wxString::Format(
_(
"Load OpenGL layer %s" ), msg ) );
834 if( map_poly.contains( layer ) )
836 polyListSubtracted = *map_poly.at( layer );
854 else if( layer ==
B_Cu )
873 polyList = &polyListSubtracted;
880 if( oglList !=
nullptr )
889 if( frontPlatedCopperPolys )
907 if( backPlatedCopperPolys )
935 if( aStatusReporter )
936 aStatusReporter->
Report(
_(
"Loading 3D models..." ) );
940 if( aStatusReporter )
945 aStatusReporter->
Report( wxString::Format(
_(
"Reload time %.3f s" ), calculation_time ) );
969 if( aOutZtop < aOutZbot )
971 float tmpFloat = aOutZbot;
979 float aOuterRadius,
float aZtop,
float aZbot,
980 unsigned int aNr_sides_per_circle,
983 std::vector< SFVEC2F > innerContour;
984 std::vector< SFVEC2F > outerContour;
986 generateRing( aCenter, aInnerRadius, aOuterRadius, aNr_sides_per_circle, innerContour,
987 outerContour,
false );
989 for(
unsigned int i = 0; i < ( innerContour.size() - 1 ); ++i )
991 const SFVEC2F& vi0 = innerContour[i + 0];
992 const SFVEC2F& vi1 = innerContour[i + 1];
993 const SFVEC2F& vo0 = outerContour[i + 0];
994 const SFVEC2F& vo1 = outerContour[i + 1];
997 SFVEC3F( vi0.x, vi0.y, aZtop ),
998 SFVEC3F( vo0.x, vo0.y, aZtop ),
999 SFVEC3F( vo1.x, vo1.y, aZtop ) );
1002 SFVEC3F( vo1.x, vo1.y, aZbot ),
1003 SFVEC3F( vo0.x, vo0.y, aZbot ),
1004 SFVEC3F( vi0.x, vi0.y, aZbot ) );
1013 float aOuterRadius,
float aZtop,
float aZbot,
1014 unsigned int aNr_sides_per_circle,
1026 float radialDiff = aOuterRadius - aInnerRadius;
1030 if( angleRad < 0.01f )
1033 float innerHeight = radialDiff / tanf( angleRad );
1034 float totalHeight = aZtop - aZbot;
1037 if( innerHeight > totalHeight )
1038 innerHeight = totalHeight;
1040 float zInnerTop = aZbot + innerHeight;
1042 std::vector< SFVEC2F > innerContour;
1043 std::vector< SFVEC2F > outerContour;
1045 generateRing( aCenter, aInnerRadius, aOuterRadius, aNr_sides_per_circle, innerContour,
1046 outerContour,
false );
1048 for(
unsigned int i = 0; i < ( innerContour.size() - 1 ); ++i )
1050 const SFVEC2F& vi0 = innerContour[i + 0];
1051 const SFVEC2F& vi1 = innerContour[i + 1];
1052 const SFVEC2F& vo0 = outerContour[i + 0];
1053 const SFVEC2F& vo1 = outerContour[i + 1];
1057 SFVEC3F( vi0.x, vi0.y, zInnerTop ),
1058 SFVEC3F( vo0.x, vo0.y, aZtop ),
1059 SFVEC3F( vo1.x, vo1.y, aZtop ) );
1063 SFVEC3F( vo1.x, vo1.y, aZbot ),
1064 SFVEC3F( vo0.x, vo0.y, aZbot ),
1065 SFVEC3F( vi0.x, vi0.y, aZbot ) );
1079 const float delta = 2.0f * glm::pi<float>() / (float) aNr_sides_per_circle;
1081 for(
unsigned int i = 0; i < aNr_sides_per_circle; ++i )
1083 float a0 =
delta * i;
1084 float a1 =
delta * ( i + 1 );
1085 const SFVEC3F p0( aCenter.x + cosf( a0 ) * aRadius,
1086 aCenter.y + sinf( a0 ) * aRadius, aZ );
1087 const SFVEC3F p1( aCenter.x + cosf( a1 ) * aRadius,
1088 aCenter.y + sinf( a1 ) * aRadius, aZ );
1089 const SFVEC3F c( aCenter.x, aCenter.y, aZ );
1100 float aDepth,
unsigned int aNr_sides_per_circle,
1103 const float delta = 2.0f * glm::pi<float>() / (float) aNr_sides_per_circle;
1104 const SFVEC3F c( aCenter.x, aCenter.y, aTop ? aZ - aDepth : aZ + aDepth );
1106 for(
unsigned int i = 0; i < aNr_sides_per_circle; ++i )
1108 float a0 =
delta * i;
1109 float a1 =
delta * ( i + 1 );
1110 const SFVEC3F p0( aCenter.x + cosf( a0 ) * aRadius,
1111 aCenter.y + sinf( a0 ) * aRadius, aZ );
1112 const SFVEC3F p1( aCenter.x + cosf( a1 ) * aRadius,
1113 aCenter.y + sinf( a1 ) * aRadius, aZ );
1128 float aHoleInnerRadius,
1131 float aPlatingThickness3d,
1138 if( !aDstLayer || aPlatingThickness3d <= 0.0f || aHoleInnerRadius <= 0.0f )
1147 if( aSizeIU <= 0 || aDepthIU <= 0 )
1150 const float radius = aSizeIU * 0.5f * aUnitScale;
1151 const float depth = aDepthIU * aUnitScale;
1153 if(
radius <= aHoleInnerRadius || depth <= 0.0f )
1156 float zEnd = aIsFront ? ( aZSurface - depth ) : ( aZSurface + depth );
1161 const float zTop = std::max( aZSurface, zEnd );
1162 const float zBot = std::min( aZSurface, zEnd );
1164 const int diameterBIU = std::max( aSizeIU,
1166 (
int) ( ( aHoleInnerRadius * 2.0f )
1168 const unsigned int nrSegments =
1169 std::max( 12u,
m_boardAdapter.GetCircleSegmentCount( diameterBIU ) );
1174 nrSegments, aDstLayer );
1178 float csTopRadius =
radius;
1179 float csBotRadius = aHoleInnerRadius;
1181 std::vector< SFVEC2F > innerContourTop, outerContourTop;
1182 std::vector< SFVEC2F > innerContourBot, outerContourBot;
1184 generateRing( aHoleCenter, csTopRadius, csTopRadius + aPlatingThickness3d, nrSegments,
1185 innerContourTop, outerContourTop,
false );
1186 generateRing( aHoleCenter, csBotRadius, csBotRadius + aPlatingThickness3d, nrSegments,
1187 innerContourBot, outerContourBot,
false );
1189 for(
unsigned int i = 0; i < ( innerContourTop.size() - 1 ); ++i )
1191 const SFVEC2F& vi0_top = innerContourTop[i + 0];
1192 const SFVEC2F& vi1_top = innerContourTop[i + 1];
1193 const SFVEC2F& vo0_top = outerContourTop[i + 0];
1194 const SFVEC2F& vo1_top = outerContourTop[i + 1];
1196 const SFVEC2F& vi0_bot = innerContourBot[i + 0];
1197 const SFVEC2F& vi1_bot = innerContourBot[i + 1];
1198 const SFVEC2F& vo0_bot = outerContourBot[i + 0];
1199 const SFVEC2F& vo1_bot = outerContourBot[i + 1];
1202 SFVEC3F( vi1_top.x, vi1_top.y, zTop ),
1203 SFVEC3F( vi0_top.x, vi0_top.y, zTop ),
1204 SFVEC3F( vi0_bot.x, vi0_bot.y, zBot ),
1205 SFVEC3F( vi1_bot.x, vi1_bot.y, zBot ) );
1208 SFVEC3F( vo1_top.x, vo1_top.y, zTop ),
1209 SFVEC3F( vo0_top.x, vo0_top.y, zTop ),
1210 SFVEC3F( vo0_bot.x, vo0_bot.y, zBot ),
1211 SFVEC3F( vo1_bot.x, vo1_bot.y, zBot ) );
1226 float averageDiameter =
m_boardAdapter.GetAverageViaHoleDiameter();
1227 unsigned int averageSegCount =
m_boardAdapter.GetCircleSegmentCount( averageDiameter );
1228 unsigned int trianglesEstimate = averageSegCount * 8 *
m_boardAdapter.GetViaCount();
1238 bool isBackdrilled =
via->GetSecondaryDrillSize().has_value();
1239 bool isTertiarydrilled =
via->GetTertiaryDrillSize().has_value();
1250 && !hasFrontPostMachining && !hasBackPostMachining )
1255 const float holediameter =
via->GetDrillValue() * aUnitScale;
1256 const int nrSegments =
m_boardAdapter.GetCircleSegmentCount(
via->GetDrillValue() );
1257 const float hole_inner_radius = holediameter / 2.0f;
1259 const SFVEC2F via_center(
via->GetStart().x * aUnitScale,
1260 -
via->GetStart().y * aUnitScale );
1263 via->LayerPair( &top_layer, &bottom_layer );
1265 float ztop, zbot,
dummy;
1270 wxASSERT( zbot < ztop );
1272 float ztop_plated = ztop;
1273 float zbot_plated = zbot;
1283 zbot_plated = std::max( zbot_plated, secZEnd );
1286 if( isTertiarydrilled )
1294 ztop_plated = std::min( ztop_plated, terZEnd );
1297 auto applyViaPostMachining = [&](
bool isFront )
1299 auto modeOpt = isFront ?
via->GetFrontPostMachining()
1300 :
via->GetBackPostMachining();
1308 int sizeIU = isFront ?
via->GetFrontPostMachiningSize()
1309 :
via->GetBackPostMachiningSize();
1310 int depthIU = isFront ?
via->GetFrontPostMachiningDepth()
1311 :
via->GetBackPostMachiningDepth();
1312 float zSurface = isFront ? ztop : zbot;
1316 sizeIU, depthIU, hole_inner_radius, zSurface,
1317 isFront, aPlatingThickness3d, aUnitScale, &zEnd ) )
1320 ztop_plated = std::min( ztop_plated, zEnd );
1322 zbot_plated = std::max( zbot_plated, zEnd );
1326 if( hasFrontPostMachining )
1327 applyViaPostMachining(
true );
1328 if( hasBackPostMachining )
1329 applyViaPostMachining(
false );
1336 const float padFrontSurface =
1339 const float padBackSurface =
1345 for(
const PAD*
pad : footprint->Pads() )
1350 if( !
pad->HasHole() )
1356 const SFVEC2F padCenter(
pad->GetPosition().x * aUnitScale,
1357 -
pad->GetPosition().y * aUnitScale );
1358 const float holeInnerRadius =
1359 pad->GetDrillSize().x * 0.5f * aUnitScale;
1361 auto emitPadPostMachining = [&](
bool isFront )
1363 auto modeOpt = isFront ?
pad->GetFrontPostMachining()
1364 :
pad->GetBackPostMachining();
1372 int sizeIU = isFront ?
pad->GetFrontPostMachiningSize()
1373 :
pad->GetBackPostMachiningSize();
1374 int depthIU = isFront ?
pad->GetFrontPostMachiningDepth()
1375 :
pad->GetBackPostMachiningDepth();
1376 float zSurface = isFront ? padFrontSurface : padBackSurface;
1379 sizeIU, depthIU, holeInnerRadius, zSurface,
1380 isFront, aPlatingThickness3d, aUnitScale,
1384 emitPadPostMachining(
true );
1385 emitPadPostMachining(
false );
1391 delete layerTriangleVIA;
1419 via->GetDrill() / 2 + aPlatingThickness,
1429 for(
const PAD*
pad : footprint->Pads() )
1433 if( !
pad->HasHole() )
1436 pad->TransformHoleToPolygon( tht_outer_holes_poly, aPlatingThickness,
1438 pad->TransformHoleToPolygon( tht_inner_holes_poly, 0,
1455 if( holes2D.size() > 0 &&
m_boardAdapter.m_Cfg->m_Render.show_plated_barrels )
1457 float layer_z_top, layer_z_bot,
dummy;
1464 for(
const OBJECT_2D* itemOnLayer : holes2D )
1466 const OBJECT_2D* object2d_A = itemOnLayer;
1484 layer_z_bot, layer_z_top,
1485 aUnitScale,
false );
1488 layer_z_top, layer_z_top );
1491 delete layerTriangles;
1511 const float holediameter =
via->GetDrillValue() * aUnitScale;
1512 const float hole_radius = holediameter / 2.0f + 2.0f * aPlatingThickness3d;
1514 -
via->GetStart().y * aUnitScale );
1515 unsigned int seg =
m_boardAdapter.GetCircleSegmentCount(
via->GetDrillValue() );
1518 via->LayerPair( &top_layer, &bottom_layer );
1519 float ztop, zbot,
dummy;
1532 const auto frontPostMachining =
1534 const auto backPostMachining =
1542 bool hasFrontBackdrill =
via->GetSecondaryDrillStartLayer() ==
F_Cu;
1543 bool hasBackBackdrill =
via->GetSecondaryDrillStartLayer() ==
B_Cu;
1545 const float depth = hole_radius * 0.3f;
1547 if( frontCovering && !hasFrontPostMachining && !hasFrontBackdrill )
1549 if( filled || !frontPlugged )
1555 if( backCovering && !hasBackPostMachining && !hasBackBackdrill )
1557 if( filled || !backPlugged )
1580 const int platingThickness =
m_boardAdapter.GetHolePlatingThickness();
1582 const float platingThickness3d = platingThickness * unitScale;
1595 if( wxFrame* frame =
dynamic_cast<wxFrame*
>(
m_canvas->GetParent() ) )
1631 wxString libraryName = footprint->GetFPID().GetLibNickname();
1632 wxString footprintBasePath = wxEmptyString;
1639 std::optional<LIBRARY_TABLE_ROW*> fpRow =
1652 for(
const FP_3DMODEL& fp_model : footprint->Models() )
1654 if( fp_model.m_Show && !fp_model.m_Filename.empty() )
1656 if( aStatusReporter )
1660 wxFileName fn( fp_model.m_Filename );
1661 aStatusReporter->
Report( wxString::Format(
_(
"Loading %s..." ),
1662 fn.GetFullName() ) );
1670 std::vector<const EMBEDDED_FILES*> embeddedFilesStack;
1671 embeddedFilesStack.push_back( footprint->GetEmbeddedFiles() );
1672 embeddedFilesStack.push_back(
m_boardAdapter.GetBoard()->GetEmbeddedFiles() );
1674 const S3DMODEL* modelPtr = cacheMgr->
GetModel( fp_model.m_Filename, footprintBasePath,
1675 std::move( embeddedFilesStack ) );
MATERIAL_MODE
Render 3d model shape materials mode.
Defines math related functions.
std::map< PCB_LAYER_ID, SHAPE_POLY_SET * > MAP_POLY
A type that stores polysets for each layer id.
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.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
const LIST_OBJECT2D & GetList() const
const SFVEC2F & GetCenter() const
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...
static const LSET & PhysicalLayersMask()
Return a mask holding all layers which are physically realized.
static OBJECT_2D_STATS & Instance()
OBJECT_2D_TYPE GetObjectType() const
Store the OpenGL display lists to related with a layer.
Simple non-intersecting polygon with 4 points.
const SFVEC2F & GetV3() const
const SFVEC2F & GetV0() const
const SFVEC2F & GetV1() const
const SFVEC2F & GetV2() const
static FOOTPRINT_LIBRARY_ADAPTER * FootprintLibAdapter(PROJECT *aProject)
BOARD_ADAPTER & m_boardAdapter
Settings reference in use for this render.
OPENGL_RENDER_LIST * m_board
void reload(REPORTER *aStatusReporter, REPORTER *aWarningReporter)
OPENGL_RENDER_LIST * generateHoles(const LIST_OBJECT2D &aListHolesObject2d, const SHAPE_POLY_SET &aPoly, float aZtop, float aZbot, bool aInvertFaces, const BVH_CONTAINER_2D *aThroughHoles=nullptr)
void generateCylinder(const SFVEC2F &aCenter, float aInnerRadius, float aOuterRadius, float aZtop, float aZbot, unsigned int aNr_sides_per_circle, TRIANGLE_DISPLAY_LIST *aDstLayer)
OPENGL_RENDER_LIST * m_outerThroughHoleRings
OPENGL_RENDER_LIST * m_offboardPadsFront
void generateRing(const SFVEC2F &aCenter, float aInnerRadius, float aOuterRadius, unsigned int aNr_sides_per_circle, std::vector< SFVEC2F > &aInnerContourResult, std::vector< SFVEC2F > &aOuterContourResult, bool aInvertOrder)
SHAPE_POLY_SET m_antiBoardPolys
The negative polygon representation of the board outline.
void load3dModels(REPORTER *aStatusReporter)
Load footprint models from the cache and load it to openGL lists in the form of MODEL_3D objects.
void generateViasAndPads()
OPENGL_RENDER_LIST * generateLayerList(const BVH_CONTAINER_2D *aContainer, const SHAPE_POLY_SET *aPolyList, PCB_LAYER_ID aLayer, const BVH_CONTAINER_2D *aThroughHoles=nullptr)
OPENGL_RENDER_LIST * m_microviaHoles
OPENGL_RENDER_LIST * createBoard(const SHAPE_POLY_SET &aBoardPoly, const BVH_CONTAINER_2D *aThroughHoles=nullptr)
void Load3dModelsIfNeeded()
Load footprint models if they are not already loaded, i.e.
void addObjectTriangles(const RING_2D *aRing, TRIANGLE_DISPLAY_LIST *aDstLayer, float aZtop, float aZbot)
MAP_OGL_DISP_LISTS m_layers
MAP_OGL_DISP_LISTS m_innerLayerHoles
OPENGL_RENDER_LIST * m_boardWithHoles
void generateInvCone(const SFVEC2F &aCenter, float aInnerRadius, float aOuterRadius, float aZtop, float aZbot, unsigned int aNr_sides_per_circle, TRIANGLE_DISPLAY_LIST *aDstLayer, EDA_ANGLE aAngle)
MAP_OGL_DISP_LISTS m_outerLayerHoles
OPENGL_RENDER_LIST * m_offboardPadsBack
std::map< wxString, MODEL_3D * > m_3dModelMap
OPENGL_RENDER_LIST * m_viaBackCover
OPENGL_RENDER_LIST * m_viaFrontCover
OPENGL_RENDER_LIST * generateEmptyLayerList(PCB_LAYER_ID aLayer)
LIST_TRIANGLES m_triangles
store pointers so can be deleted latter
OPENGL_RENDER_LIST * m_outerViaThroughHoles
OPENGL_RENDER_LIST * m_outerThroughHoles
void generateViaCovers(float aPlatingThickness3d, float aUnitScale)
OPENGL_RENDER_LIST * m_platedPadsFront
void generatePlatedHoleShells(int aPlatingThickness, float aUnitScale)
void generateDisk(const SFVEC2F &aCenter, float aRadius, float aZ, unsigned int aNr_sides_per_circle, TRIANGLE_DISPLAY_LIST *aDstLayer, bool aTop)
OPENGL_RENDER_LIST * m_postMachinePlugs
Board material plugs for backdrill/counterbore/countersink.
bool appendPostMachiningGeometry(TRIANGLE_DISPLAY_LIST *aDstLayer, const SFVEC2F &aHoleCenter, PAD_DRILL_POST_MACHINING_MODE aMode, int aSizeIU, int aDepthIU, float aHoleInnerRadius, float aZSurface, bool aIsFront, float aPlatingThickness3d, float aUnitScale, float *aZEnd)
OPENGL_RENDER_LIST * m_antiBoard
void getLayerZPos(PCB_LAYER_ID aLayerID, float &aOutZtop, float &aOutZbot) const
OPENGL_RENDER_LIST * m_padHoles
void addTopAndBottomTriangles(TRIANGLE_DISPLAY_LIST *aDst, const SFVEC2F &v0, const SFVEC2F &v1, const SFVEC2F &v2, float top, float bot)
void generateViaBarrels(float aPlatingThickness3d, float aUnitScale)
OPENGL_RENDER_LIST * m_platedPadsBack
void generateDimple(const SFVEC2F &aCenter, float aRadius, float aZ, float aDepth, unsigned int aNr_sides_per_circle, TRIANGLE_DISPLAY_LIST *aDstLayer, bool aTop)
void backfillPostMachine()
Create ring-shaped plugs for holes that have backdrill or post-machining.
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.
float GetOuterRadius() const
float GetInnerRadius() const
const SFVEC2F & GetCenter() const
const SFVEC2F & GetLeftEnd() const
const SFVEC2F & GetRightEnd() const
const SFVEC2F & GetLeftStar() const
const SFVEC2F & GetLeftDir() const
const SFVEC2F & GetEnd() const
float GetRadiusSquared() const
const SFVEC2F & GetStart() const
const SFVEC2F & GetRightDir() const
const SFVEC2F & GetRightStar() const
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 RemoveAllContours()
Remove all outlines & holes (clears) the polygon set.
void BooleanAdd(const SHAPE_POLY_SET &b)
Perform boolean polyset union.
void BooleanIntersection(const SHAPE_POLY_SET &b)
Perform boolean polyset intersection.
int OutlineCount() const
Return the number of outlines in the set.
SHAPE_POLY_SET CloneDropTriangulation() const
void BooleanSubtract(const SHAPE_POLY_SET &b)
Perform boolean polyset difference.
A wrapper for reporting to a specific text location in a statusbar.
const SFVEC2F & GetP2() const
const SFVEC2F & GetP3() const
const SFVEC2F & GetP1() const
Store arrays of triangles to be used to create display lists.
TRIANGLE_LIST * m_layer_bot_segment_ends
void AddToMiddleContours(const SHAPE_LINE_CHAIN &outlinePath, float zBot, float zTop, double aBiuTo3Du, bool aInvertFaceDirection, const BVH_CONTAINER_2D *aThroughHoles=nullptr)
TRIANGLE_LIST * m_layer_middle_contours_quads
TRIANGLE_LIST * m_layer_top_segment_ends
TRIANGLE_LIST * m_layer_bot_triangles
TRIANGLE_LIST * m_layer_top_triangles
void AddTriangle(const SFVEC3F &aV1, const SFVEC3F &aV2, const SFVEC3F &aV3)
void AddQuad(const SFVEC3F &aV1, const SFVEC3F &aV2, const SFVEC3F &aV3, const SFVEC3F &aV4)
unsigned int GetVertexSize() const
std::list< OBJECT_2D * > LIST_OBJECT2D
void TransformCircleToPolygon(SHAPE_LINE_CHAIN &aBuffer, const VECTOR2I &aCenter, int aRadius, int aError, ERROR_LOC aErrorLoc, int aMinSegCount=0)
Convert a circle to a polygon, using multiple straight lines.
Declaration of the eda_3d_viewer class.
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
int64_t GetRunningMicroSecs()
An alternate way to calculate an elapsed time (in microsecondes) to class PROF_COUNTER.
#define SIZE_OF_CIRCLE_TEXTURE
std::vector< FAB_LAYER_COLOR > dummy
Store the a model based on meshes and materials.
KIBIS top(path, &reporter)
void ConvertPolygonToTriangles(const SHAPE_POLY_SET &aPolyList, CONTAINER_2D_BASE &aDstContainer, float aBiuTo3dUnitsScale, const BOARD_ITEM &aBoardItem)
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
VECTOR2< int32_t > VECTOR2I