Import Altium radial dimensions to KiCad radial dimensions.
(We converted them to KiCad leaders in 6.0 because we didn't have radial dimensions yet.) Fixes https://gitlab.com/kicad/code/kicad/issues/8789
This commit is contained in:
parent
295a6408c3
commit
3c0e3610e2
|
@ -561,7 +561,7 @@ void ALTIUM_PCB::Parse( const CFB::CompoundFileReader& aReader,
|
||||||
// the dimension record. (Yes, there is a REFERENCE0OBJECTID, but it doesn't point to the
|
// the dimension record. (Yes, there is a REFERENCE0OBJECTID, but it doesn't point to the
|
||||||
// dimensioned object.) We attempt to plug this gap by finding a colocated arc or circle
|
// dimensioned object.) We attempt to plug this gap by finding a colocated arc or circle
|
||||||
// and using its radius. If there are more than one such arcs/circles, well, :shrug:.
|
// and using its radius. If there are more than one such arcs/circles, well, :shrug:.
|
||||||
for( PCB_DIMENSION_BASE* dim : m_radialDimensions )
|
for( PCB_DIM_RADIAL* dim : m_radialDimensions )
|
||||||
{
|
{
|
||||||
int radius = 0;
|
int radius = 0;
|
||||||
|
|
||||||
|
@ -599,17 +599,16 @@ void ALTIUM_PCB::Parse( const CFB::CompoundFileReader& aReader,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Force a measured value, calculate the value text, and then stick it into the override
|
// Move the radius point onto the circumference
|
||||||
// text (since leaders don't have calculated text).
|
|
||||||
dim->SetMeasuredValue( radius );
|
|
||||||
dim->SetText( dim->GetPrefix() + dim->GetValueText() + dim->GetSuffix() );
|
|
||||||
dim->SetPrefix( wxEmptyString );
|
|
||||||
dim->SetSuffix( wxEmptyString );
|
|
||||||
|
|
||||||
// Move the leader line start to the radius point
|
|
||||||
VECTOR2I radialLine = dim->GetEnd() - dim->GetStart();
|
VECTOR2I radialLine = dim->GetEnd() - dim->GetStart();
|
||||||
radialLine = radialLine.Resize( radius );
|
int totalLength = radialLine.EuclideanNorm();
|
||||||
dim->SetStart( dim->GetStart() + (wxPoint) radialLine );
|
|
||||||
|
// Enforce a minimum on the radialLine else we won't have enough precision to get the
|
||||||
|
// angle from it.
|
||||||
|
radialLine = radialLine.Resize( std::max( radius, 2 ) );
|
||||||
|
dim->SetEnd( dim->GetStart() + (wxPoint) radialLine );
|
||||||
|
dim->SetLeaderLength( totalLength - radius );
|
||||||
|
dim->Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
// center board
|
// center board
|
||||||
|
@ -651,34 +650,32 @@ int ALTIUM_PCB::GetNetCode( uint16_t aId ) const
|
||||||
const ARULE6* ALTIUM_PCB::GetRule( ALTIUM_RULE_KIND aKind, const wxString& aName ) const
|
const ARULE6* ALTIUM_PCB::GetRule( ALTIUM_RULE_KIND aKind, const wxString& aName ) const
|
||||||
{
|
{
|
||||||
const auto rules = m_rules.find( aKind );
|
const auto rules = m_rules.find( aKind );
|
||||||
|
|
||||||
if( rules == m_rules.end() )
|
if( rules == m_rules.end() )
|
||||||
{
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
|
||||||
for( const ARULE6& rule : rules->second )
|
for( const ARULE6& rule : rules->second )
|
||||||
{
|
{
|
||||||
if( rule.name == aName )
|
if( rule.name == aName )
|
||||||
{
|
|
||||||
return &rule;
|
return &rule;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ARULE6* ALTIUM_PCB::GetRuleDefault( ALTIUM_RULE_KIND aKind ) const
|
const ARULE6* ALTIUM_PCB::GetRuleDefault( ALTIUM_RULE_KIND aKind ) const
|
||||||
{
|
{
|
||||||
const auto rules = m_rules.find( aKind );
|
const auto rules = m_rules.find( aKind );
|
||||||
|
|
||||||
if( rules == m_rules.end() )
|
if( rules == m_rules.end() )
|
||||||
{
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
|
||||||
for( const ARULE6& rule : rules->second )
|
for( const ARULE6& rule : rules->second )
|
||||||
{
|
{
|
||||||
if( rule.scope1expr == "All" && rule.scope2expr == "All" )
|
if( rule.scope1expr == "All" && rule.scope2expr == "All" )
|
||||||
{
|
|
||||||
return &rule;
|
return &rule;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -713,18 +710,21 @@ void ALTIUM_PCB::ParseBoard6Data( const CFB::CompoundFileReader& aReader,
|
||||||
ABOARD6 elem( reader );
|
ABOARD6 elem( reader );
|
||||||
|
|
||||||
if( reader.GetRemainingBytes() != 0 )
|
if( reader.GetRemainingBytes() != 0 )
|
||||||
{
|
|
||||||
THROW_IO_ERROR( "Board6 stream is not fully parsed" );
|
THROW_IO_ERROR( "Board6 stream is not fully parsed" );
|
||||||
}
|
|
||||||
|
|
||||||
m_board->GetDesignSettings().SetAuxOrigin( elem.sheetpos );
|
m_board->GetDesignSettings().SetAuxOrigin( elem.sheetpos );
|
||||||
m_board->GetDesignSettings().SetGridOrigin( elem.sheetpos );
|
m_board->GetDesignSettings().SetGridOrigin( elem.sheetpos );
|
||||||
|
|
||||||
// read layercount from stackup, because LAYERSETSCOUNT is not always correct?!
|
// read layercount from stackup, because LAYERSETSCOUNT is not always correct?!
|
||||||
size_t layercount = 0;
|
size_t layercount = 0;
|
||||||
for( size_t i = static_cast<size_t>( ALTIUM_LAYER::TOP_LAYER );
|
size_t layer = static_cast<size_t>( ALTIUM_LAYER::TOP_LAYER );
|
||||||
i < elem.stackup.size() && i != 0; i = elem.stackup[i - 1].nextId, layercount++ )
|
|
||||||
;
|
while( layer < elem.stackup.size() && layer != 0 )
|
||||||
|
{
|
||||||
|
layer = elem.stackup[ layer - 1 ].nextId;
|
||||||
|
layercount++;
|
||||||
|
}
|
||||||
|
|
||||||
size_t kicadLayercount = ( layercount % 2 == 0 ) ? layercount : layercount + 1;
|
size_t kicadLayercount = ( layercount % 2 == 0 ) ? layercount : layercount + 1;
|
||||||
m_board->SetCopperLayerCount( kicadLayercount );
|
m_board->SetCopperLayerCount( kicadLayercount );
|
||||||
|
|
||||||
|
@ -871,11 +871,11 @@ void ALTIUM_PCB::HelperCreateBoardOutline( const std::vector<ALTIUM_VERTICE>& aV
|
||||||
{
|
{
|
||||||
shape->SetShape( SHAPE_T::ARC );
|
shape->SetShape( SHAPE_T::ARC );
|
||||||
|
|
||||||
double includedAngle = cur->endangle - cur->startangle;
|
double includedAngle = cur->endangle - cur->startangle;
|
||||||
double startradiant = DEG2RAD( cur->startangle );
|
double startAngle = DEG2RAD( cur->endangle );
|
||||||
wxPoint arcStartOffset = wxPoint( KiROUND( std::cos( startradiant ) * cur->radius ),
|
wxPoint startOffset = wxPoint( KiROUND( std::cos( startAngle ) * cur->radius ),
|
||||||
-KiROUND( std::sin( startradiant ) * cur->radius ) );
|
-KiROUND( std::sin( startAngle ) * cur->radius ) );
|
||||||
wxPoint arcStart = cur->center + arcStartOffset;
|
wxPoint arcStart = cur->center + startOffset;
|
||||||
|
|
||||||
shape->SetCenter( cur->center );
|
shape->SetCenter( cur->center );
|
||||||
shape->SetStart( arcStart );
|
shape->SetStart( arcStart );
|
||||||
|
@ -883,10 +883,10 @@ void ALTIUM_PCB::HelperCreateBoardOutline( const std::vector<ALTIUM_VERTICE>& aV
|
||||||
|
|
||||||
if( !last->isRound )
|
if( !last->isRound )
|
||||||
{
|
{
|
||||||
double endradiant = DEG2RAD( cur->endangle );
|
double endAngle = DEG2RAD( cur->endangle );
|
||||||
wxPoint arcEndOffset = wxPoint( KiROUND( std::cos( endradiant ) * cur->radius ),
|
wxPoint endOffset = wxPoint( KiROUND( std::cos( endAngle ) * cur->radius ),
|
||||||
-KiROUND( std::sin( endradiant ) * cur->radius ) );
|
-KiROUND( std::sin( endAngle ) * cur->radius ) );
|
||||||
wxPoint arcEnd = cur->center + arcEndOffset;
|
wxPoint arcEnd = cur->center + endOffset;
|
||||||
|
|
||||||
PCB_SHAPE* shape2 = new PCB_SHAPE( m_board, SHAPE_T::SEGMENT );
|
PCB_SHAPE* shape2 = new PCB_SHAPE( m_board, SHAPE_T::SEGMENT );
|
||||||
m_board->Add( shape2, ADD_MODE::APPEND );
|
m_board->Add( shape2, ADD_MODE::APPEND );
|
||||||
|
@ -899,9 +899,9 @@ void ALTIUM_PCB::HelperCreateBoardOutline( const std::vector<ALTIUM_VERTICE>& aV
|
||||||
double lineLengthEnd = GetLineLength( last->position, arcEnd );
|
double lineLengthEnd = GetLineLength( last->position, arcEnd );
|
||||||
|
|
||||||
if( lineLengthStart > lineLengthEnd )
|
if( lineLengthStart > lineLengthEnd )
|
||||||
shape2->SetEnd( cur->center + arcEndOffset );
|
shape2->SetEnd( cur->center + endOffset );
|
||||||
else
|
else
|
||||||
shape2->SetEnd( cur->center + arcStartOffset );
|
shape2->SetEnd( cur->center + startOffset );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
last = cur;
|
last = cur;
|
||||||
|
@ -941,9 +941,7 @@ void ALTIUM_PCB::ParseClasses6Data( const CFB::CompoundFileReader& aReader,
|
||||||
}
|
}
|
||||||
|
|
||||||
if( reader.GetRemainingBytes() != 0 )
|
if( reader.GetRemainingBytes() != 0 )
|
||||||
{
|
|
||||||
THROW_IO_ERROR( "Classes6 stream is not fully parsed" );
|
THROW_IO_ERROR( "Classes6 stream is not fully parsed" );
|
||||||
}
|
|
||||||
|
|
||||||
m_board->m_LegacyNetclassesLoaded = true;
|
m_board->m_LegacyNetclassesLoaded = true;
|
||||||
}
|
}
|
||||||
|
@ -989,9 +987,7 @@ void ALTIUM_PCB::ParseComponents6Data( const CFB::CompoundFileReader& aReader,
|
||||||
}
|
}
|
||||||
|
|
||||||
if( reader.GetRemainingBytes() != 0 )
|
if( reader.GetRemainingBytes() != 0 )
|
||||||
{
|
|
||||||
THROW_IO_ERROR( "Components6 stream is not fully parsed" );
|
THROW_IO_ERROR( "Components6 stream is not fully parsed" );
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1170,10 +1166,7 @@ void ALTIUM_PCB::HelperParseDimensions6Radial(const ADIMENSION6 &aElem)
|
||||||
wxPoint referencePoint0 = aElem.referencePoint.at( 0 );
|
wxPoint referencePoint0 = aElem.referencePoint.at( 0 );
|
||||||
wxPoint referencePoint1 = aElem.referencePoint.at( 1 );
|
wxPoint referencePoint1 = aElem.referencePoint.at( 1 );
|
||||||
|
|
||||||
//
|
PCB_DIM_RADIAL* dimension = new PCB_DIM_RADIAL( m_board );
|
||||||
// We don't have radial dimensions yet so fake it with a leader:
|
|
||||||
|
|
||||||
PCB_DIM_LEADER* dimension = new PCB_DIM_LEADER( m_board );
|
|
||||||
m_board->Add( dimension, ADD_MODE::APPEND );
|
m_board->Add( dimension, ADD_MODE::APPEND );
|
||||||
m_radialDimensions.push_back( dimension );
|
m_radialDimensions.push_back( dimension );
|
||||||
|
|
||||||
|
@ -1182,6 +1175,7 @@ void ALTIUM_PCB::HelperParseDimensions6Radial(const ADIMENSION6 &aElem)
|
||||||
dimension->SetStart( referencePoint0 );
|
dimension->SetStart( referencePoint0 );
|
||||||
dimension->SetEnd( aElem.xy1 );
|
dimension->SetEnd( aElem.xy1 );
|
||||||
dimension->SetLineThickness( aElem.linewidth );
|
dimension->SetLineThickness( aElem.linewidth );
|
||||||
|
dimension->SetKeepTextAligned( false );
|
||||||
|
|
||||||
dimension->SetPrefix( aElem.textprefix );
|
dimension->SetPrefix( aElem.textprefix );
|
||||||
|
|
||||||
|
@ -1910,6 +1904,34 @@ void ALTIUM_PCB::ParseArcs6Data( const CFB::CompoundFileReader& aReader,
|
||||||
if( m_progressReporter )
|
if( m_progressReporter )
|
||||||
m_progressReporter->Report( _( "Loading arcs..." ) );
|
m_progressReporter->Report( _( "Loading arcs..." ) );
|
||||||
|
|
||||||
|
auto setupShape =
|
||||||
|
[&]( AARC6& elem, PCB_LAYER_ID layer, PCB_SHAPE& shape )
|
||||||
|
{
|
||||||
|
shape.SetLayer( layer );
|
||||||
|
shape.SetStroke( STROKE_PARAMS( elem.width, PLOT_DASH_TYPE::SOLID ) );
|
||||||
|
|
||||||
|
if( elem.startangle == 0. && elem.endangle == 360. )
|
||||||
|
{
|
||||||
|
// TODO: other variants to define circle?
|
||||||
|
shape.SetShape( SHAPE_T::CIRCLE );
|
||||||
|
shape.SetStart( elem.center );
|
||||||
|
shape.SetEnd( elem.center - wxPoint( 0, elem.radius ) );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
shape.SetShape( SHAPE_T::ARC );
|
||||||
|
|
||||||
|
double includedAngle = elem.endangle - elem.startangle;
|
||||||
|
double startAngle = DEG2RAD( elem.endangle );
|
||||||
|
|
||||||
|
wxPoint startOffset = wxPoint( KiROUND( std::cos( startAngle ) * elem.radius ),
|
||||||
|
-KiROUND( std::sin( startAngle ) * elem.radius ) );
|
||||||
|
|
||||||
|
shape.SetCenter( elem.center );
|
||||||
|
shape.SetStart( elem.center + startOffset );
|
||||||
|
shape.SetArcAngleAndEnd( NormalizeAngleDegreesPos( includedAngle ) * 10.0, true );
|
||||||
|
};
|
||||||
|
|
||||||
ALTIUM_PARSER reader( aReader, aEntry );
|
ALTIUM_PARSER reader( aReader, aEntry );
|
||||||
|
|
||||||
while( reader.GetRemainingBytes() >= 4 /* TODO: use Header section of file */ )
|
while( reader.GetRemainingBytes() >= 4 /* TODO: use Header section of file */ )
|
||||||
|
@ -1929,27 +1951,7 @@ void ALTIUM_PCB::ParseArcs6Data( const CFB::CompoundFileReader& aReader,
|
||||||
if( elem.is_keepout || IsAltiumLayerAPlane( elem.layer ) )
|
if( elem.is_keepout || IsAltiumLayerAPlane( elem.layer ) )
|
||||||
{
|
{
|
||||||
PCB_SHAPE shape( nullptr ); // just a helper to get the graphic
|
PCB_SHAPE shape( nullptr ); // just a helper to get the graphic
|
||||||
shape.SetStroke( STROKE_PARAMS( elem.width, PLOT_DASH_TYPE::SOLID ) );
|
setupShape( elem, klayer, shape );
|
||||||
|
|
||||||
if( elem.startangle == 0. && elem.endangle == 360. )
|
|
||||||
{ // TODO: other variants to define circle?
|
|
||||||
shape.SetShape( SHAPE_T::CIRCLE );
|
|
||||||
shape.SetStart( elem.center );
|
|
||||||
shape.SetEnd( elem.center - wxPoint( 0, elem.radius ) );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
shape.SetShape( SHAPE_T::ARC );
|
|
||||||
|
|
||||||
double includedAngle = elem.endangle - elem.startangle;
|
|
||||||
double startradiant = DEG2RAD( elem.startangle );
|
|
||||||
wxPoint arcStartOffset = wxPoint( KiROUND( std::cos( startradiant ) * elem.radius ),
|
|
||||||
-KiROUND( std::sin( startradiant ) * elem.radius ) );
|
|
||||||
|
|
||||||
shape.SetCenter( elem.center );
|
|
||||||
shape.SetStart( elem.center + arcStartOffset );
|
|
||||||
shape.SetArcAngleAndEnd( -NormalizeAngleDegreesPos( includedAngle ) * 10.0, true );
|
|
||||||
}
|
|
||||||
|
|
||||||
ZONE* zone = new ZONE( m_board );
|
ZONE* zone = new ZONE( m_board );
|
||||||
m_board->Add( zone, ADD_MODE::APPEND );
|
m_board->Add( zone, ADD_MODE::APPEND );
|
||||||
|
@ -1969,8 +1971,6 @@ void ALTIUM_PCB::ParseArcs6Data( const CFB::CompoundFileReader& aReader,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PCB_LAYER_ID klayer = GetKicadLayer( elem.layer );
|
|
||||||
|
|
||||||
if( klayer == UNDEFINED_LAYER )
|
if( klayer == UNDEFINED_LAYER )
|
||||||
{
|
{
|
||||||
wxLogWarning( _( "Arc keepout found on an Altium layer (%d) with no KiCad "
|
wxLogWarning( _( "Arc keepout found on an Altium layer (%d) with no KiCad "
|
||||||
|
@ -2034,37 +2034,15 @@ void ALTIUM_PCB::ParseArcs6Data( const CFB::CompoundFileReader& aReader,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PCB_SHAPE* shape = HelperCreateAndAddShape( elem.component );
|
PCB_SHAPE* shape = HelperCreateAndAddShape( elem.component );
|
||||||
shape->SetStroke( STROKE_PARAMS( elem.width, PLOT_DASH_TYPE::SOLID ) );
|
|
||||||
shape->SetLayer( klayer );
|
|
||||||
|
|
||||||
if( elem.startangle == 0. && elem.endangle == 360. )
|
setupShape( elem, klayer, *shape );
|
||||||
{ // TODO: other variants to define circle?
|
|
||||||
shape->SetShape( SHAPE_T::CIRCLE );
|
|
||||||
shape->SetStart( elem.center );
|
|
||||||
shape->SetEnd( elem.center - wxPoint( 0, elem.radius ) );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
shape->SetShape( SHAPE_T::ARC );
|
|
||||||
|
|
||||||
double includedAngle = elem.endangle - elem.startangle;
|
|
||||||
double startradiant = DEG2RAD( elem.startangle );
|
|
||||||
wxPoint arcStartOffset = wxPoint( KiROUND( std::cos( startradiant ) * elem.radius ),
|
|
||||||
-KiROUND( std::sin( startradiant ) * elem.radius ) );
|
|
||||||
|
|
||||||
shape->SetCenter( elem.center );
|
|
||||||
shape->SetStart( elem.center + arcStartOffset );
|
|
||||||
shape->SetArcAngleAndEnd( -NormalizeAngleDegreesPos( includedAngle ) * 10.0, true );
|
|
||||||
}
|
|
||||||
|
|
||||||
HelperShapeSetLocalCoord( shape, elem.component );
|
HelperShapeSetLocalCoord( shape, elem.component );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( reader.GetRemainingBytes() != 0 )
|
if( reader.GetRemainingBytes() != 0 )
|
||||||
{
|
|
||||||
THROW_IO_ERROR( "Arcs6 stream is not fully parsed" );
|
THROW_IO_ERROR( "Arcs6 stream is not fully parsed" );
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -85,7 +85,7 @@ class BOARD;
|
||||||
class PCB_SHAPE;
|
class PCB_SHAPE;
|
||||||
class FOOTPRINT;
|
class FOOTPRINT;
|
||||||
class ZONE;
|
class ZONE;
|
||||||
class PCB_DIMENSION_BASE;
|
class PCB_DIM_RADIAL;
|
||||||
class PROGRESS_REPORTER;
|
class PROGRESS_REPORTER;
|
||||||
|
|
||||||
|
|
||||||
|
@ -193,7 +193,7 @@ private:
|
||||||
BOARD* m_board;
|
BOARD* m_board;
|
||||||
std::vector<FOOTPRINT*> m_components;
|
std::vector<FOOTPRINT*> m_components;
|
||||||
std::vector<ZONE*> m_polygons;
|
std::vector<ZONE*> m_polygons;
|
||||||
std::vector<PCB_DIMENSION_BASE*> m_radialDimensions;
|
std::vector<PCB_DIM_RADIAL*> m_radialDimensions;
|
||||||
std::map<wxString, wxString> m_models;
|
std::map<wxString, wxString> m_models;
|
||||||
std::map<uint32_t, wxString> m_unicodeStrings;
|
std::map<uint32_t, wxString> m_unicodeStrings;
|
||||||
size_t m_num_nets;
|
size_t m_num_nets;
|
||||||
|
|
Loading…
Reference in New Issue