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, you may find one here:
20 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21 * or you may search the http://www.gnu.org website for the version 2 license,
22 * or you may write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24 */
25
26#include "pcb_reference_image.h"
27
28#include <api/api_enums.h>
29#include <api/api_utils.h>
30#include <api/board/board_types.pb.h>
31#include <base_units.h>
32#include <bitmaps.h>
33#include <board.h>
34#include <common.h>
35#include <core/mirror.h>
36#include <eda_draw_frame.h>
37#include <footprint.h>
38#include <pcb_draw_panel_gal.h>
39#include <pcb_painter.h>
40#include <plotters/plotter.h>
42#include <geometry/shape_rect.h>
44#include <trigo.h>
45
46#include <string>
47#include <google/protobuf/any.pb.h>
48#include <properties/property.h>
50
53
54
56 PCB_LAYER_ID aLayer ) :
58{
59 m_referenceImage.SetPosition( aPos );
60}
61
62
67
68
72
73
75{
76 wxCHECK_MSG( Type() == aItem.Type(), *this,
77 wxT( "Cannot assign object type " ) + aItem.GetClass() + wxT( " to type " )
78 + GetClass() );
79
80 if( &aItem != this )
81 {
82 BOARD_ITEM::operator=( aItem );
83 const PCB_REFERENCE_IMAGE& refImg = static_cast<const PCB_REFERENCE_IMAGE&>( aItem );
85 }
86
87 return *this;
88}
89
90
92{
93 wxCHECK( aOther && aOther->Type() == PCB_REFERENCE_IMAGE_T, /* void */ );
94 *this = *static_cast<const PCB_REFERENCE_IMAGE*>( aOther );
95}
96
97
99{
100 return new PCB_REFERENCE_IMAGE( *this );
101}
102
103
105{
106 wxCHECK_RET( aItem->Type() == PCB_REFERENCE_IMAGE_T,
107 wxString::Format( wxT( "% object cannot swap data with %s object." ),
108 GetClass(), aItem->GetClass() ) );
109
111 std::swap( m_layer, item->m_layer );
112 std::swap( m_isKnockout, item->m_isKnockout );
113 std::swap( m_isLocked, item->m_isLocked );
114 std::swap( m_flags, item->m_flags );
115 std::swap( m_parent, item->m_parent );
116 std::swap( m_forceVisible, item->m_forceVisible );
117 m_referenceImage.SwapData( item->m_referenceImage );
118}
119
120
121double PCB_REFERENCE_IMAGE::ViewGetLOD( int aLayer, const KIGFX::VIEW* aView ) const
122{
123 PCB_PAINTER* painter = static_cast<PCB_PAINTER*>( aView->GetPainter() );
124 PCB_RENDER_SETTINGS* renderSettings = painter->GetSettings();
125
126 // All bitmaps are drawn on LAYER_DRAW_BITMAPS, but their
127 // associated board layer controls their visibility.
128 if( !GetBoard()->IsLayerVisible( m_layer ) )
129 return LOD_HIDE;
130
131 if( renderSettings->GetHighContrast()
133 && !renderSettings->GetLayerIsHighContrast( m_layer ) )
134 {
135 return LOD_HIDE;
136 }
137
138 if( aView->IsLayerVisible( LAYER_DRAW_BITMAPS ) )
139 return LOD_SHOW;
140
141 return LOD_HIDE;
142}
143
144
146{
147 return m_referenceImage.GetBoundingBox();
148}
149
150
152 FLASHING aFlash ) const
153{
154 const BOX2I box = GetBoundingBox();
155 return std::make_shared<SHAPE_RECT>( box.GetPosition(), box.GetWidth(), box.GetHeight() );
156}
157
158
160{
161 return m_referenceImage.GetPosition();
162}
163
164
166{
167 m_referenceImage.SetPosition( aPos );
168}
169
170
171void PCB_REFERENCE_IMAGE::Move( const VECTOR2I& aMoveVector )
172{
173 // Defer to SetPosition to check the new position overflow
174 SetPosition( GetPosition() + aMoveVector );
175}
176
177
178void PCB_REFERENCE_IMAGE::Serialize( google::protobuf::Any& aContainer ) const
179{
180 using namespace kiapi::board::types;
181
182 ReferenceImage refImage;
183
184 refImage.mutable_id()->set_value( m_Uuid.AsStdString() );
185 refImage.set_layer( ToProtoEnum<PCB_LAYER_ID, BoardLayer>( m_layer ) );
186 kiapi::common::PackVector2( *refImage.mutable_position(), m_referenceImage.GetPosition() );
187 kiapi::common::PackVector2( *refImage.mutable_transform_origin_offset(),
188 m_referenceImage.GetTransformOriginOffset() );
189
190 refImage.mutable_image_scale()->set_value( m_referenceImage.GetImageScale() );
191 refImage.set_locked( IsLocked() ? kiapi::common::types::LockedState::LS_LOCKED
192 : kiapi::common::types::LockedState::LS_UNLOCKED );
193
194 m_referenceImage.PackToBytes( *refImage.mutable_image_data() );
195
196 aContainer.PackFrom( refImage );
197}
198
199
200bool PCB_REFERENCE_IMAGE::Deserialize( const google::protobuf::Any& aContainer )
201{
202 using namespace kiapi::board::types;
203
204 ReferenceImage refImage;
205
206 if( !aContainer.UnpackTo( &refImage ) )
207 return false;
208
209 SetUuidDirect( KIID( refImage.id().value() ) );
211 SetPosition( kiapi::common::UnpackVector2( refImage.position() ) );
212 m_referenceImage.SetTransformOriginOffset( kiapi::common::UnpackVector2( refImage.transform_origin_offset() ) );
213
214 if( !refImage.image_data().empty() )
215 {
216 if( !m_referenceImage.UnpackFromBytes( refImage.image_data() ) )
217 return false;
218 }
219
220 if( refImage.has_image_scale() )
221 m_referenceImage.SetImageScale( refImage.image_scale().value() );
222
223 SetLocked( refImage.locked() == kiapi::common::types::LockedState::LS_LOCKED );
224 return true;
225}
226
227
228void PCB_REFERENCE_IMAGE::Flip( const VECTOR2I& aCentre, FLIP_DIRECTION aFlipDirection )
229{
230 m_referenceImage.Flip( aCentre, aFlipDirection );
231
232 if( GetBoard() )
234 else
236}
237
238
239void PCB_REFERENCE_IMAGE::Rotate( const VECTOR2I& aCenter, const EDA_ANGLE& aAngle )
240{
241 m_referenceImage.Rotate( aCenter, aAngle );
242}
243
244
245#if defined( DEBUG )
246void PCB_REFERENCE_IMAGE::Show( int nestLevel, std::ostream& os ) const
247{
248 // XML output:
249 wxString s = GetClass();
250
251 NestedSpace( nestLevel, os ) << '<' << s.Lower().mb_str() << m_referenceImage.GetPosition()
252 << "/>\n";
253}
254#endif
255
256
257bool PCB_REFERENCE_IMAGE::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
258{
259 return KIGEOM::BoxHitTest( aPosition, GetBoundingBox(), aAccuracy );
260}
261
262
263bool PCB_REFERENCE_IMAGE::HitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) const
264{
265 return KIGEOM::BoxHitTest( aRect, GetBoundingBox(), aContained, aAccuracy );
266}
267
268
269bool PCB_REFERENCE_IMAGE::HitTest( const SHAPE_LINE_CHAIN& aPoly, bool aContained ) const
270{
271 return KIGEOM::BoxHitTest( aPoly, GetBoundingBox(), aContained );
272}
273
274
279
280
282 std::vector<MSG_PANEL_ITEM>& aList )
283{
284 aList.emplace_back( _( "Reference Image" ), wxEmptyString );
285
286 aList.emplace_back( _( "PPI" ),
287 wxString::Format( wxT( "%d " ), m_referenceImage.GetImage().GetPPI() ) );
288 aList.emplace_back( _( "Scale" ),
289 wxString::Format( wxT( "%f " ), m_referenceImage.GetImageScale() ) );
290
291 aList.emplace_back( _( "Width" ),
292 aFrame->MessageTextFromValue( m_referenceImage.GetSize().x ) );
293 aList.emplace_back( _( "Height" ),
294 aFrame->MessageTextFromValue( m_referenceImage.GetSize().y ) );
295 aList.emplace_back( _( "Layer" ), LayerName( m_layer ) );
296}
297
298
300{
301 return { BITMAP_LAYER_FOR( m_layer ) };
302}
303
304
305bool PCB_REFERENCE_IMAGE::operator==( const BOARD_ITEM& aBoardItem ) const
306{
307 if( aBoardItem.Type() != Type() )
308 return false;
309
310 const PCB_REFERENCE_IMAGE& other = static_cast<const PCB_REFERENCE_IMAGE&>( aBoardItem );
311
312 return *this == other;
313}
314
315
317{
318 if( m_layer != aOther.m_layer )
319 return false;
320
321 if( m_referenceImage != aOther.m_referenceImage )
322 return false;
323
324 return true;
325}
326
327
328double PCB_REFERENCE_IMAGE::Similarity( const BOARD_ITEM& aOther ) const
329{
330 if( aOther.Type() != Type() )
331 return 0.0;
332
333 const PCB_REFERENCE_IMAGE& other = static_cast<const PCB_REFERENCE_IMAGE&>( aOther );
334
335 double similarity = 1.0;
336
337 if( m_layer != other.m_layer )
338 similarity *= 0.9;
339
340 similarity *= m_referenceImage.Similarity( other.m_referenceImage );
341
342 return similarity;
343}
344
345
347{
348 return m_referenceImage.GetTransformOriginOffset().x;
349}
350
351
353{
354 VECTOR2I offset = m_referenceImage.GetTransformOriginOffset();
355 offset.x = aX;
356 m_referenceImage.SetTransformOriginOffset( offset );
357}
358
359
361{
362 return m_referenceImage.GetTransformOriginOffset().y;
363}
364
365
367{
368 VECTOR2I offset = m_referenceImage.GetTransformOriginOffset();
369 offset.y = aY;
370 m_referenceImage.SetTransformOriginOffset( offset );
371}
372
373
375{
376 return m_referenceImage.GetImageScale();
377}
378
379
381{
382 m_referenceImage.SetImageScale( aScale );
383}
384
385
387{
388 return m_referenceImage.GetImage().GetSize().x;
389}
390
391
393{
394 m_referenceImage.SetWidth( aWidth );
395}
396
397
399{
400 return m_referenceImage.GetImage().GetSize().y;
401}
402
403
405{
406 m_referenceImage.SetHeight( aHeight );
407}
408
409
411{
413 {
417
418 propMgr.ReplaceProperty( TYPE_HASH( BOARD_ITEM ), _HKI( "Layer" ),
421
422 const wxString groupImage = _HKI( "Image Properties" );
423
427 groupImage );
428
429 propMgr.AddProperty( new PROPERTY<PCB_REFERENCE_IMAGE, int>( _HKI( "Transform Offset X" ),
433 groupImage );
434
435 propMgr.AddProperty( new PROPERTY<PCB_REFERENCE_IMAGE, int>( _HKI( "Transform Offset Y" ),
439 groupImage );
440
441 propMgr.AddProperty( new PROPERTY<PCB_REFERENCE_IMAGE, int>( _HKI( "Width" ),
444 groupImage );
445
446 propMgr.AddProperty( new PROPERTY<PCB_REFERENCE_IMAGE, int>( _HKI( "Height" ),
449 groupImage );
450
451 // For future use
452 const wxString greyscale = _HKI( "Greyscale" );
453 }
types::KiCadObjectType ToProtoEnum(KICAD_T aValue)
KICAD_T FromProtoEnum(types::KiCadObjectType aValue)
Definition api_enums.cpp:44
constexpr EDA_IU_SCALE pcbIUScale
Definition base_units.h:125
BITMAPS
A list of all bitmap identifiers.
@ HIDDEN
Inactive layers are hidden.
BOX2< VECTOR2I > BOX2I
Definition box2.h:922
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
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition board_item.h:268
void SetUuidDirect(const KIID &aUuid)
Raw UUID assignment.
void SetLocked(bool aLocked) override
Definition board_item.h:359
bool m_isKnockout
Definition board_item.h:491
PCB_LAYER_ID m_layer
Definition board_item.h:490
bool m_isLocked
Definition board_item.h:492
bool IsLocked() const override
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition board_item.h:316
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:103
constexpr const Vec & GetPosition() const
Definition box2.h:211
constexpr size_type GetWidth() const
Definition box2.h:214
constexpr size_type GetHeight() const
Definition box2.h:215
The base class for create windows for drawing purpose.
const KIID m_Uuid
Definition eda_item.h:528
bool m_forceVisible
Definition eda_item.h:545
KICAD_T Type() const
Returns the type of object.
Definition eda_item.h:112
EDA_ITEM_FLAGS m_flags
Definition eda_item.h:539
EDA_ITEM * m_parent
Owner.
Definition eda_item.h:540
EDA_ITEM(EDA_ITEM *parent, KICAD_T idType, bool isSCH_ITEM=false, bool isBOARD_ITEM=false)
Definition eda_item.cpp:41
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:82
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:180
static constexpr double LOD_SHOW
Return this constant from ViewGetLOD() to show the item unconditionally.
Definition view_item.h:185
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
Definition view.h:67
bool IsLayerVisible(int aLayer) const
Return information about visibility of a particular layer.
Definition view.h:431
PAINTER * GetPainter() const
Return the painter object used by the view for drawing #VIEW_ITEMS.
Definition view.h:229
Definition kiid.h:48
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:369
FLASHING
Enum used during connectivity building to ensure we do not query connectivity while building the data...
Definition layer_ids.h:184
@ LAYER_DRAW_BITMAPS
Draw images.
Definition layer_ids.h:284
PCB_LAYER_ID
A quick note on layer IDs:
Definition layer_ids.h:60
FLIP_DIRECTION
Definition mirror.h:27
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:44
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:86
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:687