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 ) );
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 ) );
252 float aZbot,
bool aInvertFaces,
257 if( aListHolesObject2d.size() > 0 )
263 for(
const OBJECT_2D* itemOnLayer : aListHolesObject2d )
265 const OBJECT_2D* object2d_A = itemOnLayer;
274 layerTriangles, aZtop, aZbot );
279 layerTriangles, aZtop, aZbot );
283 wxFAIL_MSG( wxT(
"RENDER_3D_OPENGL::generateHoles: Object type not implemented" ) );
294 aInvertFaces, aThroughHoles );
299 delete layerTriangles;
311 if( aContainer ==
nullptr )
316 if( listObject2d.size() == 0 )
319 float layer_z_bot = 0.0f;
320 float layer_z_top = 0.0f;
325 unsigned int nrTrianglesEstimation = listObject2d.size() * 8;
333 for(
const OBJECT_2D* itemOnLayer : listObject2d )
335 const OBJECT_2D* object2d_A = itemOnLayer;
341 layerTriangles, layer_z_top, layer_z_bot );
346 layerTriangles, layer_z_top, layer_z_bot );
351 layerTriangles, layer_z_top, layer_z_bot );
356 layerTriangles, layer_z_top, layer_z_bot );
361 layerTriangles, layer_z_top, layer_z_bot );
365 wxFAIL_MSG( wxT(
"RENDER_3D_OPENGL: Object type is not implemented" ) );
383 float layer_z_bot = 0.0f;
384 float layer_z_top = 0.0f;
408 if( listBoardObject2d.size() > 0 )
412 const float layer_z_top = 1.0f;
413 const float layer_z_bot = 0.0f;
419 for(
const OBJECT_2D* itemOnLayer : listBoardObject2d )
421 const OBJECT_2D* object2d_A = itemOnLayer;
441 layer_z_top, layer_z_top );
444 delete layerTriangles;
464 m_camera.SetBoardLookAtPos( camera_pos );
466 if( aStatusReporter )
467 aStatusReporter->
Report(
_(
"Load OpenGL: board" ) );
492 if( aStatusReporter )
493 aStatusReporter->
Report(
_(
"Load OpenGL: holes and vias" ) );
515 wxASSERT( innerMapHoles.size() == outerMapHoles.size() );
519 if( outerMapHoles.size() > 0 )
521 float layer_z_bot = 0.0f;
522 float layer_z_top = 0.0f;
524 for(
const auto& [ layer, poly ] : outerMapHoles )
529 layer_z_top, layer_z_bot,
false );
532 for(
const auto& [ layer, poly ] : innerMapHoles )
537 layer_z_top, layer_z_bot,
false );
545 if( aStatusReporter )
546 aStatusReporter->
Report(
_(
"Load OpenGL: layers" ) );
548 std::bitset<LAYER_3D_END> visibilityFlags =
m_boardAdapter.GetVisibleLayers();
552 for(
const auto& [ layer, container2d ] :
m_boardAdapter.GetLayerMap() )
557 if( aStatusReporter )
560 aStatusReporter->
Report( wxString::Format(
_(
"Load OpenGL layer %s" ), msg ) );
570 if( map_poly.contains( layer ) )
572 polyListSubtracted = *map_poly.at( layer );
597 polyList = &polyListSubtracted;
604 if( oglList !=
nullptr )
613 if( frontPlatedCopperPolys )
628 if( backPlatedCopperPolys )
653 if( aStatusReporter )
654 aStatusReporter->
Report(
_(
"Loading 3D models..." ) );
658 if( aStatusReporter )
663 aStatusReporter->
Report( wxString::Format(
_(
"Reload time %.3f s" ), calculation_time ) );
687 if( aOutZtop < aOutZbot )
689 float tmpFloat = aOutZbot;
697 float aOuterRadius,
float aZtop,
float aZbot,
698 unsigned int aNr_sides_per_circle,
701 std::vector< SFVEC2F > innerContour;
702 std::vector< SFVEC2F > outerContour;
704 generateRing( aCenter, aInnerRadius, aOuterRadius, aNr_sides_per_circle, innerContour,
705 outerContour,
false );
707 for(
unsigned int i = 0; i < ( innerContour.size() - 1 ); ++i )
709 const SFVEC2F& vi0 = innerContour[i + 0];
710 const SFVEC2F& vi1 = innerContour[i + 1];
711 const SFVEC2F& vo0 = outerContour[i + 0];
712 const SFVEC2F& vo1 = outerContour[i + 1];
715 SFVEC3F( vi0.x, vi0.y, aZtop ),
716 SFVEC3F( vo0.x, vo0.y, aZtop ),
717 SFVEC3F( vo1.x, vo1.y, aZtop ) );
720 SFVEC3F( vo1.x, vo1.y, aZbot ),
721 SFVEC3F( vo0.x, vo0.y, aZbot ),
722 SFVEC3F( vi0.x, vi0.y, aZbot ) );
734 const float delta = 2.0f * glm::pi<float>() / (float) aNr_sides_per_circle;
736 for(
unsigned int i = 0; i < aNr_sides_per_circle; ++i )
738 float a0 =
delta * i;
739 float a1 =
delta * ( i + 1 );
740 const SFVEC3F p0( aCenter.x + cosf( a0 ) * aRadius,
741 aCenter.y + sinf( a0 ) * aRadius, aZ );
742 const SFVEC3F p1( aCenter.x + cosf( a1 ) * aRadius,
743 aCenter.y + sinf( a1 ) * aRadius, aZ );
744 const SFVEC3F c( aCenter.x, aCenter.y, aZ );
755 float aDepth,
unsigned int aNr_sides_per_circle,
758 const float delta = 2.0f * glm::pi<float>() / (float) aNr_sides_per_circle;
759 const SFVEC3F c( aCenter.x, aCenter.y, aTop ? aZ - aDepth : aZ + aDepth );
761 for(
unsigned int i = 0; i < aNr_sides_per_circle; ++i )
763 float a0 =
delta * i;
764 float a1 =
delta * ( i + 1 );
765 const SFVEC3F p0( aCenter.x + cosf( a0 ) * aRadius,
766 aCenter.y + sinf( a0 ) * aRadius, aZ );
767 const SFVEC3F p1( aCenter.x + cosf( a1 ) * aRadius,
768 aCenter.y + sinf( a1 ) * aRadius, aZ );
783 const int platingThickness =
m_boardAdapter.GetHolePlatingThickness();
784 const float platingThickness3d = platingThickness *
m_boardAdapter.BiuTo3dUnits();
788 float averageDiameter =
m_boardAdapter.GetAverageViaHoleDiameter();
789 unsigned int averageSegCount =
m_boardAdapter.GetCircleSegmentCount( averageDiameter );
790 unsigned int trianglesEstimate = averageSegCount * 8 *
m_boardAdapter.GetViaCount();
807 const int nrSegments =
m_boardAdapter.GetCircleSegmentCount(
via->GetDrillValue() );
808 const float hole_inner_radius = holediameter / 2.0f;
814 via->LayerPair( &top_layer, &bottom_layer );
816 float ztop, zbot,
dummy;
821 wxASSERT( zbot < ztop );
825 generateCylinder( via_center, hole_inner_radius, hole_inner_radius + platingThickness3d,
826 ztop, zbot, nrSegments, layerTriangleVIA );
833 delete layerTriangleVIA;
855 via->GetDrill() / 2 + platingThickness,
867 for(
const PAD*
pad : footprint->Pads() )
871 if( !
pad->HasHole() )
874 pad->TransformHoleToPolygon( tht_outer_holes_poly, platingThickness,
876 pad->TransformHoleToPolygon( tht_inner_holes_poly, 0,
894 if( holes2D.size() > 0 &&
m_boardAdapter.m_Cfg->m_Render.show_plated_barrels )
896 float layer_z_top, layer_z_bot,
dummy;
904 for(
const OBJECT_2D* itemOnLayer : holes2D )
906 const OBJECT_2D* object2d_A = itemOnLayer;
924 layer_z_bot, layer_z_top,
928 layer_z_top, layer_z_top );
931 delete layerTriangles;
946 const float hole_radius = holediameter / 2.0f + 2.0 * platingThickness3d;
952 via->LayerPair( &top_layer, &bottom_layer );
953 float ztop, zbot,
dummy;
964 const float depth = hole_radius * 0.3f;
968 if( filled || !frontPlugged )
976 if( filled || !backPlugged )
999 if( wxFrame* frame =
dynamic_cast<wxFrame*
>(
m_canvas->GetParent() ) )
1033 wxString libraryName = footprint->GetFPID().GetLibNickname();
1034 wxString footprintBasePath = wxEmptyString;
1043 ->
FindRow( libraryName,
false );
1046 footprintBasePath = fpRow->
GetFullURI(
true );
1054 for(
const FP_3DMODEL& fp_model : footprint->Models() )
1056 if( fp_model.m_Show && !fp_model.m_Filename.empty() )
1058 if( aStatusReporter )
1062 wxFileName fn( fp_model.m_Filename );
1063 aStatusReporter->
Report( wxString::Format(
_(
"Loading %s..." ),
1064 fn.GetFullName() ) );
1072 std::vector<const EMBEDDED_FILES*> embeddedFilesStack;
1073 embeddedFilesStack.push_back( footprint->GetEmbeddedFiles() );
1074 embeddedFilesStack.push_back(
m_boardAdapter.GetBoard()->GetEmbeddedFiles() );
1078 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
Hold a record identifying a library accessed by the appropriate footprint library #PLUGIN object in t...
const FP_LIB_TABLE_ROW * FindRow(const wxString &aNickName, bool aCheckIfEnabled=false)
Return an FP_LIB_TABLE_ROW if aNickName is found in this table or in any chained fall back table frag...
const wxString GetFullURI(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 FP_LIB_TABLE * PcbFootprintLibs(PROJECT *aProject)
Return the table of footprint libraries without Kiway.
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
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
TRIANGLE_LIST * m_layer_top_segment_ends
TRIANGLE_LIST * m_layer_bot_triangles
TRIANGLE_LIST * m_layer_top_triangles
void AddToMiddleContourns(const SHAPE_LINE_CHAIN &outlinePath, float zBot, float zTop, double aBiuTo3Du, bool aInvertFaceDirection, const BVH_CONTAINER_2D *aThroughHoles=nullptr)
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