30#include <idf_parser.h>
46#define LINE_WIDTH (pcbIUScale.mmToIU( 0.1 ))
59 std::list<IDF_SEGMENT*>& aLines )
70 sp.x = aGraphic->
GetStart().
x * aScale + aOffX;
71 sp.y = -aGraphic->
GetStart().
y * aScale + aOffY;
72 ep.x = aGraphic->
GetEnd().
x * aScale + aOffX;
73 ep.y = -aGraphic->
GetEnd().
y * aScale + aOffY;
74 aLines.push_back(
new IDF_SEGMENT( sp, ep ) );
87 double bottom = -aGraphic->
GetEnd().
y * aScale + aOffY;
91 corners[0] = IDF_POINT(
left,
top );
92 corners[1] = IDF_POINT(
right,
top );
93 corners[2] = IDF_POINT(
right, bottom );
94 corners[3] = IDF_POINT(
left, bottom );
96 aLines.push_back(
new IDF_SEGMENT( corners[0], corners[1] ) );
97 aLines.push_back(
new IDF_SEGMENT( corners[1], corners[2] ) );
98 aLines.push_back(
new IDF_SEGMENT( corners[2], corners[3] ) );
99 aLines.push_back(
new IDF_SEGMENT( corners[3], corners[0] ) );
108 sp.x = aGraphic->
GetCenter().
x * aScale + aOffX;
109 sp.y = -aGraphic->
GetCenter().
y * aScale + aOffY;
110 ep.x = aGraphic->
GetStart().
x * aScale + aOffX;
111 ep.y = -aGraphic->
GetStart().
y * aScale + aOffY;
122 sp.x = aGraphic->
GetCenter().
x * aScale + aOffX;
123 sp.y = -aGraphic->
GetCenter().
y * aScale + aOffY;
124 ep.x = sp.x - aGraphic->
GetRadius() * aScale;
129 aLines.push_back(
new IDF_SEGMENT( sp, ep, 360.0,
true ) );
146 for(
int jj = 0; jj <
chain.PointCount(); ++jj )
154 sp.x = start.
x * aScale + aOffX;
155 sp.y = -start.
y * aScale + aOffY;
156 ep.x =
end.x * aScale + aOffX;
157 ep.y = -
end.y * aScale + aOffY;
158 aLines.push_back(
new IDF_SEGMENT( sp, ep ) );
171 for(
size_t ii = 1; ii < pts.size(); ++ii )
173 if( pts[ii - 1] == pts[ii] )
176 sp.x = pts[ii - 1].x * aScale + aOffX;
177 sp.y = -pts[ii - 1].y * aScale + aOffY;
178 ep.x = pts[ii].x * aScale + aOffX;
179 ep.y = -pts[ii].y * aScale + aOffY;
180 aLines.push_back(
new IDF_SEGMENT( sp, ep ) );
198 double scale = aIDFBoard.GetUserScale();
199 std::list< IDF_SEGMENT* > lines;
200 IDF_OUTLINE* outline =
nullptr;
206 aIDFBoard.GetUserOffset( offX, offY );
227 outline =
new IDF_OUTLINE;
228 IDF3::GetOutline( lines, *outline );
230 if( outline->empty() )
233 aIDFBoard.AddBoardOutline( outline );
237 while( !lines.empty() )
240 outline =
new IDF_OUTLINE;
242 IDF3::GetOutline( lines, *outline );
244 if( outline->empty() )
250 aIDFBoard.AddBoardOutline( outline );
262 while( !lines.empty() )
264 delete lines.front();
271 outline =
new IDF_OUTLINE;
304 outline->push(
new IDF_SEGMENT( p1, p2 ) );
306 for(
int i = 1; i < 4; ++i )
313 outline->push(
new IDF_SEGMENT( p1, p2 ) );
316 aIDFBoard.AddBoardOutline( outline );
326 bool aIncludeUnspecified,
bool aIncludeDNP )
332 wxString footprintBasePath = wxEmptyString;
336 std::optional<LIBRARY_TABLE_ROW*> fpRow =
342 if( crefdes.empty() || !crefdes.compare(
"~" ) )
348 if( cvalue.empty() || !cvalue.compare(
"~" ) )
351 crefdes =
"NOREFDES";
356 double scale = aIDFBoard.GetUserScale();
357 IDF3::KEY_PLATING kplate;
363 aIDFBoard.GetUserOffset( dx, dy );
367 std::list<IDF_SEGMENT*> cutoutLines;
378 while( !cutoutLines.empty() )
380 IDF_OUTLINE* cutout =
new IDF_OUTLINE;
381 IDF3::GetOutline( cutoutLines, *cutout );
383 if( cutout->empty() )
390 if( !aIDFBoard.AddBoardOutline( cutout ) )
394 for(
auto pad : aFootprint->
Pads() )
396 drill = (double)
pad->GetDrillSize().x *
scale;
397 x =
pad->GetPosition().x *
scale + dx;
398 y = -
pad->GetPosition().y *
scale + dy;
412 if( tstr.empty() || !tstr.compare(
"0" ) || !tstr.compare(
"~" )
413 || ( kplate == IDF3::NPTH )
428 && (
pad->GetDrillSize().x !=
pad->GetDrillSize().y ) )
434 double dlength =
pad->GetDrillSize().y *
scale;
439 double angle =
pad->GetOrientation().AsDegrees();
447 if( dlength < drill )
449 std::swap( drill, dlength );
460 aIDFBoard.AddSlot( drill, dlength, angle, x, y );
464 IDF_DRILL_DATA *dp =
new IDF_DRILL_DATA( drill, x, y, kplate, crefdes,
465 pintype, IDF3::ECAD );
467 if( !aIDFBoard.AddDrill( dp ) )
471 std::ostringstream ostr;
472 ostr << __FILE__ <<
":" << __LINE__ <<
":" << __FUNCTION__;
473 ostr <<
"(): could not add drill";
475 throw std::runtime_error( ostr.str() );
491 IDF3_COMPONENT*
comp =
nullptr;
493 auto sM = aFootprint->
Models().begin();
494 auto eM = aFootprint->
Models().end();
506 std::vector<const EMBEDDED_FILES*> embeddedFilesStack;
510 idfFile.Assign(
resolver->ResolvePath( sM->m_Filename, footprintBasePath, std::move( embeddedFilesStack ) ) );
511 idfExt = idfFile.GetExt();
513 if( idfExt.Cmp( wxT(
"idf" ) ) && idfExt.Cmp( wxT(
"IDF" ) ) )
527 if( refdes.empty() || !refdes.compare(
"~" ) )
528 refdes = aIDFBoard.GetNewRefDes();
531 IDF3_COMP_OUTLINE* outline;
533 outline = aIDFBoard.GetComponentOutline( idfFile.GetFullPath() );
536 throw( std::runtime_error( aIDFBoard.GetError() ) );
539 double locx = sM->m_Offset.x;
540 double locy = sM->m_Offset.y;
541 double locz = sM->m_Offset.z;
542 double lrot = sM->m_Rotation.z;
562 while( rotz >= 360.0 ) rotz -= 360.0;
565 while( rotz <= -360.0 ) rotz += 360.0;
568 if(
comp ==
nullptr )
569 comp = aIDFBoard.FindComponent( refdes );
571 if(
comp ==
nullptr )
573 comp =
new IDF3_COMPONENT( &aIDFBoard );
575 if(
comp ==
nullptr )
576 throw( std::runtime_error( aIDFBoard.GetError() ) );
578 comp->SetRefDes( refdes );
584 rotz, IDF3::LYR_TOP );
590 rotz, IDF3::LYR_BOTTOM );
593 comp->SetPlacement( IDF3::PS_ECAD );
595 aIDFBoard.AddComponent(
comp );
599 double refX, refY, refA;
600 IDF3::IDF_LAYER side;
602 if( !
comp->GetPosition( refX, refY, refA, side ) )
609 rotz, IDF3::LYR_TOP );
615 rotz, IDF3::LYR_BOTTOM );
618 comp->SetPlacement( IDF3::PS_ECAD );
634 if( (
top && side == IDF3::LYR_BOTTOM ) || ( !
top && side == IDF3::LYR_TOP )
635 || ( refA > 0.0001 ) || ( refX > 0.0001 ) )
637 comp->GetPosition( refX, refY, refA, side );
639 std::ostringstream ostr;
640 ostr <<
"* " << __FILE__ <<
":" << __LINE__ <<
":" << __FUNCTION__ <<
"():\n";
641 ostr <<
"* conflicting Reference Designator '" << refdes <<
"'\n";
643 ostr <<
" vs. " << refX <<
"\n";
645 ostr <<
" vs. " << refY <<
"\n";
646 ostr <<
"* angle: " << rotz;
647 ostr <<
" vs. " << refA <<
"\n";
650 ostr <<
"* TOP vs. ";
652 ostr <<
"* BOTTOM vs. ";
654 if( side == IDF3::LYR_TOP )
659 throw( std::runtime_error( ostr.str() ) );
665 IDF3_COMP_OUTLINE_DATA* data =
new IDF3_COMP_OUTLINE_DATA(
comp, outline );
667 data->SetOffsets( locx, locy, locz, lrot );
668 comp->AddOutlineData( data );
682 double aYRef,
bool aIncludeUnspecified,
bool aIncludeDNP,
687 wxCHECK( aResolver,
false );
689 IDF3_BOARD idfBoard( IDF3::CAD_ELEC );
698 IDF3::IDF_UNIT idfUnit;
702 idfUnit = IDF3::UNIT_THOU;
703 idfBoard.SetUserPrecision( 1 );
707 idfUnit = IDF3::UNIT_MM;
708 idfBoard.SetUserPrecision( 5 );
713 idfBoard.SetUserScale(
scale );
715 idfBoard.SetBoardName(
TO_UTF8( brdName.GetFullName() ) );
716 idfBoard.SetBoardVersion( 0 );
717 idfBoard.SetLibraryVersion( 0 );
719 std::ostringstream ostr;
721 idfBoard.SetIDFSource( ostr.str() );
726 idfBoard.SetUserOffset( -aXRef, aYRef );
735 if( !idfBoard.WriteFile( aFullFileName, idfUnit,
false ) )
738 *aErrorMsg =
From_UTF8( idfBoard.GetError().c_str() );
746 *aErrorMsg = ioe.
What();
750 catch(
const std::exception& e )
763 bool aUseThou,
double aXRef,
double aYRef,
764 bool aIncludeUnspecified,
bool aIncludeDNP )
769 bool ok =
ExportBoardToIDF3( aPcb, aFullFileName, aUseThou, aXRef, aYRef, aIncludeUnspecified,
770 aIncludeDNP,
res, &errorMsg );
775 msg <<
_(
"IDF Export Failed:\n" ) << errorMsg;
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
SHAPE_POLY_SET & GetPolyShape()
void RebuildBezierToSegmentsPointsList(int aMaxError)
Rebuild the m_bezierPoints vertex list that approximate the Bezier curve by a list of segments.
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
const std::vector< VECTOR2I > & GetBezierPoints() const
bool IsPolyShapeValid() const
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)
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
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
Represent a set of closed polygons.
int OutlineCount() const
Return the number of outlines in the set.
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
@ 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 ...
bool ExportBoardToIDF3(BOARD *aPcb, const wxString &aFullFileName, bool aUseThou, double aXRef, double aYRef, bool aIncludeUnspecified, bool aIncludeDNP, FILENAME_RESOLVER *aResolver, wxString *aErrorMsg)
Generate IDFv3 compliant board (*.emn) and library (*.emp) files representing the user's PCB design.
static void idf_append_shape(PCB_SHAPE *aGraphic, double aScale, double aOffX, double aOffY, std::list< IDF_SEGMENT * > &aLines)
Convert a single Edge_Cuts graphic into IDF segments and append them to aLines.
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)
const SHAPE_LINE_CHAIN chain
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
VECTOR2< int32_t > VECTOR2I