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 m_referenceImage.SwapData( item->m_referenceImage );
114}
115
116
117double PCB_REFERENCE_IMAGE::ViewGetLOD( int aLayer, const KIGFX::VIEW* aView ) const
118{
119 PCB_PAINTER* painter = static_cast<PCB_PAINTER*>( aView->GetPainter() );
120 PCB_RENDER_SETTINGS* renderSettings = painter->GetSettings();
121
122 // All bitmaps are drawn on LAYER_DRAW_BITMAPS, but their
123 // associated board layer controls their visibility.
124 if( !GetBoard()->IsLayerVisible( m_layer ) )
125 return LOD_HIDE;
126
127 if( renderSettings->GetHighContrast()
129 && !renderSettings->GetLayerIsHighContrast( m_layer ) )
130 {
131 return LOD_HIDE;
132 }
133
134 if( aView->IsLayerVisible( LAYER_DRAW_BITMAPS ) )
135 return LOD_SHOW;
136
137 return LOD_HIDE;
138}
139
140
142{
143 return m_referenceImage.GetBoundingBox();
144}
145
146
148 FLASHING aFlash ) const
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 m_referenceImage.PackToBytes( *refImage.mutable_image_data() );
191
192 aContainer.PackFrom( refImage );
193}
194
195
196bool PCB_REFERENCE_IMAGE::Deserialize( const google::protobuf::Any& aContainer )
197{
198 using namespace kiapi::board::types;
199
200 ReferenceImage refImage;
201
202 if( !aContainer.UnpackTo( &refImage ) )
203 return false;
204
205 SetUuidDirect( KIID( refImage.id().value() ) );
207 SetPosition( kiapi::common::UnpackVector2( refImage.position() ) );
208 m_referenceImage.SetTransformOriginOffset( kiapi::common::UnpackVector2( refImage.transform_origin_offset() ) );
209
210 if( !refImage.image_data().empty() )
211 {
212 if( !m_referenceImage.UnpackFromBytes( refImage.image_data() ) )
213 return false;
214 }
215
216 if( refImage.has_image_scale() )
217 m_referenceImage.SetImageScale( refImage.image_scale().value() );
218
219 SetLocked( refImage.locked() == kiapi::common::types::LockedState::LS_LOCKED );
220 return true;
221}
222
223
224void PCB_REFERENCE_IMAGE::Flip( const VECTOR2I& aCentre, FLIP_DIRECTION aFlipDirection )
225{
226 m_referenceImage.Flip( aCentre, aFlipDirection );
227
228 if( GetBoard() )
230 else
232}
233
234
235void PCB_REFERENCE_IMAGE::Rotate( const VECTOR2I& aCenter, const EDA_ANGLE& aAngle )
236{
237 m_referenceImage.Rotate( aCenter, aAngle );
238}
239
240
241#if defined( DEBUG )
242void PCB_REFERENCE_IMAGE::Show( int nestLevel, std::ostream& os ) const
243{
244 // XML output:
245 wxString s = GetClass();
246
247 NestedSpace( nestLevel, os ) << '<' << s.Lower().mb_str() << m_referenceImage.GetPosition()
248 << "/>\n";
249}
250#endif
251
252
253bool PCB_REFERENCE_IMAGE::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
254{
255 return KIGEOM::BoxHitTest( aPosition, GetBoundingBox(), aAccuracy );
256}
257
258
259bool PCB_REFERENCE_IMAGE::HitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) const
260{
261 return KIGEOM::BoxHitTest( aRect, GetBoundingBox(), aContained, aAccuracy );
262}
263
264
265bool PCB_REFERENCE_IMAGE::HitTest( const SHAPE_LINE_CHAIN& aPoly, bool aContained ) const
266{
267 return KIGEOM::BoxHitTest( aPoly, GetBoundingBox(), aContained );
268}
269
270
275
276
278 std::vector<MSG_PANEL_ITEM>& aList )
279{
280 aList.emplace_back( _( "Reference Image" ), wxEmptyString );
281
282 aList.emplace_back( _( "PPI" ),
283 wxString::Format( wxT( "%d " ), m_referenceImage.GetImage().GetPPI() ) );
284 aList.emplace_back( _( "Scale" ),
285 wxString::Format( wxT( "%f " ), m_referenceImage.GetImageScale() ) );
286
287 aList.emplace_back( _( "Width" ),
288 aFrame->MessageTextFromValue( m_referenceImage.GetSize().x ) );
289 aList.emplace_back( _( "Height" ),
290 aFrame->MessageTextFromValue( m_referenceImage.GetSize().y ) );
291 aList.emplace_back( _( "Layer" ), LayerName( m_layer ) );
292}
293
294
296{
297 return { BITMAP_LAYER_FOR( m_layer ) };
298}
299
300
301bool PCB_REFERENCE_IMAGE::operator==( const BOARD_ITEM& aBoardItem ) const
302{
303 if( aBoardItem.Type() != Type() )
304 return false;
305
306 const PCB_REFERENCE_IMAGE& other = static_cast<const PCB_REFERENCE_IMAGE&>( aBoardItem );
307
308 return *this == other;
309}
310
311
313{
314 if( m_layer != aOther.m_layer )
315 return false;
316
317 if( m_referenceImage != aOther.m_referenceImage )
318 return false;
319
320 return true;
321}
322
323
324double PCB_REFERENCE_IMAGE::Similarity( const BOARD_ITEM& aOther ) const
325{
326 if( aOther.Type() != Type() )
327 return 0.0;
328
329 const PCB_REFERENCE_IMAGE& other = static_cast<const PCB_REFERENCE_IMAGE&>( aOther );
330
331 double similarity = 1.0;
332
333 if( m_layer != other.m_layer )
334 similarity *= 0.9;
335
336 similarity *= m_referenceImage.Similarity( other.m_referenceImage );
337
338 return similarity;
339}
340
341
343{
344 return m_referenceImage.GetTransformOriginOffset().x;
345}
346
347
349{
350 VECTOR2I offset = m_referenceImage.GetTransformOriginOffset();
351 offset.x = aX;
352 m_referenceImage.SetTransformOriginOffset( offset );
353}
354
355
357{
358 return m_referenceImage.GetTransformOriginOffset().y;
359}
360
361
363{
364 VECTOR2I offset = m_referenceImage.GetTransformOriginOffset();
365 offset.y = aY;
366 m_referenceImage.SetTransformOriginOffset( offset );
367}
368
369
371{
372 return m_referenceImage.GetImageScale();
373}
374
375
377{
378 m_referenceImage.SetImageScale( aScale );
379}
380
381
383{
384 return m_referenceImage.GetImage().GetSize().x;
385}
386
387
389{
390 m_referenceImage.SetWidth( aWidth );
391}
392
393
395{
396 return m_referenceImage.GetImage().GetSize().y;
397}
398
399
401{
402 m_referenceImage.SetHeight( aHeight );
403}
404
405
407{
409 {
413
414 propMgr.ReplaceProperty( TYPE_HASH( BOARD_ITEM ), _HKI( "Layer" ),
417
418 const wxString groupImage = _HKI( "Image Properties" );
419
423 groupImage );
424
425 propMgr.AddProperty( new PROPERTY<PCB_REFERENCE_IMAGE, int>( _HKI( "Transform Offset X" ),
429 groupImage );
430
431 propMgr.AddProperty( new PROPERTY<PCB_REFERENCE_IMAGE, int>( _HKI( "Transform Offset Y" ),
435 groupImage );
436
437 propMgr.AddProperty( new PROPERTY<PCB_REFERENCE_IMAGE, int>( _HKI( "Width" ),
440 groupImage );
441
442 propMgr.AddProperty( new PROPERTY<PCB_REFERENCE_IMAGE, int>( _HKI( "Height" ),
445 groupImage );
446
447 // For future use
448 const wxString greyscale = _HKI( "Greyscale" );
449 }
types::KiCadObjectType ToProtoEnum(KICAD_T aValue)
KICAD_T FromProtoEnum(types::KiCadObjectType aValue)
Definition api_enums.cpp:47
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:918
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition board_item.h:81
BOARD_ITEM(BOARD_ITEM *aParent, KICAD_T idtype, PCB_LAYER_ID aLayer=F_Cu)
Definition board_item.h:83
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition board_item.h:265
void SetUuidDirect(const KIID &aUuid)
Raw UUID assignment.
void SetLocked(bool aLocked) override
Definition board_item.h:356
bool m_isKnockout
Definition board_item.h:509
PCB_LAYER_ID m_layer
Definition board_item.h:508
bool m_isLocked
Definition board_item.h:510
bool IsLocked() const override
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition board_item.h:313
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
BOARD_ITEM & operator=(const BOARD_ITEM &aOther)
Definition board_item.h:100
constexpr const Vec & GetPosition() const
Definition box2.h:207
constexpr size_type GetWidth() const
Definition box2.h:210
constexpr size_type GetHeight() const
Definition box2.h:211
The base class for create windows for drawing purpose.
const KIID m_Uuid
Definition eda_item.h:531
bool m_forceVisible
Definition eda_item.h:548
KICAD_T Type() const
Returns the type of object.
Definition eda_item.h:108
EDA_ITEM_FLAGS m_flags
Definition eda_item.h:542
EDA_ITEM * m_parent
Owner.
Definition eda_item.h:543
EDA_ITEM(EDA_ITEM *parent, KICAD_T idType, bool isSCH_ITEM=false, bool isBOARD_ITEM=false)
Definition eda_item.cpp:37
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:78
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:44
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.
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.
std::shared_ptr< SHAPE > GetEffectiveShape(PCB_LAYER_ID aLayer=UNDEFINED_LAYER, FLASHING aFlash=FLASHING::DEFAULT) const override
Some pad shapes can be complex (rounded/chamfered rectangle), even without considering custom shapes.
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 SetHeight(int aHeight)
PCB_REFERENCE_IMAGE & operator=(const BOARD_ITEM &aItem)
void CopyFrom(const BOARD_ITEM *aOther) override
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().
The common library.
#define _(s)
a few functions useful in geometry calculations.
PCB_LAYER_ID FlipLayer(PCB_LAYER_ID aLayerId, int aCopperLayersCount)
Definition layer_id.cpp:173
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:365
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 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)
#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:82
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683