Draw off-board pads when drawing off-board silk.

This commit is contained in:
Jeff Young 2023-09-22 20:48:13 +01:00
parent bdb7b99fc8
commit da1405ec6a
9 changed files with 130 additions and 161 deletions

View File

@ -89,7 +89,6 @@ BOARD_ADAPTER::BOARD_ADAPTER() :
m_IsPreviewer( false ),
m_board( nullptr ),
m_3dModelManager( nullptr ),
m_renderSettings( nullptr ),
m_colors( nullptr ),
m_layerZcoordTop(),
m_layerZcoordBottom()
@ -140,6 +139,8 @@ BOARD_ADAPTER::BOARD_ADAPTER() :
m_platedPadsFront = nullptr;
m_platedPadsBack = nullptr;
m_offboardPadsFront = nullptr;
m_offboardPadsBack = nullptr;
m_frontPlatedPadPolys = nullptr;
m_backPlatedPadPolys = nullptr;

View File

@ -245,6 +245,8 @@ public:
const MAP_CONTAINER_2D_BASE& GetLayerMap() const noexcept { return m_layerMap; }
const BVH_CONTAINER_2D* GetPlatedPadsFront() const noexcept { return m_platedPadsFront; }
const BVH_CONTAINER_2D* GetPlatedPadsBack() const noexcept { return m_platedPadsBack; }
const BVH_CONTAINER_2D* GetOffboardPadsFront() const noexcept { return m_offboardPadsFront; }
const BVH_CONTAINER_2D* GetOffboardPadsBack() const noexcept { return m_offboardPadsBack; }
const MAP_CONTAINER_2D_BASE& GetLayerHoleMap() const noexcept { return m_layerHoleMap; }
const BVH_CONTAINER_2D& GetTH_IDs() const noexcept { return m_TH_IDs; }
@ -421,7 +423,6 @@ public:
private:
BOARD* m_board;
S3D_CACHE* m_3dModelManager;
RENDER_SETTINGS* m_renderSettings;
COLOR_SETTINGS* m_colors;
VECTOR2I m_boardPos; ///< Board center position in board internal units.
@ -452,6 +453,8 @@ private:
BVH_CONTAINER_2D* m_platedPadsFront;
BVH_CONTAINER_2D* m_platedPadsBack;
BVH_CONTAINER_2D* m_offboardPadsFront;
BVH_CONTAINER_2D* m_offboardPadsBack;
BVH_CONTAINER_2D m_TH_ODs; ///< List of PTH outer diameters
BVH_CONTAINER_2D m_TH_IDs; ///< List of PTH inner diameters

View File

@ -135,6 +135,8 @@ void BOARD_ADAPTER::destroyLayers()
DELETE_AND_FREE( m_platedPadsFront )
DELETE_AND_FREE( m_platedPadsBack )
DELETE_AND_FREE( m_offboardPadsFront )
DELETE_AND_FREE( m_offboardPadsBack )
m_TH_ODs.Clear();
m_TH_IDs.Clear();
@ -248,6 +250,12 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
m_platedPadsBack = new BVH_CONTAINER_2D;
}
if( cfg.show_off_board_silk )
{
m_offboardPadsFront = new BVH_CONTAINER_2D;
m_offboardPadsBack = new BVH_CONTAINER_2D;
}
if( aStatusReporter )
aStatusReporter->Report( _( "Create tracks and vias" ) );
@ -992,10 +1000,8 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
}
// End Build Tech layers
#if 1
// A somewhat experimental feature: if we're rendering off-board silk, turn any pads of
// footprints which are entirely outside the board outline into silk. This makes off-board
// footprints more visually recognizable.
// If we're rendering off-board silk, also render pads of footprints which are entirely
// outside the board outline. This makes off-board footprints more visually recognizable.
if( cfg.show_off_board_silk )
{
BOX2I boardBBox = m_board_poly.BBox();
@ -1005,19 +1011,15 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
if( !footprint->GetBoundingBox().Intersects( boardBBox ) )
{
if( footprint->IsFlipped() )
{
BVH_CONTAINER_2D *layerContainer = m_layerMap[ B_SilkS ];
addPads( footprint, layerContainer, B_Cu, false, false );
}
addPads( footprint, m_offboardPadsBack, B_Cu, false, false );
else
{
BVH_CONTAINER_2D *layerContainer = m_layerMap[ F_SilkS ];
addPads( footprint, layerContainer, F_Cu, false, false );
addPads( footprint, m_offboardPadsFront, F_Cu, false, false );
}
}
m_offboardPadsFront->BuildBVH();
m_offboardPadsBack->BuildBVH();
}
}
#endif
// Simplify layer polygons

View File

@ -644,6 +644,15 @@ void RENDER_3D_OPENGL::reload( REPORTER* aStatusReporter, REPORTER* aWarningRepo
}
}
if( m_boardAdapter.m_Cfg->m_Render.show_off_board_silk )
{
if( const BVH_CONTAINER_2D* padsFront = m_boardAdapter.GetOffboardPadsFront() )
m_offboardPadsFront = generateLayerList( padsFront, nullptr, F_Cu );
if( const BVH_CONTAINER_2D* padsBack = m_boardAdapter.GetOffboardPadsBack() )
m_offboardPadsBack = generateLayerList( padsBack, nullptr, B_Cu );
}
// Load 3D models
if( aStatusReporter )
aStatusReporter->Report( _( "Loading 3D models..." ) );

View File

@ -471,34 +471,7 @@ void OPENGL_RENDER_LIST::DrawAll( bool aDrawMiddle ) const
}
void OPENGL_RENDER_LIST::DrawAllCameraCulled( float zCameraPos, bool aDrawMiddle ) const
{
zCameraPos = m_haveTransformation
? ( ( zCameraPos - m_zPositionTransformation ) / m_zScaleTransformation )
: zCameraPos;
if( aDrawMiddle )
DrawMiddle();
if( zCameraPos > m_zTop )
{
DrawTop();
}
else
{
if( zCameraPos < m_zBot )
{
DrawBot();
}
else
{
// If camera is in the middle dont draw it.
}
}
}
void OPENGL_RENDER_LIST::DrawAllCameraCulled( bool aDrawMiddle,
void OPENGL_RENDER_LIST::DrawCulled( bool aDrawMiddle,
const OPENGL_RENDER_LIST* aSubtractList,
const OPENGL_RENDER_LIST* bSubtractList,
const OPENGL_RENDER_LIST* cSubtractList,

View File

@ -194,9 +194,7 @@ public:
*
* @param zCameraPos is the camera z axis position.
*/
void DrawAllCameraCulled( float zCameraPos, bool aDrawMiddle = true ) const;
void DrawAllCameraCulled( bool aDrawMiddle,
void DrawCulled( bool aDrawMiddle,
const OPENGL_RENDER_LIST* aSubtractList = nullptr,
const OPENGL_RENDER_LIST* bSubtractList = nullptr,
const OPENGL_RENDER_LIST* cSubtractList = nullptr,

View File

@ -60,6 +60,8 @@ RENDER_3D_OPENGL::RENDER_3D_OPENGL( EDA_3D_CANVAS* aCanvas, BOARD_ADAPTER& aAdap
m_platedPadsFront = nullptr;
m_platedPadsBack = nullptr;
m_offboardPadsFront = nullptr;
m_offboardPadsBack = nullptr;
m_outerThroughHoles = nullptr;
m_outerThroughHoleRings = nullptr;
@ -541,8 +543,7 @@ bool RENDER_3D_OPENGL::Redraw( bool aIsMoving, REPORTER* aStatusReporter,
bool skipThickness = aIsMoving && cfg.opengl_thickness_disableOnMove;
bool skipRenderHoles = aIsMoving && cfg.opengl_holes_disableOnMove;
bool skipRenderVias = aIsMoving && cfg.opengl_vias_disableOnMove;
bool drawMiddleSegments = !skipThickness;
bool showThickness = !skipThickness;
std::bitset<LAYER_3D_END> layerFlags = m_boardAdapter.GetVisibleLayers();
@ -557,11 +558,11 @@ bool RENDER_3D_OPENGL::Redraw( bool aIsMoving, REPORTER* aStatusReporter,
// Display copper and tech layers
for( MAP_OGL_DISP_LISTS::const_iterator ii = m_layers.begin(); ii != m_layers.end(); ++ii )
{
const PCB_LAYER_ID layer_id = ( PCB_LAYER_ID )( ii->first );
bool isSilkLayer = layer_id == F_SilkS || layer_id == B_SilkS;
bool isMaskLayer = layer_id == F_Mask || layer_id == B_Mask;
bool isPasteLayer = layer_id == F_Paste || layer_id == B_Paste;
bool isCopperLayer = layer_id >= F_Cu && layer_id <= B_Cu;
const PCB_LAYER_ID layer = ( PCB_LAYER_ID )( ii->first );
bool isSilkLayer = layer == F_SilkS || layer == B_SilkS;
bool isMaskLayer = layer == F_Mask || layer == B_Mask;
bool isPasteLayer = layer == F_Paste || layer == B_Paste;
bool isCopperLayer = layer >= F_Cu && layer <= B_Cu;
// Mask layers are not processed here because they are a special case
if( isMaskLayer )
@ -574,7 +575,7 @@ bool RENDER_3D_OPENGL::Redraw( bool aIsMoving, REPORTER* aStatusReporter,
if( layerFlags.test( LAYER_3D_BOARD ) && m_boardAdapter.m_BoardBodyColor.a > opacity_min )
{
if( ( layer_id > F_Cu ) && ( layer_id < B_Cu ) )
if( layer > F_Cu && layer < B_Cu )
continue;
}
@ -587,63 +588,56 @@ bool RENDER_3D_OPENGL::Redraw( bool aIsMoving, REPORTER* aStatusReporter,
if( cfg.differentiate_plated_copper )
setCopperMaterial();
else
setLayerMaterial( layer_id );
setLayerMaterial( layer );
if( skipRenderHoles )
{
pLayerDispList->DrawAllCameraCulled( m_camera.GetPos().z, drawMiddleSegments );
OPENGL_RENDER_LIST* outerTH = nullptr;
OPENGL_RENDER_LIST* viaHoles = nullptr;
// Draw plated pads
if( layer_id == F_Cu && m_platedPadsFront )
if( !skipRenderHoles )
{
setPlatedCopperAndDepthOffset( layer_id );
m_platedPadsFront->DrawAllCameraCulled( m_camera.GetPos().z, drawMiddleSegments );
outerTH = m_outerThroughHoles;
viaHoles = m_outerLayerHoles[layer];
}
else if( layer_id == B_Cu && m_platedPadsBack )
{
setPlatedCopperAndDepthOffset( layer_id );
m_platedPadsBack->DrawAllCameraCulled( m_camera.GetPos().z, drawMiddleSegments );
}
unsetDepthOffset();
}
else
{
if( m_outerThroughHoles )
m_outerThroughHoles->ApplyScalePosition( pLayerDispList );
if( m_antiBoard )
m_antiBoard->ApplyScalePosition( pLayerDispList );
const OPENGL_RENDER_LIST* viasHolesLayer = m_outerLayerHoles[ layer_id ];
if( outerTH )
outerTH->ApplyScalePosition( pLayerDispList );
pLayerDispList->DrawAllCameraCulled( drawMiddleSegments, m_outerThroughHoles,
viasHolesLayer, m_antiBoard );
pLayerDispList->DrawCulled( showThickness, outerTH, viaHoles, m_antiBoard );
// Draw plated pads
if( layer_id == F_Cu && m_platedPadsFront )
// Draw plated & offboard pads
if( layer == F_Cu && ( m_platedPadsFront || m_offboardPadsFront ) )
{
setPlatedCopperAndDepthOffset( layer_id );
m_platedPadsFront->DrawAllCameraCulled( drawMiddleSegments, m_outerThroughHoles,
viasHolesLayer, m_antiBoard );
setPlatedCopperAndDepthOffset( layer );
if( m_platedPadsFront )
m_platedPadsFront->DrawCulled( showThickness, outerTH, viaHoles, m_antiBoard );
if( m_offboardPadsFront )
m_offboardPadsFront->DrawCulled( showThickness, outerTH, viaHoles );
}
else if( layer_id == B_Cu && m_platedPadsBack )
else if( layer == B_Cu && ( m_platedPadsBack || m_offboardPadsBack ) )
{
setPlatedCopperAndDepthOffset( layer_id );
m_platedPadsBack->DrawAllCameraCulled( drawMiddleSegments, m_outerThroughHoles,
viasHolesLayer, m_antiBoard );
setPlatedCopperAndDepthOffset( layer );
if( m_platedPadsBack )
m_platedPadsBack->DrawCulled( showThickness, outerTH, viaHoles, m_antiBoard );
if( m_offboardPadsBack )
m_offboardPadsBack->DrawCulled( showThickness, outerTH, viaHoles );
}
unsetDepthOffset();
}
}
else if( isPasteLayer && skipRenderHoles )
{
// Do not render paste layers when skipRenderHoles is enabled or we get z-fight issues
}
else
{
setLayerMaterial( layer_id );
setLayerMaterial( layer );
OPENGL_RENDER_LIST* throughHolesOuter = nullptr;
OPENGL_RENDER_LIST* anti_board = nullptr;
@ -656,11 +650,11 @@ bool RENDER_3D_OPENGL::Redraw( bool aIsMoving, REPORTER* aStatusReporter,
if( isSilkLayer && cfg.show_off_board_silk )
anti_board = nullptr;
else if( LSET::PhysicalLayersMask().test( layer_id ) )
else if( LSET::PhysicalLayersMask().test( layer ) )
anti_board = m_antiBoard;
if( isSilkLayer && cfg.subtract_mask_from_silk && !cfg.show_off_board_silk )
solder_mask = m_layers[ (layer_id == B_SilkS) ? B_Mask : F_Mask ];
solder_mask = m_layers[ ( layer == B_SilkS) ? B_Mask : F_Mask ];
if( throughHolesOuter )
throughHolesOuter->ApplyScalePosition( pLayerDispList );
@ -671,8 +665,7 @@ bool RENDER_3D_OPENGL::Redraw( bool aIsMoving, REPORTER* aStatusReporter,
if( solder_mask )
solder_mask->ApplyScalePosition( pLayerDispList );
pLayerDispList->DrawAllCameraCulled( drawMiddleSegments, solder_mask, throughHolesOuter,
anti_board );
pLayerDispList->DrawCulled( showThickness, solder_mask, throughHolesOuter, anti_board );
}
glPopMatrix();
@ -702,13 +695,13 @@ bool RENDER_3D_OPENGL::Redraw( bool aIsMoving, REPORTER* aStatusReporter,
if( layerFlags.test( LAYER_3D_SOLDERMASK_BOTTOM ) )
{
renderSolderMaskLayer( B_Mask, m_boardAdapter.GetLayerTopZPos( B_Mask ),
drawMiddleSegments, skipRenderHoles );
showThickness, skipRenderHoles );
}
if( layerFlags.test( LAYER_3D_SOLDERMASK_TOP ) )
{
renderSolderMaskLayer( F_Mask, m_boardAdapter.GetLayerBottomZPos( F_Mask ),
drawMiddleSegments, skipRenderHoles );
showThickness, skipRenderHoles );
}
}
else
@ -716,13 +709,13 @@ bool RENDER_3D_OPENGL::Redraw( bool aIsMoving, REPORTER* aStatusReporter,
if( layerFlags.test( LAYER_3D_SOLDERMASK_TOP ) )
{
renderSolderMaskLayer( F_Mask, m_boardAdapter.GetLayerBottomZPos( F_Mask ),
drawMiddleSegments, skipRenderHoles );
showThickness, skipRenderHoles );
}
if( layerFlags.test( LAYER_3D_SOLDERMASK_BOTTOM ) )
{
renderSolderMaskLayer( B_Mask, m_boardAdapter.GetLayerTopZPos( B_Mask ),
drawMiddleSegments, skipRenderHoles );
showThickness, skipRenderHoles );
}
}
@ -851,72 +844,59 @@ void RENDER_3D_OPENGL::setArrowMaterial()
void RENDER_3D_OPENGL::freeAllLists()
{
#define DELETE_AND_FREE( ptr ) \
{ \
delete ptr; \
ptr = nullptr; \
} \
#define DELETE_AND_FREE_MAP( map ) \
{ \
for( auto& [ layer, ptr ] : map ) \
delete ptr; \
\
map.clear(); \
}
if( glIsList( m_grid ) )
glDeleteLists( m_grid, 1 );
m_grid = 0;
for( const auto& [ layerId, renderList ] : m_layers )
delete renderList;
DELETE_AND_FREE_MAP( m_layers )
m_layers.clear();
DELETE_AND_FREE( m_platedPadsFront )
DELETE_AND_FREE( m_platedPadsBack )
DELETE_AND_FREE( m_offboardPadsFront )
DELETE_AND_FREE( m_offboardPadsBack )
delete m_platedPadsFront;
m_platedPadsFront = nullptr;
delete m_platedPadsBack;
m_platedPadsBack = nullptr;
for( const auto& [ layerId, renderList ] : m_outerLayerHoles )
delete renderList;
m_outerLayerHoles.clear();
for( const auto& [ layerId, renderList ] : m_innerLayerHoles )
delete renderList;
m_innerLayerHoles.clear();
DELETE_AND_FREE_MAP( m_outerLayerHoles )
DELETE_AND_FREE_MAP( m_innerLayerHoles )
for( TRIANGLE_DISPLAY_LIST* list : m_triangles )
delete list;
m_triangles.clear();
for( const auto& [ name, model ] : m_3dModelMap )
delete model;
m_3dModelMap.clear();
DELETE_AND_FREE_MAP( m_3dModelMap )
m_3dModelMatrixMap.clear();
delete m_board;
m_board = nullptr;
DELETE_AND_FREE( m_board )
DELETE_AND_FREE( m_boardWithHoles )
DELETE_AND_FREE( m_antiBoard )
delete m_boardWithHoles;
m_boardWithHoles = nullptr;
DELETE_AND_FREE( m_outerThroughHoles )
DELETE_AND_FREE( m_outerViaThroughHoles )
DELETE_AND_FREE( m_outerThroughHoleRings )
delete m_antiBoard;
m_antiBoard = nullptr;
delete m_outerThroughHoles;
m_outerThroughHoles = nullptr;
delete m_outerViaThroughHoles;
m_outerViaThroughHoles = nullptr;
delete m_outerThroughHoleRings;
m_outerThroughHoleRings = nullptr;
delete m_vias;
m_vias = nullptr;
delete m_padHoles;
m_padHoles = nullptr;
DELETE_AND_FREE( m_vias )
DELETE_AND_FREE( m_padHoles )
}
void RENDER_3D_OPENGL::renderSolderMaskLayer( PCB_LAYER_ID aLayerID, float aZPos,
bool aDrawMiddleSegments, bool aSkipRenderHoles )
bool aShowThickness, bool aSkipRenderHoles )
{
wxASSERT( (aLayerID == B_Mask) || (aLayerID == F_Mask) );
@ -932,7 +912,7 @@ void RENDER_3D_OPENGL::renderSolderMaskLayer( PCB_LAYER_ID aLayerID, float aZPos
setLayerMaterial( aLayerID );
m_board->SetItIsTransparent( true );
m_board->DrawAllCameraCulled( aDrawMiddleSegments, solder_mask, via_holes );
m_board->DrawCulled( aShowThickness, solder_mask, via_holes );
}
}

View File

@ -101,7 +101,7 @@ private:
void addObjectTriangles( const ROUND_SEGMENT_2D* aSeg, TRIANGLE_DISPLAY_LIST* aDstLayer,
float aZtop, float aZbot );
void renderSolderMaskLayer( PCB_LAYER_ID aLayerID, float aZPos, bool aDrawMiddleSegments,
void renderSolderMaskLayer( PCB_LAYER_ID aLayerID, float aZPos, bool aShowThickness,
bool aSkipRenderHoles );
void renderBoardBody( bool aSkipRenderHoles );
@ -211,6 +211,8 @@ private:
MAP_OGL_DISP_LISTS m_layers;
OPENGL_RENDER_LIST* m_platedPadsFront;
OPENGL_RENDER_LIST* m_platedPadsBack;
OPENGL_RENDER_LIST* m_offboardPadsFront;
OPENGL_RENDER_LIST* m_offboardPadsBack;
MAP_OGL_DISP_LISTS m_outerLayerHoles;
MAP_OGL_DISP_LISTS m_innerLayerHoles;
OPENGL_RENDER_LIST* m_board;

View File

@ -366,8 +366,7 @@ void APPEARANCE_CONTROLS_3D::OnLayerVisibilityChanged( int aLayer, bool isVisibl
UpdateLayerCtls();
if( doFastRefresh
&& m_frame->GetAdapter().m_Cfg->m_Render.engine == RENDER_ENGINE::OPENGL )
if( doFastRefresh && m_frame->GetAdapter().m_Cfg->m_Render.engine == RENDER_ENGINE::OPENGL )
{
RENDER_3D_OPENGL* renderer =
static_cast<RENDER_3D_OPENGL*>( m_frame->GetCanvas()->GetCurrentRender() );
@ -375,7 +374,9 @@ void APPEARANCE_CONTROLS_3D::OnLayerVisibilityChanged( int aLayer, bool isVisibl
m_frame->GetCanvas()->Request_refresh();
}
else
{
m_frame->NewDisplay( true );
}
}