44#include <wx/filedlg.h>
48 return iu / 1e9 / 0.0254;
65 return m_type == PAD_ATTRIB::NPTH ||
m_type == PAD_ATTRIB::PTH;
108 return outLayers.none();
132 virtual bool Run()
override;
156 case PAD_SHAPE::CIRCLE:
157 case PAD_SHAPE::OVAL:
161 case PAD_SHAPE::ROUNDRECT:
165 case PAD_SHAPE::RECTANGLE:
173 "Hyperlynx exporter (supported shapes are oval, rectangle, "
174 "rounded rectangle, and circle)." ),
184 snprintf( buf,
sizeof( buf ),
"%d, %.9f, %.9f, %.1f, M",
208 std::map<BOARD_ITEM*, HYPERLYNX_PAD_STACK*>
m_padMap;
210 std::shared_ptr<FILE_OUTPUTFORMATTER>
m_out;
250 m_out->Print( 0,
"{VERSION=2.14}\n" );
251 m_out->Print( 0,
"{UNITS=ENGLISH LENGTH}\n\n" );
261 if( outLayers.none() )
266 if( outLayers == layerMask )
274 m_out->Print( 1,
"(\"%s\", %s)\n",
280 m_out->Print( 0,
"}\n\n" );
292 wxLogError(
_(
"Board outline is malformed. Run DRC for a full analysis." ) );
303 m_out->Print( 1,
"(PERIMETER_SEGMENT X1=%.9f Y1=%.9f X2=%.9f Y2=%.9f)\n",
311 m_out->Print( 0,
"}\n\n" );
332 m_out->Print( 0,
"{STACKUP\n" );
341 int plating_thickness = 0;
342 double resistivity = 1.724e-8;
343 m_out->Print( 1,
"(SIGNAL T=%g P=%g C=%g L=\"%.20s\" M=COPPER)\n",
344 iu2hyp( item->GetThickness( 0 ) ),
345 iu2hyp( plating_thickness ),
351 if( item->GetSublayersCount() < 2 )
353 m_out->Print( 1,
"(DIELECTRIC T=%g C=%g L=\"DE_%.17s\" M=\"%.20s\")\n",
354 iu2hyp( item->GetThickness( 0 ) ),
355 item->GetEpsilonR( 0 ),
357 TO_UTF8( item->GetMaterial( 0 ) ) );
359 else for(
int idx = 0; idx < item->GetSublayersCount(); idx++ )
361 m_out->Print( 1,
"(DIELECTRIC T=%g C=%g L=\"DE%d_%.16s\" M=\"%.20s\")\n",
362 iu2hyp( item->GetThickness( idx ) ),
363 item->GetEpsilonR( idx ),
366 TO_UTF8( item->GetMaterial( idx ) ) );
371 m_out->Print( 0,
"}\n\n" );
379 m_out->Print( 0,
"{DEVICES\n" );
383 wxString ref = footprint->GetReference();
387 ref = wxT(
"EMPTY" );
389 m_out->Print( 1,
"(? REF=\"%s\" L=\"%s\")\n",
390 (
const char*) ref.c_str(),
391 (
const char*) layerName.c_str() );
393 m_out->Print( 0,
"}\n\n" );
403 for(
PAD*
pad : footprint->Pads() )
412 if(
PCB_VIA*
via = dyn_cast<PCB_VIA*>( track ) )
430 if(
PAD*
pad = dyn_cast<PAD*>( item ) )
436 wxString ref =
pad->GetParentFootprint()->GetReference();
439 ref = wxT(
"EMPTY" );
441 wxString padName =
pad->GetNumber();
443 if( padName.IsEmpty() )
444 padName = wxT(
"1" );
447 m_out->Print( 1,
"(PIN X=%.10f Y=%.10f R=\"%s.%s\" P=%d)\n",
450 (
const char*) ref.c_str(),
451 (
const char*) padName.c_str(),
452 pstackIter->second->GetId() );
455 else if(
PCB_VIA*
via = dyn_cast<PCB_VIA*>( item ) )
461 m_out->Print( 1,
"(VIA X=%.10f Y=%.10f P=%d)\n",
464 pstackIter->second->GetId() );
467 else if(
PCB_TRACK* track = dyn_cast<PCB_TRACK*>( item ) )
471 m_out->Print( 1,
"(SEG X1=%.10f Y1=%.10f X2=%.10f Y2=%.10f W=%.10f L=\"%s\")\n",
472 iu2hyp( track->GetStart().x ),
473 iu2hyp( -track->GetStart().y ),
474 iu2hyp( track->GetEnd().x ),
475 iu2hyp( -track->GetEnd().y ),
476 iu2hyp( track->GetWidth() ),
477 (
const char*) layerName.c_str() );
479 else if(
PCB_ARC* arc = dyn_cast<PCB_ARC*>( item ) )
486 std::swap( start,
end );
488 m_out->Print( 1,
"(ARC X1=%.10f Y1=%.10f X2=%.10f Y2=%.10f XC=%.10f YC=%.10f R=%.10f W=%.10f L=\"%s\")\n",
493 iu2hyp( arc->GetCenter().x ),
494 iu2hyp( -arc->GetCenter().y ),
495 iu2hyp( arc->GetRadius() ),
496 iu2hyp( arc->GetWidth() ),
497 (
const char*) layerName.c_str() );
499 else if(
ZONE* zone = dyn_cast<ZONE*>( item ) )
513 m_out->Print( 1,
"{POLYGON T=POUR L=\"%s\" ID=%d X=%.10f Y=%.10f\n",
514 (
const char*) layerName.c_str(),
521 m_out->Print( 2,
"(LINE X=%.10f Y=%.10f)\n",
527 m_out->Print( 1,
"}\n" );
529 for(
int h = 0; h < fill.
HoleCount( i ); h++ )
534 m_out->Print( 1,
"{POLYVOID ID=%d X=%.10f Y=%.10f\n",
539 for(
int v = 0; v < holeShape.
PointCount(); v++ )
541 m_out->Print( 2,
"(LINE X=%.10f Y=%.10f)\n",
546 m_out->Print( 2,
"(LINE X=%.10f Y=%.10f)\n",
549 m_out->Print( 1,
"}\n" );
564 std::vector<BOARD_ITEM*> rv;
572 if( item->GetNetCode() == netcode || ( netcode < 0 && item->GetNetCode() <= 0 ) )
580 for(
PAD*
pad : footprint->Pads() )
590 rv.push_back( item );
596 rv.push_back( zone );
609 int netcode = netInfo->GetNetCode();
610 bool isNullNet = netInfo->GetNetCode() <= 0 || netInfo->GetNetname().IsEmpty();
617 if( netObjects.size() )
619 m_out->Print( 0,
"{NET=\"%s\"\n", (
const char*) netInfo->GetNetname().c_str() );
621 m_out->Print( 0,
"}\n\n" );
631 m_out->Print( 0,
"{NET=\"EmptyNet%d\"\n", idx );
633 m_out->Print( 0,
"}\n\n" );
667 wxString wildcard = wxT(
"*.hyp" );
671 fn.SetExt( wxT(
"hyp") );
673 wxFileDialog dlg(
m_frame,
_(
"Export Hyperlynx Layout" ), fn.GetPath(), fn.GetFullName(),
674 wildcard, wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
676 if( dlg.ShowModal() != wxID_OK )
682 fn.SetExt( wxT(
"hyp" ) );
@ BS_ITEM_TYPE_DIELECTRIC
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
const LSET & GetEnabledLayers() const
Return a bit-mask of all the layers that are enabled.
BOARD_STACKUP & GetStackupDescriptor()
int ExportHyperlynx(const TOOL_EVENT &aEvent)
void SetOutputFilename(const wxFileName &aPath)
void SetBoard(BOARD *aBoard)
wxFileName m_outputFilePath
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Manage one layer needed to make a physical board.
Manage layers needed to make a physical board.
const std::vector< BOARD_STACKUP_ITEM * > & GetList() const
Information pertinent to a Pcbnew printed circuit board.
bool GetBoardPolygonOutlines(SHAPE_POLY_SET &aOutlines, OUTLINE_ERROR_HANDLER *aErrorHandler=nullptr, bool aAllowUseArcsInPolygons=false, bool aIncludeNPTHAsOutlines=false)
Extract the board outlines and build a closed polygon from lines, arcs and circle items on edge cut l...
const NETINFO_LIST & GetNetInfo() const
const ZONES & Zones() const
int GetCopperLayerCount() const
const FOOTPRINTS & Footprints() const
const TRACKS & Tracks() const
const wxString & GetFileName() const
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Return the name of a aLayer.
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
virtual bool Run() override
void writeSinglePadStack(HYPERLYNX_PAD_STACK &aStack)
const std::string formatPadShape(const HYPERLYNX_PAD_STACK &aStack)
std::vector< HYPERLYNX_PAD_STACK * > m_padStacks
std::map< BOARD_ITEM *, HYPERLYNX_PAD_STACK * > m_padMap
bool writeNetObjects(const std::vector< BOARD_ITEM * > &aObjects)
HYPERLYNX_PAD_STACK * addPadStack(HYPERLYNX_PAD_STACK stack)
std::shared_ptr< FILE_OUTPUTFORMATTER > m_out
const std::vector< BOARD_ITEM * > collectNetObjects(int netcode)
HYPERLYNX_PAD_STACK(BOARD *aBoard, const PAD *aPad)
bool operator==(const HYPERLYNX_PAD_STACK &other) const
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
LSEQ is a sequence (and therefore also a set) of PCB_LAYER_IDs.
LSET is a set of PCB_LAYER_IDs.
LSEQ CuStack() const
Return a sequence of copper layers in starting from the front/top and extending to the back/bottom.
LSEQ Seq(const LSEQ &aSequence) const
Return an LSEQ from the union of this LSET and a desired sequence.
static LSET AllCuMask()
return AllCuMask( MAX_CU_LAYERS );
Handle the data for a net.
static constexpr PCB_LAYER_ID ALL_LAYERS
! Temporary layer identifier to identify code that is not padstack-aware
LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
const VECTOR2I & GetDrillSize() const
PAD_SHAPE GetShape(PCB_LAYER_ID aLayer) const
EDA_ANGLE GetOrientation() const
Return the rotation angle of the pad.
const VECTOR2I & GetSize(PCB_LAYER_ID aLayer) const
int GetWidth() const override
int GetDrillValue() const
Calculate the drill value for vias (m_drill if > 0, or default drill value for the board).
virtual LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)
Report a string with a given severity.
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.
int SegmentCount() const
Return the number of segments in this line chain.
const SEG CSegment(int aIndex) const
Return a constant copy of the aIndex segment in the line chain.
Represent a set of closed polygons.
int HoleCount(int aOutline) const
Returns the number of holes in a given outline.
void Simplify()
Simplify the polyset (merges overlapping polys, eliminates degeneracy/self-intersections)
const SHAPE_LINE_CHAIN & CHole(int aOutline, int aHole) const
int OutlineCount() const
Return the number of outlines in the set.
SHAPE_POLY_SET CloneDropTriangulation() const
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
Handle a list of polygons defining a copper zone.
static double iu2hyp(double iu)
PCB_LAYER_ID
A quick note on layer IDs:
This file contains miscellaneous commonly used macros and functions.
PAD_ATTRIB
The set of pad shapes, used with PAD::{Set,Get}Attribute().
PAD_SHAPE
The set of pad shapes, used with PAD::{Set,Get}Shape()
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.