48 TEMP_FILE_HOLDER(
const std::string& aPrefix,
const std::string& aSuffix )
50 std::filesystem::path dir = std::filesystem::temp_directory_path() / aPrefix;
51 std::filesystem::create_directories( dir );
52 m_path = dir / (
"board" + aSuffix );
58 std::filesystem::remove( m_path, ec );
59 std::filesystem::remove( m_path.parent_path(), ec );
62 const std::filesystem::path& Path()
const {
return m_path; }
65 std::filesystem::path m_path;
69int mm(
double aMillimetres )
79 if( prim->GetShape() == aShape )
96 for(
int ii = 0; ii < expOutline.
PointCount(); ++ii )
115 auto board = std::make_unique<BOARD>();
116 auto fp = std::make_unique<FOOTPRINT>( board.get() );
118 fp->SetReference(
"U1" );
122 fp->SetPosition(
VECTOR2I( mm( 50.0 ), mm( 25.0 ) ) );
124 fp->SetTransformScale( 2.0, 1.5 );
126 auto pad = std::make_unique<PAD>( fp.get() );
127 pad->SetNumber(
"1" );
137 bezier->SetStart(
VECTOR2I( mm( 0.0 ), mm( 0.0 ) ) );
138 bezier->SetBezierC1(
VECTOR2I( mm( 1.0 ), mm( 2.0 ) ) );
139 bezier->SetBezierC2(
VECTOR2I( mm( 3.0 ), mm( -1.0 ) ) );
140 bezier->SetEnd(
VECTOR2I( mm( 4.0 ), mm( 0.5 ) ) );
141 bezier->SetWidth( mm( 0.1 ) );
150 chain.SetClosed(
true );
157 poly->SetPolyShape( polySet );
158 poly->SetWidth( mm( 0.1 ) );
162 const VECTOR2I expBezierStart = bezier->GetLibraryStart();
163 const VECTOR2I expBezierC1 = bezier->GetLibraryBezierC1();
164 const VECTOR2I expBezierC2 = bezier->GetLibraryBezierC2();
165 const VECTOR2I expBezierEnd = bezier->GetLibraryEnd();
166 const int expBezierWidth = bezier->GetWidth();
168 const int expPolyWidth = poly->
GetWidth();
173 TEMP_FILE_HOLDER tmp(
"kicad_qa_custom_pad_primitive_roundtrip",
".kicad_pcb" );
179 FOOTPRINT* fpFound = reloaded->Footprints().empty() ? nullptr : reloaded->Footprints().front();
180 BOOST_REQUIRE_MESSAGE( fpFound,
"Footprint not found in reloaded board" );
181 BOOST_REQUIRE_MESSAGE( !fpFound->
Pads().empty(),
"Pad not found in reloaded footprint" );
183 PAD* padFound = fpFound->
Pads().front();
186 BOOST_REQUIRE_MESSAGE( bezierFound,
"Bezier primitive not found in reloaded pad" );
199 BOOST_REQUIRE_MESSAGE( polyFound,
"Polygon primitive not found in reloaded pad" );
209 auto board = std::make_unique<BOARD>();
210 auto fp = std::make_unique<FOOTPRINT>( board.get() );
211 fp->SetReference(
"U1" );
212 fp->SetPosition(
VECTOR2I( mm( 50.0 ), mm( 50.0 ) ) );
213 fp->SetTransformScale( 2.0, 1.5 );
215 auto pad = std::make_unique<PAD>( fp.get() );
216 pad->SetNumber(
"1" );
223 TEMP_FILE_HOLDER tmp(
"kicad_qa_scaled_fp_roundtrip",
".kicad_pcb" );
228 FOOTPRINT* r = reloaded->Footprints().front();
229 BOOST_CHECK_CLOSE( r->
GetScaleX(), 2.0, 1e-6 );
230 BOOST_CHECK_CLOSE( r->
GetScaleY(), 1.5, 1e-6 );
236 auto board = std::make_unique<BOARD>();
237 auto fp = std::make_unique<FOOTPRINT>( board.get() );
238 fp->SetReference(
"U1" );
239 fp->SetPosition(
VECTOR2I( mm( 50.0 ), mm( 50.0 ) ) );
241 fp->SetTransformScale( 2.0, 1.5 );
243 auto pad = std::make_unique<PAD>( fp.get() );
244 pad->SetNumber(
"1" );
249 pad->SetPosition(
VECTOR2I( mm( 53.0 ), mm( 51.0 ) ) );
258 TEMP_FILE_HOLDER tmp(
"kicad_qa_pad_pos_orient_roundtrip",
".kicad_pcb" );
263 PAD* r = reloaded->Footprints().front()->Pads().front();
272 auto board = std::make_unique<BOARD>();
273 auto fp = std::make_unique<FOOTPRINT>( board.get() );
274 fp->SetReference(
"U1" );
275 fp->SetPosition(
VECTOR2I( mm( 50.0 ), mm( 50.0 ) ) );
276 fp->SetTransformScale( 2.0, 1.5 );
278 auto pad = std::make_unique<PAD>( fp.get() );
279 pad->SetNumber(
"1" );
291 TEMP_FILE_HOLDER tmp(
"kicad_qa_pad_delta_roundtrip",
".kicad_pcb" );
296 PAD* r = reloaded->Footprints().front()->Pads().front();
307 auto board = std::make_unique<BOARD>();
308 auto fp = std::make_unique<FOOTPRINT>( board.get() );
309 fp->SetReference(
"U1" );
310 fp->SetPosition(
VECTOR2I( mm( 50.0 ), mm( 50.0 ) ) );
311 fp->SetTransformScale( 2.0, 1.5 );
313 auto pad = std::make_unique<PAD>( fp.get() );
314 pad->SetNumber(
"1" );
326 TEMP_FILE_HOLDER tmp(
"kicad_qa_pad_offset_roundtrip",
".kicad_pcb" );
331 PAD* r = reloaded->Footprints().front()->Pads().front();
342 auto board = std::make_unique<BOARD>();
343 auto fp = std::make_unique<FOOTPRINT>( board.get() );
344 fp->SetReference(
"U1" );
345 fp->SetPosition(
VECTOR2I( mm( 50.0 ), mm( 50.0 ) ) );
347 fp->SetTransformScale( 2.0, 1.5 );
349 auto pt = std::make_unique<PCB_POINT>( fp.get() );
350 pt->SetLayer(
F_Cu );
351 pt->SetPosition(
VECTOR2I( mm( 55.0 ), mm( 52.0 ) ) );
358 TEMP_FILE_HOLDER tmp(
"kicad_qa_fp_point_roundtrip",
".kicad_pcb" );
363 FOOTPRINT* r = reloaded->Footprints().front();
375 auto board = std::make_unique<BOARD>();
376 auto fp = std::make_unique<FOOTPRINT>( board.get() );
377 fp->SetReference(
"U1" );
378 fp->SetPosition(
VECTOR2I( mm( 50.0 ), mm( 50.0 ) ) );
379 fp->SetTransformScale( 2.0, 1.5 );
381 auto pad = std::make_unique<PAD>( fp.get() );
382 pad->SetNumber(
"1" );
394 TEMP_FILE_HOLDER tmp(
"kicad_qa_rotated_pad_roundtrip",
".kicad_pcb" );
399 PAD* r = reloaded->Footprints().front()->Pads().front();
415 auto makePad = [&](
const EDA_ANGLE& aRelOrient )
422 pad->SetOrientation( aRelOrient );
constexpr EDA_IU_SCALE pcbIUScale
General utilities for PCB file IO for QA programs.
Information pertinent to a Pcbnew printed circuit board.
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
constexpr size_type GetWidth() const
bool IsPolyShapeValid() const
LSET is a set of PCB_LAYER_IDs.
static constexpr PCB_LAYER_ID ALL_LAYERS
! Temporary layer identifier to identify code that is not padstack-aware
const std::vector< std::shared_ptr< PCB_SHAPE > > & GetPrimitives(PCB_LAYER_ID aLayer) const
Accessor to the basic shape list for custom-shaped pads.
const BOX2I GetBoundingBox() const override
The bounding box is cached, so this will be efficient most of the time.
const VECTOR2I & GetDelta(PCB_LAYER_ID aLayer) const
VECTOR2I GetPosition() const override
VECTOR2I GetOffset(PCB_LAYER_ID aLayer) const
VECTOR2I GetSize(PCB_LAYER_ID aLayer) const
EDA_ANGLE GetOrientation() const
Return the rotation angle of the pad.
A PCB_POINT is a 0-dimensional point that is used to mark a position on a PCB, or more usually a foot...
VECTOR2I GetPosition() const override
VECTOR2I GetLibraryBezierC1() const
int GetWidth() const override
VECTOR2I GetLibraryEnd() const
VECTOR2I GetLibraryStart() const
SHAPE_POLY_SET GetLibraryPolyShape() const
VECTOR2I GetLibraryBezierC2() const
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
int PointCount() const
Return the number of points (vertices) in this line chain.
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
Represent a set of closed polygons.
int AddOutline(const SHAPE_LINE_CHAIN &aOutline)
Adds a new outline to the set and returns its index.
int OutlineCount() const
Return the number of outlines in the set.
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
virtual int GetWidth() const
static constexpr EDA_ANGLE ANGLE_0
std::unique_ptr< BOARD > ReadBoardFromFileOrStream(const std::string &aFilename, std::istream &aFallback)
Read a board from a file, or another stream, as appropriate.
void DumpBoardToFile(BOARD &board, const std::string &aFilename)
Utility function to simply write a Board out to a file.
@ SMD
Smd pad, appears on the solder paste layer (default)
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
BOOST_AUTO_TEST_CASE(BezierAndPolyOnTransformedFootprint)
A custom pad's bezier and polygon primitives must survive a save/reload unchanged,...
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
BOOST_AUTO_TEST_SUITE_END()
BOOST_TEST_MESSAGE("\n=== Real-World Polygon PIP Benchmark ===\n"<< formatTable(table))
const SHAPE_LINE_CHAIN chain
BOOST_CHECK_EQUAL(result, "25.4")
VECTOR2< int32_t > VECTOR2I