73#define EXPORT_CUSTOM_PADS_CONVEX_HULL
92 errorText = ioe.
What();
101 SetStatusText( wxString(
_(
"BOARD exported OK." ) ) );
122 wxLogWarning(
_(
"Board outline is malformed. Run DRC for a full analysis." ) );
153static inline double scale(
int kicadDist )
156 return kicadDist / (
pcbIUScale.IU_PER_MM / 1000.0 );
161static inline double IU2um(
int kicadDist )
163 return kicadDist * ( 1000.0 /
pcbIUScale.IU_PER_MM );
167static inline double mapX(
int x )
173static inline double mapY(
int y )
200 return mapPt( fpRelative );
209 std::vector<PCB_LAYER_ID> layers = aPad->
Padstack().UniqueLayers();
213 bool swallowedByHole = !layers.empty();
220 swallowedByHole =
false;
224 if( swallowedByHole )
239 path->AppendPoint( aStart );
240 path->AppendPoint( aEnd );
241 path->SetLayerId( aLayerName );
271 const std::vector<std::string>& aLayerNames )
278 if( offset.
x || offset.
y )
280 dsnOffset =
mapPt( offset );
283 std::ostringstream oss;
284 oss.imbue( std::locale::classic() );
285 oss << std::fixed << std::setprecision( 6 )
286 <<
'[' << dsnOffset.
x <<
',' << dsnOffset.
y <<
']';
287 id.m_offset = oss.str();
290 std::ostringstream dims;
291 dims << std::fixed << std::setprecision( 6 );
293 switch( aPad->
GetShape( aPadLayer ) )
297 for(
const std::string& layerName : aLayerNames )
301 aPadstack->
Append( shape );
307 circle->SetLayerId( layerName );
309 circle->SetVertex( dsnOffset );
312 id.m_family =
"Round";
313 dims <<
IU2um( padSize.
x ) <<
"_um";
319 double dx =
scale( padSize.
x ) / 2.0;
320 double dy =
scale( padSize.
y ) / 2.0;
322 POINT lowerLeft( -dx, -dy );
323 POINT upperRight( dx, dy );
325 lowerLeft += dsnOffset;
326 upperRight += dsnOffset;
328 for(
const std::string& layerName : aLayerNames )
332 aPadstack->
Append( shape );
342 id.m_family =
"Rect";
343 dims <<
IU2um( padSize.
x ) <<
"x" <<
IU2um( padSize.
y ) <<
"_um";
349 double dx =
scale( padSize.
x ) / 2.0;
350 double dy =
scale( padSize.
y ) / 2.0;
360 pstart =
POINT( -dr, 0.0 );
361 pstop =
POINT( dr, 0.0 );
368 pstart =
POINT( 0.0, -dr );
369 pstop =
POINT( 0.0, dr );
375 for(
const std::string& layerName : aLayerNames )
380 aPadstack->
Append( shape );
388 id.m_family =
"Oval";
389 dims <<
IU2um( padSize.
x ) <<
"x" <<
IU2um( padSize.
y ) <<
"_um";
395 double dx =
scale( padSize.
x ) / 2.0;
396 double dy =
scale( padSize.
y ) / 2.0;
404 POINT lowerLeft( -dx - ddy, -dy - ddx );
405 POINT upperLeft( -dx + ddy, +dy + ddx );
406 POINT upperRight( +dx - ddy, +dy - ddx );
407 POINT lowerRight( +dx + ddy, -dy + ddx );
409 lowerLeft += dsnOffset;
410 upperLeft += dsnOffset;
411 upperRight += dsnOffset;
412 lowerRight += dsnOffset;
414 for(
const std::string& layerName : aLayerNames )
418 aPadstack->
Append( shape );
421 PATH* polygon =
new PATH( shape, T_polygon );
433 id.m_family =
"Trapz";
434 dims <<
IU2um( padSize.
x ) <<
"x" <<
IU2um( padSize.
y ) <<
"_"
444 const int circleToSegmentsCount = 36;
456 double correctionFactor = cos(
M_PI / (
double) circleToSegmentsCount );
457 int extra_clearance =
KiROUND( rradius * ( 1.0 - correctionFactor ) );
459 psize.
x += extra_clearance * 2;
460 psize.
y += extra_clearance * 2;
461 rradius += extra_clearance;
471 for(
const std::string& layerName : aLayerNames )
475 aPadstack->
Append( shape );
478 PATH* polygon =
new PATH( shape, T_polygon );
487 for(
int idx = 0; idx < polygonal_shape.
PointCount(); idx++ )
495 first_corner = corner;
501 id.m_family =
"RoundRect";
502 dims <<
IU2um( padSize.
x ) <<
'x'
503 <<
IU2um( padSize.
y ) <<
'_'
504 <<
IU2um( rradius ) <<
"_um_"
506 << std::hex << std::uppercase
513 std::vector<VECTOR2I> polygonal_shape;
517#ifdef EXPORT_CUSTOM_PADS_CONVEX_HULL
522 for(
int ii = 0; ii < p_outline.
PointCount(); ++ii )
523 polygonal_shape.push_back( wxPoint( p_outline.
CPoint( ii ) ) );
527 if( polygonal_shape.front() != polygonal_shape.back() )
528 polygonal_shape.push_back( polygonal_shape.front() );
530 for(
const std::string& layerName : aLayerNames )
534 aPadstack->
Append( shape );
537 PATH* polygon =
new PATH( shape, T_polygon );
543 for(
const VECTOR2I& pt : polygonal_shape )
554 id.m_family =
"Cust";
555 dims <<
IU2um( padSize.
x ) <<
'x' <<
IU2um( padSize.
y ) <<
'_'
557 << polygonal_shape.size() <<
"_um_"
563 id.m_dims = dims.str();
571 std::string uniqifier;
585 std::vector<std::pair<PCB_LAYER_ID, std::vector<std::string>>> layerGroups;
587 bool onAllCopperLayers = ( (aPad->
GetLayerSet() & all_cu) == all_cu );
589 if( onAllCopperLayers )
592 for(
int layer=0; layer < copperCount; ++layer )
596 if( onAllCopperLayers || aPad->
IsOnLayer( kilayer ) )
599 auto group = std::find_if( layerGroups.begin(), layerGroups.end(),
600 [&](
const auto& aGroup )
602 return aGroup.first == padLayer;
605 if(
group == layerGroups.end() )
606 layerGroups.emplace_back( padLayer, std::vector<std::string>{
m_layerIds[layer] } );
610 if( !onAllCopperLayers )
614 else if( layer == copperCount - 1 )
617 uniqifier += fmt::format(
"{}", layer );
624 if( layerGroups.empty() )
626 padstack->
SetPadstackId( (
"Empty" + uniqifier +
"Pad" ).c_str() );
631 std::vector<SPECCTRA_SHAPE_ID> shapeIds;
633 for(
const auto& [padLayer, names] : layerGroups )
636 bool uniform = std::all_of( shapeIds.begin(), shapeIds.end(),
639 return aId == shapeIds.front();
643 std::ostringstream oss;
647 oss << shapeIds.front().m_family << uniqifier << shapeIds.front().m_offset <<
"Pad_"
648 << shapeIds.front().m_dims;
656 for(
size_t ndx = 0; ndx < shapeIds.size(); ++ndx )
658 for(
const std::string&
name : layerGroups[ndx].second )
661 hash.
add( shapeIds[ndx].m_family );
662 hash.
add( shapeIds[ndx].m_offset );
663 hash.
add( shapeIds[ndx].m_dims );
666 oss <<
"Complex" << uniqifier << shapeIds.front().m_offset <<
"Pad_"
667 << shapeIds.front().m_family <<
'_' << shapeIds.front().m_dims <<
'_'
696 for(
int p = 0; p < fpItems.
GetCount(); ++p )
703 double diameter =
scale(
pad->GetDrillSize().x );
710 for(
int layer=0; layer<layerCount; ++layer )
714 image->m_keepouts.push_back( keepout );
720 circle->SetDiameter( diameter );
721 circle->SetVertex( vertex );
731 if( !mask_copper_layers.any() )
741 padstack = (
PADSTACK*) *iter.base();
750 padNumber =
pad->GetNumber();
753 if( padNumber != wxEmptyString && pinmap.find( padNumber ) == pinmap.end() )
755 pinmap[ padNumber ] = 0;
759 int duplicates = ++pinmap[ padNumber ];
762 "@" + std::to_string( duplicates );
765 pin->m_kiNetCode =
pad->GetNetCode();
790 image->Append( outline );
795 path->SetAperture( 0 );
796 path->SetLayerId(
"signal" );
798 for(
int ii = 0; ii <
chain.PointCount(); ++ii )
801 path->AppendPoint(
mapPt( corner, aFootprint ) );
809 for(
int i = 0; i < fpItems.
GetCount(); ++i )
823 image->Append( outline );
828 path->SetLayerId(
"signal" );
838 image->Append( outline );
844 path->SetLayerId(
"signal" );
853 for(
int ii = 0; ii < polyline.
PointCount(); ++ii )
856 path->AppendPoint(
mapPt( corner, aFootprint ) );
866 image->Append( outline );
871 path->SetLayerId(
"signal" );
873 path->AppendPoint(
mapPt( corner, aFootprint ) );
876 path->AppendPoint(
mapPt( corner, aFootprint ) );
879 path->AppendPoint(
mapPt( corner, aFootprint ) );
882 path->AppendPoint(
mapPt( corner, aFootprint ) );
885 path->AppendPoint(
mapPt( corner, aFootprint ) );
897 image->Append( outline );
898 path =
new PATH( outline, T_polygon );
901 path->SetAperture( 0 );
902 path->SetLayerId(
"signal" );
910 for(
int ii = 0; ii < poly.
PointCount(); ++ii )
913 path->AppendPoint(
mapPt( corner, aFootprint ) );
926 if( !zone->GetIsRuleArea() )
930 ZONE untransformedZone( *zone );
942 if( zone->GetDoNotAllowVias() && zone->GetDoNotAllowTracks() )
943 keepout_type = T_keepout;
944 else if( zone->GetDoNotAllowVias() )
945 keepout_type = T_via_keepout;
946 else if( zone->GetDoNotAllowTracks() )
947 keepout_type = T_wire_keepout;
949 keepout_type = T_keepout;
958 image->m_keepouts.push_back( keepout );
960 PATH* mainPolygon =
new PATH( keepout, T_polygon );
967 bool is_first_point =
true;
970 for( iterator = untransformedZone.
IterateWithHoles(); iterator; iterator++ )
979 is_first_point =
false;
993 PATH* cutout =
nullptr;
994 bool isStartContour =
true;
997 for( iterator++; iterator; iterator++ )
1001 is_first_point =
true;
1002 window =
new WINDOW( keepout );
1005 cutout =
new PATH( window, T_polygon );
1021 if( is_first_point )
1024 is_first_point =
false;
1041 int aTopLayer,
int aBotLayer )
1045 double dsnDiameter =
scale( aCopperDiameter );
1047 for(
int layer=aTopLayer; layer<=aBotLayer; ++layer )
1051 padstack->
Append( shape );
1057 circle->SetDiameter( dsnDiameter );
1061 snprintf(
name,
sizeof(
name ),
"Via[%d-%d]_%.6g:%.6g_um",
1062 aTopLayer, aBotLayer, dsnDiameter,
1064 IU2um( aDrillDiameter ) );
1078 aVia->
LayerPair( &topLayerNum, &botLayerNum );
1083 if( topLayer > botLayer )
1084 std::swap( topLayer, botLayer );
1093 std::ostringstream oss;
1095 oss <<
"Via[" << topLayer <<
'-' << botLayer <<
']' << std::fixed << std::setprecision( 6 );
1097 for(
int layer = topLayer; layer <= botLayer; ++layer )
1104 padstack->
Append( shape );
1110 circle->SetDiameter( dsnDiameter );
1113 oss <<
'_' << dsnDiameter;
1131 path->layer_id =
"pcb";
1135 for(
int ii = 0; ii < outline.
PointCount(); ii++ )
1150 PATH* poly_ko =
new PATH(
nullptr, T_polygon );
1154 m_pcb->m_structure->m_keepouts.push_back( keepout );
1158 for(
int jj = 0; jj < hole.
PointCount(); jj++ )
1176 wxString ret = aValue;
1177 ret.Replace( wxT(
"\"" ), wxT(
"''" ) );
1190 std::map<FOOTPRINT*, std::string> componentIds;
1192 std::set<wxString> used;
1196 wxString ref = footprint->GetReference();
1199 ref = wxT(
"REF**" );
1201 wxString unique = ref;
1203 for(
int suffix = 1; !used.insert( unique.Lower() ).second; ++suffix )
1204 unique = wxString::Format( wxT(
"%s_%d" ), ref, suffix );
1206 componentIds[footprint] =
TO_UTF8( unique );
1222 for(
int pcbNdx=0; pcbNdx<layerCount; ++pcbNdx )
1226 m_pcb->m_structure->m_layers.push_back( layer );
1235 case LT_SIGNAL: layerType = T_signal;
break;
1236 case LT_POWER: layerType = T_power;
break;
1240 case LT_MIXED: layerType = T_signal;
break;
1241 case LT_JUMPER: layerType = T_jumper;
break;
1248 property->name =
"index";
1249 property->value = std::to_string( pcbNdx );
1254 m_pcb->m_parser->space_in_quoted_tokens =
true;
1261 m_pcb->m_unit->units = T_um;
1262 m_pcb->m_resolution->units = T_um;
1263 m_pcb->m_resolution->value = 10;
1272 m_pcb->m_structure->SetBOUNDARY( boundary );
1279 int defaultTrackWidth = netSettings->GetDefaultNetclass()->GetTrackWidth();
1280 int defaultClearance = netSettings->GetDefaultNetclass()->GetClearance();
1283 std::vector<std::string>& rules =
m_pcb->m_structure->m_rules->m_rules;
1285 std::snprintf( rule,
sizeof( rule ),
"(width %.6g)",
scale( defaultTrackWidth ) );
1286 rules.push_back( rule );
1288 std::snprintf( rule,
sizeof( rule ),
"(clearance %.6g)",
clearance );
1289 rules.push_back( rule );
1296 std::snprintf( rule,
sizeof( rule ),
"(clearance %.6g (type smd_smd))",
clearance );
1297 rules.push_back( rule );
1304 int netlessZones = 0;
1309 if( aChain.PointCount() < 3 )
1312 for(
int v = 0; v < aChain.PointCount(); v++ )
1320 if( zone->GetIsRuleArea() || !zone->IsOnCopperLayer() )
1324 wxCHECK2( zoneOutline && zoneOutline->
OutlineCount() > 0,
continue );
1329 wxCHECK2( zoneOutlineFractured.
OutlineCount() == 1,
continue );
1334 std::string netId = zone->GetNetname().utf8_string();
1339 no_net->
m_net_id =
"@:no_net_" + std::to_string( netlessZones++ );
1340 m_pcb->m_network->m_nets.push_back( no_net );
1351 wiring->
wires.push_back( wire );
1355 PATH* mainPolygon =
new PATH( wire, T_polygon );
1358 appendClosedChain( mainPolygon, zoneOutlineFractured.
COutline( 0 ) );
1362 if( !zoneFill || zoneFill->
IsEmpty() )
1381 PATH* cutout =
new PATH( window, T_polygon );
1384 appendClosedChain( cutout, hole );
1394 if( !zone->GetIsRuleArea() )
1402 if( zone->GetDoNotAllowVias() && zone->GetDoNotAllowTracks() )
1403 keepout_type = T_keepout;
1404 else if( zone->GetDoNotAllowVias() )
1405 keepout_type = T_via_keepout;
1406 else if( zone->GetDoNotAllowTracks() )
1407 keepout_type = T_wire_keepout;
1409 keepout_type = T_keepout;
1418 m_pcb->m_structure->m_keepouts.push_back( keepout );
1420 PATH* mainPolygon =
new PATH( keepout, T_polygon );
1427 bool is_first_point =
true;
1430 for( iterator = zone->IterateWithHoles(); iterator; iterator++ )
1434 if( is_first_point )
1437 is_first_point =
false;
1450 WINDOW* window =
nullptr;
1451 PATH* cutout =
nullptr;
1453 bool isStartContour =
true;
1456 for( iterator++; iterator; iterator++ )
1458 if( isStartContour )
1460 is_first_point =
true;
1461 window =
new WINDOW( keepout );
1464 cutout =
new PATH( window, T_polygon );
1476 if( is_first_point )
1479 is_first_point =
false;
1495 std::string componentId;
1496 int highestNetCode = 0;
1501 highestNetCode = std::max( highestNetCode, i->GetNetCode() );
1506 m_nets.resize( highestNetCode + 1,
nullptr );
1508 for(
unsigned i = 1 ; i <
m_nets.size(); ++i )
1513 if( i->GetNetCode() > 0 )
1523 componentId = componentIds[footprint];
1533 int netcode =
pin.m_kiNetCode;
1561 comp->m_places.push_back( place );
1563 place->
SetRotation( footprint->GetOrientationDegrees() );
1569 if( footprint->GetFlag() )
1582 boost::ptr_set<PADSTACK>::auto_type ps =
m_padstackset.release( i );
1585 m_pcb->m_library->AddPadstack( padstack );
1589 for(
unsigned n = 1; n <
m_nets.size(); ++n )
1596 m_pcb->m_network->m_nets.push_back( net );
1603 std::unordered_map<wxString, NETCLASS*> netclassesInUse;
1607 NETCLASS* netclass = net->GetNetClass();
1614 if( !netclassesInUse.contains(
name ) )
1615 netclassesInUse[
name] = netclass;
1637 wxASSERT(
m_pcb->m_library->m_vias.size() == 0 );
1638 m_pcb->m_library->AppendVia(
via );
1644 for(
const auto& [
name, netclass] : netclassesInUse )
1665 if( !track->IsType( { PCB_TRACE_T, PCB_ARC_T } ) )
1668 int netcode = track->GetNetCode();
1678 wiring->
wires.push_back( wire );
1681 if( track->IsLocked() )
1692 path->aperture_width =
scale( track->GetWidth() );
1693 path->AppendPoint(
mapPt( track->GetStart() ) );
1694 path->AppendPoint(
mapPt( track->GetEnd() ) );
1707 int netcode =
via->GetNetCode();
1722 m_pcb->m_wiring->wire_vias.push_back( dsnVia );
1732 if(
via->IsLocked() )
1747 VIA* vias =
m_pcb->m_structure->m_via;
1749 for(
unsigned viaNdx = 0; viaNdx <
m_pcb->m_library->m_vias.size(); ++viaNdx )
1750 vias->
AppendVia(
m_pcb->m_library->m_vias[viaNdx].m_padstack_id.c_str() );
1756 exportNETCLASS( netSettings->GetDefaultNetclass().get(), aBoard );
1758 for(
const auto& [
name, netclass] : netclassesInUse )
1797 m_pcb->m_network->m_classes.push_back( clazz );
1803 if( net->GetNetClass()->GetName() == clazz->
m_class_id )
1813 std::snprintf(
text,
sizeof(
text ),
"(width %.6g)",
scale( trackWidth ) );
1837 snprintf(
text,
sizeof(
text ),
"(use_via \"%s\")",
via->GetPadstackId().c_str() );
1851 footprint->SetFlag( 0 );
1853 if( footprint->GetLayer() ==
B_Cu )
1856 footprint->SetFlag( 1 );
1874 if( footprint->GetFlag() )
1877 footprint->SetFlag( 0 );
constexpr int ARC_HIGH_DEF
constexpr EDA_IU_SCALE pcbIUScale
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
Handles how to draw a screen (a board, a schematic ...)
bool IsContentModified() const
void SetContentModified(bool aModified=true)
std::shared_ptr< NET_SETTINGS > m_NetSettings
Information pertinent to a Pcbnew printed circuit board.
const NETINFO_LIST & GetNetInfo() const
NETINFO_ITEM * FindNet(int aNetcode) const
Search for a net with the given netcode.
const ZONES & Zones() const
LAYER_T GetLayerType(PCB_LAYER_ID aLayer) const
Return the type of the copper layer given by aLayer.
void SynchronizeNetsAndNetClasses(bool aResetTrackAndViaSizes)
Copy NETCLASS info to each NET, based on NET membership in a NETCLASS.
int GetCopperLayerCount() const
const FOOTPRINTS & Footprints() const
const TRACKS & Tracks() const
bool GetBoardPolygonOutlines(SHAPE_POLY_SET &aOutlines, bool aInferOutlineIfNecessary, 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...
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
constexpr size_type GetWidth() const
constexpr size_type GetHeight() const
int GetCount() const
Return the number of objects in the list.
The <class_descriptor> in the specctra spec.
std::vector< std::string > m_circuit
circuit descriptor list
std::vector< std::string > m_net_ids
Implement a <component_descriptor> in the specctra dsn spec.
Used for <keepout_descriptor> and <plane_descriptor>.
void AddWindow(WINDOW *aWindow)
void SetShape(ELEM *aShape)
DSN_T layer_type
one of: T_signal, T_power, T_mixed, T_jumper
A <net_descriptor> in the DSN spec.
std::vector< PIN_REF > m_pins
Hold either a via or a pad definition.
std::string m_padstack_id
void SetPadstackId(const char *aPadstackId)
Support both the <path_descriptor> and the <polygon_descriptor> per the specctra dsn spec.
void SetLayerId(const std::string &aLayerId)
void AppendPoint(const POINT &aPoint)
Implement a <placement_reference> in the specctra dsn spec.
void SetVertex(const POINT &aVertex)
void SetRotation(double aRotation)
std::string m_part_number
std::string m_component_id
reference designator
void SetLayerId(const std::string &aLayerId)
void SetCorners(const POINT &aPoint0, const POINT &aPoint1)
std::vector< std::string > m_rules
rules are saved in std::string form.
A "(shape ..)" element in the specctra dsn spec.
A DSN data tree, usually coming from a DSN file.
int m_top_via_layer
specctra cu layers, 0 based index:
IMAGE * makeIMAGE(BOARD *aBoard, FOOTPRINT *aFootprint)
Allocates an I#MAGE on the heap and creates all the PINs according to the PADs in the FOOTPRINT.
void buildLayerMaps(BOARD *aBoard)
Create a few data translation structures for layer name and number mapping between the DSN::PCB struc...
std::map< int, PCB_LAYER_ID > m_pcbLayer2kicad
maps PCB layer number to BOARD layer numbers
void ExportPCB(const wxString &aFilename, bool aNameChange=false)
Write the internal PCB instance out as a SPECTRA DSN format file.
SHAPE_POLY_SET m_brd_outlines
void FlipFOOTPRINTs(BOARD *aBoard)
Flip the footprints which are on the back side of the board to the front.
bool m_footprintsAreFlipped
void deleteNETs()
Delete all the NETs that may be in here.
void fillBOUNDARY(BOARD *aBoard, BOUNDARY *aBoundary)
Make the board perimeter for the DSN file by filling the BOUNDARY element in the specctra element tre...
PADSTACK * makePADSTACK(BOARD *aBoard, PAD *aPad)
Create a PADSTACK which matches the given pad.
void SetPCB(PCB *aPcb)
Delete any existing PCB and replaces it with the given one.
std::vector< std::string > m_layerIds
indexed by PCB layer number
static PCB * MakePCB()
Make a PCB with all the default ELEMs and parts on the heap.
bool BuiltBoardOutlines(BOARD *aBoard)
Build the board outlines and store it in m_brd_outlines.
void exportNETCLASS(const NETCLASS *aNetClass, const BOARD *aBoard)
Export aNetClass to the DSN file.
PADSTACK * makeVia(int aCopperDiameter, int aDrillDiameter, int aTopLayer, int aBotLayer)
Make a round through hole PADSTACK using the given KiCad diameter in deci-mils.
boost::ptr_set< PADSTACK > m_padstackset
std::map< PCB_LAYER_ID, int > m_kicadLayer2pcb
maps BOARD layer number to PCB layer numbers
std::vector< NET * > m_nets
we don't want ownership here permanently, so we don't use boost::ptr_vector
void FromBOARD(BOARD *aBoard)
Add the entire BOARD to the PCB but does not write it out.
void RevertFOOTPRINTs(BOARD *aBoard)
Flip the footprints which were on the back side of the board back to the back.
A <via_descriptor> in the specctra dsn spec.
void AppendVia(const char *aViaName)
void SetShape(ELEM *aShape)
A <wire_via_descriptor> in the specctra dsn spec.
std::string m_padstack_id
std::vector< POINT > m_vertexes
A <wire_shape_descriptor> in the specctra dsn spec.
void AddWindow(WINDOW *aWindow)
void SetShape(ELEM *aShape)
A <wiring_descriptor> in the specctra dsn spec.
boost::ptr_vector< WIRE > wires
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
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()
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
LSET is a set of PCB_LAYER_IDs.
static const LSET & AllCuMask()
return AllCuMask( MAX_CU_LAYERS );
LSEQ CuStack() const
Return a sequence of copper layers in starting from the front/top and extending to the back/bottom.
static LSET AllCuMask(int aCuLayerCount)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
A streaming C++ equivalent for MurmurHash3_x64_128.
FORCE_INLINE void add(const std::string &input)
FORCE_INLINE HASH_128 digest()
A collection of nets and the parameters used to route or test these nets.
int GetViaDiameter() const
static const char Default[]
the name of the default NETCLASS
const wxString GetName() const
Gets the name of this (maybe aggregate) netclass in a format for internal usage or for export to exte...
bool HasTrackWidth() const
int GetTrackWidth() const
bool HasClearance() const
Handle the data for a net.
const wxString & GetNetname() const
Wrapper class, so you can iterate through NETINFO_ITEM*s, not std::pair<int/wxString,...
Container for NETINFO_ITEM elements, which are the nets.
@ NORMAL
Shape is the same on all layers.
static constexpr PCB_LAYER_ID ALL_LAYERS
! The layer identifier to use for the single defintion on normal padstacks
LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
void MergePrimitivesAsPolygon(PCB_LAYER_ID aLayer, SHAPE_POLY_SET *aMergedPolygon, ERROR_LOC aErrorLoc=ERROR_INSIDE) const
Merge all basic shapes to a SHAPE_POLY_SET.
int GetRoundRectCornerRadius(PCB_LAYER_ID aLayer) const
const BOX2I GetBoundingBox() const override
The bounding box is cached, so this will be efficient most of the time.
bool IsOnLayer(PCB_LAYER_ID aLayer) const override
Test to see if this object is on the given layer.
const VECTOR2I & GetDelta(PCB_LAYER_ID aLayer) const
VECTOR2I GetOffset(PCB_LAYER_ID aLayer) const
VECTOR2I GetDrillSize() const
PAD_SHAPE GetShape(PCB_LAYER_ID aLayer) const
VECTOR2I GetSize(PCB_LAYER_ID aLayer) const
const PADSTACK & Padstack() const
int GetChamferPositions(PCB_LAYER_ID aLayer) const
double GetChamferRectRatio(PCB_LAYER_ID aLayer) const
PCB_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
bool ExportSpecctraFile(const wxString &aFullFilename)
Export the current BOARD to a specctra dsn file.
int GetWidth() const override
void TransformShapeToPolygon(SHAPE_POLY_SET &aBuffer, PCB_LAYER_ID aLayer, int aClearance, int aError, ERROR_LOC aErrorLoc, bool ignoreLineWidth=false) const override
Convert the shape to a closed polygon.
bool IsOnLayer(PCB_LAYER_ID aLayer) const override
Test to see if this object is on the given layer.
PCB_LAYER_ID GetLayer() const override
Return the primary layer this item is on.
Collect all BOARD_ITEM objects of a given set of KICAD_T type(s).
void Collect(BOARD_ITEM *aBoard, const std::vector< KICAD_T > &aTypes)
Collect BOARD_ITEM objects using this class's Inspector method, which does the collection.
const PADSTACK & Padstack() 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).
void LayerPair(PCB_LAYER_ID *top_layer, PCB_LAYER_ID *bottom_layer) const
Return the 2 layers used by the via (the via actually uses all layers between these 2 layers)
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.
bool IsEndContour() const
Represent a set of closed polygons.
ITERATOR_TEMPLATE< VECTOR2I > ITERATOR
bool IsEmpty() const
Return true if the set is empty (no polygons at all)
int FullPointCount() const
Return the number of points in the shape poly set.
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Appends a vertex at the end of the given outline/hole (default: the last outline)
void Simplify()
Simplify the polyset (merges overlapping polys, eliminates degeneracy/self-intersections)
std::vector< SHAPE_LINE_CHAIN > POLYGON
represents a single polygon outline with holes.
void Unfracture()
Convert a single outline slitted ("fractured") polygon into a set ouf outlines with holes.
SHAPE_LINE_CHAIN & Outline(int aIndex)
Return the reference to aIndex-th outline in the set.
int OutlineCount() const
Return the number of outlines in the set.
void Fracture(bool aSimplify=true)
Convert a set of polygons with holes to a single outline with "slits"/"fractures" connecting the oute...
void BooleanSubtract(const SHAPE_POLY_SET &b)
Perform boolean polyset difference.
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
const std::vector< POLYGON > & CPolygons() const
const char * c_str() const
Handle a list of polygons defining a copper zone.
SHAPE_POLY_SET::ITERATOR IterateWithHoles()
Return an iterator to visit all points of the zone's main outline with holes.
void Rotate(const VECTOR2I &aCentre, const EDA_ANGLE &aAngle) override
Rotate the outlines.
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
This file is part of the common library.
int ConvertArcToPolyline(SHAPE_LINE_CHAIN &aPolyline, VECTOR2I aCenter, int aRadius, const EDA_ANGLE &aStartAngleDeg, const EDA_ANGLE &aArcAngleDeg, double aAccuracy, ERROR_LOC aErrorLoc)
Generate a polyline to approximate a arc.
void TransformRoundChamferedRectToPolygon(SHAPE_POLY_SET &aBuffer, const VECTOR2I &aPosition, const VECTOR2I &aSize, const EDA_ANGLE &aRotation, int aCornerRadius, double aChamferRatio, int aChamferCorners, int aInflate, int aError, ERROR_LOC aErrorLoc)
Convert a rectangle with rounded corners and/or chamfered corners to a polygon.
void BuildConvexHull(std::vector< VECTOR2I > &aResult, const std::vector< VECTOR2I > &aPoly)
Calculate the convex hull of a list of points in counter-clockwise order.
static bool empty(const wxTextEntryBase *aCtrl)
static constexpr EDA_ANGLE ANGLE_0
static constexpr EDA_ANGLE ANGLE_360
static constexpr EDA_ANGLE ANGLE_180
@ RECTANGLE
Use RECTANGLE instead of RECT to avoid collision in a Windows header.
a few functions useful in geometry calculations.
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
PCB_LAYER_ID
A quick note on layer IDs:
This file contains miscellaneous commonly used macros and functions.
@ TOP_BOTTOM
Flip top to bottom (around the X axis)
This source file implements export and import capabilities to the specctra dsn file format.
std::map< wxString, int > PINMAP
data type used to ensure unique-ness of pin names, holding (wxString and int)
static double mapX(int x)
static SPECCTRA_SHAPE_ID appendPadstackShape(PADSTACK *aPadstack, PAD *aPad, PCB_LAYER_ID aPadLayer, const std::vector< std::string > &aLayerNames)
Append the copper aPad carries on aPadLayer to aPadstack, one shape per Specctra layer id in aLayerNa...
static double mapY(int y)
static double IU2um(int kicadDist)
Convert integer internal units to float um.
static POINT mapPt(const VECTOR2I &pt)
Convert a KiCad point into a DSN file point.
static bool isRoundKeepout(PAD *aPad)
Decide if the pad is a copper-less through hole which needs to be made into a round keepout.
static std::string sanitizeForDSNString(const wxString &aValue)
static double scale(int kicadDist)
Convert a distance from Pcbnew internal units to the reported Specctra DSN units in floating point fo...
void ExportBoardToSpecctraFile(BOARD *aBoard, const wxString &aFullFilename)
Helper method to export board to DSN file.
static PATH * makePath(const POINT &aStart, const POINT &aEnd, const std::string &aLayerName)
Create a PATH element with a single straight line, a pair of vertices.
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
@ NET
This item represents a net.
A <pin_reference> definition in the specctra dsn spec.
A point in the SPECCTRA DSN coordinate system.
void FixNegativeZero()
Change negative zero to positive zero in the IEEE floating point storage format.
The identity of the copper on one padstack layer.
bool operator==(const SPECCTRA_SHAPE_ID &aOther) const =default
std::string m_family
Shape family, eg "Round".
std::string m_dims
Dimensions, unique within a family.
std::string m_offset
Hole-to-copper offset, empty when centred.
A storage class for 128-bit hash value.
std::string ToString() const
const SHAPE_LINE_CHAIN chain
SHAPE_CIRCLE circle(c.m_circle_center, c.m_circle_radius)
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
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
@ PCB_PAD_T
class PAD, a pad in a footprint
VECTOR2< int32_t > VECTOR2I