KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_ee_item.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 The KiCad Developers, see AUTHORS.TXT for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, you may find one here:
18 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19 * or you may search the http://www.gnu.org website for the version 2 license,
20 * or you may write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
24#include <properties/property.h>
26#include <eda_item_test_utils.h>
27#include <core/typeinfo.h>
28
29#include <eda_item.h>
30#include <sch_item.h>
31
32#include <sch_marker.h>
33#include <sch_junction.h>
34#include <sch_no_connect.h>
35#include <sch_bus_entry.h>
36#include <sch_line.h>
37#include <sch_rule_area.h>
38#include <sch_shape.h>
39#include <sch_bitmap.h>
40#include <sch_text.h>
41#include <sch_label.h>
42#include <sch_textbox.h>
43#include <sch_table.h>
44#include <sch_tablecell.h>
45#include <sch_field.h>
46#include <sch_group.h>
47#include <sch_symbol.h>
48#include <sch_sheet_pin.h>
49#include <sch_sheet.h>
50#include <sch_pin.h>
51
52#include <erc/erc_settings.h>
54
56{
57public:
62 std::shared_ptr<ERC_ITEM> m_ercItem;
63
65 m_sheet(),
66 m_symbol( "test symbol" ),
67 m_pin( &m_symbol ),
69 {
70 m_sheet.SetPosition( VECTOR2I( schIUScale.mmToIU( 5 ), schIUScale.mmToIU( 10 ) ) );
71 m_sheet.SetSize( VECTOR2I( schIUScale.mmToIU( 50 ), schIUScale.mmToIU( 100 ) ) );
72 }
73
75 {
76 m_text.SetParentGroup( nullptr );
77 }
78
80 {
81 if( !IsEeschemaType( aType ) )
82 return nullptr;
83
84 if( !IsInstantiableType( aType ) )
85 return nullptr;
86
87 switch( aType )
88 {
89 case SCH_MARKER_T: return new SCH_MARKER( m_ercItem, VECTOR2I( 0, 0 ) );
90 case SCH_JUNCTION_T: return new SCH_JUNCTION();
91 case SCH_NO_CONNECT_T: return new SCH_NO_CONNECT();
93 case SCH_BUS_BUS_ENTRY_T: return new SCH_BUS_BUS_ENTRY();
94 case SCH_LINE_T: return new SCH_LINE();
95
96 case SCH_RULE_AREA_T:
97 {
98 SHAPE_POLY_SET ruleShape;
99
100 ruleShape.NewOutline();
101 auto& outline = ruleShape.Outline( 0 );
102 outline.Append( VECTOR2I( 20000, 20000) );
103 outline.Append( VECTOR2I( 22000, 20000) );
104 outline.Append( VECTOR2I( 22000, 22000) );
105 outline.Append( VECTOR2I( 20000, 22000) );
106 outline.SetClosed( true );
107 outline.Simplify( true );
108
109 SCH_RULE_AREA* ruleArea = new SCH_RULE_AREA();
110 ruleArea->SetPolyShape( ruleShape );
111
112 return ruleArea;
113 }
114
115 case SCH_SHAPE_T: return new SCH_SHAPE( SHAPE_T::ARC, LAYER_NOTES );
116 case SCH_BITMAP_T: return new SCH_BITMAP();
117 case SCH_TEXT_T: return new SCH_TEXT( VECTOR2I( 0, 0 ), "test text" );
118 case SCH_TEXTBOX_T: return new SCH_TEXTBOX( LAYER_NOTES, 0, FILL_T::NO_FILL, "test textbox" );
119 case SCH_TABLECELL_T: return new SCH_TABLECELL();
120
121 case SCH_TABLE_T:
122 {
123 SCH_TABLE* table = new SCH_TABLE( schIUScale.mmToIU( 0.1 ) );
124
125 table->SetColCount( 2 );
126
127 for( int ii = 0; ii < 4; ++ii )
128 table->InsertCell( ii, new SCH_TABLECELL() );
129
130 return table;
131 }
132
133 case SCH_LABEL_T: return new SCH_LABEL( VECTOR2I( 0, 0 ), "test label" );
134 case SCH_DIRECTIVE_LABEL_T: return new SCH_DIRECTIVE_LABEL( VECTOR2I( 0, 0 ) );
135 case SCH_GLOBAL_LABEL_T: return new SCH_GLOBALLABEL();
136 case SCH_HIER_LABEL_T: return new SCH_HIERLABEL();
137 case SCH_FIELD_T: return new SCH_FIELD( nullptr, FIELD_T::USER );
138 case SCH_SYMBOL_T: return new SCH_SYMBOL();
139
140 case SCH_SHEET_PIN_T:
141 // XXX: m_sheet pins currently have to have their initial positions calculated manually.
142 return new SCH_SHEET_PIN( &m_sheet,
143 VECTOR2I( m_sheet.GetPosition().x,
144 m_sheet.GetPosition().y + schIUScale.mmToIU( 40 ) ),
145 "test aPin" );
146
147 case SCH_SHEET_T: return new SCH_SHEET();
148 case SCH_PIN_T: return new SCH_PIN( &m_symbol );
149
150 case SCH_GROUP_T:
151 {
152 SCH_GROUP* group = new SCH_GROUP();
153
154 // Group position only makes sense if there's at least one item in the group.
155 group->AddItem( &m_text );
156
157 return group;
158 }
159
160 case SCHEMATIC_T:
161 case LIB_SYMBOL_T: return nullptr;
162
163 default:
164 BOOST_FAIL( wxString::Format(
165 "Unhandled type: %d "
166 "(if you created a new type you need to handle it in this switch statement)",
167 aType ) );
168 return nullptr;
169 }
170 }
171
172 static void CompareItems( EDA_ITEM* aItem, EDA_ITEM* aOriginalItem )
173 {
174 BOOST_CHECK_EQUAL( aItem->GetPosition(), aOriginalItem->GetPosition() );
176 aOriginalItem->GetBoundingBox().GetTop() );
178 aOriginalItem->GetBoundingBox().GetLeft() );
180 aOriginalItem->GetBoundingBox().GetBottom() );
182 aOriginalItem->GetBoundingBox().GetRight() );
183 }
184};
185
186
187BOOST_FIXTURE_TEST_SUITE( EeItem, TEST_EE_ITEM_FIXTURE )
188
189
191{
192 for( int i = 0; i < MAX_STRUCT_TYPE_ID; i++ )
193 {
194 KICAD_T type = static_cast<KICAD_T>( i );
195
196 auto item = std::unique_ptr<EDA_ITEM>( Instantiate( type ) );
197
198 if( item == nullptr )
199 continue;
200
201 BOOST_TEST_CONTEXT( "Class: " << item->GetClass() )
202 {
204 item.get(),
205 []( EDA_ITEM* aOriginalItem, VECTOR2I aRef )
206 {
207 auto item = std::unique_ptr<EDA_ITEM>( aOriginalItem->Clone() );
208 VECTOR2I originalPos = item->GetPosition();
209
210 SCH_ITEM* schItem = dynamic_cast<SCH_ITEM*>( item.get() );
211
212 // Move to a point, then go back.
213 // This has to be an identity transformation.
214
215 if( schItem != nullptr )
216 {
217 schItem->Move( aRef );
218 BOOST_CHECK_EQUAL( schItem->GetPosition(), originalPos + aRef );
219
220 schItem->Move( -aRef );
221 }
222
223 CompareItems( item.get(), aOriginalItem );
224 } );
225 }
226 }
227}
228
229
231{
232 for( int i = 0; i < MAX_STRUCT_TYPE_ID; i++ )
233 {
234 KICAD_T type = static_cast<KICAD_T>( i );
235
236 auto item = std::unique_ptr<EDA_ITEM>( Instantiate( type ) );
237
238 if( item == nullptr )
239 continue;
240
241 BOOST_TEST_CONTEXT( "Class: " << item->GetClass() )
242 {
243 // Four equivalent 90 degree rotations are an identity.
244 // (warning: only for items having no autoplaced fields).
245
246 if( item->GetClass() == "SCH_SHEET_PIN" )
247 {
248 auto newItem = std::unique_ptr<EDA_ITEM>( item->Clone() );
249
250 SCH_ITEM* schItem = dynamic_cast<SCH_ITEM*>( newItem.get() );
251
252 if( schItem != nullptr )
253 {
255 // Only rotating pins around the center of parent sheet works.
256 schItem->Rotate( m_sheet.GetBodyBoundingBox().GetCenter(), false );
257 schItem->Rotate( m_sheet.GetBodyBoundingBox().GetCenter(), false );
258 schItem->Rotate( m_sheet.GetBodyBoundingBox().GetCenter(), false );
259 schItem->Rotate( m_sheet.GetBodyBoundingBox().GetCenter(), false );
260 }
261
262 CompareItems( newItem.get(), item.get() );
263 }
264 else
265 {
267 item.get(),
268 []( EDA_ITEM* aOriginalItem, VECTOR2I aRef )
269 {
270 auto item = std::unique_ptr<EDA_ITEM>( aOriginalItem->Clone() );
271
272 SCH_ITEM* schItem = dynamic_cast<SCH_ITEM*>( item.get() );
273
274 if( schItem != nullptr )
275 {
276 schItem->SetFieldsAutoplaced( AUTOPLACE_NONE );
277 schItem->Rotate( aRef, false );
278 schItem->Rotate( aRef, false );
279 schItem->Rotate( aRef, false );
280 schItem->Rotate( aRef, false );
281 }
282
283 CompareItems( item.get(), aOriginalItem );
284 } );
285 }
286 }
287 }
288}
289
290
291BOOST_AUTO_TEST_CASE( MirrorHorizontally )
292{
293 for( int i = 0; i < MAX_STRUCT_TYPE_ID; i++ )
294 {
295 KICAD_T type = static_cast<KICAD_T>( i );
296
297 auto item = std::unique_ptr<EDA_ITEM>( Instantiate( type ) );
298
299 if( item == nullptr )
300 continue;
301
302 BOOST_TEST_CONTEXT( "Class: " << item->GetClass() )
303 {
305 item.get(),
306 []( EDA_ITEM* aOriginalItem, VECTOR2I aRef )
307 {
308 auto item = std::unique_ptr<EDA_ITEM>( aOriginalItem->Clone() );
309
310 SCH_ITEM* schItem = dynamic_cast<SCH_ITEM*>( item.get() );
311
312 // Two mirrorings are an identity
313 // (warning: only for text items having no autoplaced fields).
314 if( schItem != nullptr )
315 {
316 schItem->SetFieldsAutoplaced( AUTOPLACE_NONE );
317 schItem->MirrorHorizontally( aRef.x );
318 schItem->MirrorHorizontally( aRef.x );
319 }
320
321 CompareItems( item.get(), aOriginalItem );
322 } );
323 }
324 }
325}
326
327
328BOOST_AUTO_TEST_CASE( MirrorVertically )
329{
330 for( int i = 0; i < MAX_STRUCT_TYPE_ID; i++ )
331 {
332 KICAD_T type = static_cast<KICAD_T>( i );
333
334 auto item = std::unique_ptr<EDA_ITEM>( Instantiate( type ) );
335
336 if( item == nullptr )
337 continue;
338
339 BOOST_TEST_CONTEXT( "Class: " << item->GetClass() )
340 {
342 item.get(),
343 []( EDA_ITEM* aOriginalItem, VECTOR2I aRef )
344 {
345 auto item = std::unique_ptr<EDA_ITEM>( aOriginalItem->Clone() );
346
347 SCH_ITEM* schItem = dynamic_cast<SCH_ITEM*>( item.get() );
348
349 // Two mirrorings are an identity
350 // (warning only for text items having no autoplaced fields).
351
352 if( schItem != nullptr )
353 {
354 schItem->SetFieldsAutoplaced( AUTOPLACE_NONE );
355 schItem->MirrorVertically( aRef.y );
356 schItem->MirrorVertically( aRef.y );
357 }
358
359 CompareItems( item.get(), aOriginalItem );
360 } );
361 }
362 }
363}
364
constexpr EDA_IU_SCALE schIUScale
Definition base_units.h:127
constexpr coord_type GetLeft() const
Definition box2.h:228
constexpr coord_type GetRight() const
Definition box2.h:217
constexpr coord_type GetTop() const
Definition box2.h:229
constexpr coord_type GetBottom() const
Definition box2.h:222
A base class for most all the KiCad significant classes used in schematics and boards.
Definition eda_item.h:100
virtual VECTOR2I GetPosition() const
Definition eda_item.h:279
virtual const BOX2I GetBoundingBox() const
Return the orthogonal bounding box of this object for display purposes.
Definition eda_item.cpp:120
void SetPolyShape(const SHAPE_POLY_SET &aShape)
Definition eda_shape.h:423
Define a library symbol object.
Definition lib_symbol.h:83
Object to handle a bitmap image that can be inserted in a schematic.
Definition sch_bitmap.h:40
Class for a bus to bus entry.
Class for a wire to bus entry.
A set of SCH_ITEMs (i.e., without duplicates).
Definition sch_group.h:52
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition sch_item.h:168
void SetFieldsAutoplaced(AUTOPLACE_ALGO aAlgo)
Definition sch_item.h:630
virtual void Rotate(const VECTOR2I &aCenter, bool aRotateCCW)
Rotate the item around aCenter 90 degrees in the clockwise direction.
Definition sch_item.h:426
Segment description base class to describe items which have 2 end points (track, wire,...
Definition sch_line.h:42
Define a sheet pin (label) used in sheets to create hierarchical schematics.
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition sch_sheet.h:48
Schematic symbol object.
Definition sch_symbol.h:76
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
Represent a set of closed polygons.
SHAPE_LINE_CHAIN & Outline(int aIndex)
Return the reference to aIndex-th outline in the set.
int NewOutline()
Creates a new empty polygon in the set and returns its index.
EDA_ITEM * Instantiate(KICAD_T aType)
static void CompareItems(EDA_ITEM *aItem, EDA_ITEM *aOriginalItem)
std::shared_ptr< ERC_ITEM > m_ercItem
static void IterateOverPositionsAndReferences(T *aItem, void(*aCallback)(T *, VECTOR2I))
@ NO_FILL
Definition eda_shape.h:64
@ ERCE_DRIVER_CONFLICT
Conflicting drivers (labels, etc) on a subgraph.
@ LAYER_NOTES
Definition layer_ids.h:469
Class to handle a set of SCH_ITEMs.
@ AUTOPLACE_NONE
Definition sch_item.h:70
@ USER
The field ID hasn't been set yet; field is invalid.
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
BOOST_AUTO_TEST_CASE(Move)
BOOST_AUTO_TEST_SUITE_END()
std::vector< std::vector< std::string > > table
BOOST_TEST_CONTEXT("Test Clearance")
BOOST_CHECK_EQUAL(result, "25.4")
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition typeinfo.h:75
@ SCH_GROUP_T
Definition typeinfo.h:174
@ SCH_TABLE_T
Definition typeinfo.h:166
@ SCH_LINE_T
Definition typeinfo.h:164
@ LIB_SYMBOL_T
Definition typeinfo.h:149
@ SCH_NO_CONNECT_T
Definition typeinfo.h:161
@ MAX_STRUCT_TYPE_ID
Definition typeinfo.h:244
@ SCH_SYMBOL_T
Definition typeinfo.h:173
@ SCH_TABLECELL_T
Definition typeinfo.h:167
@ SCH_FIELD_T
Definition typeinfo.h:151
@ SCH_DIRECTIVE_LABEL_T
Definition typeinfo.h:172
@ SCH_LABEL_T
Definition typeinfo.h:168
@ SCH_SHEET_T
Definition typeinfo.h:176
@ SCH_MARKER_T
Definition typeinfo.h:159
@ SCH_SHAPE_T
Definition typeinfo.h:150
@ SCH_RULE_AREA_T
Definition typeinfo.h:171
@ SCH_HIER_LABEL_T
Definition typeinfo.h:170
@ SCH_BUS_BUS_ENTRY_T
Definition typeinfo.h:163
@ SCHEMATIC_T
Definition typeinfo.h:205
@ SCH_SHEET_PIN_T
Definition typeinfo.h:175
@ SCH_TEXT_T
Definition typeinfo.h:152
@ SCH_BUS_WIRE_ENTRY_T
Definition typeinfo.h:162
@ SCH_BITMAP_T
Definition typeinfo.h:165
@ SCH_TEXTBOX_T
Definition typeinfo.h:153
@ SCH_GLOBAL_LABEL_T
Definition typeinfo.h:169
@ SCH_JUNCTION_T
Definition typeinfo.h:160
@ SCH_PIN_T
Definition typeinfo.h:154
constexpr bool IsInstantiableType(const KICAD_T aType)
Definition typeinfo.h:320
constexpr bool IsEeschemaType(const KICAD_T aType)
Definition typeinfo.h:382
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:687