CADSTAR PCB Archive Importer: Load TEMPLATEs, COPPERs and NETs (including Tracks and Vias)
This commit is contained in:
parent
05de678f4e
commit
866c069873
|
@ -47,6 +47,17 @@ void CADSTAR_ARCHIVE_PARSER::POINT::Parse( XNODE* aNode )
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void CADSTAR_ARCHIVE_PARSER::LONGPOINT::Parse( XNODE* aNode )
|
||||
{
|
||||
wxASSERT( aNode->GetName() == wxT( "PT" ) );
|
||||
|
||||
x = GetXmlAttributeIDLong( aNode, 0 );
|
||||
y = GetXmlAttributeIDLong( aNode, 1 );
|
||||
}
|
||||
|
||||
|
||||
bool CADSTAR_ARCHIVE_PARSER::VERTEX::IsVertex( XNODE* aNode )
|
||||
{
|
||||
wxString aNodeName = aNode->GetName();
|
||||
|
@ -241,7 +252,7 @@ long CADSTAR_ARCHIVE_PARSER::GetXmlAttributeIDLong( XNODE* aNode, unsigned int a
|
|||
|
||||
void CADSTAR_ARCHIVE_PARSER::CheckNoChildNodes( XNODE* aNode )
|
||||
{
|
||||
if( aNode->GetChildren() )
|
||||
if( aNode && aNode->GetChildren() )
|
||||
{
|
||||
THROW_UNKNOWN_NODE_IO_ERROR( aNode->GetChildren()->GetName(), aNode->GetName() );
|
||||
}
|
||||
|
@ -250,7 +261,7 @@ void CADSTAR_ARCHIVE_PARSER::CheckNoChildNodes( XNODE* aNode )
|
|||
|
||||
void CADSTAR_ARCHIVE_PARSER::CheckNoNextNodes( XNODE* aNode )
|
||||
{
|
||||
if( aNode->GetNext() )
|
||||
if( aNode && aNode->GetNext() )
|
||||
{
|
||||
THROW_UNKNOWN_NODE_IO_ERROR( aNode->GetNext()->GetName(), aNode->GetParent()->GetName() );
|
||||
}
|
||||
|
|
|
@ -83,6 +83,15 @@ public:
|
|||
};
|
||||
|
||||
|
||||
struct LONGPOINT
|
||||
{
|
||||
long x = UNDEFINED_VALUE;
|
||||
long y = UNDEFINED_VALUE;
|
||||
|
||||
void Parse( XNODE* aNode );
|
||||
};
|
||||
|
||||
|
||||
enum class VERTEX_TYPE
|
||||
{
|
||||
POINT,
|
||||
|
|
|
@ -26,47 +26,53 @@
|
|||
#include <cadstar_pcb_archive_loader.h>
|
||||
|
||||
#include <board_stackup_manager/stackup_predefined_prms.h> // KEY_COPPER, KEY_CORE, KEY_PREPREG
|
||||
#include <class_drawsegment.h> // DRAWSEGMENT
|
||||
#include <limits> // std::numeric_limits
|
||||
#include <trigo.h>
|
||||
|
||||
#include <class_board.h>
|
||||
#include <class_dimension.h>
|
||||
#include <class_drawsegment.h> // DRAWSEGMENT
|
||||
#include <class_edge_mod.h>
|
||||
#include <class_module.h>
|
||||
#include <class_pcb_text.h>
|
||||
#include <class_track.h>
|
||||
#include <class_zone.h>
|
||||
#include <convert_basic_shapes_to_polygon.h>
|
||||
#include <trigo.h>
|
||||
|
||||
#include <limits> // std::numeric_limits
|
||||
|
||||
void CADSTAR_PCB_ARCHIVE_LOADER::Load( ::BOARD* aBoard )
|
||||
{
|
||||
mBoard = aBoard;
|
||||
Parse();
|
||||
|
||||
wxPoint designSize =
|
||||
Assignments.Technology.DesignArea.first - Assignments.Technology.DesignArea.second;
|
||||
LONGPOINT designLimit = Assignments.Technology.DesignLimit;
|
||||
|
||||
//Note: can't use getKiCadPoint() due wxPoint being int - need long long to make the check
|
||||
long long designSizeXkicad = (long long) designSize.x * KiCadUnitMultiplier;
|
||||
long long designSizeYkicad = (long long) designSize.y * KiCadUnitMultiplier;
|
||||
long long maxDesignSizekicad = (long long) std::numeric_limits<int>::max()
|
||||
+ std::abs( std::numeric_limits<int>::min() );
|
||||
long long designSizeXkicad = (long long) designLimit.x * KiCadUnitMultiplier;
|
||||
long long designSizeYkicad = (long long) designLimit.y * KiCadUnitMultiplier;
|
||||
|
||||
// Max size limited by the positive dimention of wxPoint
|
||||
long long maxDesignSizekicad = (long long) std::numeric_limits<int>::max();
|
||||
|
||||
if( designSizeXkicad > maxDesignSizekicad || designSizeYkicad > maxDesignSizekicad )
|
||||
THROW_IO_ERROR( wxString::Format(
|
||||
_( "The design is too large and cannot be imported into KiCad. \n"
|
||||
"Please reduce the maximum design size in CADSTAR by navigating to: \n"
|
||||
"Design Tab -> Properties -> Design Options -> Maximum Design Size. \n"
|
||||
"Current Design size: %d, %d micrometers. \n"
|
||||
"Maximum permitted design size: %d, %d micrometers.\n" ),
|
||||
designSizeXkicad / 1000, designSizeYkicad / 1000, maxDesignSizekicad / 1000,
|
||||
maxDesignSizekicad / 1000 ) );
|
||||
"Current Design size: %.2f, %.2f milimetres. \n"
|
||||
"Maximum permitted design size: %.2f, %.2f milimetres.\n" ),
|
||||
(double) designSizeXkicad / 1E6, (double) designSizeYkicad / 1E6,
|
||||
(double) maxDesignSizekicad / 1E6, (double) maxDesignSizekicad / 1E6 ) );
|
||||
|
||||
mDesignCenter =
|
||||
( Assignments.Technology.DesignArea.first + Assignments.Technology.DesignArea.second )
|
||||
/ 2;
|
||||
|
||||
if( Layout.NetSynch == NETSYNCH::WARNING )
|
||||
wxLogWarning(
|
||||
_( "The selected file indicates that nets might be out of synchronisation "
|
||||
"with the schematic. It is recommended that you carry out an 'Align Nets' "
|
||||
"procedure in CADSTAR and re-import, to avoid inconsistencies between the "
|
||||
"PCB and the schematic. " ) );
|
||||
|
||||
loadBoardStackup();
|
||||
loadComponentLibrary();
|
||||
|
@ -74,6 +80,9 @@ void CADSTAR_PCB_ARCHIVE_LOADER::Load( ::BOARD* aBoard )
|
|||
loadFigures();
|
||||
loadAreas();
|
||||
loadComponents();
|
||||
loadTemplates();
|
||||
loadCoppers();
|
||||
loadNets();
|
||||
|
||||
//TODO: process all other items
|
||||
|
||||
|
@ -166,6 +175,7 @@ void CADSTAR_PCB_ARCHIVE_LOADER::loadBoardStackup()
|
|||
kicadLayerID = getKiCadCopperLayerID( ++numElecAndPowerLayers );
|
||||
kicadLayerType = BOARD_STACKUP_ITEM_TYPE::BS_ITEM_TYPE_COPPER;
|
||||
layerTypeName = KEY_COPPER;
|
||||
mPowerPlaneLayers.push_back( curLayer.ID ); //we will need to add a Copper zone
|
||||
break;
|
||||
|
||||
case LAYER_TYPE::CONSTRUCTION:
|
||||
|
@ -427,7 +437,8 @@ void CADSTAR_PCB_ARCHIVE_LOADER::loadLibraryPads( const SYMDEF& aComponent, MODU
|
|||
PADCODE csPadcode = getPadCode( csPad.PadCodeID );
|
||||
|
||||
D_PAD* pad = new D_PAD( aModule );
|
||||
aModule->Add( pad, ADD_MODE::APPEND );
|
||||
aModule->Add( pad, ADD_MODE::INSERT ); // insert so that we get correct behaviour when finding pads
|
||||
// in the module by PAD_ID - see loadNets()
|
||||
|
||||
switch( csPad.Side )
|
||||
{
|
||||
|
@ -460,7 +471,7 @@ void CADSTAR_PCB_ARCHIVE_LOADER::loadLibraryPads( const SYMDEF& aComponent, MODU
|
|||
csPad.Identifier );
|
||||
|
||||
pad->SetPos0( getKiCadPoint( csPad.Position ) - aModule->GetPosition() );
|
||||
pad->SetOrientation( getKiCadAngle( csPad.OrientAngle ) );
|
||||
pad->SetOrientation( getAngleTenthDegree( csPad.OrientAngle ) );
|
||||
|
||||
switch( csPadcode.Shape.ShapeType )
|
||||
{
|
||||
|
@ -544,7 +555,7 @@ void CADSTAR_PCB_ARCHIVE_LOADER::loadLibraryPads( const SYMDEF& aComponent, MODU
|
|||
if( csPadcode.ReliefWidth != UNDEFINED_VALUE )
|
||||
pad->SetThermalWidth( getKiCadLength( csPadcode.ReliefWidth ) );
|
||||
|
||||
pad->SetOrientation( pad->GetOrientation() + getKiCadAngle( csPadcode.Shape.OrientAngle ) );
|
||||
pad->SetOrientation( pad->GetOrientation() + getAngleTenthDegree( csPadcode.Shape.OrientAngle ) );
|
||||
|
||||
if( csPadcode.DrillDiameter != UNDEFINED_VALUE )
|
||||
{
|
||||
|
@ -665,7 +676,7 @@ void CADSTAR_PCB_ARCHIVE_LOADER::loadComponents()
|
|||
m->SetValue( wxEmptyString );
|
||||
|
||||
m->SetPosition( getKiCadPoint( comp.Origin ) );
|
||||
m->SetOrientation( getKiCadAngle( comp.OrientAngle ) );
|
||||
m->SetOrientation( getAngleTenthDegree( comp.OrientAngle ) );
|
||||
m->SetReference( comp.Name );
|
||||
|
||||
if( comp.Mirror )
|
||||
|
@ -676,11 +687,305 @@ void CADSTAR_PCB_ARCHIVE_LOADER::loadComponents()
|
|||
|
||||
loadComponentAttributes( comp, m );
|
||||
m->SetDescription( getPart( comp.PartID ).Definition.Name );
|
||||
|
||||
mComponentMap.insert( { comp.ID, m } );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CADSTAR_PCB_ARCHIVE_LOADER::loadComponentAttributes( const COMPONENT& aComponent, MODULE* aModule )
|
||||
void CADSTAR_PCB_ARCHIVE_LOADER::loadTemplates()
|
||||
{
|
||||
for( std::pair<TEMPLATE_ID, TEMPLATE> tempPair : Layout.Templates )
|
||||
{
|
||||
TEMPLATE& csTemplate = tempPair.second;
|
||||
|
||||
ZONE_CONTAINER* zone = getZoneFromCadstarShape(
|
||||
csTemplate.Shape, getLineThickness( csTemplate.LineCodeID ) );
|
||||
|
||||
mBoard->Add( zone, ADD_MODE::APPEND );
|
||||
|
||||
zone->SetZoneName( csTemplate.Name );
|
||||
zone->SetLayer( getKiCadLayer( csTemplate.LayerID ) );
|
||||
|
||||
if( !csTemplate.NetID.IsEmpty() )
|
||||
zone->SetNet( getKiCadNet( csTemplate.NetID ) );
|
||||
|
||||
if( csTemplate.Pouring.AllowInNoRouting )
|
||||
wxLogError( wxString::Format(
|
||||
_( "The CADSTAR template '%s' has the setting 'Allow in No Routing Areas' "
|
||||
"enabled. This setting has no KiCad equivalent, so it has been ignored." ),
|
||||
csTemplate.Name ) );
|
||||
|
||||
if( csTemplate.Pouring.BoxIsolatedPins )
|
||||
wxLogError( wxString::Format(
|
||||
_( "The CADSTAR template '%s' has the setting 'Box Isolated Pins'"
|
||||
"enabled. This setting has no KiCad equivalent, so it has been ignored." ),
|
||||
csTemplate.Name ) );
|
||||
|
||||
if( csTemplate.Pouring.AutomaticRepour )
|
||||
wxLogWarning( wxString::Format(
|
||||
_( "The CADSTAR template '%s' has the setting 'Automatic Repour'"
|
||||
"enabled. This setting has no KiCad equivalent, so it has been ignored." ),
|
||||
csTemplate.Name ) );
|
||||
|
||||
// Sliver width has different behaviour to KiCad Zone's minimum thickness
|
||||
// In Cadstar 'Sliver width' has to be greater than the Copper thickness, whereas in
|
||||
// Kicad it is the opposite.
|
||||
if( csTemplate.Pouring.SliverWidth != 0 )
|
||||
wxLogError( wxString::Format(
|
||||
_( "The CADSTAR template '%s' has a non-zero value defined for the "
|
||||
"'Sliver Width' setting. There is no KiCad equivalent for "
|
||||
"this, so this setting was ignored." ),
|
||||
csTemplate.Name ) );
|
||||
|
||||
|
||||
if( csTemplate.Pouring.MinIsolatedCopper != csTemplate.Pouring.MinDisjointCopper )
|
||||
wxLogError( wxString::Format(
|
||||
_( "The CADSTAR template '%s' has different settings for 'Retain Poured Copper "
|
||||
"- Disjoint' and 'Retain Poured Copper - Isolated'. KiCad does not "
|
||||
"distinguish between these two settings. The setting for disjoint copper "
|
||||
"has been applied as the minimum island area of the KiCad Zone." ),
|
||||
csTemplate.Name ) );
|
||||
|
||||
if( csTemplate.Pouring.MinDisjointCopper < 0 )
|
||||
zone->SetMinIslandArea( -1 );
|
||||
else
|
||||
zone->SetMinIslandArea(
|
||||
(long long) getKiCadLength( csTemplate.Pouring.MinDisjointCopper )
|
||||
* (long long) getKiCadLength( csTemplate.Pouring.MinDisjointCopper ) );
|
||||
|
||||
zone->SetZoneClearance( getKiCadLength( csTemplate.Pouring.AdditionalIsolation ) );
|
||||
|
||||
if( csTemplate.Pouring.FillType == TEMPLATE::POURING::COPPER_FILL_TYPE::HATCHED )
|
||||
{
|
||||
zone->SetFillMode( ZONE_FILL_MODE::HATCH_PATTERN );
|
||||
zone->SetHatchGap( getKiCadHatchCodeGap( csTemplate.Pouring.HatchCodeID ) );
|
||||
zone->SetHatchThickness( getKiCadHatchCodeThickness( csTemplate.Pouring.HatchCodeID ) );
|
||||
zone->SetHatchOrientation( getHatchCodeAngleDegrees( csTemplate.Pouring.HatchCodeID ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
zone->SetFillMode( ZONE_FILL_MODE::POLYGONS );
|
||||
}
|
||||
|
||||
if( csTemplate.Pouring.ThermalReliefOnPads != csTemplate.Pouring.ThermalReliefOnVias
|
||||
|| csTemplate.Pouring.ThermalReliefPadsAngle
|
||||
!= csTemplate.Pouring.ThermalReliefViasAngle )
|
||||
wxLogWarning( wxString::Format(
|
||||
_( "The CADSTAR template '%s' has different settings for thermal relief "
|
||||
"in pads and vias. KiCad only supports one single setting for both. The "
|
||||
"setting for pads has been applied." ),
|
||||
csTemplate.Name ) );
|
||||
|
||||
if( csTemplate.Pouring.ThermalReliefOnPads )
|
||||
{
|
||||
zone->SetThermalReliefGap( getKiCadLength( csTemplate.Pouring.ClearanceWidth ) );
|
||||
zone->SetThermalReliefCopperBridge( getKiCadLength(
|
||||
getCopperCode( csTemplate.Pouring.ReliefCopperCodeID ).CopperWidth ) );
|
||||
zone->SetPadConnection( ZONE_CONNECTION::THERMAL );
|
||||
}
|
||||
else
|
||||
zone->SetPadConnection( ZONE_CONNECTION::FULL );
|
||||
}
|
||||
|
||||
//Now create power plane layers:
|
||||
for( LAYER_ID layer : mPowerPlaneLayers )
|
||||
{
|
||||
wxASSERT( Assignments.Layerdefs.Layers.find( layer ) != Assignments.Layerdefs.Layers.end() );
|
||||
|
||||
//The net name will equal the layer name
|
||||
wxString powerPlaneLayerName = Assignments.Layerdefs.Layers.at( layer ).Name;
|
||||
NET_ID netid = wxEmptyString;
|
||||
|
||||
for( std::pair<NET_ID, NET> netPair : Layout.Nets )
|
||||
{
|
||||
NET net = netPair.second;
|
||||
|
||||
if( net.Name == powerPlaneLayerName )
|
||||
{
|
||||
netid = net.ID;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( netid.IsEmpty() )
|
||||
{
|
||||
wxLogError( wxString::Format(
|
||||
_( "The CADSTAR layer '%s' is defined as a power plane layer. However no "
|
||||
"net with such name exists. The layer has been loaded but no copper zone "
|
||||
"was created." ),
|
||||
powerPlaneLayerName ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
for( std::pair<BOARD_ID, BOARD> boardPair : Layout.Boards )
|
||||
{
|
||||
//create a zone in each board shape
|
||||
BOARD& board = boardPair.second;
|
||||
int defaultLineThicknesss =
|
||||
mBoard->GetDesignSettings().GetLineThickness( PCB_LAYER_ID::Edge_Cuts );
|
||||
ZONE_CONTAINER* zone =
|
||||
getZoneFromCadstarShape( board.Shape, defaultLineThicknesss );
|
||||
|
||||
mBoard->Add( zone, ADD_MODE::APPEND );
|
||||
|
||||
zone->SetZoneName( powerPlaneLayerName );
|
||||
zone->SetLayer( getKiCadLayer( layer ) );
|
||||
zone->SetFillMode( ZONE_FILL_MODE::POLYGONS );
|
||||
zone->SetPadConnection( ZONE_CONNECTION::FULL );
|
||||
zone->SetMinIslandArea( -1 );
|
||||
zone->SetNet( getKiCadNet( netid ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void CADSTAR_PCB_ARCHIVE_LOADER::loadCoppers()
|
||||
{
|
||||
for( std::pair<COPPER_ID, COPPER> copPair : Layout.Coppers )
|
||||
{
|
||||
COPPER& csCopper = copPair.second;
|
||||
|
||||
if( !csCopper.PouredTemplateID.IsEmpty() )
|
||||
continue; //ignore copper related to a template as we've already loaded it!
|
||||
|
||||
// For now we are going to load coppers to a KiCad zone however this isn't perfect
|
||||
//TODO: Load onto a graphical polygon with a net (when KiCad has this feature)
|
||||
|
||||
if( !mDoneCopperWarning )
|
||||
{
|
||||
wxLogWarning(
|
||||
_( "The CADSTAR design contains COPPER elements, which have no direct KiCad "
|
||||
"equivalent. These have been imported as a KiCad Zone if solid or hatch "
|
||||
"filled, or as a KiCad Track if the shape was an unfilled outline (open or "
|
||||
"closed)." ) );
|
||||
mDoneCopperWarning = true;
|
||||
}
|
||||
|
||||
|
||||
if( csCopper.Shape.Type == SHAPE_TYPE::OPENSHAPE
|
||||
|| csCopper.Shape.Type == SHAPE_TYPE::OUTLINE )
|
||||
{
|
||||
std::vector<DRAWSEGMENT*> outlineSegments =
|
||||
getDrawSegmentsFromVertices( csCopper.Shape.Vertices );
|
||||
|
||||
std::vector<TRACK*> outlineTracks = makeTracksFromDrawsegments( outlineSegments, mBoard,
|
||||
getKiCadNet(csCopper.NetRef.NetID) , getKiCadLayer( csCopper.LayerID ),
|
||||
getKiCadLength( getCopperCode( csCopper.CopperCodeID ).CopperWidth ) );
|
||||
|
||||
//cleanup
|
||||
for( DRAWSEGMENT* ds : outlineSegments )
|
||||
{
|
||||
if( ds )
|
||||
delete ds;
|
||||
}
|
||||
|
||||
for( CUTOUT cutout : csCopper.Shape.Cutouts )
|
||||
{
|
||||
std::vector<DRAWSEGMENT*> cutoutSeg =
|
||||
getDrawSegmentsFromVertices( cutout.Vertices );
|
||||
|
||||
std::vector<TRACK*> cutoutTracks = makeTracksFromDrawsegments( cutoutSeg, mBoard,
|
||||
getKiCadNet( csCopper.NetRef.NetID ), getKiCadLayer( csCopper.LayerID ),
|
||||
getKiCadLength( getCopperCode( csCopper.CopperCodeID ).CopperWidth ) );
|
||||
|
||||
//cleanup
|
||||
for( DRAWSEGMENT* ds : cutoutSeg )
|
||||
{
|
||||
if( ds )
|
||||
delete ds;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ZONE_CONTAINER* zone = getZoneFromCadstarShape( csCopper.Shape,
|
||||
getKiCadLength( getCopperCode( csCopper.CopperCodeID ).CopperWidth ) );
|
||||
|
||||
mBoard->Add( zone, ADD_MODE::APPEND );
|
||||
|
||||
zone->SetZoneName( csCopper.ID );
|
||||
zone->SetLayer( getKiCadLayer( csCopper.LayerID ) );
|
||||
|
||||
if( csCopper.Shape.Type == SHAPE_TYPE::HATCHED )
|
||||
{
|
||||
zone->SetFillMode( ZONE_FILL_MODE::HATCH_PATTERN );
|
||||
zone->SetHatchGap( getKiCadHatchCodeGap( csCopper.Shape.HatchCodeID ) );
|
||||
zone->SetHatchThickness( getKiCadHatchCodeThickness( csCopper.Shape.HatchCodeID ) );
|
||||
zone->SetHatchOrientation( getHatchCodeAngleDegrees( csCopper.Shape.HatchCodeID ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
zone->SetFillMode( ZONE_FILL_MODE::POLYGONS );
|
||||
}
|
||||
|
||||
zone->SetPadConnection( ZONE_CONNECTION::FULL );
|
||||
zone->SetNet( getKiCadNet( csCopper.NetRef.NetID ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CADSTAR_PCB_ARCHIVE_LOADER::loadNets()
|
||||
{
|
||||
for( std::pair<NET_ID, NET> netPair : Layout.Nets )
|
||||
{
|
||||
NET net = netPair.second;
|
||||
wxString netname = net.Name;
|
||||
|
||||
if( netname.IsEmpty() )
|
||||
netname = "$" + net.SignalNum;
|
||||
|
||||
for( NET::CONNECTION connection : net.Connections )
|
||||
{
|
||||
if( !connection.Unrouted )
|
||||
loadNetTracks( net.ID, connection.Route );
|
||||
|
||||
//TODO: all other elements
|
||||
}
|
||||
|
||||
for( std::pair<NETELEMENT_ID, NET::VIA> viaPair : net.Vias )
|
||||
{
|
||||
NET::VIA via = viaPair.second;
|
||||
loadNetVia( net.ID, via );
|
||||
}
|
||||
|
||||
for( std::pair<NETELEMENT_ID, NET::PIN> pinPair : net.Pins )
|
||||
{
|
||||
NET::PIN pin = pinPair.second;
|
||||
MODULE* m = getModuleFromCadstarID( pin.ComponentID );
|
||||
|
||||
if( m == nullptr )
|
||||
{
|
||||
wxLogWarning( wxString::Format(
|
||||
_( "The net '%s' references component ID '%s' which does not exist. "
|
||||
"This has been ignored," ),
|
||||
netname, pin.ComponentID ) );
|
||||
}
|
||||
else if( ( pin.PadID - (long) 1 ) > m->Pads().size() )
|
||||
{
|
||||
wxLogWarning( wxString::Format(
|
||||
_( "The net '%s' references non-existent pad index '%d' in component '%s'. "
|
||||
"This has been ignored." ),
|
||||
netname, pin.PadID, m->GetReference() ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
// The below works because we have added the pads in the correct order to the module and
|
||||
// it so happens that PAD_ID in Cadstar is a sequential, numerical ID
|
||||
m->Pads().at( pin.PadID - (long) 1 )->SetNet( getKiCadNet( net.ID ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CADSTAR_PCB_ARCHIVE_LOADER::loadComponentAttributes(
|
||||
const COMPONENT& aComponent, MODULE* aModule )
|
||||
{
|
||||
for( std::pair<ATTRIBUTE_ID, ATTRIBUTE_VALUE> attrPair : aComponent.AttributeValues )
|
||||
{
|
||||
|
@ -715,9 +1020,88 @@ void CADSTAR_PCB_ARCHIVE_LOADER::loadComponentAttributes( const COMPONENT& aComp
|
|||
}
|
||||
|
||||
|
||||
void CADSTAR_PCB_ARCHIVE_LOADER::drawCadstarShape( const SHAPE& aCadstarShape, const PCB_LAYER_ID& aKiCadLayer,
|
||||
const LINECODE_ID& aCadstarLinecodeID, const wxString& aShapeName,
|
||||
BOARD_ITEM_CONTAINER* aContainer )
|
||||
void CADSTAR_PCB_ARCHIVE_LOADER::loadNetTracks(
|
||||
const NET_ID& aCadstarNetID, const NET::ROUTE& aCadstarRoute )
|
||||
{
|
||||
std::vector<DRAWSEGMENT*> dsVector;
|
||||
|
||||
POINT prevEnd = aCadstarRoute.StartPoint;
|
||||
|
||||
for( const NET::ROUTE_VERTEX& v : aCadstarRoute.RouteVertices )
|
||||
{
|
||||
DRAWSEGMENT* ds = getDrawSegmentFromVertex( prevEnd, v.Vertex );
|
||||
ds->SetLayer( getKiCadLayer( aCadstarRoute.LayerID ) );
|
||||
ds->SetWidth( getKiCadLength( v.RouteWidth ) );
|
||||
dsVector.push_back( ds );
|
||||
prevEnd = v.Vertex.End;
|
||||
}
|
||||
|
||||
//Todo add real netcode to the tracks
|
||||
std::vector<TRACK*> tracks =
|
||||
makeTracksFromDrawsegments( dsVector, mBoard, getKiCadNet( aCadstarNetID ) );
|
||||
|
||||
//cleanup
|
||||
for( DRAWSEGMENT* ds : dsVector )
|
||||
{
|
||||
if( ds )
|
||||
delete ds;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CADSTAR_PCB_ARCHIVE_LOADER::loadNetVia(
|
||||
const NET_ID& aCadstarNetID, const NET::VIA& aCadstarVia )
|
||||
{
|
||||
VIA* via = new VIA( mBoard );
|
||||
mBoard->Add( via, ADD_MODE::APPEND );
|
||||
|
||||
VIACODE csViaCode = getViaCode( aCadstarVia.ViaCodeID );
|
||||
LAYERPAIR csLayerPair = getLayerPair( aCadstarVia.LayerPairID );
|
||||
|
||||
via->SetPosition( getKiCadPoint( aCadstarVia.Location ) );
|
||||
via->SetDrill( getKiCadLength( csViaCode.DrillDiameter ) );
|
||||
via->SetLocked( aCadstarVia.Fixed );
|
||||
|
||||
if( csViaCode.Shape.ShapeType != PAD_SHAPE_TYPE::CIRCLE )
|
||||
wxLogError( wxString::Format(
|
||||
_( "The CADSTAR via code '%s' has different shape from a circle defined. "
|
||||
"KiCad only supports circular vias so this via type has been changed to "
|
||||
"be a via with circular shape of %.2f mm diameter." ),
|
||||
csViaCode.Name,
|
||||
(double) ( (double) getKiCadLength( csViaCode.Shape.Size ) / 1E6 ) ) );
|
||||
|
||||
via->SetWidth( getKiCadLength( csViaCode.Shape.Size ) );
|
||||
|
||||
bool start_layer_outside =
|
||||
csLayerPair.PhysicalLayerStart == 1
|
||||
|| csLayerPair.PhysicalLayerStart == Assignments.Technology.MaxPhysicalLayer;
|
||||
bool end_layer_outside =
|
||||
csLayerPair.PhysicalLayerEnd == 1
|
||||
|| csLayerPair.PhysicalLayerEnd == Assignments.Technology.MaxPhysicalLayer;
|
||||
|
||||
if( start_layer_outside && end_layer_outside )
|
||||
{
|
||||
via->SetViaType( VIATYPE::THROUGH );
|
||||
}
|
||||
else if( ( !start_layer_outside ) && ( !end_layer_outside ) )
|
||||
{
|
||||
via->SetViaType( VIATYPE::BLIND_BURIED );
|
||||
}
|
||||
else
|
||||
{
|
||||
via->SetViaType( VIATYPE::MICROVIA );
|
||||
}
|
||||
|
||||
via->SetLayerPair( getKiCadCopperLayerID( csLayerPair.PhysicalLayerStart ),
|
||||
getKiCadCopperLayerID( csLayerPair.PhysicalLayerEnd ) );
|
||||
via->SetNet( getKiCadNet( aCadstarNetID ) );
|
||||
///todo add netcode to the via
|
||||
}
|
||||
|
||||
|
||||
void CADSTAR_PCB_ARCHIVE_LOADER::drawCadstarShape( const SHAPE& aCadstarShape,
|
||||
const PCB_LAYER_ID& aKiCadLayer, const LINECODE_ID& aCadstarLinecodeID,
|
||||
const wxString& aShapeName, BOARD_ITEM_CONTAINER* aContainer )
|
||||
{
|
||||
int lineThickness = getLineThickness( aCadstarLinecodeID );
|
||||
|
||||
|
@ -772,9 +1156,9 @@ void CADSTAR_PCB_ARCHIVE_LOADER::drawCadstarCutoutsAsSegments( const std::vector
|
|||
}
|
||||
|
||||
|
||||
void CADSTAR_PCB_ARCHIVE_LOADER::drawCadstarVerticesAsSegments( const std::vector<VERTEX>& aCadstarVertices,
|
||||
const PCB_LAYER_ID& aKiCadLayer, const int& aLineThickness,
|
||||
BOARD_ITEM_CONTAINER* aContainer )
|
||||
void CADSTAR_PCB_ARCHIVE_LOADER::drawCadstarVerticesAsSegments(
|
||||
const std::vector<VERTEX>& aCadstarVertices, const PCB_LAYER_ID& aKiCadLayer,
|
||||
const int& aLineThickness, BOARD_ITEM_CONTAINER* aContainer )
|
||||
{
|
||||
std::vector<DRAWSEGMENT*> drawSegments =
|
||||
getDrawSegmentsFromVertices( aCadstarVertices, aContainer );
|
||||
|
@ -799,26 +1183,37 @@ std::vector<DRAWSEGMENT*> CADSTAR_PCB_ARCHIVE_LOADER::getDrawSegmentsFromVertice
|
|||
return drawSegments;
|
||||
|
||||
const VERTEX* prev = &aCadstarVertices.at( 0 ); // first one should always be a point vertex
|
||||
double arcStartAngle, arcEndAngle, arcAngle;
|
||||
bool cw = false;
|
||||
const VERTEX* cur;
|
||||
|
||||
for( size_t i = 1; i < aCadstarVertices.size(); i++ )
|
||||
{
|
||||
const VERTEX* cur = &aCadstarVertices[i];
|
||||
DRAWSEGMENT* ds;
|
||||
cw = false;
|
||||
cur = &aCadstarVertices.at( i );
|
||||
drawSegments.push_back( getDrawSegmentFromVertex( prev->End, *cur, aContainer ) );
|
||||
prev = cur;
|
||||
}
|
||||
|
||||
wxPoint startPoint = getKiCadPoint( prev->End );
|
||||
wxPoint endPoint = getKiCadPoint( cur->End );
|
||||
return drawSegments;
|
||||
}
|
||||
|
||||
|
||||
DRAWSEGMENT* CADSTAR_PCB_ARCHIVE_LOADER::getDrawSegmentFromVertex( const POINT& aCadstarStartPoint,
|
||||
const VERTEX& aCadstarVertex, BOARD_ITEM_CONTAINER* aContainer )
|
||||
{
|
||||
DRAWSEGMENT* ds;
|
||||
bool cw = false;
|
||||
double arcStartAngle, arcEndAngle, arcAngle;
|
||||
|
||||
wxPoint startPoint = getKiCadPoint( aCadstarStartPoint );
|
||||
wxPoint endPoint = getKiCadPoint( aCadstarVertex.End );
|
||||
wxPoint centerPoint;
|
||||
|
||||
if( cur->Type == VERTEX_TYPE::ANTICLOCKWISE_SEMICIRCLE
|
||||
|| cur->Type == VERTEX_TYPE::CLOCKWISE_SEMICIRCLE )
|
||||
if( aCadstarVertex.Type == VERTEX_TYPE::ANTICLOCKWISE_SEMICIRCLE
|
||||
|| aCadstarVertex.Type == VERTEX_TYPE::CLOCKWISE_SEMICIRCLE )
|
||||
centerPoint = ( startPoint + endPoint ) / 2;
|
||||
else
|
||||
centerPoint = getKiCadPoint( cur->Center );
|
||||
centerPoint = getKiCadPoint( aCadstarVertex.Center );
|
||||
|
||||
switch( cur->Type )
|
||||
switch( aCadstarVertex.Type )
|
||||
{
|
||||
|
||||
case VERTEX_TYPE::POINT:
|
||||
|
@ -868,11 +1263,7 @@ std::vector<DRAWSEGMENT*> CADSTAR_PCB_ARCHIVE_LOADER::getDrawSegmentsFromVertice
|
|||
if( isModule( aContainer ) && ds != nullptr )
|
||||
( (EDGE_MODULE*) ds )->SetLocalCoord();
|
||||
|
||||
drawSegments.push_back( ds );
|
||||
prev = cur;
|
||||
}
|
||||
|
||||
return drawSegments;
|
||||
return ds;
|
||||
}
|
||||
|
||||
|
||||
|
@ -992,6 +1383,73 @@ SHAPE_LINE_CHAIN CADSTAR_PCB_ARCHIVE_LOADER::getLineChainFromDrawsegments(
|
|||
}
|
||||
|
||||
|
||||
std::vector<TRACK*> CADSTAR_PCB_ARCHIVE_LOADER::makeTracksFromDrawsegments(
|
||||
const std::vector<DRAWSEGMENT*> aDrawsegments, BOARD_ITEM_CONTAINER* aParentContainer,
|
||||
NETINFO_ITEM* aNet, const PCB_LAYER_ID& aLayerOverride, int aWidthOverride )
|
||||
{
|
||||
std::vector<TRACK*> tracks;
|
||||
|
||||
for( DRAWSEGMENT* ds : aDrawsegments )
|
||||
{
|
||||
TRACK* track;
|
||||
|
||||
switch( ds->GetShape() )
|
||||
{
|
||||
case STROKE_T::S_ARC:
|
||||
if( ds->GetClass() == wxT( "MGRAPHIC" ) )
|
||||
{
|
||||
EDGE_MODULE* em = (EDGE_MODULE*) ds;
|
||||
SHAPE_ARC arc( em->GetStart0(), em->GetEnd0(), (double) em->GetAngle() / 10.0 );
|
||||
track = new ARC( aParentContainer, &arc );
|
||||
}
|
||||
else
|
||||
{
|
||||
SHAPE_ARC arc( ds->GetCenter(), ds->GetArcStart(), (double) ds->GetAngle() / 10.0 );
|
||||
track = new ARC( aParentContainer, &arc );
|
||||
}
|
||||
break;
|
||||
case STROKE_T::S_SEGMENT:
|
||||
if( ds->GetClass() == wxT( "MGRAPHIC" ) )
|
||||
{
|
||||
EDGE_MODULE* em = (EDGE_MODULE*) ds;
|
||||
track = new TRACK( aParentContainer );
|
||||
track->SetStart( em->GetStart0() );
|
||||
track->SetEnd( em->GetEnd0() );
|
||||
}
|
||||
else
|
||||
{
|
||||
track = new TRACK( aParentContainer );
|
||||
track->SetStart( ds->GetStart() );
|
||||
track->SetEnd( ds->GetEnd() );
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
wxASSERT_MSG( true, "Drawsegment type is unexpected. Ignored." );
|
||||
continue;
|
||||
}
|
||||
|
||||
if( aWidthOverride == -1 )
|
||||
track->SetWidth( ds->GetWidth() );
|
||||
else
|
||||
track->SetWidth( aWidthOverride );
|
||||
|
||||
if( aLayerOverride == PCB_LAYER_ID::UNDEFINED_LAYER )
|
||||
track->SetLayer( ds->GetLayer() );
|
||||
else
|
||||
track->SetLayer( aLayerOverride );
|
||||
|
||||
if( aNet != nullptr )
|
||||
track->SetNet( aNet );
|
||||
|
||||
tracks.push_back( track );
|
||||
aParentContainer->Add( track, ADD_MODE::APPEND );
|
||||
}
|
||||
|
||||
return tracks;
|
||||
}
|
||||
|
||||
|
||||
void CADSTAR_PCB_ARCHIVE_LOADER::addAttribute( const ATTRIBUTE_LOCATION& aCadstarAttrLoc,
|
||||
const ATTRIBUTE_ID& aCadstarAttributeID, MODULE* aModule, const wxString& aAttributeValue )
|
||||
{
|
||||
|
@ -1044,7 +1502,7 @@ void CADSTAR_PCB_ARCHIVE_LOADER::addAttribute( const ATTRIBUTE_LOCATION& aCadsta
|
|||
txt->SetPos0( rotatedTextPos );
|
||||
txt->SetLayer( getKiCadLayer( aCadstarAttrLoc.LayerID ) );
|
||||
txt->SetMirrored( aCadstarAttrLoc.Mirror );
|
||||
txt->SetTextAngle( getKiCadAngle( aCadstarAttrLoc.OrientAngle ) - aModule->GetOrientation() );
|
||||
txt->SetTextAngle( getAngleTenthDegree( aCadstarAttrLoc.OrientAngle ) - aModule->GetOrientation() );
|
||||
|
||||
TEXTCODE tc = getTextCode( aCadstarAttrLoc.TextCodeID );
|
||||
|
||||
|
@ -1109,7 +1567,6 @@ void CADSTAR_PCB_ARCHIVE_LOADER::addAttribute( const ATTRIBUTE_LOCATION& aCadsta
|
|||
|
||||
int CADSTAR_PCB_ARCHIVE_LOADER::getLineThickness( const LINECODE_ID& aCadstarLineCodeID )
|
||||
{
|
||||
|
||||
wxCHECK( Assignments.Codedefs.LineCodes.find( aCadstarLineCodeID )
|
||||
!= Assignments.Codedefs.LineCodes.end(),
|
||||
mBoard->GetDesignSettings().GetLineThickness( PCB_LAYER_ID::Edge_Cuts ) );
|
||||
|
@ -1118,7 +1575,19 @@ int CADSTAR_PCB_ARCHIVE_LOADER::getLineThickness( const LINECODE_ID& aCadstarLin
|
|||
}
|
||||
|
||||
|
||||
CADSTAR_PCB_ARCHIVE_LOADER::TEXTCODE CADSTAR_PCB_ARCHIVE_LOADER::getTextCode( const TEXTCODE_ID& aCadstarTextCodeID )
|
||||
CADSTAR_PCB_ARCHIVE_LOADER::COPPERCODE CADSTAR_PCB_ARCHIVE_LOADER::getCopperCode(
|
||||
const COPPERCODE_ID& aCadstaCopperCodeID )
|
||||
{
|
||||
wxCHECK( Assignments.Codedefs.CopperCodes.find( aCadstaCopperCodeID )
|
||||
!= Assignments.Codedefs.CopperCodes.end(),
|
||||
COPPERCODE() );
|
||||
|
||||
return Assignments.Codedefs.CopperCodes.at( aCadstaCopperCodeID );
|
||||
}
|
||||
|
||||
|
||||
CADSTAR_PCB_ARCHIVE_LOADER::TEXTCODE CADSTAR_PCB_ARCHIVE_LOADER::getTextCode(
|
||||
const TEXTCODE_ID& aCadstarTextCodeID )
|
||||
{
|
||||
wxCHECK( Assignments.Codedefs.TextCodes.find( aCadstarTextCodeID )
|
||||
!= Assignments.Codedefs.TextCodes.end(),
|
||||
|
@ -1128,7 +1597,8 @@ CADSTAR_PCB_ARCHIVE_LOADER::TEXTCODE CADSTAR_PCB_ARCHIVE_LOADER::getTextCode( co
|
|||
}
|
||||
|
||||
|
||||
CADSTAR_PCB_ARCHIVE_LOADER::PADCODE CADSTAR_PCB_ARCHIVE_LOADER::getPadCode( const PADCODE_ID& aCadstarPadCodeID )
|
||||
CADSTAR_PCB_ARCHIVE_LOADER::PADCODE CADSTAR_PCB_ARCHIVE_LOADER::getPadCode(
|
||||
const PADCODE_ID& aCadstarPadCodeID )
|
||||
{
|
||||
wxCHECK( Assignments.Codedefs.PadCodes.find( aCadstarPadCodeID )
|
||||
!= Assignments.Codedefs.PadCodes.end(),
|
||||
|
@ -1138,6 +1608,28 @@ CADSTAR_PCB_ARCHIVE_LOADER::PADCODE CADSTAR_PCB_ARCHIVE_LOADER::getPadCode( cons
|
|||
}
|
||||
|
||||
|
||||
CADSTAR_PCB_ARCHIVE_LOADER::VIACODE CADSTAR_PCB_ARCHIVE_LOADER::getViaCode(
|
||||
const VIACODE_ID& aCadstarViaCodeID )
|
||||
{
|
||||
wxCHECK( Assignments.Codedefs.ViaCodes.find( aCadstarViaCodeID )
|
||||
!= Assignments.Codedefs.ViaCodes.end(),
|
||||
VIACODE() );
|
||||
|
||||
return Assignments.Codedefs.ViaCodes.at( aCadstarViaCodeID );
|
||||
}
|
||||
|
||||
|
||||
CADSTAR_PCB_ARCHIVE_LOADER::LAYERPAIR CADSTAR_PCB_ARCHIVE_LOADER::getLayerPair(
|
||||
const LAYERPAIR_ID& aCadstarLayerPairID )
|
||||
{
|
||||
wxCHECK( Assignments.Codedefs.LayerPairs.find( aCadstarLayerPairID )
|
||||
!= Assignments.Codedefs.LayerPairs.end(),
|
||||
LAYERPAIR() );
|
||||
|
||||
return Assignments.Codedefs.LayerPairs.at( aCadstarLayerPairID );
|
||||
}
|
||||
|
||||
|
||||
wxString CADSTAR_PCB_ARCHIVE_LOADER::getAttributeName( const ATTRIBUTE_ID& aCadstarAttributeID )
|
||||
{
|
||||
wxCHECK( Assignments.Codedefs.AttributeNames.find( aCadstarAttributeID )
|
||||
|
@ -1158,7 +1650,8 @@ wxString CADSTAR_PCB_ARCHIVE_LOADER::getAttributeValue( const ATTRIBUTE_ID& aCad
|
|||
}
|
||||
|
||||
|
||||
CADSTAR_PCB_ARCHIVE_LOADER::PART CADSTAR_PCB_ARCHIVE_LOADER::getPart( const PART_ID& aCadstarPartID )
|
||||
CADSTAR_PCB_ARCHIVE_LOADER::PART CADSTAR_PCB_ARCHIVE_LOADER::getPart(
|
||||
const PART_ID& aCadstarPartID )
|
||||
{
|
||||
wxCHECK( Parts.PartDefinitions.find( aCadstarPartID ) != Parts.PartDefinitions.end(), PART() );
|
||||
|
||||
|
@ -1166,6 +1659,127 @@ CADSTAR_PCB_ARCHIVE_LOADER::PART CADSTAR_PCB_ARCHIVE_LOADER::getPart( const PART
|
|||
}
|
||||
|
||||
|
||||
CADSTAR_PCB_ARCHIVE_LOADER::HATCHCODE CADSTAR_PCB_ARCHIVE_LOADER::getHatchCode(
|
||||
const HATCHCODE_ID& aCadstarHatchcodeID )
|
||||
{
|
||||
wxCHECK( Assignments.Codedefs.HatchCodes.find( aCadstarHatchcodeID )
|
||||
!= Assignments.Codedefs.HatchCodes.end(),
|
||||
HATCHCODE() );
|
||||
|
||||
return Assignments.Codedefs.HatchCodes.at( aCadstarHatchcodeID );
|
||||
}
|
||||
|
||||
|
||||
double CADSTAR_PCB_ARCHIVE_LOADER::getHatchCodeAngleDegrees( const HATCHCODE_ID& aCadstarHatchcodeID )
|
||||
{
|
||||
checkAndLogHatchCode( aCadstarHatchcodeID );
|
||||
HATCHCODE hcode = getHatchCode( aCadstarHatchcodeID );
|
||||
|
||||
if( hcode.Hatches.size() < 1 )
|
||||
return mBoard->GetDesignSettings().GetDefaultZoneSettings().m_HatchOrientation;
|
||||
else
|
||||
return getAngleDegrees( hcode.Hatches.at( 0 ).OrientAngle );
|
||||
}
|
||||
|
||||
|
||||
int CADSTAR_PCB_ARCHIVE_LOADER::getKiCadHatchCodeThickness(
|
||||
const HATCHCODE_ID& aCadstarHatchcodeID )
|
||||
{
|
||||
checkAndLogHatchCode( aCadstarHatchcodeID );
|
||||
HATCHCODE hcode = getHatchCode( aCadstarHatchcodeID );
|
||||
|
||||
if( hcode.Hatches.size() < 1 )
|
||||
return mBoard->GetDesignSettings().GetDefaultZoneSettings().m_HatchThickness;
|
||||
else
|
||||
return getKiCadLength( hcode.Hatches.at( 0 ).LineWidth );
|
||||
}
|
||||
|
||||
|
||||
int CADSTAR_PCB_ARCHIVE_LOADER::getKiCadHatchCodeGap( const HATCHCODE_ID& aCadstarHatchcodeID )
|
||||
{
|
||||
checkAndLogHatchCode( aCadstarHatchcodeID );
|
||||
HATCHCODE hcode = getHatchCode( aCadstarHatchcodeID );
|
||||
|
||||
if( hcode.Hatches.size() < 1 )
|
||||
return mBoard->GetDesignSettings().GetDefaultZoneSettings().m_HatchGap;
|
||||
else
|
||||
return getKiCadLength( hcode.Hatches.at( 0 ).Step );
|
||||
}
|
||||
|
||||
|
||||
void CADSTAR_PCB_ARCHIVE_LOADER::checkAndLogHatchCode( const HATCHCODE_ID& aCadstarHatchcodeID )
|
||||
{
|
||||
if( mHatchcodesTested.find( aCadstarHatchcodeID ) != mHatchcodesTested.end() )
|
||||
{
|
||||
return; //already checked
|
||||
}
|
||||
else
|
||||
{
|
||||
HATCHCODE hcode = getHatchCode( aCadstarHatchcodeID );
|
||||
|
||||
if( hcode.Hatches.size() != 2 )
|
||||
{
|
||||
wxLogWarning( wxString::Format(
|
||||
_( "The CADSTAR Hatching code '%s' has %d hatches defined. "
|
||||
"KiCad only supports 2 hatches (crosshatching) 90 degrees apart. "
|
||||
"The imported hatching is crosshatched." ),
|
||||
hcode.Name, (int) hcode.Hatches.size() ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( hcode.Hatches.at( 0 ).LineWidth != hcode.Hatches.at( 1 ).LineWidth )
|
||||
{
|
||||
wxLogWarning( wxString::Format(
|
||||
_( "The CADSTAR Hatching code '%s' has different line widths for each "
|
||||
"hatch. KiCad only supports one width for the haching. The imported "
|
||||
"hatching uses the width defined in the first hatch definition, i.e. "
|
||||
"%.2f mm." ),
|
||||
hcode.Name,
|
||||
(double) ((double) getKiCadLength( hcode.Hatches.at( 0 ).LineWidth ) ) / 1E6 ) );
|
||||
}
|
||||
|
||||
if( hcode.Hatches.at( 0 ).Step != hcode.Hatches.at( 1 ).Step )
|
||||
{
|
||||
wxLogWarning( wxString::Format(
|
||||
_( "The CADSTAR Hatching code '%s' has different step sizes for each "
|
||||
"hatch. KiCad only supports one step size for the haching. The imported "
|
||||
"hatching uses the step size defined in the first hatching definition, "
|
||||
"i.e. %.2f mm." ),
|
||||
hcode.Name,
|
||||
(double) ( (double) getKiCadLength( hcode.Hatches.at( 0 ).Step ) )
|
||||
/ 1E6 ) );
|
||||
}
|
||||
|
||||
if( abs( hcode.Hatches.at( 0 ).OrientAngle - hcode.Hatches.at( 1 ).OrientAngle )
|
||||
!= 90000 )
|
||||
{
|
||||
wxLogWarning( wxString::Format(
|
||||
_( "The hatches in CADSTAR Hatching code '%s' have an angle "
|
||||
"difference of %.1f degrees. KiCad only supports hatching 90 "
|
||||
"degrees apart. The imported hatching has two hatches 90 "
|
||||
"degrees apart, oriented %.1f degrees from horizontal." ),
|
||||
hcode.Name,
|
||||
getAngleDegrees( abs( hcode.Hatches.at( 0 ).OrientAngle
|
||||
- hcode.Hatches.at( 1 ).OrientAngle ) ),
|
||||
getAngleDegrees( hcode.Hatches.at( 0 ).OrientAngle ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
mHatchcodesTested.insert( aCadstarHatchcodeID );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
MODULE* CADSTAR_PCB_ARCHIVE_LOADER::getModuleFromCadstarID(
|
||||
const COMPONENT_ID& aCadstarComponentID )
|
||||
{
|
||||
if( mComponentMap.find( aCadstarComponentID ) == mComponentMap.end() )
|
||||
return nullptr;
|
||||
else
|
||||
return mComponentMap.at( aCadstarComponentID );
|
||||
}
|
||||
|
||||
|
||||
wxPoint CADSTAR_PCB_ARCHIVE_LOADER::getKiCadPoint( wxPoint aCadstarPoint )
|
||||
{
|
||||
wxPoint retval;
|
||||
|
@ -1184,8 +1798,36 @@ double CADSTAR_PCB_ARCHIVE_LOADER::getPolarAngle( wxPoint aPoint )
|
|||
}
|
||||
|
||||
|
||||
NETINFO_ITEM* CADSTAR_PCB_ARCHIVE_LOADER::getKiCadNet( const NET_ID& aCadstarNetID )
|
||||
{
|
||||
if( aCadstarNetID.IsEmpty() )
|
||||
return nullptr;
|
||||
else if( mNetMap.find( aCadstarNetID ) != mNetMap.end() )
|
||||
{
|
||||
return mNetMap.at(aCadstarNetID);
|
||||
}
|
||||
else
|
||||
{
|
||||
wxCHECK( Layout.Nets.find( aCadstarNetID ) != Layout.Nets.end(), nullptr );
|
||||
|
||||
NET csNet = Layout.Nets.at( aCadstarNetID );
|
||||
|
||||
NETINFO_ITEM* netInfo = new NETINFO_ITEM( mBoard, csNet.Name, ++mNumNets );
|
||||
mBoard->Add( netInfo, ADD_MODE::APPEND );
|
||||
//todo also add the Netclass
|
||||
|
||||
return netInfo;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
PCB_LAYER_ID CADSTAR_PCB_ARCHIVE_LOADER::getKiCadCopperLayerID( unsigned int aLayerNum )
|
||||
{
|
||||
if(aLayerNum == Assignments.Technology.MaxPhysicalLayer)
|
||||
return PCB_LAYER_ID::B_Cu;
|
||||
|
||||
switch( aLayerNum )
|
||||
{
|
||||
// clang-format off
|
||||
|
@ -1229,6 +1871,10 @@ PCB_LAYER_ID CADSTAR_PCB_ARCHIVE_LOADER::getKiCadCopperLayerID( unsigned int aLa
|
|||
|
||||
bool CADSTAR_PCB_ARCHIVE_LOADER::isLayerSet( const LAYER_ID& aCadstarLayerID )
|
||||
{
|
||||
wxCHECK( Assignments.Layerdefs.Layers.find( aCadstarLayerID )
|
||||
!= Assignments.Layerdefs.Layers.end(),
|
||||
false );
|
||||
|
||||
LAYER& layer = Assignments.Layerdefs.Layers.at( aCadstarLayerID );
|
||||
|
||||
switch( layer.Type )
|
||||
|
@ -1248,10 +1894,17 @@ bool CADSTAR_PCB_ARCHIVE_LOADER::isLayerSet( const LAYER_ID& aCadstarLayerID )
|
|||
|
||||
PCB_LAYER_ID CADSTAR_PCB_ARCHIVE_LOADER::getKiCadLayer( const LAYER_ID& aCadstarLayerID )
|
||||
{
|
||||
if( mLayermap.find( aCadstarLayerID ) == mLayermap.end() )
|
||||
return PCB_LAYER_ID::UNDEFINED_LAYER; //Possibly should be an ASSERT?
|
||||
else
|
||||
return mLayermap[aCadstarLayerID];
|
||||
if( Assignments.Layerdefs.Layers.find( aCadstarLayerID ) != Assignments.Layerdefs.Layers.end() )
|
||||
{
|
||||
if( Assignments.Layerdefs.Layers.at( aCadstarLayerID ).Type == LAYER_TYPE::NOLAYER )
|
||||
//The "no layer" is common for CADSTAR documentation symbols
|
||||
//map it to undefined layer for later processing
|
||||
return PCB_LAYER_ID::UNDEFINED_LAYER;
|
||||
}
|
||||
|
||||
wxCHECK( mLayermap.find( aCadstarLayerID ) != mLayermap.end(), PCB_LAYER_ID::UNDEFINED_LAYER );
|
||||
|
||||
return mLayermap.at(aCadstarLayerID);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -28,19 +28,33 @@
|
|||
|
||||
#include <cadstar_pcb_archive_parser.h>
|
||||
#include <class_board.h>
|
||||
#include <set>
|
||||
|
||||
class BOARD;
|
||||
|
||||
class CADSTAR_PCB_ARCHIVE_LOADER : public CADSTAR_PCB_ARCHIVE_PARSER
|
||||
{
|
||||
public:
|
||||
explicit CADSTAR_PCB_ARCHIVE_LOADER( wxString aFilename ) : CADSTAR_PCB_ARCHIVE_PARSER( aFilename )
|
||||
explicit CADSTAR_PCB_ARCHIVE_LOADER( wxString aFilename )
|
||||
: CADSTAR_PCB_ARCHIVE_PARSER( aFilename )
|
||||
{
|
||||
mBoard = nullptr;
|
||||
mDesignCenter.x = 0;
|
||||
mDesignCenter.y = 0;
|
||||
mDoneCopperWarning = false;
|
||||
mNumNets = 0;
|
||||
}
|
||||
|
||||
~CADSTAR_PCB_ARCHIVE_LOADER()
|
||||
{
|
||||
for( std::pair<SYMDEF_ID, MODULE*> libItem : mLibraryMap )
|
||||
{
|
||||
MODULE* mod = libItem.second;
|
||||
|
||||
if( mod )
|
||||
delete mod;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Loads a CADSTAR PCB Archive file into the KiCad BOARD object given
|
||||
|
@ -54,12 +68,27 @@ private:
|
|||
///< Populated by loadBoardStackup().
|
||||
std::map<SYMDEF_ID, MODULE*> mLibraryMap; ///< Map between Cadstar and KiCad
|
||||
///< components in the library. Populated
|
||||
///< by loadComponentLibrary().
|
||||
///< by loadComponentLibrary(). Owns the
|
||||
///< MODULE objects.
|
||||
std::map<COMPONENT_ID, MODULE*> mComponentMap; ///< Map between Cadstar and KiCad
|
||||
///< components on the board. Does NOT own
|
||||
///< the MODULE objects (these should have
|
||||
///< been loaded to mBoard).
|
||||
std::map<NET_ID, NETINFO_ITEM*> mNetMap; ///< Map between Cadstar and KiCad Nets
|
||||
std::map<PHYSICAL_LAYER_ID, LAYER_ID> mCopperLayers; ///< Map of CADSTAR Physical layers to
|
||||
///< CADSTAR Layer IDs
|
||||
std::vector<LAYER_ID> mPowerPlaneLayers; ///< List of layers that are marked as
|
||||
///< power plane in CADSTAR. This is used
|
||||
///< by "loadtemplates"
|
||||
wxPoint mDesignCenter; ///< Used for calculating the required
|
||||
///< offset to apply to the Cadstar design
|
||||
///< so that it fits in KiCad canvas
|
||||
std::set<HATCHCODE_ID> mHatchcodesTested; ///< Used by checkAndLogHatchCode() to
|
||||
///< avoid multiple duplicate warnings
|
||||
bool mDoneCopperWarning; ///< Used by loadCoppers() to avoid
|
||||
///< multiple duplicate warnings
|
||||
int mNumNets; ///< Number of nets loaded so far
|
||||
|
||||
|
||||
// Functions for loading individual elements:
|
||||
void loadBoardStackup();
|
||||
|
@ -68,6 +97,9 @@ private:
|
|||
void loadFigures();
|
||||
void loadAreas();
|
||||
void loadComponents();
|
||||
void loadTemplates();
|
||||
void loadCoppers();
|
||||
void loadNets();
|
||||
|
||||
// Helper functions for loading:
|
||||
void logBoardStackupWarning(
|
||||
|
@ -75,6 +107,8 @@ private:
|
|||
void loadLibraryFigures( const SYMDEF& aComponent, MODULE* aModule );
|
||||
void loadLibraryPads( const SYMDEF& aComponent, MODULE* aModule );
|
||||
void loadComponentAttributes( const COMPONENT& aComponent, MODULE* aModule );
|
||||
void loadNetTracks( const NET_ID& aCadstarNetID, const NET::ROUTE& aCadstarRoute );
|
||||
void loadNetVia( const NET_ID& aCadstarNetID, const NET::VIA& aCadstarVia );
|
||||
|
||||
/**
|
||||
* @brief
|
||||
|
@ -114,7 +148,7 @@ private:
|
|||
|
||||
/**
|
||||
* @brief Returns a vector of pointers to DRAWSEGMENT objects. Caller owns the objects.
|
||||
* @param aCadstarVertices *
|
||||
* @param aCadstarVertices
|
||||
* @param aContainer to draw on (e.g. mBoard). Can be nullptr.
|
||||
* @return
|
||||
*/
|
||||
|
@ -122,6 +156,15 @@ private:
|
|||
const std::vector<VERTEX>& aCadstarVertices,
|
||||
BOARD_ITEM_CONTAINER* aContainer = nullptr );
|
||||
|
||||
/**
|
||||
* @brief Returns a pointer to a DRAWSEGMENT object. Caller owns the object.
|
||||
* @param aCadstarStartPoint
|
||||
* @param aCadstarVertex
|
||||
* @param aContainer to draw on (e.g. mBoard). Can be nullptr.
|
||||
* @return
|
||||
*/
|
||||
DRAWSEGMENT* getDrawSegmentFromVertex( const POINT& aCadstarStartPoint,
|
||||
const VERTEX& aCadstarVertex, BOARD_ITEM_CONTAINER* aContainer = nullptr );
|
||||
|
||||
/**
|
||||
* @brief
|
||||
|
@ -150,6 +193,22 @@ private:
|
|||
*/
|
||||
SHAPE_LINE_CHAIN getLineChainFromDrawsegments( const std::vector<DRAWSEGMENT*> aDrawSegments );
|
||||
|
||||
/**
|
||||
* @brief Returns a vector of pointers to TRACK/ARC objects. Caller owns the objects
|
||||
* @param aDrawsegments
|
||||
* @param aParentContainer sets this as the parent of each TRACK object and Add()s it to the parent
|
||||
* @param aNet sets all the tracks to this net, unless nullptr
|
||||
* @param aLayerOverride Sets all tracks to this layer, or, if it is UNDEFINED_LAYER, uses the layers
|
||||
* in the DrawSegments
|
||||
* @param aWidthOverride Sets all tracks to this width, or, if it is UNDEFINED_LAYER, uses the width
|
||||
* in the DrawSegments
|
||||
* @return
|
||||
*/
|
||||
std::vector<TRACK*> makeTracksFromDrawsegments( const std::vector<DRAWSEGMENT*> aDrawsegments,
|
||||
BOARD_ITEM_CONTAINER* aParentContainer, NETINFO_ITEM* aNet = nullptr,
|
||||
const PCB_LAYER_ID& aLayerOverride = PCB_LAYER_ID::UNDEFINED_LAYER,
|
||||
int aWidthOverride = -1 );
|
||||
|
||||
/**
|
||||
* @brief Adds a CADSTAR Attribute to a KiCad module
|
||||
* @param aCadstarAttrLoc
|
||||
|
@ -170,11 +229,11 @@ private:
|
|||
int getLineThickness( const LINECODE_ID& aCadstarLineCodeID );
|
||||
|
||||
|
||||
COPPERCODE getCopperCode( const COPPERCODE_ID& aCadstaCopperCodeID );
|
||||
TEXTCODE getTextCode( const TEXTCODE_ID& aCadstarTextCodeID );
|
||||
|
||||
|
||||
PADCODE getPadCode( const PADCODE_ID& aCadstarPadCodeID );
|
||||
|
||||
VIACODE getViaCode( const VIACODE_ID& aCadstarViaCodeID );
|
||||
LAYERPAIR getLayerPair( const LAYERPAIR_ID& aCadstarLayerPairID );
|
||||
|
||||
wxString getAttributeName( const ATTRIBUTE_ID& aCadstarAttributeID );
|
||||
|
||||
|
@ -184,6 +243,13 @@ private:
|
|||
|
||||
PART getPart( const PART_ID& aCadstarPartID );
|
||||
|
||||
HATCHCODE getHatchCode( const HATCHCODE_ID& aCadstarHatchcodeID );
|
||||
void checkAndLogHatchCode( const HATCHCODE_ID& aCadstarHatchcodeID );
|
||||
MODULE* getModuleFromCadstarID( const COMPONENT_ID& aCadstarComponentID );
|
||||
double getHatchCodeAngleDegrees( const HATCHCODE_ID& aCadstarHatchcodeID );
|
||||
int getKiCadHatchCodeThickness( const HATCHCODE_ID& aCadstarHatchcodeID );
|
||||
int getKiCadHatchCodeGap( const HATCHCODE_ID& aCadstarHatchcodeID );
|
||||
|
||||
/**
|
||||
* @brief Scales, offsets and inverts y axis to make the point usable directly in KiCad
|
||||
* @param aCadstarPoint
|
||||
|
@ -206,11 +272,21 @@ private:
|
|||
* @param aCadstarAngle
|
||||
* @return
|
||||
*/
|
||||
double getKiCadAngle( const long long& aCadstarAngle )
|
||||
double getAngleTenthDegree( const long long& aCadstarAngle )
|
||||
{
|
||||
return (double) aCadstarAngle / 100.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* @param aCadstarAngle
|
||||
* @return
|
||||
*/
|
||||
double getAngleDegrees( const long long& aCadstarAngle )
|
||||
{
|
||||
return (double) aCadstarAngle / 1000.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* @param aPoint
|
||||
|
@ -218,6 +294,14 @@ private:
|
|||
*/
|
||||
double getPolarAngle( wxPoint aPoint );
|
||||
|
||||
/**
|
||||
* @brief Searches mNetMap and returns the NETINFO_ITEM pointer if exists. Otherwise
|
||||
* creates a new one and adds it to mBoard.
|
||||
* @param aCadstarNetID
|
||||
* @return
|
||||
*/
|
||||
NETINFO_ITEM* getKiCadNet( const NET_ID& aCadstarNetID );
|
||||
|
||||
|
||||
/**
|
||||
* @brief
|
||||
|
|
|
@ -268,9 +268,9 @@ void CADSTAR_PCB_ARCHIVE_PARSER::RULESET::Parse( XNODE* aNode )
|
|||
AreaViaCodeID = GetXmlAttributeIDString( cNode, 0 );
|
||||
else if( nodeName == wxT( "SPACINGCODE" ) )
|
||||
{
|
||||
SPACINGCODE scode;
|
||||
scode.Parse( cNode );
|
||||
SpacingCodes.push_back( scode );
|
||||
SPACINGCODE spacingcode;
|
||||
spacingcode.Parse( cNode );
|
||||
SpacingCodes.insert( std::make_pair( spacingcode.ID, spacingcode ) );
|
||||
}
|
||||
else
|
||||
THROW_UNKNOWN_NODE_IO_ERROR( nodeName, aNode->GetName() );
|
||||
|
@ -322,7 +322,7 @@ void CADSTAR_PCB_ARCHIVE_PARSER::CODEDEFS::Parse( XNODE* aNode )
|
|||
{
|
||||
SPACINGCODE spacingcode;
|
||||
spacingcode.Parse( cNode );
|
||||
SpacingCodes.push_back( spacingcode );
|
||||
SpacingCodes.insert( std::make_pair( spacingcode.ID, spacingcode ) );
|
||||
}
|
||||
else if( nodeName == wxT( "RULESET" ) )
|
||||
{
|
||||
|
@ -883,7 +883,7 @@ void CADSTAR_PCB_ARCHIVE_PARSER::SPACINGCODE::Parse( XNODE* aNode )
|
|||
{
|
||||
wxASSERT( aNode->GetName() == wxT( "SPACINGCODE" ) );
|
||||
|
||||
Code = GetXmlAttributeIDString( aNode, 0 );
|
||||
ID = GetXmlAttributeIDString( aNode, 0 );
|
||||
Spacing = GetXmlAttributeIDLong( aNode, 1 );
|
||||
|
||||
XNODE* cNode = aNode->GetChildren();
|
||||
|
@ -1390,8 +1390,7 @@ void CADSTAR_PCB_ARCHIVE_PARSER::TECHNOLOGY_SECTION::Parse( XNODE* aNode )
|
|||
ViaGrid = GetXmlAttributeIDLong( cNode, 0 );
|
||||
else if( cNodeName == wxT( "DESIGNORIGIN" ) )
|
||||
{
|
||||
std::vector<POINT> pts = ParseAllChildPoints( cNode, true, 1 );
|
||||
DesignOrigin = pts[0];
|
||||
DesignOrigin.Parse( cNode->GetChildren() );
|
||||
}
|
||||
else if( cNodeName == wxT( "DESIGNAREA" ) )
|
||||
{
|
||||
|
@ -1400,13 +1399,11 @@ void CADSTAR_PCB_ARCHIVE_PARSER::TECHNOLOGY_SECTION::Parse( XNODE* aNode )
|
|||
}
|
||||
else if( cNodeName == wxT( "DESIGNREF" ) )
|
||||
{
|
||||
std::vector<POINT> pts = ParseAllChildPoints( cNode, true, 1 );
|
||||
DesignRef = pts[0];
|
||||
DesignOrigin.Parse( cNode->GetChildren() );
|
||||
}
|
||||
else if( cNodeName == wxT( "DESIGNLIMIT" ) )
|
||||
{
|
||||
std::vector<POINT> pts = ParseAllChildPoints( cNode, true, 1 );
|
||||
DesignLimit = pts[0];
|
||||
DesignLimit.Parse( cNode->GetChildren() );
|
||||
}
|
||||
else if( cNodeName == wxT( "BACKOFFJCTS" ) )
|
||||
BackOffJunctions = true;
|
||||
|
|
|
@ -26,9 +26,8 @@
|
|||
#ifndef CADSTAR_PCB_ARCHIVE_PARSER_H_
|
||||
#define CADSTAR_PCB_ARCHIVE_PARSER_H_
|
||||
|
||||
#include <boost/serialization/strong_typedef.hpp>
|
||||
#include <plugins/cadstar/cadstar_archive_parser.h>
|
||||
#include <map>
|
||||
#include <plugins/cadstar/cadstar_archive_parser.h>
|
||||
#include <vector>
|
||||
|
||||
|
||||
|
@ -39,10 +38,6 @@
|
|||
#define UNDEFINED_MATERIAL_ID ( MATERIAL_ID ) wxEmptyString
|
||||
#define UNDEFINED_PHYSICAL_LAYER ( PHYSICAL_LAYER_ID ) - 1
|
||||
|
||||
/**
|
||||
* Default spacing class for all nets
|
||||
*/
|
||||
#define NO_SPACE_CLASS_ID ( SPACING_CLASS_ID ) wxT( "NO_SPACE_CLASS" )
|
||||
|
||||
/**
|
||||
* Component Name Attribute ID - typically used for placement of designators on silk screen.
|
||||
|
@ -86,6 +81,7 @@ public:
|
|||
typedef wxString COPPERCODE_ID;
|
||||
typedef wxString PADCODE_ID;
|
||||
typedef wxString VIACODE_ID;
|
||||
typedef wxString SPACINGCODE_ID;
|
||||
typedef wxString LAYERPAIR_ID;
|
||||
typedef wxString ATTRIBUTE_ID;
|
||||
typedef wxString NETCLASS_ID;
|
||||
|
@ -394,7 +390,45 @@ public:
|
|||
void Parse( XNODE* aNode );
|
||||
};
|
||||
|
||||
wxString Code; //TODO convert to an enum class containing all valid spacings
|
||||
/**
|
||||
* @brief Possible spacing rules:
|
||||
* - A_A = Component Placement to Component Placement
|
||||
* - C_B = Copper to Board
|
||||
* - C_C = Copper to Copper
|
||||
* - H_H = Hole to Hole
|
||||
* - OT_P = Optimal Route to Pad (Optional Rule)
|
||||
* - OT_T = Optimal Route to Route (Optional Rule)
|
||||
* - OT_V = Optimal Route to Via (Optional Rule)
|
||||
* - P_B = Pad to Board
|
||||
* - P_C = Pad to Copper
|
||||
* - P_P = Pad to Pad
|
||||
* - P_S = Pad to SMD pad (Optional Rule)
|
||||
* - P_V = Pad to Via
|
||||
* - T_B = Route to Board outline
|
||||
* - T_C = Route to Copper
|
||||
* - T_P = Route to Pad
|
||||
* - T_T = Route to Route
|
||||
* - T_S = Route to SMD Pad (Optional Rule)
|
||||
* - T_V = Route to Via
|
||||
* - S_B = SMD Pad to Board (Optional Rule)
|
||||
* - S_C = SMD Pad to Copper (Optional Rule)
|
||||
* - S_S = SMD Pad to SMD Pad (Optional Rule)
|
||||
* - L_B = Test Land to Board
|
||||
* - L_O = Test Land to Component
|
||||
* - L_L = Test Land to Test Land
|
||||
* - V_B = Via to Board
|
||||
* - V_C = Via to Copper
|
||||
* - V_S = Via to SMD Pad (Optional Rule)
|
||||
* - V_V = Via to Via
|
||||
*
|
||||
* Other design rules are in:
|
||||
* TECHNOLOGY->MAXMITER = Maximum Mitre (This parameter is not actually checked in Cadstar)
|
||||
* TECHNOLOGY->MINMITER = Minimum Mitre (This parameter is not actually checked in Cadstar)
|
||||
* TECHNOLOGY->MINUNNECKED = Minimum Thicker Track Length
|
||||
* TECHNOLOGY->MINNECKED = Minimum Thinner Track Length
|
||||
* TECHNOLOGY->MINROUTEWIDTH = Thin Route Width
|
||||
*/
|
||||
SPACINGCODE_ID ID;
|
||||
long Spacing;
|
||||
std::vector<REASSIGN> Reassigns; ///< Can have different spacings on differnt layers
|
||||
|
||||
|
@ -720,7 +754,8 @@ public:
|
|||
///< will be used when inserting new vias within an area that
|
||||
///< has been assigned this rule set. ("VIACODEREF")
|
||||
|
||||
std::vector<SPACINGCODE> SpacingCodes; ///< Overrides these spacing rules in the specific
|
||||
std::map<SPACINGCODE_ID, SPACINGCODE>
|
||||
SpacingCodes; ///< Overrides these spacing rules in the specific
|
||||
///< area.
|
||||
void Parse( XNODE* aNode );
|
||||
};
|
||||
|
@ -733,7 +768,7 @@ public:
|
|||
std::map<TEXTCODE_ID, TEXTCODE> TextCodes;
|
||||
std::map<ROUTECODE_ID, ROUTECODE> RouteCodes;
|
||||
std::map<COPPERCODE_ID, COPPERCODE> CopperCodes;
|
||||
std::vector<SPACINGCODE> SpacingCodes; ///< Spacing Design Rules
|
||||
std::map<SPACINGCODE_ID, SPACINGCODE> SpacingCodes; ///< Spacing Design Rules
|
||||
std::map<RULESET_ID, RULESET> Rulesets; ///< Used for area design rules
|
||||
std::map<PADCODE_ID, PADCODE> PadCodes;
|
||||
std::map<VIACODE_ID, VIACODE> ViaCodes;
|
||||
|
@ -790,10 +825,10 @@ public:
|
|||
long TrackGrid; ///< Grid for Routes (equal X and Y steps)
|
||||
long ViaGrid; ///< Grid for Vias (equal X and Y steps)
|
||||
|
||||
POINT DesignOrigin;
|
||||
LONGPOINT DesignOrigin;
|
||||
std::pair<POINT, POINT> DesignArea;
|
||||
POINT DesignRef; ///< Appears to be 0,0 always
|
||||
POINT DesignLimit;
|
||||
LONGPOINT DesignRef; ///< Appears to be 0,0 always
|
||||
LONGPOINT DesignLimit;
|
||||
|
||||
bool BackOffJunctions = false;
|
||||
bool BackOffWidthChange = false;
|
||||
|
@ -1850,13 +1885,20 @@ public:
|
|||
///< aperture etc ...) used on a plotting machine"
|
||||
///< (param1)
|
||||
|
||||
long ClearanceWidth; ///< (param2)
|
||||
long SliverWidth; ///< (param3)
|
||||
long AdditionalIsolation; ///< (param4)
|
||||
long ThermalReliefPadsAngle; ///< Disabled when !ThermalReliefOnPads (param5)
|
||||
long ClearanceWidth; ///< Specifies the space around pads when pouring
|
||||
///< (i.e. Thermal relief clearance)
|
||||
long SliverWidth; ///< Minimum width of copper that may be created
|
||||
long AdditionalIsolation; ///< This is the gap to apply in routes and pads
|
||||
///< in addition to the existing pad-to-copper or
|
||||
///< route-to-copper spacing (see SPACINGCODE.ID)
|
||||
long ThermalReliefPadsAngle; ///< Orientation for the thermal reliefs. Disabled when !ThermalReliefOnPads (param5)
|
||||
long ThermalReliefViasAngle; ///< Disabled when !ThermalReliefOnVias (param6)
|
||||
long MinIsolatedCopper = UNDEFINED_VALUE; ///< Disabled when UNDEFINED_VALUE (param7)
|
||||
long MinDisjointCopper = UNDEFINED_VALUE; ///< Disabled when UNDEFINED_VALUE (param8)
|
||||
long MinIsolatedCopper = UNDEFINED_VALUE; ///< The value is the length of one side of
|
||||
///< a notional square. Disabled when
|
||||
///< UNDEFINED_VALUE
|
||||
long MinDisjointCopper = UNDEFINED_VALUE; ///< The value is the length of one side of
|
||||
///< a notional square. Disabled when
|
||||
///< UNDEFINED_VALUE
|
||||
|
||||
bool ThermalReliefOnPads = true; ///< false when subnode "NOPINRELIEF" is present
|
||||
bool ThermalReliefOnVias = true; ///< false when subnode "NOVIARELIEF" is present
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include <cadstar_pcb_archive_loader.h>
|
||||
#include <cadstar_pcb_archive_plugin.h>
|
||||
#include <class_board.h>
|
||||
#include <properties.h>
|
||||
|
||||
|
||||
CADSTAR_PCB_ARCHIVE_PLUGIN::CADSTAR_PCB_ARCHIVE_PLUGIN()
|
||||
|
@ -62,5 +63,26 @@ BOARD* CADSTAR_PCB_ARCHIVE_PLUGIN::Load(
|
|||
CADSTAR_PCB_ARCHIVE_LOADER tempPCB( aFileName );
|
||||
tempPCB.Load( m_board );
|
||||
|
||||
//center the board:
|
||||
if( aProperties )
|
||||
{
|
||||
UTF8 page_width;
|
||||
UTF8 page_height;
|
||||
|
||||
if( aProperties->Value( "page_width", &page_width )
|
||||
&& aProperties->Value( "page_height", &page_height ) )
|
||||
{
|
||||
EDA_RECT bbbox = m_board->GetBoardEdgesBoundingBox();
|
||||
|
||||
int w = atoi( page_width.c_str() );
|
||||
int h = atoi( page_height.c_str() );
|
||||
|
||||
int desired_x = ( w - bbbox.GetWidth() ) / 2;
|
||||
int desired_y = ( h - bbbox.GetHeight() ) / 2;
|
||||
|
||||
m_board->Move( wxPoint( desired_x - bbbox.GetX(), desired_y - bbbox.GetY() ) );
|
||||
}
|
||||
}
|
||||
|
||||
return m_board;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue