71#define EXPORT_CUSTOM_PADS_CONVEX_HULL
90 errorText = ioe.
What();
99 SetStatusText( wxString(
_(
"BOARD exported OK." ) ) );
120 wxLogWarning(
_(
"Board outline is malformed. Run DRC for a full analysis." ) );
151static inline double scale(
int kicadDist )
154 return kicadDist / (
pcbIUScale.IU_PER_MM / 1000.0 );
159static inline double IU2um(
int kicadDist )
161 return kicadDist * ( 1000.0 /
pcbIUScale.IU_PER_MM );
165static inline double mapX(
int x )
171static inline double mapY(
int y )
198 return mapPt( fpRelative );
207 std::vector<PCB_LAYER_ID> layers = aPad->
Padstack().UniqueLayers();
211 bool swallowedByHole = !layers.empty();
218 swallowedByHole =
false;
222 if( swallowedByHole )
237 path->AppendPoint( aStart );
238 path->AppendPoint( aEnd );
239 path->SetLayerId( aLayerName );
269 const std::vector<std::string>& aLayerNames )
276 if( offset.
x || offset.
y )
278 dsnOffset =
mapPt( offset );
281 std::ostringstream oss;
282 oss.imbue( std::locale::classic() );
283 oss << std::fixed << std::setprecision( 6 )
284 <<
'[' << dsnOffset.
x <<
',' << dsnOffset.
y <<
']';
285 id.m_offset = oss.str();
288 std::ostringstream dims;
289 dims << std::fixed << std::setprecision( 6 );
291 switch( aPad->
GetShape( aPadLayer ) )
295 for(
const std::string& layerName : aLayerNames )
299 aPadstack->
Append( shape );
305 circle->SetLayerId( layerName );
307 circle->SetVertex( dsnOffset );
310 id.m_family =
"Round";
311 dims <<
IU2um( padSize.
x ) <<
"_um";
317 double dx =
scale( padSize.
x ) / 2.0;
318 double dy =
scale( padSize.
y ) / 2.0;
320 POINT lowerLeft( -dx, -dy );
321 POINT upperRight( dx, dy );
323 lowerLeft += dsnOffset;
324 upperRight += dsnOffset;
326 for(
const std::string& layerName : aLayerNames )
330 aPadstack->
Append( shape );
340 id.m_family =
"Rect";
341 dims <<
IU2um( padSize.
x ) <<
"x" <<
IU2um( padSize.
y ) <<
"_um";
347 double dx =
scale( padSize.
x ) / 2.0;
348 double dy =
scale( padSize.
y ) / 2.0;
358 pstart =
POINT( -dr, 0.0 );
359 pstop =
POINT( dr, 0.0 );
366 pstart =
POINT( 0.0, -dr );
367 pstop =
POINT( 0.0, dr );
373 for(
const std::string& layerName : aLayerNames )
378 aPadstack->
Append( shape );
386 id.m_family =
"Oval";
387 dims <<
IU2um( padSize.
x ) <<
"x" <<
IU2um( padSize.
y ) <<
"_um";
393 double dx =
scale( padSize.
x ) / 2.0;
394 double dy =
scale( padSize.
y ) / 2.0;
402 POINT lowerLeft( -dx - ddy, -dy - ddx );
403 POINT upperLeft( -dx + ddy, +dy + ddx );
404 POINT upperRight( +dx - ddy, +dy - ddx );
405 POINT lowerRight( +dx + ddy, -dy + ddx );
407 lowerLeft += dsnOffset;
408 upperLeft += dsnOffset;
409 upperRight += dsnOffset;
410 lowerRight += dsnOffset;
412 for(
const std::string& layerName : aLayerNames )
416 aPadstack->
Append( shape );
419 PATH* polygon =
new PATH( shape, T_polygon );
431 id.m_family =
"Trapz";
432 dims <<
IU2um( padSize.
x ) <<
"x" <<
IU2um( padSize.
y ) <<
"_"
442 const int circleToSegmentsCount = 36;
454 double correctionFactor = cos(
M_PI / (
double) circleToSegmentsCount );
455 int extra_clearance =
KiROUND( rradius * ( 1.0 - correctionFactor ) );
457 psize.
x += extra_clearance * 2;
458 psize.
y += extra_clearance * 2;
459 rradius += extra_clearance;
469 for(
const std::string& layerName : aLayerNames )
473 aPadstack->
Append( shape );
476 PATH* polygon =
new PATH( shape, T_polygon );
485 for(
int idx = 0; idx < polygonal_shape.
PointCount(); idx++ )
493 first_corner = corner;
499 id.m_family =
"RoundRect";
500 dims <<
IU2um( padSize.
x ) <<
'x'
501 <<
IU2um( padSize.
y ) <<
'_'
502 <<
IU2um( rradius ) <<
"_um_"
504 << std::hex << std::uppercase
511 std::vector<VECTOR2I> polygonal_shape;
515#ifdef EXPORT_CUSTOM_PADS_CONVEX_HULL
520 for(
int ii = 0; ii < p_outline.
PointCount(); ++ii )
521 polygonal_shape.push_back( wxPoint( p_outline.
CPoint( ii ) ) );
525 if( polygonal_shape.front() != polygonal_shape.back() )
526 polygonal_shape.push_back( polygonal_shape.front() );
528 for(
const std::string& layerName : aLayerNames )
532 aPadstack->
Append( shape );
535 PATH* polygon =
new PATH( shape, T_polygon );
541 for(
const VECTOR2I& pt : polygonal_shape )
552 id.m_family =
"Cust";
553 dims <<
IU2um( padSize.
x ) <<
'x' <<
IU2um( padSize.
y ) <<
'_'
555 << polygonal_shape.size() <<
"_um_"
561 id.m_dims = dims.str();
569 std::string uniqifier;
583 std::vector<std::pair<PCB_LAYER_ID, std::vector<std::string>>> layerGroups;
585 bool onAllCopperLayers = ( (aPad->
GetLayerSet() & all_cu) == all_cu );
587 if( onAllCopperLayers )
590 for(
int layer=0; layer < copperCount; ++layer )
594 if( onAllCopperLayers || aPad->
IsOnLayer( kilayer ) )
597 auto group = std::find_if( layerGroups.begin(), layerGroups.end(),
598 [&](
const auto& aGroup )
600 return aGroup.first == padLayer;
603 if(
group == layerGroups.end() )
604 layerGroups.emplace_back( padLayer, std::vector<std::string>{
m_layerIds[layer] } );
608 if( !onAllCopperLayers )
612 else if( layer == copperCount - 1 )
615 uniqifier += char(
'0' + layer);
622 if( layerGroups.empty() )
624 padstack->
SetPadstackId( (
"Empty" + uniqifier +
"Pad" ).c_str() );
629 std::vector<SPECCTRA_SHAPE_ID> shapeIds;
631 for(
const auto& [padLayer, names] : layerGroups )
634 bool uniform = std::all_of( shapeIds.begin(), shapeIds.end(),
637 return aId == shapeIds.front();
641 std::ostringstream oss;
645 oss << shapeIds.front().m_family << uniqifier << shapeIds.front().m_offset <<
"Pad_"
646 << shapeIds.front().m_dims;
654 for(
size_t ndx = 0; ndx < shapeIds.size(); ++ndx )
656 for(
const std::string&
name : layerGroups[ndx].second )
659 hash.
add( shapeIds[ndx].m_family );
660 hash.
add( shapeIds[ndx].m_offset );
661 hash.
add( shapeIds[ndx].m_dims );
664 oss <<
"Complex" << uniqifier << shapeIds.front().m_offset <<
"Pad_"
665 << shapeIds.front().m_family <<
'_' << shapeIds.front().m_dims <<
'_'
694 for(
int p = 0; p < fpItems.
GetCount(); ++p )
701 double diameter =
scale(
pad->GetDrillSize().x );
708 for(
int layer=0; layer<layerCount; ++layer )
712 image->m_keepouts.push_back( keepout );
718 circle->SetDiameter( diameter );
719 circle->SetVertex( vertex );
729 if( !mask_copper_layers.any() )
739 padstack = (
PADSTACK*) *iter.base();
748 padNumber =
pad->GetNumber();
751 if( padNumber != wxEmptyString && pinmap.find( padNumber ) == pinmap.end() )
753 pinmap[ padNumber ] = 0;
757 int duplicates = ++pinmap[ padNumber ];
760 "@" + std::to_string( duplicates );
763 pin->m_kiNetCode =
pad->GetNetCode();
788 image->Append( outline );
793 path->SetAperture( 0 );
794 path->SetLayerId(
"signal" );
796 for(
int ii = 0; ii <
chain.PointCount(); ++ii )
799 path->AppendPoint(
mapPt( corner, aFootprint ) );
807 for(
int i = 0; i < fpItems.
GetCount(); ++i )
821 image->Append( outline );
826 path->SetLayerId(
"signal" );
836 image->Append( outline );
842 path->SetLayerId(
"signal" );
851 for(
int ii = 0; ii < polyline.
PointCount(); ++ii )
854 path->AppendPoint(
mapPt( corner, aFootprint ) );
864 image->Append( outline );
869 path->SetLayerId(
"signal" );
871 path->AppendPoint(
mapPt( corner, aFootprint ) );
874 path->AppendPoint(
mapPt( corner, aFootprint ) );
877 path->AppendPoint(
mapPt( corner, aFootprint ) );
880 path->AppendPoint(
mapPt( corner, aFootprint ) );
883 path->AppendPoint(
mapPt( corner, aFootprint ) );
895 image->Append( outline );
896 path =
new PATH( outline, T_polygon );
899 path->SetAperture( 0 );
900 path->SetLayerId(
"signal" );
908 for(
int ii = 0; ii < poly.
PointCount(); ++ii )
911 path->AppendPoint(
mapPt( corner, aFootprint ) );
924 if( !zone->GetIsRuleArea() )
928 ZONE untransformedZone( *zone );
940 if( zone->GetDoNotAllowVias() && zone->GetDoNotAllowTracks() )
941 keepout_type = T_keepout;
942 else if( zone->GetDoNotAllowVias() )
943 keepout_type = T_via_keepout;
944 else if( zone->GetDoNotAllowTracks() )
945 keepout_type = T_wire_keepout;
947 keepout_type = T_keepout;
956 image->m_keepouts.push_back( keepout );
958 PATH* mainPolygon =
new PATH( keepout, T_polygon );
965 bool is_first_point =
true;
968 for( iterator = untransformedZone.
IterateWithHoles(); iterator; iterator++ )
977 is_first_point =
false;
991 PATH* cutout =
nullptr;
992 bool isStartContour =
true;
995 for( iterator++; iterator; iterator++ )
999 is_first_point =
true;
1000 window =
new WINDOW( keepout );
1003 cutout =
new PATH( window, T_polygon );
1019 if( is_first_point )
1022 is_first_point =
false;
1039 int aTopLayer,
int aBotLayer )
1043 double dsnDiameter =
scale( aCopperDiameter );
1045 for(
int layer=aTopLayer; layer<=aBotLayer; ++layer )
1049 padstack->
Append( shape );
1055 circle->SetDiameter( dsnDiameter );
1059 snprintf(
name,
sizeof(
name ),
"Via[%d-%d]_%.6g:%.6g_um",
1060 aTopLayer, aBotLayer, dsnDiameter,
1062 IU2um( aDrillDiameter ) );
1076 aVia->
LayerPair( &topLayerNum, &botLayerNum );
1081 if( topLayer > botLayer )
1082 std::swap( topLayer, botLayer );
1091 std::ostringstream oss;
1093 oss <<
"Via[" << topLayer <<
'-' << botLayer <<
']' << std::fixed << std::setprecision( 6 );
1095 for(
int layer = topLayer; layer <= botLayer; ++layer )
1102 padstack->Append( shape );
1106 shape->SetShape(
circle );
1108 circle->SetDiameter( dsnDiameter );
1111 oss <<
'_' << dsnDiameter;
1117 padstack->SetPadstackId( oss.str().c_str() );
1129 path->layer_id =
"pcb";
1133 for(
int ii = 0; ii < outline.
PointCount(); ii++ )
1148 PATH* poly_ko =
new PATH(
nullptr, T_polygon );
1152 m_pcb->m_structure->m_keepouts.push_back( keepout );
1156 for(
int jj = 0; jj < hole.
PointCount(); jj++ )
1174 wxString ret = aValue;
1175 ret.Replace( wxT(
"\"" ), wxT(
"''" ) );
1188 std::map<FOOTPRINT*, std::string> componentIds;
1190 std::set<wxString> used;
1194 wxString ref = footprint->GetReference();
1197 ref = wxT(
"REF**" );
1199 wxString unique = ref;
1201 for(
int suffix = 1; !used.insert( unique.Lower() ).second; ++suffix )
1202 unique = wxString::Format( wxT(
"%s_%d" ), ref, suffix );
1204 componentIds[footprint] =
TO_UTF8( unique );
1220 for(
int pcbNdx=0; pcbNdx<layerCount; ++pcbNdx )
1224 m_pcb->m_structure->m_layers.push_back( layer );
1233 case LT_SIGNAL: layerType = T_signal;
break;
1234 case LT_POWER: layerType = T_power;
break;
1238 case LT_MIXED: layerType = T_signal;
break;
1239 case LT_JUMPER: layerType = T_jumper;
break;
1246 property->name =
"index";
1247 property->value = std::to_string( pcbNdx );
1252 m_pcb->m_parser->space_in_quoted_tokens =
true;
1259 m_pcb->m_unit->units = T_um;
1260 m_pcb->m_resolution->units = T_um;
1261 m_pcb->m_resolution->value = 10;
1270 m_pcb->m_structure->SetBOUNDARY( boundary );
1277 int defaultTrackWidth = netSettings->GetDefaultNetclass()->GetTrackWidth();
1278 int defaultClearance = netSettings->GetDefaultNetclass()->GetClearance();
1281 std::vector<std::string>& rules =
m_pcb->m_structure->m_rules->m_rules;
1283 std::snprintf( rule,
sizeof( rule ),
"(width %.6g)",
scale( defaultTrackWidth ) );
1284 rules.push_back( rule );
1286 std::snprintf( rule,
sizeof( rule ),
"(clearance %.6g)",
clearance );
1287 rules.push_back( rule );
1294 std::snprintf( rule,
sizeof( rule ),
"(clearance %.6g (type smd_smd))",
clearance );
1295 rules.push_back( rule );
1302 int netlessZones = 0;
1307 if( aChain.PointCount() < 3 )
1310 for(
int v = 0; v < aChain.PointCount(); v++ )
1318 if( zone->GetIsRuleArea() || !zone->IsOnCopperLayer() )
1322 wxCHECK2( zoneOutline && zoneOutline->
OutlineCount() > 0,
continue );
1327 wxCHECK2( zoneOutlineFractured.
OutlineCount() == 1,
continue );
1332 std::string netId = zone->GetNetname().utf8_string();
1337 no_net->
m_net_id =
"@:no_net_" + std::to_string( netlessZones++ );
1338 m_pcb->m_network->m_nets.push_back( no_net );
1349 wiring->
wires.push_back( wire );
1353 PATH* mainPolygon =
new PATH( wire, T_polygon );
1356 appendClosedChain( mainPolygon, zoneOutlineFractured.
COutline( 0 ) );
1360 if( !zoneFill || zoneFill->
IsEmpty() )
1379 PATH* cutout =
new PATH( window, T_polygon );
1382 appendClosedChain( cutout, hole );
1392 if( !zone->GetIsRuleArea() )
1400 if( zone->GetDoNotAllowVias() && zone->GetDoNotAllowTracks() )
1401 keepout_type = T_keepout;
1402 else if( zone->GetDoNotAllowVias() )
1403 keepout_type = T_via_keepout;
1404 else if( zone->GetDoNotAllowTracks() )
1405 keepout_type = T_wire_keepout;
1407 keepout_type = T_keepout;
1416 m_pcb->m_structure->m_keepouts.push_back( keepout );
1418 PATH* mainPolygon =
new PATH( keepout, T_polygon );
1425 bool is_first_point =
true;
1428 for( iterator = zone->IterateWithHoles(); iterator; iterator++ )
1432 if( is_first_point )
1435 is_first_point =
false;
1448 WINDOW* window =
nullptr;
1449 PATH* cutout =
nullptr;
1451 bool isStartContour =
true;
1454 for( iterator++; iterator; iterator++ )
1456 if( isStartContour )
1458 is_first_point =
true;
1459 window =
new WINDOW( keepout );
1462 cutout =
new PATH( window, T_polygon );
1474 if( is_first_point )
1477 is_first_point =
false;
1493 std::string componentId;
1494 int highestNetCode = 0;
1499 highestNetCode = std::max( highestNetCode, i->GetNetCode() );
1504 m_nets.resize( highestNetCode + 1,
nullptr );
1506 for(
unsigned i = 1 ; i <
m_nets.size(); ++i )
1511 if( i->GetNetCode() > 0 )
1521 componentId = componentIds[footprint];
1531 int netcode =
pin.m_kiNetCode;
1559 comp->m_places.push_back( place );
1561 place->
SetRotation( footprint->GetOrientationDegrees() );
1567 if( footprint->GetFlag() )
1580 boost::ptr_set<PADSTACK>::auto_type ps =
m_padstackset.release( i );
1583 m_pcb->m_library->AddPadstack( padstack );
1587 for(
unsigned n = 1; n <
m_nets.size(); ++n )
1594 m_pcb->m_network->m_nets.push_back( net );
1601 std::unordered_map<wxString, NETCLASS*> netclassesInUse;
1605 NETCLASS* netclass = net->GetNetClass();
1612 if( !netclassesInUse.contains(
name ) )
1613 netclassesInUse[
name] = netclass;
1635 wxASSERT(
m_pcb->m_library->m_vias.size() == 0 );
1636 m_pcb->m_library->AppendVia(
via );
1642 for(
const auto& [
name, netclass] : netclassesInUse )
1663 if( !track->IsType( { PCB_TRACE_T, PCB_ARC_T } ) )
1666 int netcode = track->GetNetCode();
1676 wiring->
wires.push_back( wire );
1679 if( track->IsLocked() )
1690 path->aperture_width =
scale( track->GetWidth() );
1691 path->AppendPoint(
mapPt( track->GetStart() ) );
1692 path->AppendPoint(
mapPt( track->GetEnd() ) );
1705 int netcode =
via->GetNetCode();
1720 m_pcb->m_wiring->wire_vias.push_back( dsnVia );
1730 if(
via->IsLocked() )
1745 VIA* vias =
m_pcb->m_structure->m_via;
1747 for(
unsigned viaNdx = 0; viaNdx <
m_pcb->m_library->m_vias.size(); ++viaNdx )
1748 vias->
AppendVia(
m_pcb->m_library->m_vias[viaNdx].m_padstack_id.c_str() );
1754 exportNETCLASS( netSettings->GetDefaultNetclass().get(), aBoard );
1756 for(
const auto& [
name, netclass] : netclassesInUse )
1795 m_pcb->m_network->m_classes.push_back( clazz );
1801 if( net->GetNetClass()->GetName() == clazz->
m_class_id )
1811 std::snprintf(
text,
sizeof(
text ),
"(width %.6g)",
scale( trackWidth ) );
1835 snprintf(
text,
sizeof(
text ),
"(use_via \"%s\")",
via->GetPadstackId().c_str() );
1849 footprint->SetFlag( 0 );
1851 if( footprint->GetLayer() ==
B_Cu )
1854 footprint->SetFlag( 1 );
1872 if( footprint->GetFlag() )
1875 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
Represent basic circle geometry with utility geometry functions.
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.
A PADSTACK defines the characteristics of a single or multi-layer pad, in the IPC sense of the word.
@ 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
An abstract shape on 2D plane.
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.
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)
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.
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
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