50 const float f = ( sqrtf( 2.0f ) / 2.0f ) *
radius * texture_factor;
73 float aZtop,
float aZbot )
86 float aOuterRadius,
unsigned int aNr_sides_per_circle,
87 std::vector< SFVEC2F >& aInnerContourResult,
88 std::vector< SFVEC2F >& aOuterContourResult,
91 aInnerContourResult.clear();
92 aInnerContourResult.reserve( aNr_sides_per_circle + 2 );
94 aOuterContourResult.clear();
95 aOuterContourResult.reserve( aNr_sides_per_circle + 2 );
97 const int delta = 3600 / aNr_sides_per_circle;
99 for(
int ii = 0; ii < 3600; ii +=
delta )
101 float angle = (float)( aInvertOrder ? ( 3600 - ii ) : ii )
102 * 2.0f * glm::pi<float>() / 3600.0f;
105 aInnerContourResult.emplace_back( aCenter.x + rotatedDir.x * aInnerRadius,
106 aCenter.y + rotatedDir.y * aInnerRadius );
108 aOuterContourResult.emplace_back( aCenter.x + rotatedDir.x * aOuterRadius,
109 aCenter.y + rotatedDir.y * aOuterRadius );
112 aInnerContourResult.push_back( aInnerContourResult[0] );
113 aOuterContourResult.push_back( aOuterContourResult[0] );
115 wxASSERT( aInnerContourResult.size() == aOuterContourResult.size() );
120 float aZtop,
float aZbot )
126 std::vector< SFVEC2F > innerContour;
127 std::vector< SFVEC2F > outerContour;
130 innerContour, outerContour,
false );
133 for(
unsigned int i = 0; i < ( innerContour.size() - 1 ); ++i )
135 const SFVEC2F& vi0 = innerContour[i + 0];
136 const SFVEC2F& vi1 = innerContour[i + 1];
137 const SFVEC2F& vo0 = outerContour[i + 0];
138 const SFVEC2F& vo1 = outerContour[i + 1];
141 SFVEC3F( vi0.x, vi0.y, aZtop ),
142 SFVEC3F( vo0.x, vo0.y, aZtop ),
143 SFVEC3F( vo1.x, vo1.y, aZtop ) );
146 SFVEC3F( vo1.x, vo1.y, aZbot ),
147 SFVEC3F( vo0.x, vo0.y, aZbot ),
148 SFVEC3F( vi0.x, vi0.y, aZbot ) );
154 float aZtop,
float aZbot )
166 float aZtop,
float aZbot )
183 const float radius_of_the_square = sqrtf( aSeg->
GetRadiusSquared() * 2.0f );
184 const float radius_triangle_factor = ( radius_of_the_square -
radius ) /
radius;
187 rightDir.x *
radius * radius_triangle_factor );
190 leftDir.x *
radius * radius_triangle_factor );
194 SFVEC3F( rightEnd.x + texture_factor * factorS.x,
195 rightEnd.y + texture_factor * factorS.y,
197 SFVEC3F( leftStart.x + texture_factor * factorE.x,
198 leftStart.y + texture_factor * factorE.y,
200 SFVEC3F( start.x - texture_factorF * leftDir.x *
radius * sqrtf( 2.0f ),
201 start.y - texture_factorF * leftDir.y *
radius * sqrtf( 2.0f ),
205 SFVEC3F( leftEnd.x + texture_factor * factorE.x,
206 leftEnd.y + texture_factor * factorE.y, aZtop ),
207 SFVEC3F( rightStart.x + texture_factor * factorS.x,
208 rightStart.y + texture_factor * factorS.y, aZtop ),
210 end.y - texture_factorF * rightDir.y *
radius * sqrtf( 2.0f ),
215 SFVEC3F( leftStart.x + texture_factor * factorE.x,
216 leftStart.y + texture_factor * factorE.y,
218 SFVEC3F( rightEnd.x + texture_factor * factorS.x,
219 rightEnd.y + texture_factor * factorS.y,
221 SFVEC3F( start.x - texture_factorF * leftDir.x *
radius * sqrtf( 2.0f ),
222 start.y - texture_factorF * leftDir.y *
radius * sqrtf( 2.0f ),
226 SFVEC3F( rightStart.x + texture_factor * factorS.x,
227 rightStart.y + texture_factor * factorS.y, aZbot ),
228 SFVEC3F( leftEnd.x + texture_factor * factorE.x,
229 leftEnd.y + texture_factor * factorE.y, aZbot ),
231 end.y - texture_factorF * rightDir.y *
radius * sqrtf( 2.0f ),
236 SFVEC3F( rightEnd.x, rightEnd.y, aZtop ),
237 SFVEC3F( rightStart.x, rightStart.y, aZtop ),
238 SFVEC3F( leftEnd.x, leftEnd.y, aZtop ),
239 SFVEC3F( leftStart.x, leftStart.y, aZtop ) );
242 SFVEC3F( rightEnd.x, rightEnd.y, aZbot ),
243 SFVEC3F( leftStart.x, leftStart.y, aZbot ),
244 SFVEC3F( leftEnd.x, leftEnd.y, aZbot ),
245 SFVEC3F( rightStart.x, rightStart.y, aZbot ) );
253 if( aListHolesObject2d.size() == 0 )
260 for(
const OBJECT_2D* object2d : aListHolesObject2d )
262 switch( object2d->GetObjectType() )
273 wxFAIL_MSG( wxT(
"RENDER_3D_OPENGL::generateHoles: Object type not implemented" ) );
288 delete layerTriangles;
298 if( aContainer ==
nullptr )
303 if( listObject2d.size() == 0 )
312 unsigned int nrTrianglesEstimation = listObject2d.size() * 8;
320 for(
const OBJECT_2D* object2d : listObject2d )
322 switch( object2d->GetObjectType() )
345 wxFAIL_MSG( wxT(
"RENDER_3D_OPENGL: Object type is not implemented" ) );
363 float layer_z_bot = 0.0f;
364 float layer_z_top = 0.0f;
388 if( listBoardObject2d.size() > 0 )
392 const float layer_z_top = 1.0f;
393 const float layer_z_bot = 0.0f;
399 for(
const OBJECT_2D* itemOnLayer : listBoardObject2d )
401 const OBJECT_2D* object2d_A = itemOnLayer;
421 layer_z_top, layer_z_top );
424 delete layerTriangles;
444 m_camera.SetBoardLookAtPos( camera_pos );
446 if( aStatusReporter )
447 aStatusReporter->
Report(
_(
"Load OpenGL: board" ) );
472 if( aStatusReporter )
473 aStatusReporter->
Report(
_(
"Load OpenGL: holes and vias" ) );
495 wxASSERT( innerMapHoles.size() == outerMapHoles.size() );
499 if( outerMapHoles.size() > 0 )
501 float layer_z_bot = 0.0f;
502 float layer_z_top = 0.0f;
504 for(
const auto& [ layer, poly ] : outerMapHoles )
509 layer_z_top, layer_z_bot,
false );
512 for(
const auto& [ layer, poly ] : innerMapHoles )
517 layer_z_top, layer_z_bot,
false );
525 if( aStatusReporter )
526 aStatusReporter->
Report(
_(
"Load OpenGL: layers" ) );
528 std::bitset<LAYER_3D_END> visibilityFlags =
m_boardAdapter.GetVisibleLayers();
532 for(
const auto& [ layer, container2d ] :
m_boardAdapter.GetLayerMap() )
537 if( aStatusReporter )
540 aStatusReporter->
Report( wxString::Format(
_(
"Load OpenGL layer %s" ), msg ) );
550 if( map_poly.contains( layer ) )
552 polyListSubtracted = *map_poly.at( layer );
577 polyList = &polyListSubtracted;
584 if( oglList !=
nullptr )
593 if( frontPlatedCopperPolys )
608 if( backPlatedCopperPolys )
633 if( aStatusReporter )
634 aStatusReporter->
Report(
_(
"Loading 3D models..." ) );
638 if( aStatusReporter )
643 aStatusReporter->
Report( wxString::Format(
_(
"Reload time %.3f s" ), calculation_time ) );
667 if( aOutZtop < aOutZbot )
669 float tmpFloat = aOutZbot;
677 float aOuterRadius,
float aZtop,
float aZbot,
678 unsigned int aNr_sides_per_circle,
681 std::vector< SFVEC2F > innerContour;
682 std::vector< SFVEC2F > outerContour;
684 generateRing( aCenter, aInnerRadius, aOuterRadius, aNr_sides_per_circle, innerContour,
685 outerContour,
false );
687 for(
unsigned int i = 0; i < ( innerContour.size() - 1 ); ++i )
689 const SFVEC2F& vi0 = innerContour[i + 0];
690 const SFVEC2F& vi1 = innerContour[i + 1];
691 const SFVEC2F& vo0 = outerContour[i + 0];
692 const SFVEC2F& vo1 = outerContour[i + 1];
695 SFVEC3F( vi0.x, vi0.y, aZtop ),
696 SFVEC3F( vo0.x, vo0.y, aZtop ),
697 SFVEC3F( vo1.x, vo1.y, aZtop ) );
700 SFVEC3F( vo1.x, vo1.y, aZbot ),
701 SFVEC3F( vo0.x, vo0.y, aZbot ),
702 SFVEC3F( vi0.x, vi0.y, aZbot ) );
714 const float delta = 2.0f * glm::pi<float>() / (float) aNr_sides_per_circle;
716 for(
unsigned int i = 0; i < aNr_sides_per_circle; ++i )
718 float a0 =
delta * i;
719 float a1 =
delta * ( i + 1 );
720 const SFVEC3F p0( aCenter.x + cosf( a0 ) * aRadius,
721 aCenter.y + sinf( a0 ) * aRadius, aZ );
722 const SFVEC3F p1( aCenter.x + cosf( a1 ) * aRadius,
723 aCenter.y + sinf( a1 ) * aRadius, aZ );
724 const SFVEC3F c( aCenter.x, aCenter.y, aZ );
735 float aDepth,
unsigned int aNr_sides_per_circle,
738 const float delta = 2.0f * glm::pi<float>() / (float) aNr_sides_per_circle;
739 const SFVEC3F c( aCenter.x, aCenter.y, aTop ? aZ - aDepth : aZ + aDepth );
741 for(
unsigned int i = 0; i < aNr_sides_per_circle; ++i )
743 float a0 =
delta * i;
744 float a1 =
delta * ( i + 1 );
745 const SFVEC3F p0( aCenter.x + cosf( a0 ) * aRadius,
746 aCenter.y + sinf( a0 ) * aRadius, aZ );
747 const SFVEC3F p1( aCenter.x + cosf( a1 ) * aRadius,
748 aCenter.y + sinf( a1 ) * aRadius, aZ );
763 const int platingThickness =
m_boardAdapter.GetHolePlatingThickness();
764 const float platingThickness3d = platingThickness *
m_boardAdapter.BiuTo3dUnits();
768 float averageDiameter =
m_boardAdapter.GetAverageViaHoleDiameter();
769 unsigned int averageSegCount =
m_boardAdapter.GetCircleSegmentCount( averageDiameter );
770 unsigned int trianglesEstimate = averageSegCount * 8 *
m_boardAdapter.GetViaCount();
787 const int nrSegments =
m_boardAdapter.GetCircleSegmentCount(
via->GetDrillValue() );
788 const float hole_inner_radius = holediameter / 2.0f;
794 via->LayerPair( &top_layer, &bottom_layer );
796 float ztop, zbot,
dummy;
801 wxASSERT( zbot < ztop );
805 generateCylinder( via_center, hole_inner_radius, hole_inner_radius + platingThickness3d,
806 ztop, zbot, nrSegments, layerTriangleVIA );
813 delete layerTriangleVIA;
835 via->GetDrill() / 2 + platingThickness,
847 for(
const PAD*
pad : footprint->Pads() )
851 if( !
pad->HasHole() )
854 pad->TransformHoleToPolygon( tht_outer_holes_poly, platingThickness,
856 pad->TransformHoleToPolygon( tht_inner_holes_poly, 0,
874 if( holes2D.size() > 0 &&
m_boardAdapter.m_Cfg->m_Render.show_plated_barrels )
876 float layer_z_top, layer_z_bot,
dummy;
884 for(
const OBJECT_2D* itemOnLayer : holes2D )
886 const OBJECT_2D* object2d_A = itemOnLayer;
904 layer_z_bot, layer_z_top,
908 layer_z_top, layer_z_top );
911 delete layerTriangles;
926 const float hole_radius = holediameter / 2.0f + 2.0 * platingThickness3d;
932 via->LayerPair( &top_layer, &bottom_layer );
933 float ztop, zbot,
dummy;
944 const float depth = hole_radius * 0.3f;
948 if( filled || !frontPlugged )
956 if( filled || !backPlugged )
979 if( wxFrame* frame =
dynamic_cast<wxFrame*
>(
m_canvas->GetParent() ) )
1015 wxString libraryName = footprint->GetFPID().GetLibNickname();
1016 wxString footprintBasePath = wxEmptyString;
1023 std::optional<LIBRARY_TABLE_ROW*> fpRow =
1036 for(
const FP_3DMODEL& fp_model : footprint->Models() )
1038 if( fp_model.m_Show && !fp_model.m_Filename.empty() )
1040 if( aStatusReporter )
1044 wxFileName fn( fp_model.m_Filename );
1045 aStatusReporter->
Report( wxString::Format(
_(
"Loading %s..." ),
1046 fn.GetFullName() ) );
1054 std::vector<const EMBEDDED_FILES*> embeddedFilesStack;
1055 embeddedFilesStack.push_back( footprint->GetEmbeddedFiles() );
1056 embeddedFilesStack.push_back(
m_boardAdapter.GetBoard()->GetEmbeddedFiles() );
1058 const S3DMODEL* modelPtr = cacheMgr->
GetModel( fp_model.m_Filename, footprintBasePath,
1059 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
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
OPENGL_RENDER_LIST * m_platedPadsFront
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_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)
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)
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_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:
@ 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.
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