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 if( m_referenceImage.Flip( aCentre, aFlipDirection ) )
234 {
235 if( GetBoard() )
237 else
239 }
240}
241
242
243void PCB_REFERENCE_IMAGE::Rotate( const VECTOR2I& aCenter, const EDA_ANGLE& aAngle )
244{
245 m_referenceImage.Rotate( aCenter, aAngle );
246}
247
248
249void PCB_REFERENCE_IMAGE::Mirror( const VECTOR2I& aMirrorRef, FLIP_DIRECTION aFlipDirection )
250{
251 // Mirror the content about the axis through aMirrorRef without changing layers.
252 m_referenceImage.Flip( aMirrorRef, aFlipDirection );
253}
254
255
256#if defined( DEBUG )
257void PCB_REFERENCE_IMAGE::Show( int nestLevel, std::ostream& os ) const
258{
259 // XML output:
260 wxString s = GetClass();
261
262 NestedSpace( nestLevel, os ) << '<' << s.Lower().mb_str() << m_referenceImage.GetPosition()
263 << "/>\n";
264}
265#endif
266
267
268bool PCB_REFERENCE_IMAGE::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
269{
270 return KIGEOM::BoxHitTest( aPosition, GetBoundingBox(), aAccuracy );
271}
272
273
274bool PCB_REFERENCE_IMAGE::HitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) const
275{
276 return KIGEOM::BoxHitTest( aRect, GetBoundingBox(), aContained, aAccuracy );
277}
278
279
280bool PCB_REFERENCE_IMAGE::HitTest( const SHAPE_LINE_CHAIN& aPoly, bool aContained ) const
281{
282 return KIGEOM::BoxHitTest( aPoly, GetBoundingBox(), aContained );
283}
284
285
290
291
293 std::vector<MSG_PANEL_ITEM>& aList )
294{
295 aList.emplace_back( _( "Reference Image" ), wxEmptyString );
296
297 aList.emplace_back( _( "PPI" ),
298 wxString::Format( wxT( "%d " ), m_referenceImage.GetImage().GetPPI() ) );
299 aList.emplace_back( _( "Scale" ),
300 wxString::Format( wxT( "%f " ), m_referenceImage.GetImageScale() ) );
301
302 aList.emplace_back( _( "Width" ),
303 aFrame->MessageTextFromValue( m_referenceImage.GetSize().x ) );
304 aList.emplace_back( _( "Height" ),
305 aFrame->MessageTextFromValue( m_referenceImage.GetSize().y ) );
306 aList.emplace_back( _( "Layer" ), LayerName( m_layer ) );
307}
308
309
311{
312 return { BITMAP_LAYER_FOR( m_layer ) };
313}
314
315
316bool PCB_REFERENCE_IMAGE::operator==( const BOARD_ITEM& aBoardItem ) const
317{
318 if( aBoardItem.Type() != Type() )
319 return false;
320
321 const PCB_REFERENCE_IMAGE& other = static_cast<const PCB_REFERENCE_IMAGE&>( aBoardItem );
322
323 return *this == other;
324}
325
326
328{
329 if( m_layer != aOther.m_layer )
330 return false;
331
332 if( m_referenceImage != aOther.m_referenceImage )
333 return false;
334
335 return true;
336}
337
338
339double PCB_REFERENCE_IMAGE::Similarity( const BOARD_ITEM& aOther ) const
340{
341 if( aOther.Type() != Type() )
342 return 0.0;
343
344 const PCB_REFERENCE_IMAGE& other = static_cast<const PCB_REFERENCE_IMAGE&>( aOther );
345
346 double similarity = 1.0;
347
348 if( m_layer != other.m_layer )
349 similarity *= 0.9;
350
351 similarity *= m_referenceImage.Similarity( other.m_referenceImage );
352
353 return similarity;
354}
355
356
358{
359 return m_referenceImage.GetTransformOriginOffset().x;
360}
361
362
364{
365 VECTOR2I offset = m_referenceImage.GetTransformOriginOffset();
366 offset.x = aX;
367 m_referenceImage.SetTransformOriginOffset( offset );
368}
369
370
372{
373 return m_referenceImage.GetTransformOriginOffset().y;
374}
375
376
378{
379 VECTOR2I offset = m_referenceImage.GetTransformOriginOffset();
380 offset.y = aY;
381 m_referenceImage.SetTransformOriginOffset( offset );
382}
383
384
386{
387 return m_referenceImage.GetImageScale();
388}
389
390
392{
393 m_referenceImage.SetImageScale( aScale );
394}
395
396
398{
399 return m_referenceImage.GetImage().GetSize().x;
400}
401
402
404{
405 m_referenceImage.SetWidth( aWidth );
406}
407
408
410{
411 return m_referenceImage.GetImage().GetSize().y;
412}
413
414
416{
417 m_referenceImage.SetHeight( aHeight );
418}
419
420
422{
424 {
428
429 propMgr.ReplaceProperty( TYPE_HASH( BOARD_ITEM ), _HKI( "Layer" ),
432
433 const wxString groupImage = _HKI( "Image Properties" );
434
437 groupImage );
438
439 propMgr.AddProperty( new PROPERTY<PCB_REFERENCE_IMAGE, int>( _HKI( "Transform Offset X" ),
442 groupImage );
443
444 propMgr.AddProperty( new PROPERTY<PCB_REFERENCE_IMAGE, int>( _HKI( "Transform Offset Y" ),
447 groupImage );
448
449 propMgr.AddProperty( new PROPERTY<PCB_REFERENCE_IMAGE, int>( _HKI( "Width" ),
451 groupImage );
452
453 propMgr.AddProperty( new PROPERTY<PCB_REFERENCE_IMAGE, int>( _HKI( "Height" ),
455 groupImage );
456
457 // For future use
458 const wxString greyscale = _HKI( "Greyscale" );
459 }
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:128
BITMAPS
A list of all bitmap identifiers.
@ HIDDEN
Inactive layers are hidden.
BOX2< VECTOR2I > BOX2I
Definition box2.h:914
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:593
void SetUuidDirect(const KIID &aUuid)
Raw UUID assignment.
void SetLocked(bool aLocked) override
Definition board_item.h:418
bool m_isKnockout
Definition board_item.h:587
PCB_LAYER_ID m_layer
Definition board_item.h:586
bool m_isLocked
Definition board_item.h:588
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:599
bool m_forceVisible
Definition eda_item.h:614
KICAD_T Type() const
Returns the type of object.
Definition eda_item.h:110
EDA_ITEM_FLAGS m_flags
Definition eda_item.h:608
std::map< wxString, wxString > m_customProperties
Definition eda_item.h:617
EDA_ITEM * m_parent
Owner.
Definition eda_item.h:609
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:429
PAINTER * GetPainter() const
Return the painter object used by the view for drawing VIEW_ITEM objects.
Definition view.h:227
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
Return the all the layers within the VIEW the object is painted on.
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.
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)
Macro to generate unique identifier for a type.
Definition property.h:74
@ PT_COORD
Coordinate expressed in distance units (mm/inch)
Definition property.h:65
#define REGISTER_TYPE(x)
Helper macro to map type hashes to names.
@ PCB_REFERENCE_IMAGE_T
class PCB_REFERENCE_IMAGE, bitmap on a layer
Definition typeinfo.h:81
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:708