Source 3D dimensions from board stackup.
Also includes a performance improvemnt by caching the 3D model matrices.
This commit is contained in:
parent
2538ad16aa
commit
dabc75bee8
|
@ -39,6 +39,15 @@
|
|||
#include <wx/log.h>
|
||||
|
||||
|
||||
#define DEFAULT_BOARD_THICKNESS Millimeter2iu( 1.6 )
|
||||
#define DEFAULT_COPPER_THICKNESS Millimeter2iu( 0.035 ) // for 35 um
|
||||
// The solder mask layer (and silkscreen) thickness
|
||||
#define DEFAULT_TECH_LAYER_THICKNESS Millimeter2iu( 0.025 )
|
||||
// The solder paste thickness is chosen bigger than the solder mask layer
|
||||
// to be sure is covers the mask when overlapping.
|
||||
#define SOLDERPASTE_LAYER_THICKNESS Millimeter2iu( 0.04 )
|
||||
|
||||
|
||||
CUSTOM_COLORS_LIST BOARD_ADAPTER::g_SilkscreenColors;
|
||||
CUSTOM_COLORS_LIST BOARD_ADAPTER::g_MaskColors;
|
||||
CUSTOM_COLORS_LIST BOARD_ADAPTER::g_PasteColors;
|
||||
|
@ -91,12 +100,14 @@ BOARD_ADAPTER::BOARD_ADAPTER() :
|
|||
m_throughHoleOds.Clear();
|
||||
m_throughHoleAnnularRings.Clear();
|
||||
|
||||
m_copperLayersCount = -1;
|
||||
m_epoxyThickness3DU = 0.0f;
|
||||
m_copperThickness3DU = 0.0f;
|
||||
m_nonCopperLayerThickness3DU = 0.0f;
|
||||
m_solderPasteLayerThickness3DU = 0.0f;
|
||||
m_copperLayersCount = 2;
|
||||
|
||||
m_biuTo3Dunits = 1.0;
|
||||
m_boardBodyThickness3DU = DEFAULT_BOARD_THICKNESS * m_biuTo3Dunits;
|
||||
m_frontCopperThickness3DU = DEFAULT_COPPER_THICKNESS * m_biuTo3Dunits;
|
||||
m_backCopperThickness3DU = DEFAULT_COPPER_THICKNESS * m_biuTo3Dunits;
|
||||
m_nonCopperLayerThickness3DU = DEFAULT_TECH_LAYER_THICKNESS * m_biuTo3Dunits;
|
||||
m_solderPasteLayerThickness3DU = SOLDERPASTE_LAYER_THICKNESS * m_biuTo3Dunits;
|
||||
|
||||
m_trackCount = 0;
|
||||
m_viaCount = 0;
|
||||
|
@ -255,18 +266,10 @@ bool BOARD_ADAPTER::IsFootprintShown( FOOTPRINT_ATTR_T aFPAttributes ) const
|
|||
}
|
||||
|
||||
|
||||
// !TODO: define the actual copper thickness by user from board stackup
|
||||
#define COPPER_THICKNESS Millimeter2iu( 0.035 ) // for 35 um
|
||||
// The solder mask layer (and silkscreen) thickness
|
||||
#define TECH_LAYER_THICKNESS Millimeter2iu( 0.025 )
|
||||
// The solder paste thickness is chosen bigger than the solder mask layer
|
||||
// to be sure is covers the mask when overlapping.
|
||||
#define SOLDERPASTE_LAYER_THICKNESS Millimeter2iu( 0.04 )
|
||||
|
||||
int BOARD_ADAPTER::GetHolePlatingThickness() const noexcept
|
||||
{
|
||||
return m_board ? m_board->GetDesignSettings().GetHolePlatingThickness()
|
||||
: 0.035 * PCB_IU_PER_MM;
|
||||
: DEFAULT_COPPER_THICKNESS;
|
||||
}
|
||||
|
||||
|
||||
|
@ -335,20 +338,51 @@ void BOARD_ADAPTER::InitSettings( REPORTER* aStatusReporter, REPORTER* aWarningR
|
|||
// Calculate the conversion to apply to all positions.
|
||||
m_biuTo3Dunits = RANGE_SCALE_3D / std::max( m_boardSize.x, m_boardSize.y );
|
||||
|
||||
m_epoxyThickness3DU = m_board
|
||||
? m_board->GetDesignSettings().GetBoardThickness() * m_biuTo3Dunits
|
||||
: 1.6 * PCB_IU_PER_MM * m_biuTo3Dunits;
|
||||
|
||||
// !TODO: use value defined by user (currently use default values by ctor
|
||||
m_copperThickness3DU = COPPER_THICKNESS * m_biuTo3Dunits;
|
||||
m_nonCopperLayerThickness3DU = TECH_LAYER_THICKNESS * m_biuTo3Dunits;
|
||||
m_boardBodyThickness3DU = DEFAULT_BOARD_THICKNESS * m_biuTo3Dunits;
|
||||
m_frontCopperThickness3DU = DEFAULT_COPPER_THICKNESS * m_biuTo3Dunits;
|
||||
m_backCopperThickness3DU = DEFAULT_COPPER_THICKNESS * m_biuTo3Dunits;
|
||||
m_nonCopperLayerThickness3DU = DEFAULT_TECH_LAYER_THICKNESS * m_biuTo3Dunits;
|
||||
m_solderPasteLayerThickness3DU = SOLDERPASTE_LAYER_THICKNESS * m_biuTo3Dunits;
|
||||
|
||||
if( m_board )
|
||||
{
|
||||
const BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings();
|
||||
|
||||
if( bds.GetStackupDescriptor().GetCount() )
|
||||
{
|
||||
int thickness = 0;
|
||||
|
||||
for( BOARD_STACKUP_ITEM* item : bds.GetStackupDescriptor().GetList() )
|
||||
{
|
||||
switch( item->GetType() )
|
||||
{
|
||||
case BS_ITEM_TYPE_DIELECTRIC:
|
||||
thickness += item->GetThickness();
|
||||
break;
|
||||
|
||||
case BS_ITEM_TYPE_COPPER:
|
||||
if( item->GetBrdLayerId() == F_Cu )
|
||||
m_frontCopperThickness3DU = item->GetThickness() * m_biuTo3Dunits;
|
||||
else if( item->GetBrdLayerId() == B_Cu )
|
||||
m_backCopperThickness3DU = item->GetThickness() * m_biuTo3Dunits;
|
||||
else if( item->IsEnabled() )
|
||||
thickness += item->GetThickness();
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_boardBodyThickness3DU = thickness * m_biuTo3Dunits;
|
||||
}
|
||||
}
|
||||
|
||||
// Init Z position of each layer
|
||||
// calculate z position for each copper layer
|
||||
// Zstart = -m_epoxyThickness / 2.0 is the z position of the back (bottom layer) (layer id = 31)
|
||||
// Zstart = +m_epoxyThickness / 2.0 is the z position of the front (top layer) (layer id = 0)
|
||||
// all unused copper layer z position are set to 0
|
||||
|
||||
// ____==__________==________==______ <- Bottom = +m_epoxyThickness / 2.0,
|
||||
// | | Top = Bottom + m_copperThickness
|
||||
|
@ -360,24 +394,26 @@ void BOARD_ADAPTER::InitSettings( REPORTER* aStatusReporter, REPORTER* aWarningR
|
|||
|
||||
for( layer = 0; layer < m_copperLayersCount; ++layer )
|
||||
{
|
||||
m_layerZcoordBottom[layer] = m_epoxyThickness3DU / 2.0f -
|
||||
(m_epoxyThickness3DU * layer / (m_copperLayersCount - 1) );
|
||||
// This approximates internal layer positions (because we're treating all the dielectric
|
||||
// layers as having the same thickness). But we don't render them anyway so it doesn't
|
||||
// really matter.
|
||||
m_layerZcoordBottom[layer] = m_boardBodyThickness3DU / 2.0f -
|
||||
(m_boardBodyThickness3DU * layer / (m_copperLayersCount - 1) );
|
||||
|
||||
if( layer < (m_copperLayersCount / 2) )
|
||||
m_layerZcoordTop[layer] = m_layerZcoordBottom[layer] + m_copperThickness3DU;
|
||||
m_layerZcoordTop[layer] = m_layerZcoordBottom[layer] + m_frontCopperThickness3DU;
|
||||
else
|
||||
m_layerZcoordTop[layer] = m_layerZcoordBottom[layer] - m_copperThickness3DU;
|
||||
m_layerZcoordTop[layer] = m_layerZcoordBottom[layer] - m_backCopperThickness3DU;
|
||||
}
|
||||
|
||||
#define layerThicknessMargin 1.1
|
||||
const float zpos_offset = m_nonCopperLayerThickness3DU * layerThicknessMargin;
|
||||
|
||||
// Fill remaining unused copper layers and back layer zpos
|
||||
// with -m_epoxyThickness / 2.0
|
||||
// Fill remaining unused copper layers and back layer zpos with -m_boardBodyThickness / 2.0
|
||||
for( ; layer < MAX_CU_LAYERS; layer++ )
|
||||
{
|
||||
m_layerZcoordBottom[layer] = -(m_epoxyThickness3DU / 2.0f);
|
||||
m_layerZcoordTop[layer] = -(m_epoxyThickness3DU / 2.0f) - m_copperThickness3DU;
|
||||
m_layerZcoordBottom[layer] = -( m_boardBodyThickness3DU / 2.0f );
|
||||
m_layerZcoordTop[layer] = -( m_boardBodyThickness3DU / 2.0f ) - m_backCopperThickness3DU;
|
||||
}
|
||||
|
||||
// This is the top of the copper layer thickness.
|
||||
|
|
|
@ -157,39 +157,23 @@ public:
|
|||
}
|
||||
|
||||
/**
|
||||
* Get the current epoxy thickness.
|
||||
*
|
||||
* @return epoxy thickness in 3D units.
|
||||
* Get the board body thickness, including internal copper layers (in 3D units).
|
||||
*/
|
||||
float GetEpoxyThickness() const noexcept
|
||||
{
|
||||
return m_epoxyThickness3DU;
|
||||
}
|
||||
float GetBoardBodyThickness() const noexcept { return m_boardBodyThickness3DU; }
|
||||
|
||||
/**
|
||||
* Get the current non copper layers thickness.
|
||||
*
|
||||
* @return thickness in 3D units of non copper layers.
|
||||
* Get the non copper layers thickness (in 3D units).
|
||||
*/
|
||||
float GetNonCopperLayerThickness() const noexcept
|
||||
{
|
||||
return m_nonCopperLayerThickness3DU;
|
||||
}
|
||||
float GetNonCopperLayerThickness() const noexcept { return m_nonCopperLayerThickness3DU; }
|
||||
|
||||
/**
|
||||
* Get the current copper layer thickness.
|
||||
*
|
||||
* @return thickness in 3D units of copper layers.
|
||||
* Get the copper layer thicknesses (in 3D units).
|
||||
*/
|
||||
float GetCopperThickness() const noexcept
|
||||
{
|
||||
return m_copperThickness3DU;
|
||||
}
|
||||
float GetFrontCopperThickness() const noexcept { return m_frontCopperThickness3DU; }
|
||||
float GetBackCopperThickness() const noexcept { return m_backCopperThickness3DU; }
|
||||
|
||||
/**
|
||||
* Get the current copper layer thickness.
|
||||
*
|
||||
* @return thickness in board units.
|
||||
* Get the hole plating thickness (NB: in BOARD UNITS!).
|
||||
*/
|
||||
int GetHolePlatingThickness() const noexcept;
|
||||
|
||||
|
@ -604,8 +588,9 @@ private:
|
|||
std::array<float, PCB_LAYER_ID_COUNT> m_layerZcoordBottom; ///< Bottom (Start) Z position of
|
||||
///< each layer in 3D units.
|
||||
|
||||
float m_copperThickness3DU;
|
||||
float m_epoxyThickness3DU;
|
||||
float m_frontCopperThickness3DU;
|
||||
float m_backCopperThickness3DU;
|
||||
float m_boardBodyThickness3DU;
|
||||
float m_nonCopperLayerThickness3DU;
|
||||
float m_solderPasteLayerThickness3DU;
|
||||
|
||||
|
|
|
@ -533,8 +533,8 @@ void RENDER_3D_OPENGL::renderBoardBody( bool aSkipRenderHoles )
|
|||
|
||||
if( ogl_disp_list )
|
||||
{
|
||||
ogl_disp_list->ApplyScalePosition( -m_boardAdapter.GetEpoxyThickness() / 2.0f,
|
||||
m_boardAdapter.GetEpoxyThickness() );
|
||||
ogl_disp_list->ApplyScalePosition( -m_boardAdapter.GetBoardBodyThickness() / 2.0f,
|
||||
m_boardAdapter.GetBoardBodyThickness() );
|
||||
|
||||
ogl_disp_list->SetItIsTransparent( true );
|
||||
|
||||
|
@ -1049,41 +1049,29 @@ void RENDER_3D_OPENGL::freeAllLists()
|
|||
delete m_platedPadsBack;
|
||||
m_platedPadsBack = nullptr;
|
||||
|
||||
for( MAP_OGL_DISP_LISTS::const_iterator ii = m_outerLayerHoles.begin();
|
||||
ii != m_outerLayerHoles.end();
|
||||
++ii )
|
||||
{
|
||||
OPENGL_RENDER_LIST* pLayerDispList = static_cast<OPENGL_RENDER_LIST*>( ii->second );
|
||||
delete pLayerDispList;
|
||||
}
|
||||
|
||||
for( const std::pair<const PCB_LAYER_ID, OPENGL_RENDER_LIST*> entry : m_outerLayerHoles )
|
||||
delete entry.second;
|
||||
|
||||
m_outerLayerHoles.clear();
|
||||
|
||||
for( MAP_OGL_DISP_LISTS::const_iterator ii = m_innerLayerHoles.begin();
|
||||
ii != m_innerLayerHoles.end();
|
||||
++ii )
|
||||
{
|
||||
OPENGL_RENDER_LIST* pLayerDispList = static_cast<OPENGL_RENDER_LIST*>( ii->second );
|
||||
delete pLayerDispList;
|
||||
}
|
||||
for( const std::pair<const PCB_LAYER_ID, OPENGL_RENDER_LIST*> entry : m_innerLayerHoles )
|
||||
delete entry.second;
|
||||
|
||||
m_innerLayerHoles.clear();
|
||||
|
||||
for( LIST_TRIANGLES::const_iterator ii = m_triangles.begin(); ii != m_triangles.end(); ++ii )
|
||||
{
|
||||
delete *ii;
|
||||
}
|
||||
|
||||
m_triangles.clear();
|
||||
|
||||
for( MAP_3DMODEL::const_iterator ii = m_3dModelMap.begin(); ii != m_3dModelMap.end(); ++ii )
|
||||
{
|
||||
MODEL_3D* pointer = static_cast<MODEL_3D*>(ii->second);
|
||||
delete pointer;
|
||||
}
|
||||
for( const std::pair<const wxString&, MODEL_3D*>& entry : m_3dModelMap )
|
||||
delete entry.second;
|
||||
|
||||
m_3dModelMap.clear();
|
||||
|
||||
m_3dModelMatrixMap.clear();
|
||||
|
||||
delete m_board;
|
||||
m_board = nullptr;
|
||||
|
||||
|
@ -1267,18 +1255,29 @@ void RENDER_3D_OPENGL::renderFootprint( const FOOTPRINT* aFootprint, bool aRende
|
|||
{
|
||||
glPushMatrix();
|
||||
|
||||
// FIXME: don't do this over and over again unless the
|
||||
// values have changed. cache the matrix somewhere.
|
||||
std::vector<double> key = { sM.m_Offset.x, sM.m_Offset.y, sM.m_Offset.z,
|
||||
sM.m_Rotation.x, sM.m_Rotation.y, sM.m_Rotation.z,
|
||||
sM.m_Scale.x, sM.m_Scale.y, sM.m_Scale.z };
|
||||
|
||||
auto it = m_3dModelMatrixMap.find( key );
|
||||
|
||||
if( it != m_3dModelMatrixMap.end() )
|
||||
{
|
||||
glMultMatrixf( glm::value_ptr( it->second ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
glm::mat4 mtx( 1 );
|
||||
mtx = glm::translate( mtx, { sM.m_Offset.x, sM.m_Offset.y, sM.m_Offset.z } );
|
||||
mtx = glm::rotate( mtx, glm::radians( (float) -sM.m_Rotation.z ),
|
||||
{ 0.0f, 0.0f, 1.0f } );
|
||||
mtx = glm::rotate( mtx, glm::radians( (float) -sM.m_Rotation.y ),
|
||||
{ 0.0f, 1.0f, 0.0f } );
|
||||
mtx = glm::rotate( mtx, glm::radians( (float) -sM.m_Rotation.x ),
|
||||
{ 1.0f, 0.0f, 0.0f } );
|
||||
mtx = glm::rotate( mtx, glm::radians( (float) -sM.m_Rotation.z ), { 0.0f, 0.0f, 1.0f } );
|
||||
mtx = glm::rotate( mtx, glm::radians( (float) -sM.m_Rotation.y ), { 0.0f, 1.0f, 0.0f } );
|
||||
mtx = glm::rotate( mtx, glm::radians( (float) -sM.m_Rotation.x ), { 1.0f, 0.0f, 0.0f } );
|
||||
mtx = glm::scale( mtx, { sM.m_Scale.x, sM.m_Scale.y, sM.m_Scale.z } );
|
||||
m_3dModelMatrixMap[ key ] = mtx;
|
||||
|
||||
glMultMatrixf( glm::value_ptr( mtx ) );
|
||||
}
|
||||
|
||||
|
||||
if( aRenderTransparentOnly )
|
||||
{
|
||||
|
|
|
@ -41,10 +41,8 @@
|
|||
|
||||
#include <map>
|
||||
|
||||
|
||||
typedef std::map< PCB_LAYER_ID, OPENGL_RENDER_LIST* > MAP_OGL_DISP_LISTS;
|
||||
typedef std::list<TRIANGLE_DISPLAY_LIST* > LIST_TRIANGLES;
|
||||
typedef std::map< wxString, MODEL_3D* > MAP_3DMODEL;
|
||||
|
||||
#define SIZE_OF_CIRCLE_TEXTURE 1024
|
||||
|
||||
|
@ -208,7 +206,9 @@ private:
|
|||
OPENGL_RENDER_LIST* m_vias;
|
||||
OPENGL_RENDER_LIST* m_padHoles;
|
||||
|
||||
MAP_3DMODEL m_3dModelMap;
|
||||
// Caches
|
||||
std::map< wxString, MODEL_3D* > m_3dModelMap;
|
||||
std::map< std::vector<double>, glm::mat4 > m_3dModelMatrixMap;
|
||||
|
||||
BOARD_ITEM* m_currentRollOverItem;
|
||||
|
||||
|
|
|
@ -654,11 +654,11 @@ void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningRe
|
|||
{
|
||||
createItemsFromContainer( m_boardAdapter.GetPlatedPadsFront(), F_Cu, &m_materials.m_Copper,
|
||||
m_boardAdapter.m_CopperColor,
|
||||
m_boardAdapter.GetCopperThickness() * 0.1f );
|
||||
m_boardAdapter.GetFrontCopperThickness() * 0.1f );
|
||||
|
||||
createItemsFromContainer( m_boardAdapter.GetPlatedPadsBack(), B_Cu, &m_materials.m_Copper,
|
||||
m_boardAdapter.m_CopperColor,
|
||||
-m_boardAdapter.GetCopperThickness() * 0.1f );
|
||||
-m_boardAdapter.GetBackCopperThickness() * 0.1f );
|
||||
}
|
||||
|
||||
if( !aOnlyLoadCopperAndShapes )
|
||||
|
@ -952,10 +952,10 @@ void RENDER_3D_RAYTRACE::insertHole( const PCB_VIA* aVia )
|
|||
aVia->LayerPair( &top_layer, &bottom_layer );
|
||||
|
||||
float topZ = m_boardAdapter.GetLayerBottomZPos( top_layer )
|
||||
+ m_boardAdapter.GetCopperThickness();
|
||||
+ m_boardAdapter.GetFrontCopperThickness();
|
||||
|
||||
float botZ = m_boardAdapter.GetLayerBottomZPos( bottom_layer )
|
||||
- m_boardAdapter.GetCopperThickness();
|
||||
- m_boardAdapter.GetBackCopperThickness();
|
||||
|
||||
const SFVEC2F center = SFVEC2F( aVia->GetStart().x * m_boardAdapter.BiuTo3dUnits(),
|
||||
-aVia->GetStart().y * m_boardAdapter.BiuTo3dUnits() );
|
||||
|
@ -1003,10 +1003,10 @@ void RENDER_3D_RAYTRACE::insertHole( const PAD* aPad )
|
|||
CONST_LIST_OBJECT2D antiOutlineIntersectionList;
|
||||
|
||||
const float topZ = m_boardAdapter.GetLayerBottomZPos( F_Cu )
|
||||
+ m_boardAdapter.GetCopperThickness() * 0.99f;
|
||||
+ m_boardAdapter.GetFrontCopperThickness() * 0.99f;
|
||||
|
||||
const float botZ = m_boardAdapter.GetLayerBottomZPos( B_Cu )
|
||||
- m_boardAdapter.GetCopperThickness() * 0.99f;
|
||||
- m_boardAdapter.GetBackCopperThickness() * 0.99f;
|
||||
|
||||
if( drillsize.x == drillsize.y ) // usual round hole
|
||||
{
|
||||
|
|
|
@ -603,6 +603,10 @@ public:
|
|||
*/
|
||||
void SetCopperLayerCount( int aNewLayerCount );
|
||||
|
||||
/**
|
||||
* The full thickness of the board including copper and masks.
|
||||
* @return
|
||||
*/
|
||||
inline int GetBoardThickness() const { return m_boardThickness; }
|
||||
inline void SetBoardThickness( int aThickness ) { m_boardThickness = aThickness; }
|
||||
|
||||
|
|
|
@ -1386,6 +1386,7 @@ unsigned int DIALOG_NET_INSPECTOR::calculateViaLength( const PCB_TRACK* aTrack )
|
|||
else
|
||||
{
|
||||
int dielectricLayers = bds.GetCopperLayerCount() - 1;
|
||||
// FIXME: not all dielectric layers are the same thickness!
|
||||
int layerThickness = bds.GetBoardThickness() / dielectricLayers;
|
||||
int effectiveBottomLayer;
|
||||
|
||||
|
|
Loading…
Reference in New Issue