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" ) );
775 wxASSERT( innerMapHoles.size() == outerMapHoles.size() );
779 if( outerMapHoles.size() > 0 )
781 float layer_z_bot = 0.0f;
782 float layer_z_top = 0.0f;
784 for(
const auto& [ layer, poly ] : outerMapHoles )
789 layer_z_top, layer_z_bot,
false );
792 for(
const auto& [ layer, poly ] : innerMapHoles )
797 layer_z_top, layer_z_bot,
false );
805 if( aStatusReporter )
806 aStatusReporter->
Report(
_(
"Load OpenGL: layers" ) );
808 std::bitset<LAYER_3D_END> visibilityFlags =
m_boardAdapter.GetVisibleLayers();
812 for(
const auto& [ layer, container2d ] :
m_boardAdapter.GetLayerMap() )
817 if( aStatusReporter )
820 aStatusReporter->
Report( wxString::Format(
_(
"Load OpenGL layer %s" ), msg ) );
830 if( map_poly.contains( layer ) )
832 polyListSubtracted = *map_poly.at( layer );
850 else if( layer ==
B_Cu )
869 polyList = &polyListSubtracted;
876 if( oglList !=
nullptr )
885 if( frontPlatedCopperPolys )
903 if( backPlatedCopperPolys )
931 if( aStatusReporter )
932 aStatusReporter->
Report(
_(
"Loading 3D models..." ) );
936 if( aStatusReporter )
941 aStatusReporter->
Report( wxString::Format(
_(
"Reload time %.3f s" ), calculation_time ) );
965 if( aOutZtop < aOutZbot )
967 float tmpFloat = aOutZbot;
975 float aOuterRadius,
float aZtop,
float aZbot,
976 unsigned int aNr_sides_per_circle,
979 std::vector< SFVEC2F > innerContour;
980 std::vector< SFVEC2F > outerContour;
982 generateRing( aCenter, aInnerRadius, aOuterRadius, aNr_sides_per_circle, innerContour,
983 outerContour,
false );
985 for(
unsigned int i = 0; i < ( innerContour.size() - 1 ); ++i )
987 const SFVEC2F& vi0 = innerContour[i + 0];
988 const SFVEC2F& vi1 = innerContour[i + 1];
989 const SFVEC2F& vo0 = outerContour[i + 0];
990 const SFVEC2F& vo1 = outerContour[i + 1];
993 SFVEC3F( vi0.x, vi0.y, aZtop ),
994 SFVEC3F( vo0.x, vo0.y, aZtop ),
995 SFVEC3F( vo1.x, vo1.y, aZtop ) );
998 SFVEC3F( vo1.x, vo1.y, aZbot ),
999 SFVEC3F( vo0.x, vo0.y, aZbot ),
1000 SFVEC3F( vi0.x, vi0.y, aZbot ) );
1009 float aOuterRadius,
float aZtop,
float aZbot,
1010 unsigned int aNr_sides_per_circle,
1022 float radialDiff = aOuterRadius - aInnerRadius;
1026 if( angleRad < 0.01f )
1029 float innerHeight = radialDiff / tanf( angleRad );
1030 float totalHeight = aZtop - aZbot;
1033 if( innerHeight > totalHeight )
1034 innerHeight = totalHeight;
1036 float zInnerTop = aZbot + innerHeight;
1038 std::vector< SFVEC2F > innerContour;
1039 std::vector< SFVEC2F > outerContour;
1041 generateRing( aCenter, aInnerRadius, aOuterRadius, aNr_sides_per_circle, innerContour,
1042 outerContour,
false );
1044 for(
unsigned int i = 0; i < ( innerContour.size() - 1 ); ++i )
1046 const SFVEC2F& vi0 = innerContour[i + 0];
1047 const SFVEC2F& vi1 = innerContour[i + 1];
1048 const SFVEC2F& vo0 = outerContour[i + 0];
1049 const SFVEC2F& vo1 = outerContour[i + 1];
1053 SFVEC3F( vi0.x, vi0.y, zInnerTop ),
1054 SFVEC3F( vo0.x, vo0.y, aZtop ),
1055 SFVEC3F( vo1.x, vo1.y, aZtop ) );
1059 SFVEC3F( vo1.x, vo1.y, aZbot ),
1060 SFVEC3F( vo0.x, vo0.y, aZbot ),
1061 SFVEC3F( vi0.x, vi0.y, aZbot ) );
1075 const float delta = 2.0f * glm::pi<float>() / (float) aNr_sides_per_circle;
1077 for(
unsigned int i = 0; i < aNr_sides_per_circle; ++i )
1079 float a0 =
delta * i;
1080 float a1 =
delta * ( i + 1 );
1081 const SFVEC3F p0( aCenter.x + cosf( a0 ) * aRadius,
1082 aCenter.y + sinf( a0 ) * aRadius, aZ );
1083 const SFVEC3F p1( aCenter.x + cosf( a1 ) * aRadius,
1084 aCenter.y + sinf( a1 ) * aRadius, aZ );
1085 const SFVEC3F c( aCenter.x, aCenter.y, aZ );
1096 float aDepth,
unsigned int aNr_sides_per_circle,
1099 const float delta = 2.0f * glm::pi<float>() / (float) aNr_sides_per_circle;
1100 const SFVEC3F c( aCenter.x, aCenter.y, aTop ? aZ - aDepth : aZ + aDepth );
1102 for(
unsigned int i = 0; i < aNr_sides_per_circle; ++i )
1104 float a0 =
delta * i;
1105 float a1 =
delta * ( i + 1 );
1106 const SFVEC3F p0( aCenter.x + cosf( a0 ) * aRadius,
1107 aCenter.y + sinf( a0 ) * aRadius, aZ );
1108 const SFVEC3F p1( aCenter.x + cosf( a1 ) * aRadius,
1109 aCenter.y + sinf( a1 ) * aRadius, aZ );
1124 float aHoleInnerRadius,
1127 float aPlatingThickness3d,
1134 if( !aDstLayer || aPlatingThickness3d <= 0.0f || aHoleInnerRadius <= 0.0f )
1143 if( aSizeIU <= 0 || aDepthIU <= 0 )
1146 const float radius = aSizeIU * 0.5f * aUnitScale;
1147 const float depth = aDepthIU * aUnitScale;
1149 if(
radius <= aHoleInnerRadius || depth <= 0.0f )
1152 float zEnd = aIsFront ? ( aZSurface - depth ) : ( aZSurface + depth );
1157 const float zTop = std::max( aZSurface, zEnd );
1158 const float zBot = std::min( aZSurface, zEnd );
1160 const int diameterBIU = std::max( aSizeIU,
1162 (
int) ( ( aHoleInnerRadius * 2.0f )
1164 const unsigned int nrSegments =
1165 std::max( 12u,
m_boardAdapter.GetCircleSegmentCount( diameterBIU ) );
1170 nrSegments, aDstLayer );
1174 float csTopRadius =
radius;
1175 float csBotRadius = aHoleInnerRadius;
1177 std::vector< SFVEC2F > innerContourTop, outerContourTop;
1178 std::vector< SFVEC2F > innerContourBot, outerContourBot;
1180 generateRing( aHoleCenter, csTopRadius, csTopRadius + aPlatingThickness3d, nrSegments,
1181 innerContourTop, outerContourTop,
false );
1182 generateRing( aHoleCenter, csBotRadius, csBotRadius + aPlatingThickness3d, nrSegments,
1183 innerContourBot, outerContourBot,
false );
1185 for(
unsigned int i = 0; i < ( innerContourTop.size() - 1 ); ++i )
1187 const SFVEC2F& vi0_top = innerContourTop[i + 0];
1188 const SFVEC2F& vi1_top = innerContourTop[i + 1];
1189 const SFVEC2F& vo0_top = outerContourTop[i + 0];
1190 const SFVEC2F& vo1_top = outerContourTop[i + 1];
1192 const SFVEC2F& vi0_bot = innerContourBot[i + 0];
1193 const SFVEC2F& vi1_bot = innerContourBot[i + 1];
1194 const SFVEC2F& vo0_bot = outerContourBot[i + 0];
1195 const SFVEC2F& vo1_bot = outerContourBot[i + 1];
1198 SFVEC3F( vi1_top.x, vi1_top.y, zTop ),
1199 SFVEC3F( vi0_top.x, vi0_top.y, zTop ),
1200 SFVEC3F( vi0_bot.x, vi0_bot.y, zBot ),
1201 SFVEC3F( vi1_bot.x, vi1_bot.y, zBot ) );
1204 SFVEC3F( vo1_top.x, vo1_top.y, zTop ),
1205 SFVEC3F( vo0_top.x, vo0_top.y, zTop ),
1206 SFVEC3F( vo0_bot.x, vo0_bot.y, zBot ),
1207 SFVEC3F( vo1_bot.x, vo1_bot.y, zBot ) );
1222 float averageDiameter =
m_boardAdapter.GetAverageViaHoleDiameter();
1223 unsigned int averageSegCount =
m_boardAdapter.GetCircleSegmentCount( averageDiameter );
1224 unsigned int trianglesEstimate = averageSegCount * 8 *
m_boardAdapter.GetViaCount();
1234 bool isBackdrilled =
via->GetSecondaryDrillSize().has_value();
1235 bool isTertiarydrilled =
via->GetTertiaryDrillSize().has_value();
1246 && !hasFrontPostMachining && !hasBackPostMachining )
1251 const float holediameter =
via->GetDrillValue() * aUnitScale;
1252 const int nrSegments =
m_boardAdapter.GetCircleSegmentCount(
via->GetDrillValue() );
1253 const float hole_inner_radius = holediameter / 2.0f;
1255 const SFVEC2F via_center(
via->GetStart().x * aUnitScale,
1256 -
via->GetStart().y * aUnitScale );
1259 via->LayerPair( &top_layer, &bottom_layer );
1261 float ztop, zbot,
dummy;
1266 wxASSERT( zbot < ztop );
1268 float ztop_plated = ztop;
1269 float zbot_plated = zbot;
1279 zbot_plated = std::max( zbot_plated, secZEnd );
1282 if( isTertiarydrilled )
1290 ztop_plated = std::min( ztop_plated, terZEnd );
1293 auto applyViaPostMachining = [&](
bool isFront )
1295 auto modeOpt = isFront ?
via->GetFrontPostMachining()
1296 :
via->GetBackPostMachining();
1304 int sizeIU = isFront ?
via->GetFrontPostMachiningSize()
1305 :
via->GetBackPostMachiningSize();
1306 int depthIU = isFront ?
via->GetFrontPostMachiningDepth()
1307 :
via->GetBackPostMachiningDepth();
1308 float zSurface = isFront ? ztop : zbot;
1312 sizeIU, depthIU, hole_inner_radius, zSurface,
1313 isFront, aPlatingThickness3d, aUnitScale, &zEnd ) )
1316 ztop_plated = std::min( ztop_plated, zEnd );
1318 zbot_plated = std::max( zbot_plated, zEnd );
1322 if( hasFrontPostMachining )
1323 applyViaPostMachining(
true );
1324 if( hasBackPostMachining )
1325 applyViaPostMachining(
false );
1332 const float padFrontSurface =
1335 const float padBackSurface =
1341 for(
const PAD*
pad : footprint->Pads() )
1346 if( !
pad->HasHole() )
1352 const SFVEC2F padCenter(
pad->GetPosition().x * aUnitScale,
1353 -
pad->GetPosition().y * aUnitScale );
1354 const float holeInnerRadius =
1355 pad->GetDrillSize().x * 0.5f * aUnitScale;
1357 auto emitPadPostMachining = [&](
bool isFront )
1359 auto modeOpt = isFront ?
pad->GetFrontPostMachining()
1360 :
pad->GetBackPostMachining();
1368 int sizeIU = isFront ?
pad->GetFrontPostMachiningSize()
1369 :
pad->GetBackPostMachiningSize();
1370 int depthIU = isFront ?
pad->GetFrontPostMachiningDepth()
1371 :
pad->GetBackPostMachiningDepth();
1372 float zSurface = isFront ? padFrontSurface : padBackSurface;
1375 sizeIU, depthIU, holeInnerRadius, zSurface,
1376 isFront, aPlatingThickness3d, aUnitScale,
1380 emitPadPostMachining(
true );
1381 emitPadPostMachining(
false );
1387 delete layerTriangleVIA;
1415 via->GetDrill() / 2 + aPlatingThickness,
1425 for(
const PAD*
pad : footprint->Pads() )
1429 if( !
pad->HasHole() )
1432 pad->TransformHoleToPolygon( tht_outer_holes_poly, aPlatingThickness,
1434 pad->TransformHoleToPolygon( tht_inner_holes_poly, 0,
1451 if( holes2D.size() > 0 &&
m_boardAdapter.m_Cfg->m_Render.show_plated_barrels )
1453 float layer_z_top, layer_z_bot,
dummy;
1460 for(
const OBJECT_2D* itemOnLayer : holes2D )
1462 const OBJECT_2D* object2d_A = itemOnLayer;
1480 layer_z_bot, layer_z_top,
1481 aUnitScale,
false );
1484 layer_z_top, layer_z_top );
1487 delete layerTriangles;
1507 const float holediameter =
via->GetDrillValue() * aUnitScale;
1508 const float hole_radius = holediameter / 2.0f + 2.0f * aPlatingThickness3d;
1510 -
via->GetStart().y * aUnitScale );
1511 unsigned int seg =
m_boardAdapter.GetCircleSegmentCount(
via->GetDrillValue() );
1514 via->LayerPair( &top_layer, &bottom_layer );
1515 float ztop, zbot,
dummy;
1528 const auto frontPostMachining =
1530 const auto backPostMachining =
1538 bool hasFrontBackdrill =
via->GetSecondaryDrillStartLayer() ==
F_Cu;
1539 bool hasBackBackdrill =
via->GetSecondaryDrillStartLayer() ==
B_Cu;
1541 const float depth = hole_radius * 0.3f;
1543 if( frontCovering && !hasFrontPostMachining && !hasFrontBackdrill )
1545 if( filled || !frontPlugged )
1551 if( backCovering && !hasBackPostMachining && !hasBackBackdrill )
1553 if( filled || !backPlugged )
1576 const int platingThickness =
m_boardAdapter.GetHolePlatingThickness();
1578 const float platingThickness3d = platingThickness * unitScale;
1591 if( wxFrame* frame =
dynamic_cast<wxFrame*
>(
m_canvas->GetParent() ) )
1627 wxString libraryName = footprint->GetFPID().GetLibNickname();
1628 wxString footprintBasePath = wxEmptyString;
1635 std::optional<LIBRARY_TABLE_ROW*> fpRow =
1648 for(
const FP_3DMODEL& fp_model : footprint->Models() )
1650 if( fp_model.m_Show && !fp_model.m_Filename.empty() )
1652 if( aStatusReporter )
1656 wxFileName fn( fp_model.m_Filename );
1657 aStatusReporter->
Report( wxString::Format(
_(
"Loading %s..." ),
1658 fn.GetFullName() ) );
1666 std::vector<const EMBEDDED_FILES*> embeddedFilesStack;
1667 embeddedFilesStack.push_back( footprint->GetEmbeddedFiles() );
1668 embeddedFilesStack.push_back(
m_boardAdapter.GetBoard()->GetEmbeddedFiles() );
1670 const S3DMODEL* modelPtr = cacheMgr->
GetModel( fp_model.m_Filename, footprintBasePath,
1671 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 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