34#include <idf_parser.h>
50#define LINE_WIDTH (pcbIUScale.mmToIU( 0.1 ))
62 double scale = aIDFBoard.GetUserScale();
64 std::list< IDF_SEGMENT* > lines;
65 IDF_OUTLINE* outline =
nullptr;
73 aIDFBoard.GetUserOffset( offX, offY );
94 IDF_SEGMENT* seg =
new IDF_SEGMENT( sp, ep );
97 lines.push_back( seg );
112 IDF_POINT corners[4];
113 corners[0] = IDF_POINT(
left,
top );
114 corners[1] = IDF_POINT(
right,
top );
115 corners[2] = IDF_POINT(
right, bottom );
116 corners[3] = IDF_POINT(
left, bottom );
118 lines.push_back(
new IDF_SEGMENT( corners[0], corners[1] ) );
119 lines.push_back(
new IDF_SEGMENT( corners[1], corners[2] ) );
120 lines.push_back(
new IDF_SEGMENT( corners[2], corners[3] ) );
121 lines.push_back(
new IDF_SEGMENT( corners[3], corners[0] ) );
137 lines.push_back( seg );
154 IDF_SEGMENT* seg =
new IDF_SEGMENT( sp, ep, 360.0,
true );
157 lines.push_back( seg );
177 outline =
new IDF_OUTLINE;
178 IDF3::GetOutline( lines, *outline );
180 if( outline->empty() )
183 aIDFBoard.AddBoardOutline( outline );
187 while( !lines.empty() )
190 outline =
new IDF_OUTLINE;
192 IDF3::GetOutline( lines, *outline );
194 if( outline->empty() )
200 aIDFBoard.AddBoardOutline( outline );
209 while( !lines.empty() )
211 delete lines.front();
218 outline =
new IDF_OUTLINE;
251 outline->push(
new IDF_SEGMENT( p1, p2 ) );
253 for(
int i = 1; i < 4; ++i )
260 outline->push(
new IDF_SEGMENT( p1, p2 ) );
263 aIDFBoard.AddBoardOutline( outline );
273 bool aIncludeUnspecified,
bool aIncludeDNP )
279 wxString footprintBasePath = wxEmptyString;
283 std::optional<LIBRARY_TABLE_ROW*> fpRow =
289 if( crefdes.empty() || !crefdes.compare(
"~" ) )
295 if( cvalue.empty() || !cvalue.compare(
"~" ) )
298 crefdes =
"NOREFDES";
311 double scale = aIDFBoard.GetUserScale();
312 IDF3::KEY_PLATING kplate;
318 aIDFBoard.GetUserOffset( dx, dy );
320 for(
auto pad : aFootprint->
Pads() )
322 drill = (double)
pad->GetDrillSize().x *
scale;
323 x =
pad->GetPosition().x *
scale + dx;
324 y = -
pad->GetPosition().y *
scale + dy;
338 if( tstr.empty() || !tstr.compare(
"0" ) || !tstr.compare(
"~" )
339 || ( kplate == IDF3::NPTH )
354 && (
pad->GetDrillSize().x !=
pad->GetDrillSize().y ) )
360 double dlength =
pad->GetDrillSize().y *
scale;
365 double angle =
pad->GetOrientation().AsDegrees();
373 if( dlength < drill )
375 std::swap( drill, dlength );
386 aIDFBoard.AddSlot( drill, dlength, angle, x, y );
390 IDF_DRILL_DATA *dp =
new IDF_DRILL_DATA( drill, x, y, kplate, crefdes,
391 pintype, IDF3::ECAD );
393 if( !aIDFBoard.AddDrill( dp ) )
397 std::ostringstream ostr;
398 ostr << __FILE__ <<
":" << __LINE__ <<
":" << __FUNCTION__;
399 ostr <<
"(): could not add drill";
401 throw std::runtime_error( ostr.str() );
417 IDF3_COMPONENT*
comp =
nullptr;
419 auto sM = aFootprint->
Models().begin();
420 auto eM = aFootprint->
Models().end();
432 std::vector<const EMBEDDED_FILES*> embeddedFilesStack;
436 idfFile.Assign(
resolver->ResolvePath( sM->m_Filename, footprintBasePath, std::move( embeddedFilesStack ) ) );
437 idfExt = idfFile.GetExt();
439 if( idfExt.Cmp( wxT(
"idf" ) ) && idfExt.Cmp( wxT(
"IDF" ) ) )
453 if( refdes.empty() || !refdes.compare(
"~" ) )
454 refdes = aIDFBoard.GetNewRefDes();
457 IDF3_COMP_OUTLINE* outline;
459 outline = aIDFBoard.GetComponentOutline( idfFile.GetFullPath() );
462 throw( std::runtime_error( aIDFBoard.GetError() ) );
465 double locx = sM->m_Offset.x;
466 double locy = sM->m_Offset.y;
467 double locz = sM->m_Offset.z;
468 double lrot = sM->m_Rotation.z;
488 while( rotz >= 360.0 ) rotz -= 360.0;
491 while( rotz <= -360.0 ) rotz += 360.0;
494 if(
comp ==
nullptr )
495 comp = aIDFBoard.FindComponent( refdes );
497 if(
comp ==
nullptr )
499 comp =
new IDF3_COMPONENT( &aIDFBoard );
501 if(
comp ==
nullptr )
502 throw( std::runtime_error( aIDFBoard.GetError() ) );
504 comp->SetRefDes( refdes );
510 rotz, IDF3::LYR_TOP );
516 rotz, IDF3::LYR_BOTTOM );
519 comp->SetPlacement( IDF3::PS_ECAD );
521 aIDFBoard.AddComponent(
comp );
525 double refX, refY, refA;
526 IDF3::IDF_LAYER side;
528 if( !
comp->GetPosition( refX, refY, refA, side ) )
535 rotz, IDF3::LYR_TOP );
541 rotz, IDF3::LYR_BOTTOM );
544 comp->SetPlacement( IDF3::PS_ECAD );
560 if( (
top && side == IDF3::LYR_BOTTOM ) || ( !
top && side == IDF3::LYR_TOP )
561 || ( refA > 0.0001 ) || ( refX > 0.0001 ) )
563 comp->GetPosition( refX, refY, refA, side );
565 std::ostringstream ostr;
566 ostr <<
"* " << __FILE__ <<
":" << __LINE__ <<
":" << __FUNCTION__ <<
"():\n";
567 ostr <<
"* conflicting Reference Designator '" << refdes <<
"'\n";
569 ostr <<
" vs. " << refX <<
"\n";
571 ostr <<
" vs. " << refY <<
"\n";
572 ostr <<
"* angle: " << rotz;
573 ostr <<
" vs. " << refA <<
"\n";
576 ostr <<
"* TOP vs. ";
578 ostr <<
"* BOTTOM vs. ";
580 if( side == IDF3::LYR_TOP )
585 throw( std::runtime_error( ostr.str() ) );
591 IDF3_COMP_OUTLINE_DATA* data =
new IDF3_COMP_OUTLINE_DATA(
comp, outline );
593 data->SetOffsets( locx, locy, locz, lrot );
594 comp->AddOutlineData( data );
605 bool aUseThou,
double aXRef,
double aYRef,
606 bool aIncludeUnspecified,
bool aIncludeDNP )
608 IDF3_BOARD idfBoard( IDF3::CAD_ELEC );
617 IDF3::IDF_UNIT idfUnit;
621 idfUnit = IDF3::UNIT_THOU;
622 idfBoard.SetUserPrecision( 1 );
626 idfUnit = IDF3::UNIT_MM;
627 idfBoard.SetUserPrecision( 5 );
632 idfBoard.SetUserScale(
scale );
634 idfBoard.SetBoardName(
TO_UTF8( brdName.GetFullName() ) );
635 idfBoard.SetBoardVersion( 0 );
636 idfBoard.SetLibraryVersion( 0 );
638 std::ostringstream ostr;
640 idfBoard.SetIDFSource( ostr.str() );
645 idfBoard.SetUserOffset( -aXRef, aYRef );
654 if( !idfBoard.WriteFile( aFullFileName, idfUnit,
false ) )
657 msg <<
_(
"IDF Export Failed:\n" ) <<
From_UTF8( idfBoard.GetError().c_str() );
666 msg <<
_(
"IDF Export Failed:\n" ) << ioe.
What();
671 catch(
const std::exception& e )
674 msg <<
_(
"IDF Export Failed:\n" ) <<
From_UTF8( e.what() );
constexpr EDA_IU_SCALE pcbIUScale
wxString GetBuildVersion()
Get the full KiCad version string.
int GetBoardThickness() const
The full thickness of the board including copper and masks.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Information pertinent to a Pcbnew printed circuit board.
EMBEDDED_FILES * GetEmbeddedFiles() override
const BOX2I GetBoardEdgesBoundingBox() const
Return the board bounding box calculated using exclusively the board edges (graphics on Edge....
const FOOTPRINTS & Footprints() const
const wxString & GetFileName() const
wxString GetCurrentVariant() const
PROJECT * GetProject() const
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
const DRAWINGS & Drawings() const
constexpr const Vec & GetOrigin() const
constexpr const SizeVec & GetSize() const
EDA_ANGLE GetArcAngle() const
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
Provide an extensible class to resolve 3D model paths.
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
virtual const wxString What() const
A composite of Problem() and Where()
std::optional< LIBRARY_TABLE_ROW * > GetRow(const wxString &aNickname, LIBRARY_TABLE_SCOPE aScope=LIBRARY_TABLE_SCOPE::BOTH) const
Like LIBRARY_MANAGER::GetRow but filtered to the LIBRARY_TABLE_TYPE of this adapter.
std::optional< wxString > GetFullURI(LIBRARY_TABLE_TYPE aType, const wxString &aNickname, bool aSubstituted=false) const
Return the full location specifying URI for the LIB, either in original UI form or in environment var...
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
bool Export_IDF3(BOARD *aPcb, const wxString &aFullFileName, bool aUseThou, double aXRef, double aYRef, bool aIncludeUnspecified, bool aIncludeDNP)
Create an IDF3 compliant BOARD (*.emn) and LIBRARY (*.emp) file.
wxString GetShownText(bool aAllowExtraText, int aDepth=0) const override
Return the string actually shown after processing of the base text.
VECTOR2I GetCenter() const override
This defaults to the center of the bounding box if not overridden.
static S3D_CACHE * Get3DCacheManager(PROJECT *aProject, bool updateProjDir=false)
Return a pointer to an instance of the 3D cache manager.
static FOOTPRINT_LIBRARY_ADAPTER * FootprintLibAdapter(PROJECT *aProject)
FILENAME_RESOLVER * GetResolver() noexcept
@ RECTANGLE
Use RECTANGLE instead of RECT to avoid collision in a Windows header.
static void idf_export_outline(BOARD *aPcb, IDF3_BOARD &aIDFBoard)
Retrieve line segment information from the edge layer and compiles the data into a form which can be ...
static FILENAME_RESOLVER * resolver
static void idf_export_footprint(BOARD *aPcb, FOOTPRINT *aFootprint, IDF3_BOARD &aIDFBoard, bool aIncludeUnspecified, bool aIncludeDNP)
Retrieve information from all board footprints, adds drill holes to the DRILLED_HOLES or BOARD_OUTLIN...
This file contains miscellaneous commonly used macros and functions.
@ NPTH
like PAD_PTH, but not plated mechanical use only, no connection allowed
wxString From_UTF8(const char *cstring)
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
KIBIS top(path, &reporter)
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Calculate the new point of coord coord pX, pY, for a rotation center 0, 0.
@ PCB_SHAPE_T
class PCB_SHAPE, a segment not on copper layers