PCB: Add bitmap layer per board layer

This commit is contained in:
Mike Williams 2022-06-27 14:07:52 -04:00
parent 3669cb4673
commit 99f8b21ed1
16 changed files with 142 additions and 34 deletions

View File

@ -157,7 +157,7 @@ PROJECT_LOCAL_SETTINGS::PROJECT_LOCAL_SETTINGS( PROJECT* aProject, const wxStrin
m_params.emplace_back( new PARAM<double>( "board.opacity.vias", &m_ViaOpacity, 1.0 ) );
m_params.emplace_back( new PARAM<double>( "board.opacity.pads", &m_PadOpacity, 1.0 ) );
m_params.emplace_back( new PARAM<double>( "board.opacity.zones", &m_ZoneOpacity, 0.6 ) );
m_params.emplace_back( new PARAM<double>( "board.opacity.background_images", &m_BgImageOpacity, 0.6 ) );
m_params.emplace_back( new PARAM<double>( "board.opacity.images", &m_ImageOpacity, 0.6 ) );
m_params.emplace_back( new PARAM_LIST<wxString>( "board.hidden_nets", &m_HiddenNets, {} ) );

View File

@ -1639,6 +1639,4 @@ void VIEW::ShowPreview( bool aShow )
}
const int VIEW::TOP_LAYER_MODIFIER = -VIEW_MAX_LAYERS;
} // namespace KIGFX

View File

@ -253,14 +253,19 @@ enum GAL_LAYER_ID: int
LAYER_ZONE_START,
LAYER_ZONE_END = LAYER_ZONE_START + PCB_LAYER_ID_COUNT,
/// Virtual layers for background images per board layer
LAYER_BITMAP_START,
LAYER_BITMAP_END = LAYER_BITMAP_START + PCB_LAYER_ID_COUNT,
GAL_LAYER_ID_END
};
/// Use this macro to convert a GAL layer to a 0-indexed offset from LAYER_VIAS
#define GAL_LAYER_INDEX( x ) ( x - GAL_LAYER_ID_START )
/// Macro for getting the zone layer for a given copper layer
#define ZONE_LAYER_FOR( copperLayer ) ( LAYER_ZONE_START + copperLayer )
/// Macros for getting the extra layers for a given board layer
#define BITMAP_LAYER_FOR( boardLayer ) ( LAYER_BITMAP_START + boardLayer )
#define ZONE_LAYER_FOR( boardLayer ) ( LAYER_ZONE_START + boardLayer )
constexpr int GAL_LAYER_ID_COUNT = GAL_LAYER_ID_END - GAL_LAYER_ID_START;

View File

@ -40,7 +40,7 @@ public:
m_ViaOpacity = 1.0;
m_PadOpacity = 1.0;
m_ZoneOpacity = 1.0;
m_BgImageOpacity = 1.0;
m_ImageOpacity = 1.0;
}
/// @see ZONE_DISPLAY_MODE - stored in the project
@ -58,7 +58,7 @@ public:
double m_ViaOpacity; ///< Opacity override for all types of via
double m_PadOpacity; ///< Opacity override for SMD pads and PTHs
double m_ZoneOpacity; ///< Opacity override for filled zone areas
double m_BgImageOpacity; ///< Opacity override for background images
double m_ImageOpacity; ///< Opacity override for user images
};
#endif // PCBSTRUCT_H_

View File

@ -123,7 +123,7 @@ public:
double m_ViaOpacity; ///< Opacity override for all types of via
double m_PadOpacity; ///< Opacity override for SMD pads and PTH
double m_ZoneOpacity; ///< Opacity override for filled zones
double m_BgImageOpacity; ///< Opacity override for filled zones
double m_ImageOpacity; ///< Opacity override for user images
/**
* A list of netnames that have been manually hidden in the board editor.

View File

@ -716,7 +716,11 @@ public:
*/
std::unique_ptr<VIEW> DataReference() const;
static constexpr int VIEW_MAX_LAYERS = 512; ///< maximum number of layers that may be shown
///< Maximum number of layers that may be shown
static constexpr int VIEW_MAX_LAYERS = 512;
///< Rendering order modifier for layers that are marked as top layers.
static constexpr int TOP_LAYER_MODIFIER = -VIEW_MAX_LAYERS;
protected:
struct VIEW_LAYER
@ -862,9 +866,6 @@ protected:
///< Flag to mark targets as dirty so they have to be redrawn on the next refresh event.
bool m_dirtyTargets[TARGETS_NUMBER];
///< Rendering order modifier for layers that are marked as top layers.
static const int TOP_LAYER_MODIFIER;
///< Flag to respect draw priority when drawing items.
bool m_useDrawPriority;

View File

@ -35,6 +35,7 @@
#include <common.h>
#include <eda_draw_frame.h>
#include <core/mirror.h>
#include <board.h>
#include <pcb_bitmap.h>
#include <trigo.h>
#include <geometry/shape_rect.h>
@ -43,12 +44,10 @@
#include <wx/mstream.h>
PCB_BITMAP::PCB_BITMAP( BOARD_ITEM* aParent, const VECTOR2I& pos ) :
BOARD_ITEM( aParent, PCB_BITMAP_T )
PCB_BITMAP::PCB_BITMAP( BOARD_ITEM* aParent, const VECTOR2I& pos, PCB_LAYER_ID aLayer ) :
BOARD_ITEM( aParent, PCB_BITMAP_T, aLayer )
{
m_pos = pos;
m_layer = PCB_LAYER_ID::Dwgs_User; // used only to draw/plot a rectangle,
// when a bitmap cannot be drawn or plotted
m_image = new BITMAP_BASE();
m_image->SetPixelSizeIu( (float) Mils2iu( 1000 ) / m_image->GetPPI() );
}
@ -57,7 +56,6 @@ PCB_BITMAP::PCB_BITMAP( BOARD_ITEM* aParent, const VECTOR2I& pos ) :
PCB_BITMAP::PCB_BITMAP( const PCB_BITMAP& aPCBBitmap ) : BOARD_ITEM( aPCBBitmap )
{
m_pos = aPCBBitmap.m_pos;
m_layer = aPCBBitmap.m_layer;
m_image = new BITMAP_BASE( *aPCBBitmap.m_image );
m_image->SetPixelSizeIu( (float) Mils2iu( 1000 ) / m_image->GetPPI() );
}
@ -109,6 +107,19 @@ void PCB_BITMAP::SwapData( BOARD_ITEM* aItem )
}
double PCB_BITMAP::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const
{
constexpr double HIDE = std::numeric_limits<double>::max();
// All bitmaps are drawn on LAYER_DRAW_BITMAPS, but their
// associated board layer controls their visibility.
if( !GetBoard()->IsLayerVisible( m_layer ) )
return HIDE;
return aView->IsLayerVisible( LAYER_DRAW_BITMAPS ) ? 0.0 : HIDE;
}
const EDA_RECT PCB_BITMAP::GetBoundingBox() const
{
// Bitmaps are center origin, EDA_RECTs need top-left origin
@ -201,11 +212,12 @@ void PCB_BITMAP::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_
aList.emplace_back( _( "Width" ), MessageTextFromValue( aFrame->GetUserUnits(), GetSize().x ) );
aList.emplace_back( _( "Height" ),
MessageTextFromValue( aFrame->GetUserUnits(), GetSize().y ) );
aList.emplace_back( _( "Layer" ), LayerName( m_layer ) );
}
void PCB_BITMAP::ViewGetLayers( int aLayers[], int& aCount ) const
{
aCount = 1;
aLayers[0] = LAYER_DRAW_BITMAPS;
aLayers[0] = BITMAP_LAYER_FOR( m_layer );
}

View File

@ -41,7 +41,8 @@
class PCB_BITMAP : public BOARD_ITEM
{
public:
PCB_BITMAP( BOARD_ITEM* aParent, const VECTOR2I& pos = VECTOR2I( 0, 0 ) );
PCB_BITMAP( BOARD_ITEM* aParent, const VECTOR2I& pos = VECTOR2I( 0, 0 ),
PCB_LAYER_ID aLayer = F_Cu );
PCB_BITMAP( const PCB_BITMAP& aPcbBitmap );
@ -77,6 +78,8 @@ public:
*/
const VECTOR2I GetSize() const;
double ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const override;
const EDA_RECT GetBoundingBox() const override;
std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer = UNDEFINED_LAYER,

View File

@ -136,6 +136,68 @@ const int GAL_LAYER_ORDER[] =
B_CrtYd, ZONE_LAYER_FOR( B_CrtYd ),
B_Fab, ZONE_LAYER_FOR( B_Fab ),
BITMAP_LAYER_FOR( Dwgs_User ),
BITMAP_LAYER_FOR( Cmts_User ),
BITMAP_LAYER_FOR( Eco1_User ), BITMAP_LAYER_FOR( Eco2_User ),
BITMAP_LAYER_FOR( Edge_Cuts ), BITMAP_LAYER_FOR( Margin ),
BITMAP_LAYER_FOR( User_1 ),
BITMAP_LAYER_FOR( User_2 ),
BITMAP_LAYER_FOR( User_3 ),
BITMAP_LAYER_FOR( User_4 ),
BITMAP_LAYER_FOR( User_5 ),
BITMAP_LAYER_FOR( User_6 ),
BITMAP_LAYER_FOR( User_7 ),
BITMAP_LAYER_FOR( User_8 ),
BITMAP_LAYER_FOR( User_9 ),
BITMAP_LAYER_FOR( F_Cu ),
BITMAP_LAYER_FOR( F_Mask ),
BITMAP_LAYER_FOR( F_SilkS ),
BITMAP_LAYER_FOR( F_Paste ),
BITMAP_LAYER_FOR( F_Adhes ),
BITMAP_LAYER_FOR( F_CrtYd ),
BITMAP_LAYER_FOR( F_Fab ),
BITMAP_LAYER_FOR( In1_Cu ),
BITMAP_LAYER_FOR( In2_Cu ),
BITMAP_LAYER_FOR( In3_Cu ),
BITMAP_LAYER_FOR( In4_Cu ),
BITMAP_LAYER_FOR( In5_Cu ),
BITMAP_LAYER_FOR( In6_Cu ),
BITMAP_LAYER_FOR( In7_Cu ),
BITMAP_LAYER_FOR( In8_Cu ),
BITMAP_LAYER_FOR( In9_Cu ),
BITMAP_LAYER_FOR( In10_Cu ),
BITMAP_LAYER_FOR( In11_Cu ),
BITMAP_LAYER_FOR( In12_Cu ),
BITMAP_LAYER_FOR( In13_Cu ),
BITMAP_LAYER_FOR( In14_Cu ),
BITMAP_LAYER_FOR( In15_Cu ),
BITMAP_LAYER_FOR( In16_Cu ),
BITMAP_LAYER_FOR( In17_Cu ),
BITMAP_LAYER_FOR( In18_Cu ),
BITMAP_LAYER_FOR( In19_Cu ),
BITMAP_LAYER_FOR( In20_Cu ),
BITMAP_LAYER_FOR( In21_Cu ),
BITMAP_LAYER_FOR( In22_Cu ),
BITMAP_LAYER_FOR( In23_Cu ),
BITMAP_LAYER_FOR( In24_Cu ),
BITMAP_LAYER_FOR( In25_Cu ),
BITMAP_LAYER_FOR( In26_Cu ),
BITMAP_LAYER_FOR( In27_Cu ),
BITMAP_LAYER_FOR( In28_Cu ),
BITMAP_LAYER_FOR( In29_Cu ),
BITMAP_LAYER_FOR( In30_Cu ),
BITMAP_LAYER_FOR( B_Cu ),
BITMAP_LAYER_FOR( B_Mask ),
BITMAP_LAYER_FOR( B_SilkS ),
BITMAP_LAYER_FOR( B_Paste ),
BITMAP_LAYER_FOR( B_Adhes ),
BITMAP_LAYER_FOR( B_CrtYd ),
BITMAP_LAYER_FOR( B_Fab ),
LAYER_DRAWINGSHEET
};
@ -274,6 +336,7 @@ void PCB_DRAW_PANEL_GAL::SetHighContrastLayer( PCB_LAYER_ID aLayer )
GetNetnameLayer( aLayer ), LAYER_VIA_NETNAMES,
LAYER_PAD_FR_NETNAMES, LAYER_PAD_BK_NETNAMES, LAYER_PAD_NETNAMES,
ZONE_LAYER_FOR( aLayer ),
BITMAP_LAYER_FOR( aLayer ),
LAYER_PADS_TH, LAYER_PAD_PLATEDHOLES, LAYER_PAD_HOLEWALLS, LAYER_NON_PLATEDHOLES,
LAYER_VIA_THROUGH, LAYER_VIA_BBLIND, LAYER_VIA_MICROVIA, LAYER_VIA_HOLES,
LAYER_VIA_HOLEWALLS,
@ -376,6 +439,7 @@ void PCB_DRAW_PANEL_GAL::SetTopLayer( PCB_LAYER_ID aLayer )
m_view->SetTopLayer( GetNetnameLayer( aLayer ) );
}
m_view->SetTopLayer( BITMAP_LAYER_FOR( aLayer ) );
m_view->EnableTopLayer( true );
m_view->UpdateAllLayersOrder();
}
@ -406,6 +470,9 @@ void PCB_DRAW_PANEL_GAL::SyncLayersVisibility( const BOARD* aBoard )
for( int i = LAYER_ZONE_START; i < LAYER_ZONE_END; i++ )
m_view->SetLayerVisible( i, true );
for( int i = LAYER_BITMAP_START; i < LAYER_BITMAP_END; i++ )
m_view->SetLayerVisible( i, true );
// Enable some layers that are GAL specific
m_view->SetLayerVisible( LAYER_PAD_PLATEDHOLES, true );
m_view->SetLayerVisible( LAYER_PAD_HOLEWALLS, true );
@ -501,7 +568,12 @@ void PCB_DRAW_PANEL_GAL::setDefaultLayerOrder()
int layer = GAL_LAYER_ORDER[i];
wxASSERT( layer < KIGFX::VIEW::VIEW_MAX_LAYERS );
m_view->SetLayerOrder( layer, i );
// MW: Gross hack to make SetTopLayer bring the correct bitmap layer to
// the top of the other bitmaps, but still below all the other layers
if( layer < LAYER_BITMAP_START )
m_view->SetLayerOrder( layer, i );
else
m_view->SetLayerOrder( layer, i - KIGFX::VIEW::TOP_LAYER_MODIFIER );
}
}
@ -548,11 +620,15 @@ void PCB_DRAW_PANEL_GAL::setDefaultLayerDeps()
if( IsCopperLayer( layer ) )
{
m_view->SetRequired( ZONE_LAYER_FOR( layer ), layer );
m_view->SetRequired( BITMAP_LAYER_FOR( layer ), layer );
m_view->SetLayerTarget( BITMAP_LAYER_FOR( layer ), KIGFX::TARGET_NONCACHED );
m_view->SetRequired( GetNetnameLayer( layer ), layer );
}
else if( IsNonCopperLayer( layer ) )
{
m_view->SetRequired( ZONE_LAYER_FOR( layer ), layer );
m_view->SetLayerTarget( BITMAP_LAYER_FOR( layer ), KIGFX::TARGET_NONCACHED );
m_view->SetRequired( BITMAP_LAYER_FOR( layer ), layer );
}
else if( IsNetnameLayer( layer ) )
{
@ -560,8 +636,6 @@ void PCB_DRAW_PANEL_GAL::setDefaultLayerDeps()
}
}
m_view->SetLayerTarget( LAYER_DRAW_BITMAPS, KIGFX::TARGET_NONCACHED );
m_view->SetLayerTarget( LAYER_ANCHOR, KIGFX::TARGET_NONCACHED );
m_view->SetLayerDisplayOnly( LAYER_ANCHOR );

View File

@ -77,7 +77,7 @@ PCB_RENDER_SETTINGS::PCB_RENDER_SETTINGS()
m_viaOpacity = 1.0;
m_padOpacity = 1.0;
m_zoneOpacity = 1.0;
m_bgImageOpacity = 1.0;
m_imageOpacity = 1.0;
m_ForcePadSketchModeOff = false;
m_ForcePadSketchModeOn = false;
@ -149,7 +149,7 @@ void PCB_RENDER_SETTINGS::LoadDisplayOptions( const PCB_DISPLAY_OPTIONS& aOption
m_viaOpacity = aOptions.m_ViaOpacity;
m_padOpacity = aOptions.m_PadOpacity;
m_zoneOpacity = aOptions.m_ZoneOpacity;
m_bgImageOpacity = aOptions.m_BgImageOpacity;
m_imageOpacity = aOptions.m_ImageOpacity;
}
@ -345,7 +345,7 @@ COLOR4D PCB_RENDER_SETTINGS::GetColor( const VIEW_ITEM* aItem, int aLayer ) cons
else if( item->Type() == PCB_ZONE_T || item->Type() == PCB_FP_ZONE_T )
color.a *= m_zoneOpacity;
else if( item->Type() == PCB_BITMAP_T )
color.a *= m_bgImageOpacity;
color.a *= m_imageOpacity;
// No special modifiers enabled
return color;
@ -1657,8 +1657,6 @@ void PCB_PAINTER::draw( const PCB_BITMAP* aBitmap, int aLayer )
if( img_scale != 1.0 )
m_gal->Scale( VECTOR2D( img_scale, img_scale ) );
m_gal->DrawBitmap( *aBitmap->GetImage(), m_pcbSettings.m_bgImageOpacity );
if( aBitmap->IsSelected() || aBitmap->IsBrightened() )
{
COLOR4D color = m_pcbSettings.GetColor( aBitmap, LAYER_ANCHOR );
@ -1678,7 +1676,16 @@ void PCB_PAINTER::draw( const PCB_BITMAP* aBitmap, int aLayer )
VECTOR2D end = origin + bm_size;
m_gal->DrawRectangle( origin, end );
// Hard code bitmaps as opaque when selected. Otherwise cached layers
// will not be rendered under the selected bitmap because cached layers
// are rendered after non-cached layers (e.g. bitmaps), which will have
// a closer Z order.
m_gal->DrawBitmap( *aBitmap->GetImage(), 1.0 );
}
else
m_gal->DrawBitmap( *aBitmap->GetImage(), m_pcbSettings.m_imageOpacity );
m_gal->Restore();
}

View File

@ -143,7 +143,7 @@ protected:
double m_viaOpacity; ///< Opacity override for all types of via
double m_padOpacity; ///< Opacity override for SMD pads and PTHs
double m_zoneOpacity; ///< Opacity override for filled zones
double m_bgImageOpacity; ///< Opacity override for background images
double m_imageOpacity; ///< Opacity override for user images
};

View File

@ -106,7 +106,7 @@ bool PCB_EDIT_FRAME::LoadProjectSettings()
opts.m_PadOpacity = localSettings.m_PadOpacity;
opts.m_ZoneOpacity = localSettings.m_ZoneOpacity;
opts.m_ZoneDisplayMode = localSettings.m_ZoneDisplayMode;
opts.m_BgImageOpacity = localSettings.m_BgImageOpacity;
opts.m_ImageOpacity = localSettings.m_ImageOpacity;
// No refresh here: callers of LoadProjectSettings refresh later
SetDisplayOptions( opts, false );
@ -160,7 +160,7 @@ void PCB_EDIT_FRAME::SaveProjectSettings()
localSettings.m_PadOpacity = displayOpts.m_PadOpacity;
localSettings.m_ZoneOpacity = displayOpts.m_ZoneOpacity;
localSettings.m_ZoneDisplayMode = displayOpts.m_ZoneDisplayMode;
localSettings.m_BgImageOpacity = displayOpts.m_BgImageOpacity;
localSettings.m_ImageOpacity = displayOpts.m_ImageOpacity;
// Save Design settings
const BOARD_DESIGN_SETTINGS& bds = GetDesignSettings();

View File

@ -2876,6 +2876,11 @@ PCB_BITMAP* PCB_PARSER::parsePCB_BITMAP( BOARD_ITEM* aParent )
break;
}
case T_layer:
bitmap->SetLayer( parseBoardItemLayer() );
NeedRIGHT();
break;
case T_scale:
bitmap->GetImage()->SetScale( parseDouble( "image scale factor" ) );
@ -2915,7 +2920,7 @@ PCB_BITMAP* PCB_PARSER::parsePCB_BITMAP( BOARD_ITEM* aParent )
}
default:
Expecting( "at, scale, data" );
Expecting( "at, layer, scale, data" );
}
}

View File

@ -1020,6 +1020,8 @@ void PCB_PLUGIN::format( const PCB_BITMAP* aBitmap, int aNestLevel ) const
FormatInternalUnits( aBitmap->GetPosition().x ).c_str(),
FormatInternalUnits( aBitmap->GetPosition().y ).c_str() );
formatLayer( aBitmap->GetLayer() );
if( aBitmap->GetImage()->GetScale() != 1.0 )
m_out->Print( 0, " (scale %g)", aBitmap->GetImage()->GetScale() );

View File

@ -2029,6 +2029,7 @@ bool PCB_SELECTION_TOOL::itemPassesFilter( BOARD_ITEM* aItem, bool aMultiSelect
case PCB_FP_SHAPE_T:
case PCB_SHAPE_T:
case PCB_TARGET_T:
case PCB_BITMAP_T:
if( !m_filter.graphics )
return false;

View File

@ -336,7 +336,7 @@ const APPEARANCE_CONTROLS::APPEARANCE_SETTING APPEARANCE_CONTROLS::s_objectSetti
RR( _HKI( "Vias" ), LAYER_VIAS, _HKI( "Show all vias" ), true ),
RR( _HKI( "Pads" ), LAYER_PADS, _HKI( "Show all pads" ), true ),
RR( _HKI( "Zones" ), LAYER_ZONES, _HKI( "Show copper zones" ), true ),
RR( _HKI( "Background Images" ), LAYER_DRAW_BITMAPS, _HKI( "Show user background images" ), true ),
RR( _HKI( "Images" ), LAYER_DRAW_BITMAPS, _HKI( "Show user images" ), true ),
RR(),
RR( _HKI( "Footprints Front" ), LAYER_MOD_FR, _HKI( "Show footprints that are on board's front" ) ),
RR( _HKI( "Footprints Back" ), LAYER_MOD_BK, _HKI( "Show footprints that are on board's back" ) ),
@ -2213,7 +2213,7 @@ void APPEARANCE_CONTROLS::syncObjectSettings()
m_objectSettingsMap[LAYER_VIAS]->ctl_opacity->SetValue( opts.m_ViaOpacity * 100 );
m_objectSettingsMap[LAYER_PADS]->ctl_opacity->SetValue( opts.m_PadOpacity * 100 );
m_objectSettingsMap[LAYER_ZONES]->ctl_opacity->SetValue( opts.m_ZoneOpacity * 100 );
m_objectSettingsMap[LAYER_DRAW_BITMAPS]->ctl_opacity->SetValue( opts.m_BgImageOpacity * 100 );
m_objectSettingsMap[LAYER_DRAW_BITMAPS]->ctl_opacity->SetValue( opts.m_ImageOpacity * 100 );
}
@ -2846,7 +2846,7 @@ void APPEARANCE_CONTROLS::onObjectOpacitySlider( int aLayer, float aOpacity )
case static_cast<int>( LAYER_VIAS ): options.m_ViaOpacity = aOpacity; break;
case static_cast<int>( LAYER_PADS ): options.m_PadOpacity = aOpacity; break;
case static_cast<int>( LAYER_ZONES ): options.m_ZoneOpacity = aOpacity; break;
case static_cast<int>( LAYER_DRAW_BITMAPS ): options.m_BgImageOpacity = aOpacity; break;
case static_cast<int>( LAYER_DRAW_BITMAPS ): options.m_ImageOpacity = aOpacity; break;
default: return;
}