KiCad PCB EDA Suite
Loading...
Searching...
No Matches
pcb_reference_image.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2011 jean-pierre.charras
5 * Copyright (C) 2022 Mike Williams
6 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 */
21
22#include "pcb_reference_image.h"
23
24#include <api/api_enums.h>
25#include <api/api_utils.h>
26#include <api/board/board_types.pb.h>
27#include <base_units.h>
28#include <bitmaps.h>
29#include <board.h>
30#include <common.h>
31#include <core/mirror.h>
32#include <eda_draw_frame.h>
33#include <footprint.h>
34#include <pcb_draw_panel_gal.h>
35#include <pcb_painter.h>
36#include <plotters/plotter.h>
38#include <geometry/shape_rect.h>
40#include <trigo.h>
41
42#include <string>
43#include <google/protobuf/any.pb.h>
44#include <properties/property.h>
46
49
50
52 PCB_LAYER_ID aLayer ) :
54{
55 m_referenceImage.SetPosition( aPos );
56}
57
58
63
64
68
69
71{
72 wxCHECK_MSG( Type() == aItem.Type(), *this,
73 wxT( "Cannot assign object type " ) + aItem.GetClass() + wxT( " to type " )
74 + GetClass() );
75
76 if( &aItem != this )
77 {
78 BOARD_ITEM::operator=( aItem );
79 const PCB_REFERENCE_IMAGE& refImg = static_cast<const PCB_REFERENCE_IMAGE&>( aItem );
81 }
82
83 return *this;
84}
85
86
88{
89 wxCHECK( aOther && aOther->Type() == PCB_REFERENCE_IMAGE_T, /* void */ );
90 *this = *static_cast<const PCB_REFERENCE_IMAGE*>( aOther );
91}
92
93
95{
96 return new PCB_REFERENCE_IMAGE( *this );
97}
98
99
101{
102 wxCHECK_RET( aItem->Type() == PCB_REFERENCE_IMAGE_T,
103 wxString::Format( wxT( "% object cannot swap data with %s object." ),
104 GetClass(), aItem->GetClass() ) );
105
107 std::swap( m_layer, item->m_layer );
108 std::swap( m_isKnockout, item->m_isKnockout );
109 std::swap( m_isLocked, item->m_isLocked );
110 std::swap( m_flags, item->m_flags );
111 std::swap( m_parent, item->m_parent );
112 std::swap( m_forceVisible, item->m_forceVisible );
113 std::swap( m_customProperties, item->m_customProperties );
114 m_referenceImage.SwapData( item->m_referenceImage );
115}
116
117
118double PCB_REFERENCE_IMAGE::ViewGetLOD( int aLayer, const KIGFX::VIEW* aView ) const
119{
120 PCB_PAINTER* painter = static_cast<PCB_PAINTER*>( aView->GetPainter() );
121 PCB_RENDER_SETTINGS* renderSettings = painter->GetSettings();
122
123 // All bitmaps are drawn on LAYER_DRAW_BITMAPS, but their
124 // associated board layer controls their visibility.
125 if( !GetBoard()->IsLayerVisible( m_layer ) )
126 return LOD_HIDE;
127
128 if( renderSettings->GetHighContrast()
130 && !renderSettings->GetLayerIsHighContrast( m_layer ) )
131 {
132 return LOD_HIDE;
133 }
134
135 if( aView->IsLayerVisible( LAYER_DRAW_BITMAPS ) )
136 return LOD_SHOW;
137
138 return LOD_HIDE;
139}
140
141
143{
144 return m_referenceImage.GetBoundingBox();
145}
146
147
149{
150 const BOX2I box = GetBoundingBox();
151 return std::make_shared<SHAPE_RECT>( box.GetPosition(), box.GetWidth(), box.GetHeight() );
152}
153
154
156{
157 return m_referenceImage.GetPosition();
158}
159
160
162{
163 m_referenceImage.SetPosition( aPos );
164}
165
166
167void PCB_REFERENCE_IMAGE::Move( const VECTOR2I& aMoveVector )
168{
169 // Defer to SetPosition to check the new position overflow
170 SetPosition( GetPosition() + aMoveVector );
171}
172
173
174void PCB_REFERENCE_IMAGE::Serialize( google::protobuf::Any& aContainer ) const
175{
176 using namespace kiapi::board::types;
177
178 ReferenceImage refImage;
179
180 refImage.mutable_id()->set_value( m_Uuid.AsStdString() );
181 refImage.set_layer( ToProtoEnum<PCB_LAYER_ID, BoardLayer>( m_layer ) );
182 kiapi::common::PackVector2( *refImage.mutable_position(), m_referenceImage.GetPosition() );
183 kiapi::common::PackVector2( *refImage.mutable_transform_origin_offset(),
184 m_referenceImage.GetTransformOriginOffset() );
185
186 refImage.mutable_image_scale()->set_value( m_referenceImage.GetImageScale() );
187 refImage.set_locked( IsLocked() ? kiapi::common::types::LockedState::LS_LOCKED
188 : kiapi::common::types::LockedState::LS_UNLOCKED );
189
190 if( FOOTPRINT* parent = GetParentFootprint() )
191 refImage.mutable_parent()->set_value( parent->m_Uuid.AsStdString() );
192 else if( const BOARD* board = GetBoard() )
193 refImage.mutable_parent()->set_value( board->m_Uuid.AsStdString() );
194
195 m_referenceImage.PackToBytes( *refImage.mutable_image_data() );
196
197 kiapi::common::PackCustomProperties( refImage.mutable_custom_properties(), *this );
198 aContainer.PackFrom( refImage );
199}
200
201
202bool PCB_REFERENCE_IMAGE::Deserialize( const google::protobuf::Any& aContainer )
203{
204 using namespace kiapi::board::types;
205
206 ReferenceImage refImage;
207
208 if( !aContainer.UnpackTo( &refImage ) )
209 return false;
210
211 SetUuidDirect( KIID( refImage.id().value() ) );
213 SetPosition( kiapi::common::UnpackVector2( refImage.position() ) );
214 m_referenceImage.SetTransformOriginOffset( kiapi::common::UnpackVector2( refImage.transform_origin_offset() ) );
215
216 if( !refImage.image_data().empty() )
217 {
218 if( !m_referenceImage.UnpackFromBytes( refImage.image_data() ) )
219 return false;
220 }
221
222 if( refImage.has_image_scale() )
223 m_referenceImage.SetImageScale( refImage.image_scale().value() );
224
225 SetLocked( refImage.locked() == kiapi::common::types::LockedState::LS_LOCKED );
226 kiapi::common::UnpackCustomProperties( refImage.custom_properties(), *this );
227 return true;
228}
229
230
231void PCB_REFERENCE_IMAGE::Flip( const VECTOR2I& aCentre, FLIP_DIRECTION aFlipDirection )
232{
233 m_referenceImage.Flip( aCentre, aFlipDirection );
234
235 if( GetBoard() )
237 else
239}
240
241
242void PCB_REFERENCE_IMAGE::Rotate( const VECTOR2I& aCenter, const EDA_ANGLE& aAngle )
243{
244 m_referenceImage.Rotate( aCenter, aAngle );
245}
246
247
248void PCB_REFERENCE_IMAGE::Mirror( const VECTOR2I& aMirrorRef, FLIP_DIRECTION aFlipDirection )
249{
250 // Mirror the content about the axis through aMirrorRef without changing layers.
251 m_referenceImage.Flip( aMirrorRef, aFlipDirection );
252}
253
254
255#if defined( DEBUG )
256void PCB_REFERENCE_IMAGE::Show( int nestLevel, std::ostream& os ) const
257{
258 // XML output:
259 wxString s = GetClass();
260
261 NestedSpace( nestLevel, os ) << '<' << s.Lower().mb_str() << m_referenceImage.GetPosition()
262 << "/>\n";
263}
264#endif
265
266
267bool PCB_REFERENCE_IMAGE::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
268{
269 return KIGEOM::BoxHitTest( aPosition, GetBoundingBox(), aAccuracy );
270}
271
272
273bool PCB_REFERENCE_IMAGE::HitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) const
274{
275 return KIGEOM::BoxHitTest( aRect, GetBoundingBox(), aContained, aAccuracy );
276}
277
278
279bool PCB_REFERENCE_IMAGE::HitTest( const SHAPE_LINE_CHAIN& aPoly, bool aContained ) const
280{
281 return KIGEOM::BoxHitTest( aPoly, GetBoundingBox(), aContained );
282}
283
284
289
290
292 std::vector<MSG_PANEL_ITEM>& aList )
293{
294 aList.emplace_back( _( "Reference Image" ), wxEmptyString );
295
296 aList.emplace_back( _( "PPI" ),
297 wxString::Format( wxT( "%d " ), m_referenceImage.GetImage().GetPPI() ) );
298 aList.emplace_back( _( "Scale" ),
299 wxString::Format( wxT( "%f " ), m_referenceImage.GetImageScale() ) );
300
301 aList.emplace_back( _( "Width" ),
302 aFrame->MessageTextFromValue( m_referenceImage.GetSize().x ) );
303 aList.emplace_back( _( "Height" ),
304 aFrame->MessageTextFromValue( m_referenceImage.GetSize().y ) );
305 aList.emplace_back( _( "Layer" ), LayerName( m_layer ) );
306}
307
308
310{
311 return { BITMAP_LAYER_FOR( m_layer ) };
312}
313
314
315bool PCB_REFERENCE_IMAGE::operator==( const BOARD_ITEM& aBoardItem ) const
316{
317 if( aBoardItem.Type() != Type() )
318 return false;
319
320 const PCB_REFERENCE_IMAGE& other = static_cast<const PCB_REFERENCE_IMAGE&>( aBoardItem );
321
322 return *this == other;
323}
324
325
327{
328 if( m_layer != aOther.m_layer )
329 return false;
330
331 if( m_referenceImage != aOther.m_referenceImage )
332 return false;
333
334 return true;
335}
336
337
338double PCB_REFERENCE_IMAGE::Similarity( const BOARD_ITEM& aOther ) const
339{
340 if( aOther.Type() != Type() )
341 return 0.0;
342
343 const PCB_REFERENCE_IMAGE& other = static_cast<const PCB_REFERENCE_IMAGE&>( aOther );
344
345 double similarity = 1.0;
346
347 if( m_layer != other.m_layer )
348 similarity *= 0.9;
349
350 similarity *= m_referenceImage.Similarity( other.m_referenceImage );
351
352 return similarity;
353}
354
355
357{
358 return m_referenceImage.GetTransformOriginOffset().x;
359}
360
361
363{
364 VECTOR2I offset = m_referenceImage.GetTransformOriginOffset();
365 offset.x = aX;
366 m_referenceImage.SetTransformOriginOffset( offset );
367}
368
369
371{
372 return m_referenceImage.GetTransformOriginOffset().y;
373}
374
375
377{
378 VECTOR2I offset = m_referenceImage.GetTransformOriginOffset();
379 offset.y = aY;
380 m_referenceImage.SetTransformOriginOffset( offset );
381}
382
383
385{
386 return m_referenceImage.GetImageScale();
387}
388
389
391{
392 m_referenceImage.SetImageScale( aScale );
393}
394
395
397{
398 return m_referenceImage.GetImage().GetSize().x;
399}
400
401
403{
404 m_referenceImage.SetWidth( aWidth );
405}
406
407
409{
410 return m_referenceImage.GetImage().GetSize().y;
411}
412
413
415{
416 m_referenceImage.SetHeight( aHeight );
417}
418
419
421{
423 {
427
428 propMgr.ReplaceProperty( TYPE_HASH( BOARD_ITEM ), _HKI( "Layer" ),
431
432 const wxString groupImage = _HKI( "Image Properties" );
433
436 groupImage );
437
438 propMgr.AddProperty( new PROPERTY<PCB_REFERENCE_IMAGE, int>( _HKI( "Transform Offset X" ),
441 groupImage );
442
443 propMgr.AddProperty( new PROPERTY<PCB_REFERENCE_IMAGE, int>( _HKI( "Transform Offset Y" ),
446 groupImage );
447
448 propMgr.AddProperty( new PROPERTY<PCB_REFERENCE_IMAGE, int>( _HKI( "Width" ),
450 groupImage );
451
452 propMgr.AddProperty( new PROPERTY<PCB_REFERENCE_IMAGE, int>( _HKI( "Height" ),
454 groupImage );
455
456 // For future use
457 const wxString greyscale = _HKI( "Greyscale" );
458 }
KICOMMON_API types::KiCadObjectType ToProtoEnum(KICAD_T aValue)
KICOMMON_API KICAD_T FromProtoEnum(types::KiCadObjectType aValue)
Definition api_enums.cpp:55
constexpr EDA_IU_SCALE pcbIUScale
Definition base_units.h:121
BITMAPS
A list of all bitmap identifiers.
@ HIDDEN
Inactive layers are hidden.
BOX2< VECTOR2I > BOX2I
Definition box2.h:927
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition board_item.h:84
BOARD_ITEM(BOARD_ITEM *aParent, KICAD_T idtype, PCB_LAYER_ID aLayer=F_Cu)
Definition board_item.h:86
friend class BOARD
Definition board_item.h:578
void SetUuidDirect(const KIID &aUuid)
Raw UUID assignment.
void SetLocked(bool aLocked) override
Definition board_item.h:417
bool m_isKnockout
Definition board_item.h:572
PCB_LAYER_ID m_layer
Definition board_item.h:571
bool m_isLocked
Definition board_item.h:573
bool IsLocked() const override
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition board_item.h:374
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
FOOTPRINT * GetParentFootprint() const
BOARD_ITEM & operator=(const BOARD_ITEM &aOther)
Definition board_item.h:103
constexpr const Vec & GetPosition() const
Definition box2.h:208
constexpr size_type GetWidth() const
Definition box2.h:211
constexpr size_type GetHeight() const
Definition box2.h:212
The base class for create windows for drawing purpose.
const KIID m_Uuid
Definition eda_item.h:597
bool m_forceVisible
Definition eda_item.h:612
KICAD_T Type() const
Returns the type of object.
Definition eda_item.h:110
EDA_ITEM_FLAGS m_flags
Definition eda_item.h:606
std::map< wxString, wxString > m_customProperties
Definition eda_item.h:615
EDA_ITEM * m_parent
Owner.
Definition eda_item.h:607
EDA_ITEM(EDA_ITEM *parent, KICAD_T idType, bool isSCH_ITEM=false, bool isBOARD_ITEM=false)
Definition eda_item.cpp:84
Contains methods for drawing PCB-specific items.
virtual PCB_RENDER_SETTINGS * GetSettings() override
Return a pointer to current settings that are going to be used when drawing items.
PCB specific render settings.
Definition pcb_painter.h:84
HIGH_CONTRAST_MODE m_ContrastModeDisplay
bool GetLayerIsHighContrast(int aLayerId) const
Return information whether the queried layer is marked as high-contrast.
virtual wxString GetClass() const =0
Return the class name.
static constexpr double LOD_HIDE
Return this constant from ViewGetLOD() to hide the item unconditionally.
Definition view_item.h:176
static constexpr double LOD_SHOW
Return this constant from ViewGetLOD() to show the item unconditionally.
Definition view_item.h:181
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
Definition view.h:63
bool IsLayerVisible(int aLayer) const
Return information about visibility of a particular layer.
Definition view.h:427
PAINTER * GetPainter() const
Return the painter object used by the view for drawing #VIEW_ITEMS.
Definition view.h:225
Definition kiid.h:46
Object to handle a bitmap image that can be inserted in a PCB.
void SetTransformOriginOffsetY(int aY)
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
void swapData(BOARD_ITEM *aItem) override
VECTOR2I GetPosition() const override
Get the position of the image (this is the center of the image).
double Similarity(const BOARD_ITEM &aBoardItem) const override
Return a measure of how likely the other object is to represent the same object.
void Move(const VECTOR2I &aMoveVector) override
Move this object.
virtual std::vector< int > ViewGetLayers() const override
bool HitTest(const VECTOR2I &aPosition, int aAccuracy=0) const override
Test if aPosition is inside or on the boundary of this item.
std::shared_ptr< SHAPE > GetEffectiveShape(PCB_LAYER_ID aLayer=UNDEFINED_LAYER, FLASHING aFlash=FLASHING::DEFAULT, DRC_CONSTRAINT_T aUsage=NULL_CONSTRAINT) const override
Some pad shapes can be complex (rounded/chamfered rectangle), even without considering custom shapes.
void SetTransformOriginOffsetX(int aX)
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
bool operator==(const PCB_REFERENCE_IMAGE &aOther) const
void SetImageScale(double aScale)
double ViewGetLOD(int aLayer, const KIGFX::VIEW *aView) const override
Return the level of detail (LOD) of the item.
wxString GetClass() const override
Return the class name.
void Rotate(const VECTOR2I &aCenter, const EDA_ANGLE &aAngle) override
Rotate this object.
bool Deserialize(const google::protobuf::Any &aContainer) override
Deserializes the given protobuf message into this object.
void SetPosition(const VECTOR2I &aPosition) override
Set the position of the image.
void Flip(const VECTOR2I &aCentre, FLIP_DIRECTION aFlipDirection) override
Flip this object, i.e.
BITMAPS GetMenuImage() const override
Return a pointer to an image to be used in menus.
PCB_REFERENCE_IMAGE(BOARD_ITEM *aParent, const VECTOR2I &pos=VECTOR2I(0, 0), PCB_LAYER_ID aLayer=F_Cu)
void GetMsgPanelInfo(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList) override
Populate aList of MSG_PANEL_ITEM objects with it's internal state for display purposes.
REFERENCE_IMAGE m_referenceImage
void Mirror(const VECTOR2I &aMirrorRef, FLIP_DIRECTION aFlipDirection) override
Mirror this object relative to a given horizontal axis the layer is not changed.
void SetHeight(int aHeight)
PCB_REFERENCE_IMAGE & operator=(const BOARD_ITEM &aItem)
void CopyFrom(const BOARD_ITEM *aOther) override
PROPERTY_BASE & SetIsCopyable(bool aIsCopyable=true)
Definition property.h:359
Provide class metadata.Helper macro to map type hashes to names.
void InheritsAfter(TYPE_ID aDerived, TYPE_ID aBase)
Declare an inheritance relationship between types.
static PROPERTY_MANAGER & Instance()
PROPERTY_BASE & AddProperty(PROPERTY_BASE *aProperty, const wxString &aGroup=wxEmptyString)
Register a property.
PROPERTY_BASE & ReplaceProperty(size_t aBase, const wxString &aName, PROPERTY_BASE *aNew, const wxString &aGroup=wxEmptyString)
Replace an existing property for a specific type.
VECTOR2I GetPosition() const
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
wxString MessageTextFromValue(double aValue, bool aAddUnitLabel=true, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE) const
A lower-precision version of StringFromValue().
DRC_CONSTRAINT_T
Definition drc_rule.h:49
#define _(s)
a few functions useful in geometry calculations.
PCB_LAYER_ID FlipLayer(PCB_LAYER_ID aLayerId, int aCopperLayersCount)
Definition layer_id.cpp:179
wxString LayerName(int aLayer)
Returns the default display name for a given layer.
Definition layer_id.cpp:31
#define BITMAP_LAYER_FOR(boardLayer)
Macros for getting the extra layers for a given board layer.
Definition layer_ids.h:386
FLASHING
Enum used during connectivity building to ensure we do not query connectivity while building the data...
Definition layer_ids.h:180
@ LAYER_DRAW_BITMAPS
Draw images.
Definition layer_ids.h:280
PCB_LAYER_ID
A quick note on layer IDs:
Definition layer_ids.h:56
FLIP_DIRECTION
Definition mirror.h:23
bool BoxHitTest(const VECTOR2I &aHitPoint, const BOX2I &aHittee, int aAccuracy)
Perform a point-to-box hit test.
KICOMMON_API void PackCustomProperties(google::protobuf::RepeatedPtrField< types::CustomProperty > *aOutput, const EDA_ITEM &aItem)
KICOMMON_API VECTOR2I UnpackVector2(const types::Vector2 &aInput, const EDA_IU_SCALE &aScale)
KICOMMON_API void PackVector2(types::Vector2 &aOutput, const VECTOR2I &aInput, const EDA_IU_SCALE &aScale)
KICOMMON_API void UnpackCustomProperties(const google::protobuf::RepeatedPtrField< types::CustomProperty > &aInput, EDA_ITEM &aItem)
#define _HKI(x)
Definition page_info.cpp:40
static struct PCB_REFERENCE_IMAGE_DESC _PCB_REFERENCE_IMAGE_DESC
#define TYPE_HASH(x)
Definition property.h:74
@ PT_COORD
Coordinate expressed in distance units (mm/inch)
Definition property.h:65
#define REGISTER_TYPE(x)
@ PCB_REFERENCE_IMAGE_T
class PCB_REFERENCE_IMAGE, bitmap on a layer
Definition typeinfo.h:81
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683