Improvements to Eagle dimension importing.

1) Import leaders
2) Drop radius and angle dimensions
3) Import dimension text sizes
4) Correctly interpret which side dimension offset is on
5) Correclty handle offsets for non-cardinal dimensions

Fixes https://gitlab.com/kicad/code/kicad/issues/10763
This commit is contained in:
Jeff Young 2022-04-12 13:21:27 +01:00
parent b2eb1f829e
commit 6818eff90e
3 changed files with 122 additions and 58 deletions

View File

@ -538,18 +538,20 @@ EDIMENSION::EDIMENSION( wxXmlNode* aDimension )
y2 %Coord; #REQUIRED y2 %Coord; #REQUIRED
x3 %Coord; #REQUIRED x3 %Coord; #REQUIRED
y3 %Coord; #REQUIRED y3 %Coord; #REQUIRED
textsize %Coord;
layer %Layer; #REQUIRED layer %Layer; #REQUIRED
dtype %DimensionType; "parallel" dtype %DimensionType; "parallel"
> >
*/ */
x1 = parseRequiredAttribute<ECOORD>( aDimension, wxT( "x1" ) ); x1 = parseRequiredAttribute<ECOORD>( aDimension, wxT( "x1" ) );
y1 = parseRequiredAttribute<ECOORD>( aDimension, wxT( "y1" ) ); y1 = parseRequiredAttribute<ECOORD>( aDimension, wxT( "y1" ) );
x2 = parseRequiredAttribute<ECOORD>( aDimension, wxT( "x2" ) ); x2 = parseRequiredAttribute<ECOORD>( aDimension, wxT( "x2" ) );
y2 = parseRequiredAttribute<ECOORD>( aDimension, wxT( "y2" ) ); y2 = parseRequiredAttribute<ECOORD>( aDimension, wxT( "y2" ) );
x3 = parseRequiredAttribute<ECOORD>( aDimension, wxT( "x3" ) ); x3 = parseRequiredAttribute<ECOORD>( aDimension, wxT( "x3" ) );
y3 = parseRequiredAttribute<ECOORD>( aDimension, wxT( "y3" ) ); y3 = parseRequiredAttribute<ECOORD>( aDimension, wxT( "y3" ) );
layer = parseRequiredAttribute<int>( aDimension, wxT( "layer" ) ); textsize = parseOptionalAttribute<ECOORD>( aDimension, wxT( "textsize" ) );
layer = parseRequiredAttribute<int>( aDimension, wxT( "layer" ) );
dimensionType = parseOptionalAttribute<wxString>( aDimension, wxT( "dtype" ) ); dimensionType = parseOptionalAttribute<wxString>( aDimension, wxT( "dtype" ) );
} }

View File

@ -531,13 +531,13 @@ struct EJUNCTION
/// Eagle label /// Eagle label
struct ELABEL struct ELABEL
{ {
ECOORD x; ECOORD x;
ECOORD y; ECOORD y;
ECOORD size; ECOORD size;
LAYER_NUM layer; LAYER_NUM layer;
opt_erot rot; opt_erot rot;
opt_wxString xref; opt_wxString xref;
wxString netname; wxString netname;
ELABEL( wxXmlNode* aLabel, const wxString& aNetName ); ELABEL( wxXmlNode* aLabel, const wxString& aNetName );
}; };
@ -619,14 +619,14 @@ struct EATTR
/// Eagle dimension element /// Eagle dimension element
struct EDIMENSION struct EDIMENSION
{ {
ECOORD x1; ECOORD x1;
ECOORD y1; ECOORD y1;
ECOORD x2; ECOORD x2;
ECOORD y2; ECOORD y2;
ECOORD x3; ECOORD x3;
ECOORD y3; ECOORD y3;
int layer; opt_ecoord textsize;
int layer;
opt_wxString dimensionType; opt_wxString dimensionType;
EDIMENSION( wxXmlNode* aDimension ); EDIMENSION( wxXmlNode* aDimension );

View File

@ -982,53 +982,115 @@ void EAGLE_PLUGIN::loadPlain( wxXmlNode* aGraphics )
} }
else if( grName == wxT( "dimension" ) ) else if( grName == wxT( "dimension" ) )
{ {
EDIMENSION d( gr ); const BOARD_DESIGN_SETTINGS& designSettings = m_board->GetDesignSettings();
EDIMENSION d( gr );
PCB_LAYER_ID layer = kicad_layer( d.layer ); PCB_LAYER_ID layer = kicad_layer( d.layer );
VECTOR2I pt1( kicad_x( d.x1 ), kicad_y( d.y1 ) );
VECTOR2I pt2( kicad_x( d.x2 ), kicad_y( d.y2 ) );
VECTOR2I pt3( kicad_x( d.x3 ), kicad_y( d.y3 ) );
wxSize textSize = designSettings.GetTextSize( layer );
int textThickness = designSettings.GetLineThickness( layer );
if( d.textsize )
{
double ratio = 8; // DTD says 8 is default
textThickness = KiROUND( d.textsize->ToPcbUnits() * ratio / 100 );
textSize = kicad_fontz( *d.textsize, textThickness );
}
if( layer != UNDEFINED_LAYER ) if( layer != UNDEFINED_LAYER )
{ {
const BOARD_DESIGN_SETTINGS& designSettings = m_board->GetDesignSettings(); if( d.dimensionType == wxT( "angle" ) )
PCB_DIM_ALIGNED* dimension = new PCB_DIM_ALIGNED( m_board );
m_board->Add( dimension, ADD_MODE::APPEND );
if( d.dimensionType )
{ {
// Eagle dimension graphic arms may have different lengths, but they look // Kicad doesn't (at present) support angle dimensions
// incorrect in KiCad (the graphic is tilted). Make them even length in }
// such case. else if( d.dimensionType == wxT( "radius" ) )
if( *d.dimensionType == wxT( "horizontal" ) ) {
// Radial dimensions added in 7.0....
}
else if( d.dimensionType == wxT( "leader" ) )
{
PCB_DIM_LEADER* leader = new PCB_DIM_LEADER( m_board );
m_board->Add( leader, ADD_MODE::APPEND );
leader->SetLayer( layer );
leader->SetPrecision( DIMENSION_PRECISION );
leader->SetStart( (wxPoint) pt1 );
leader->SetEnd( (wxPoint) pt2 );
leader->Text().SetPosition( (wxPoint) pt3 );
leader->Text().SetTextSize( textSize );
leader->Text().SetTextThickness( textThickness );
leader->SetLineThickness( designSettings.GetLineThickness( layer ) );
}
else // horizontal, vertical, <default>, diameter
{
PCB_DIM_ALIGNED* dimension = new PCB_DIM_ALIGNED( m_board );
m_board->Add( dimension, ADD_MODE::APPEND );
if( d.dimensionType )
{ {
int newY = ( d.y1.ToPcbUnits() + d.y2.ToPcbUnits() ) / 2; // Eagle dimension graphic arms may have different lengths, but they look
d.y1 = ECOORD( newY, ECOORD::EAGLE_UNIT::EU_NM ); // incorrect in KiCad (the graphic is tilted). Make them even length in
d.y2 = ECOORD( newY, ECOORD::EAGLE_UNIT::EU_NM ); // such case.
if( *d.dimensionType == wxT( "horizontal" ) )
{
int newY = ( pt1.y + pt2.y ) / 2;
pt1.y = newY;
pt2.y = newY;
}
else if( *d.dimensionType == wxT( "vertical" ) )
{
int newX = ( pt1.x + pt2.x ) / 2;
pt1.x = newX;
pt2.x = newX;
}
} }
else if( *d.dimensionType == wxT( "vertical" ) )
dimension->SetLayer( layer );
dimension->SetPrecision( DIMENSION_PRECISION );
// The origin and end are assumed to always be in this order from eagle
dimension->SetStart( (wxPoint) pt1 );
dimension->SetEnd( (wxPoint) pt2 );
dimension->Text().SetTextSize( textSize );
dimension->Text().SetTextThickness( textThickness );
dimension->SetLineThickness( designSettings.GetLineThickness( layer ) );
dimension->SetUnits( EDA_UNITS::MILLIMETRES );
// check which axis the dimension runs in
// because the "height" of the dimension is perpendicular to that axis
// Note the check is just if two axes are close enough to each other
// Eagle appears to have some rounding errors
if( abs( pt1.x - pt2.x ) < 50000 ) // 50000 nm = 0.05 mm
{ {
int newX = ( d.x1.ToPcbUnits() + d.x2.ToPcbUnits() ) / 2; int offset = pt3.x - pt1.x;
d.x1 = ECOORD( newX, ECOORD::EAGLE_UNIT::EU_NM );
d.x2 = ECOORD( newX, ECOORD::EAGLE_UNIT::EU_NM ); if( pt1.y > pt2.y )
dimension->SetHeight( offset );
else
dimension->SetHeight( -offset );
}
else if( abs( pt1.y - pt2.y ) < 50000 )
{
int offset = pt3.y - pt1.y;
if( pt1.x > pt2.x )
dimension->SetHeight( -offset );
else
dimension->SetHeight( offset );
}
else
{
int offset = GetLineLength( (wxPoint) pt3, (wxPoint) pt1 );
if( pt1.y > pt2.y )
dimension->SetHeight( offset );
else
dimension->SetHeight( -offset );
} }
} }
dimension->SetLayer( layer );
dimension->SetPrecision( DIMENSION_PRECISION );
// The origin and end are assumed to always be in this order from eagle
dimension->SetStart( wxPoint( kicad_x( d.x1 ), kicad_y( d.y1 ) ) );
dimension->SetEnd( wxPoint( kicad_x( d.x2 ), kicad_y( d.y2 ) ) );
dimension->Text().SetTextSize( designSettings.GetTextSize( layer ) );
dimension->Text().SetTextThickness( designSettings.GetTextThickness( layer ) );
dimension->SetLineThickness( designSettings.GetLineThickness( layer ) );
dimension->SetUnits( EDA_UNITS::MILLIMETRES );
// check which axis the dimension runs in
// because the "height" of the dimension is perpendicular to that axis
// Note the check is just if two axes are close enough to each other
// Eagle appears to have some rounding errors
if( abs( ( d.x1 - d.x2 ).ToPcbUnits() ) < 50000 ) // 50000 nm = 0.05 mm
dimension->SetHeight( kicad_x( d.x3 - d.x1 ) );
else
dimension->SetHeight( kicad_y( d.y3 - d.y1 ) );
} }
} }