Don't use clone to copy an EDA_ITEM. Use Duplicate().

Even if you give the clone a new KIID, all its children will still
be clones.

Fixes https://gitlab.com/kicad/code/kicad/issues/5982
This commit is contained in:
Jeff Young 2020-10-13 16:53:07 +01:00
parent 0cf57c7b1f
commit e789ad9fb2
1 changed files with 29 additions and 22 deletions

View File

@ -329,8 +329,10 @@ BOARD* EAGLE_PLUGIN::Load( const wxString& aFileName, BOARD* aAppendToMe, const
wxFileName fn = aFileName; wxFileName fn = aFileName;
if( !xmlDocument.Load( fn.GetFullPath() ) ) if( !xmlDocument.Load( fn.GetFullPath() ) )
{
THROW_IO_ERROR( wxString::Format( _( "Unable to read file \"%s\"" ), THROW_IO_ERROR( wxString::Format( _( "Unable to read file \"%s\"" ),
fn.GetFullPath() ) ); fn.GetFullPath() ) );
}
doc = xmlDocument.GetRoot(); doc = xmlDocument.GetRoot();
@ -1030,14 +1032,12 @@ void EAGLE_PLUGIN::loadElements( wxXmlNode* aElements )
THROW_IO_ERROR( emsg ); THROW_IO_ERROR( emsg );
} }
// copy constructor to clone the template MODULE* m = static_cast<MODULE*>( mi->second->Duplicate() );
MODULE* m = new MODULE( *mi->second );
const_cast<KIID&>( m->m_Uuid ) = KIID();
m_board->Add( m, ADD_MODE::APPEND ); m_board->Add( m, ADD_MODE::APPEND );
// update the nets within the pads of the clone // update the nets within the pads of the clone
for( auto pad : m->Pads() ) for( D_PAD* pad : m->Pads() )
{ {
wxString pn_key = makeKey( e.name, pad->GetName() ); wxString pn_key = makeKey( e.name, pad->GetName() );
@ -1129,8 +1129,10 @@ void EAGLE_PLUGIN::loadElements( wxXmlNode* aElements )
nameAttr->name = reference; nameAttr->name = reference;
m->SetReference( reference ); m->SetReference( reference );
if( refanceNamePresetInPackageLayout ) if( refanceNamePresetInPackageLayout )
m->Reference().SetVisible( true ); m->Reference().SetVisible( true );
break; break;
} }
case EATTR::NAME : case EATTR::NAME :
@ -1144,6 +1146,7 @@ void EAGLE_PLUGIN::loadElements( wxXmlNode* aElements )
case EATTR::BOTH : case EATTR::BOTH :
if( refanceNamePresetInPackageLayout ) if( refanceNamePresetInPackageLayout )
m->Reference().SetVisible( true ); m->Reference().SetVisible( true );
nameAttr->name = nameAttr->name + " = " + e.name; nameAttr->name = nameAttr->name + " = " + e.name;
m->SetReference( "NAME = " + e.name ); m->SetReference( "NAME = " + e.name );
break; break;
@ -1154,6 +1157,7 @@ void EAGLE_PLUGIN::loadElements( wxXmlNode* aElements )
default: default:
nameAttr->name = e.name; nameAttr->name = e.name;
if( refanceNamePresetInPackageLayout ) if( refanceNamePresetInPackageLayout )
m->Reference().SetVisible( true ); m->Reference().SetVisible( true );
} }
@ -1175,19 +1179,23 @@ void EAGLE_PLUGIN::loadElements( wxXmlNode* aElements )
case EATTR::VALUE : case EATTR::VALUE :
valueAttr->value = opt_wxString( e.value ); valueAttr->value = opt_wxString( e.value );
m->SetValue( e.value ); m->SetValue( e.value );
if( valueNamePresetInPackageLayout ) if( valueNamePresetInPackageLayout )
m->Value().SetVisible( true ); m->Value().SetVisible( true );
break; break;
case EATTR::NAME : case EATTR::NAME :
if( valueNamePresetInPackageLayout ) if( valueNamePresetInPackageLayout )
m->Value().SetVisible( true ); m->Value().SetVisible( true );
m->SetValue( "VALUE" ); m->SetValue( "VALUE" );
break; break;
case EATTR::BOTH : case EATTR::BOTH :
if( valueNamePresetInPackageLayout ) if( valueNamePresetInPackageLayout )
m->Value().SetVisible( true ); m->Value().SetVisible( true );
valueAttr->value = opt_wxString( "VALUE = " + e.value ); valueAttr->value = opt_wxString( "VALUE = " + e.value );
m->SetValue( "VALUE = " + e.value ); m->SetValue( "VALUE = " + e.value );
break; break;
@ -1198,13 +1206,16 @@ void EAGLE_PLUGIN::loadElements( wxXmlNode* aElements )
default: default:
valueAttr->value = opt_wxString( e.value ); valueAttr->value = opt_wxString( e.value );
if( valueNamePresetInPackageLayout ) if( valueNamePresetInPackageLayout )
m->Value().SetVisible( true ); m->Value().SetVisible( true );
} }
} }
else else
{
// No display, so default is visible, and show value of NAME // No display, so default is visible, and show value of NAME
m->Value().SetVisible( true ); m->Value().SetVisible( true );
}
} }
@ -1280,12 +1291,12 @@ ZONE_CONTAINER* EAGLE_PLUGIN::loadPolygon( wxXmlNode* aPolyNode )
if( v1.curve ) if( v1.curve )
{ {
EVERTEX v2 = vertices[i + 1]; EVERTEX v2 = vertices[i + 1];
wxPoint center = ConvertArcCenter( wxPoint center = ConvertArcCenter( wxPoint( kicad_x( v1.x ), kicad_y( v1.y ) ),
wxPoint( kicad_x( v1.x ), kicad_y( v1.y ) ), wxPoint( kicad_x( v2.x ), kicad_y( v2.y ) ),
wxPoint( kicad_x( v2.x ), kicad_y( v2.y ) ), *v1.curve ); *v1.curve );
double angle = DEG2RAD( *v1.curve ); double angle = DEG2RAD( *v1.curve );
double end_angle = atan2( kicad_y( v2.y ) - center.y, double end_angle = atan2( kicad_y( v2.y ) - center.y,
kicad_x( v2.x ) - center.x ); kicad_x( v2.x ) - center.x );
double radius = sqrt( pow( center.x - kicad_x( v1.x ), 2 ) double radius = sqrt( pow( center.x - kicad_x( v1.x ), 2 )
+ pow( center.y - kicad_y( v1.y ), 2 ) ); + pow( center.y - kicad_y( v1.y ), 2 ) );
@ -1297,7 +1308,7 @@ ZONE_CONTAINER* EAGLE_PLUGIN::loadPolygon( wxXmlNode* aPolyNode )
a -= delta_angle ) a -= delta_angle )
{ {
polygon.Append( KiROUND( radius * cos( a ) ) + center.x, polygon.Append( KiROUND( radius * cos( a ) ) + center.x,
KiROUND( radius * sin( a ) ) + center.y ); KiROUND( radius * sin( a ) ) + center.y );
} }
} }
} }
@ -1335,8 +1346,8 @@ ZONE_CONTAINER* EAGLE_PLUGIN::loadPolygon( wxXmlNode* aPolyNode )
// We divide the thickness by half because we are tracing _inside_ the zone outline // We divide the thickness by half because we are tracing _inside_ the zone outline
// This means the radius of curvature will be twice the size for an equivalent EAGLE zone // This means the radius of curvature will be twice the size for an equivalent EAGLE zone
zone->SetMinThickness( zone->SetMinThickness( std::max<int>( ZONE_THICKNESS_MIN_VALUE_MIL * IU_PER_MILS,
std::max<int>( ZONE_THICKNESS_MIN_VALUE_MIL * IU_PER_MILS, p.width.ToPcbUnits() / 2 ) ); p.width.ToPcbUnits() / 2 ) );
if( p.isolate ) if( p.isolate )
zone->SetLocalClearance( p.isolate->ToPcbUnits() ); zone->SetLocalClearance( p.isolate->ToPcbUnits() );
@ -1590,19 +1601,15 @@ void EAGLE_PLUGIN::packageWire( MODULE* aModule, wxXmlNode* aTree ) const
// line widths. // line widths.
switch( layer ) switch( layer )
{ {
case Edge_Cuts: case Edge_Cuts: width = Millimeter2iu( DEFAULT_EDGE_WIDTH ); break;
width = Millimeter2iu( DEFAULT_EDGE_WIDTH );
break;
case F_SilkS: case F_SilkS:
case B_SilkS: case B_SilkS: width = Millimeter2iu( DEFAULT_SILK_LINE_WIDTH ); break;
width = Millimeter2iu( DEFAULT_SILK_LINE_WIDTH );
break;
case F_CrtYd: case F_CrtYd:
case B_CrtYd: case B_CrtYd: width = Millimeter2iu( DEFAULT_COURTYARD_WIDTH ); break;
width = Millimeter2iu( DEFAULT_COURTYARD_WIDTH );
break; default: width = Millimeter2iu( DEFAULT_LINE_WIDTH ); break;
default:
width = Millimeter2iu( DEFAULT_LINE_WIDTH );
} }
} }
} }