Add writing of pad primitive polys with arcs, and fix a bug in reading.
Fixes https://gitlab.com/kicad/code/kicad/issues/8827
This commit is contained in:
parent
b1fd462d28
commit
0f5a8f87d3
|
@ -39,17 +39,19 @@
|
||||||
|
|
||||||
void PAD::AddPrimitivePoly( const SHAPE_POLY_SET& aPoly, int aThickness, bool aFilled )
|
void PAD::AddPrimitivePoly( const SHAPE_POLY_SET& aPoly, int aThickness, bool aFilled )
|
||||||
{
|
{
|
||||||
std::vector<wxPoint> points;
|
|
||||||
|
|
||||||
// If aPoly has holes, convert it to a polygon with no holes.
|
// If aPoly has holes, convert it to a polygon with no holes.
|
||||||
SHAPE_POLY_SET poly_no_hole;
|
SHAPE_POLY_SET poly_no_hole;
|
||||||
poly_no_hole.Append( aPoly );
|
poly_no_hole.Append( aPoly );
|
||||||
poly_no_hole.Fracture( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
poly_no_hole.Fracture( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||||
|
|
||||||
for( auto iter = poly_no_hole.CIterate(); iter; iter++ )
|
PCB_SHAPE* item = new PCB_SHAPE();
|
||||||
points.emplace_back( iter->x, iter->y );
|
item->SetShape( SHAPE_T::POLY );
|
||||||
|
item->SetFilled( aFilled );
|
||||||
AddPrimitivePoly( points, aThickness, aFilled );
|
item->SetPolyShape( poly_no_hole );
|
||||||
|
item->SetWidth( aThickness );
|
||||||
|
item->SetParent( this );
|
||||||
|
m_editPrimitives.emplace_back( item );
|
||||||
|
SetDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -842,9 +842,9 @@ void PCB_IO::format( const PCB_SHAPE* aShape, int aNestLevel ) const
|
||||||
|
|
||||||
for( int ii = 0; ii < outline.PointCount(); ++ii )
|
for( int ii = 0; ii < outline.PointCount(); ++ii )
|
||||||
{
|
{
|
||||||
int nestLevel = ii == 0 ? aNestLevel + 2 : 0;
|
int nestLevel = 0;
|
||||||
|
|
||||||
if( ii && ( !( ii % 4 ) || !ADVANCED_CFG::GetCfg().m_CompactSave ) )
|
if( !( ii % 4 ) || !ADVANCED_CFG::GetCfg().m_CompactSave )
|
||||||
{
|
{
|
||||||
// newline every 4 pts.
|
// newline every 4 pts.
|
||||||
nestLevel = aNestLevel + 2;
|
nestLevel = aNestLevel + 2;
|
||||||
|
@ -864,11 +864,11 @@ void PCB_IO::format( const PCB_SHAPE* aShape, int aNestLevel ) const
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const SHAPE_ARC& arc = outline.Arc( ind );
|
const SHAPE_ARC& arc = outline.Arc( ind );
|
||||||
m_out->Print( aNestLevel, "%s(arc (start %s) (mid %s) (end %s))",
|
m_out->Print( nestLevel, "%s(arc (start %s) (mid %s) (end %s))",
|
||||||
nestLevel ? "" : " ",
|
nestLevel ? "" : " ",
|
||||||
FormatInternalUnits( arc.GetP0() ).c_str(),
|
FormatInternalUnits( arc.GetP0() ).c_str(),
|
||||||
FormatInternalUnits( arc.GetArcMid() ).c_str(),
|
FormatInternalUnits( arc.GetArcMid() ).c_str(),
|
||||||
FormatInternalUnits( arc.GetP1() ).c_str() );
|
FormatInternalUnits( arc.GetP1() ).c_str() );
|
||||||
need_newline = true;
|
need_newline = true;
|
||||||
|
|
||||||
do
|
do
|
||||||
|
@ -973,15 +973,18 @@ void PCB_IO::format( const FP_SHAPE* aFPShape, int aNestLevel ) const
|
||||||
m_out->Print( aNestLevel, "(fp_poly%s (pts",
|
m_out->Print( aNestLevel, "(fp_poly%s (pts",
|
||||||
locked.c_str() );
|
locked.c_str() );
|
||||||
|
|
||||||
|
bool need_newline = false;
|
||||||
|
|
||||||
for( int ii = 0; ii < outline.PointCount(); ++ii )
|
for( int ii = 0; ii < outline.PointCount(); ++ii )
|
||||||
{
|
{
|
||||||
int nestLevel = 0;
|
int nestLevel = 0;
|
||||||
|
|
||||||
if( ii && ( !( ii%4 ) || !ADVANCED_CFG::GetCfg().m_CompactSave ) )
|
if( !( ii % 4 ) || !ADVANCED_CFG::GetCfg().m_CompactSave )
|
||||||
{
|
{
|
||||||
// newline every 4 pts.
|
// newline every 4 pts.
|
||||||
nestLevel = aNestLevel + 1;
|
|
||||||
m_out->Print( 0, "\n" );
|
m_out->Print( 0, "\n" );
|
||||||
|
need_newline = false;
|
||||||
|
nestLevel = aNestLevel + 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ind = outline.ArcIndex( ii );
|
int ind = outline.ArcIndex( ii );
|
||||||
|
@ -989,16 +992,19 @@ void PCB_IO::format( const FP_SHAPE* aFPShape, int aNestLevel ) const
|
||||||
if( ind < 0 )
|
if( ind < 0 )
|
||||||
{
|
{
|
||||||
m_out->Print( nestLevel, "%s(xy %s)",
|
m_out->Print( nestLevel, "%s(xy %s)",
|
||||||
nestLevel ? "" : " ", FormatInternalUnits( outline.CPoint( ii ) ).c_str() );
|
nestLevel ? "" : " ",
|
||||||
|
FormatInternalUnits( outline.CPoint( ii ) ).c_str() );
|
||||||
|
need_newline = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto& arc = outline.Arc( ind );
|
auto& arc = outline.Arc( ind );
|
||||||
m_out->Print( aNestLevel, "%s(arc (start %s) (mid %s) (end %s))",
|
m_out->Print( nestLevel, "%s(arc (start %s) (mid %s) (end %s))",
|
||||||
nestLevel ? "" : " ",
|
nestLevel ? "" : " ",
|
||||||
FormatInternalUnits( arc.GetP0() ).c_str(),
|
FormatInternalUnits( arc.GetP0() ).c_str(),
|
||||||
FormatInternalUnits( arc.GetArcMid() ).c_str(),
|
FormatInternalUnits( arc.GetArcMid() ).c_str(),
|
||||||
FormatInternalUnits( arc.GetP1() ).c_str() );
|
FormatInternalUnits( arc.GetP1() ).c_str() );
|
||||||
|
need_newline = true;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
@ -1009,7 +1015,10 @@ void PCB_IO::format( const FP_SHAPE* aFPShape, int aNestLevel ) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_out->Print( 0, ")" );
|
if( need_newline )
|
||||||
|
m_out->Print( 0, "\n" );
|
||||||
|
|
||||||
|
m_out->Print( aNestLevel + 1, ")" );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1646,33 +1655,60 @@ void PCB_IO::format( const PAD* aPad, int aNestLevel ) const
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SHAPE_T::POLY:
|
case SHAPE_T::POLY:
|
||||||
if( primitive->GetPolyShape().COutline( 0 ).CPoints().size() < 2 )
|
if( primitive->IsPolyShapeValid() )
|
||||||
break; // Malformed polygon.
|
|
||||||
|
|
||||||
{
|
|
||||||
m_out->Print( nested_level, "(gr_poly (pts\n");
|
|
||||||
|
|
||||||
// Write the polygon corners coordinates:
|
|
||||||
int newLine = 0;
|
|
||||||
|
|
||||||
for( const VECTOR2I &pt : primitive->GetPolyShape().COutline( 0 ).CPoints() )
|
|
||||||
{
|
{
|
||||||
if( newLine == 0 )
|
const SHAPE_POLY_SET& poly = primitive->GetPolyShape();
|
||||||
m_out->Print( nested_level+1, "(xy %s)",
|
const SHAPE_LINE_CHAIN& outline = poly.Outline( 0 );
|
||||||
FormatInternalUnits( (wxPoint) pt ).c_str() );
|
|
||||||
else
|
|
||||||
m_out->Print( 0, " (xy %s)",
|
|
||||||
FormatInternalUnits( (wxPoint) pt ).c_str() );
|
|
||||||
|
|
||||||
if( ++newLine > 4 || !ADVANCED_CFG::GetCfg().m_CompactSave )
|
m_out->Print( nested_level, "(gr_poly (pts" );
|
||||||
|
|
||||||
|
bool need_newline = false;
|
||||||
|
|
||||||
|
for( int ii = 0; ii < outline.PointCount(); ++ii )
|
||||||
{
|
{
|
||||||
newLine = 0;
|
nested_level = 0;
|
||||||
m_out->Print( 0, "\n" );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_out->Print( newLine ? 0 : nested_level, ")" );
|
if( !( ii % 4 ) || !ADVANCED_CFG::GetCfg().m_CompactSave )
|
||||||
}
|
{
|
||||||
|
// newline every 4 pts.
|
||||||
|
m_out->Print( 0, "\n" );
|
||||||
|
need_newline = false;
|
||||||
|
nested_level = aNestLevel + 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ind = outline.ArcIndex( ii );
|
||||||
|
|
||||||
|
if( ind < 0 )
|
||||||
|
{
|
||||||
|
m_out->Print( nested_level, "%s(xy %s)",
|
||||||
|
nested_level ? "" : " ",
|
||||||
|
FormatInternalUnits( outline.CPoint( ii ) ).c_str() );
|
||||||
|
need_newline = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const SHAPE_ARC& arc = outline.Arc( ind );
|
||||||
|
m_out->Print( nested_level, "%s(arc (start %s) (mid %s) (end %s))",
|
||||||
|
nested_level ? "" : " ",
|
||||||
|
FormatInternalUnits( arc.GetP0() ).c_str(),
|
||||||
|
FormatInternalUnits( arc.GetArcMid() ).c_str(),
|
||||||
|
FormatInternalUnits( arc.GetP1() ).c_str() );
|
||||||
|
need_newline = true;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
++ii;
|
||||||
|
} while( ii < outline.PointCount() && outline.ArcIndex( ii ) == ind );
|
||||||
|
|
||||||
|
--ii;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( need_newline )
|
||||||
|
m_out->Print( 0, "\n" );
|
||||||
|
|
||||||
|
m_out->Print( aNestLevel + 3, ")" );
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -2089,9 +2125,9 @@ void PCB_IO::format( const ZONE* aZone, int aNestLevel ) const
|
||||||
|
|
||||||
if( !( ii % 4 ) || !ADVANCED_CFG::GetCfg().m_CompactSave ) // newline every 4 pts
|
if( !( ii % 4 ) || !ADVANCED_CFG::GetCfg().m_CompactSave ) // newline every 4 pts
|
||||||
{
|
{
|
||||||
nestLevel = aNestLevel + 3;
|
|
||||||
m_out->Print( 0, "\n" );
|
m_out->Print( 0, "\n" );
|
||||||
need_newline = false;
|
need_newline = false;
|
||||||
|
nestLevel = aNestLevel + 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ind = chain.ArcIndex( ii );
|
int ind = chain.ArcIndex( ii );
|
||||||
|
@ -2106,11 +2142,11 @@ void PCB_IO::format( const ZONE* aZone, int aNestLevel ) const
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto& arc = chain.Arc( ind );
|
auto& arc = chain.Arc( ind );
|
||||||
m_out->Print( aNestLevel, "%s(arc (start %s) (mid %s) (end %s))",
|
m_out->Print( nestLevel, "%s(arc (start %s) (mid %s) (end %s))",
|
||||||
nestLevel ? "" : " ",
|
nestLevel ? "" : " ",
|
||||||
FormatInternalUnits( arc.GetP0() ).c_str(),
|
FormatInternalUnits( arc.GetP0() ).c_str(),
|
||||||
FormatInternalUnits( arc.GetArcMid() ).c_str(),
|
FormatInternalUnits( arc.GetArcMid() ).c_str(),
|
||||||
FormatInternalUnits( arc.GetP1() ).c_str() );
|
FormatInternalUnits( arc.GetP1() ).c_str() );
|
||||||
need_newline = true;
|
need_newline = true;
|
||||||
|
|
||||||
do
|
do
|
||||||
|
@ -2140,7 +2176,7 @@ void PCB_IO::format( const ZONE* aZone, int aNestLevel ) const
|
||||||
{
|
{
|
||||||
m_out->Print( aNestLevel + 1, "(filled_polygon\n" );
|
m_out->Print( aNestLevel + 1, "(filled_polygon\n" );
|
||||||
m_out->Print( aNestLevel + 2, "(layer %s)\n",
|
m_out->Print( aNestLevel + 2, "(layer %s)\n",
|
||||||
m_out->Quotew( LSET::Name( layer ) ).c_str() );
|
m_out->Quotew( LSET::Name( layer ) ).c_str() );
|
||||||
|
|
||||||
if( aZone->IsIsland( layer, ii ) )
|
if( aZone->IsIsland( layer, ii ) )
|
||||||
m_out->Print( aNestLevel + 2, "(island)\n" );
|
m_out->Print( aNestLevel + 2, "(island)\n" );
|
||||||
|
@ -2157,9 +2193,9 @@ void PCB_IO::format( const ZONE* aZone, int aNestLevel ) const
|
||||||
|
|
||||||
if( !( jj%4 ) || !ADVANCED_CFG::GetCfg().m_CompactSave ) // newline every 4 pts
|
if( !( jj%4 ) || !ADVANCED_CFG::GetCfg().m_CompactSave ) // newline every 4 pts
|
||||||
{
|
{
|
||||||
nestLevel = aNestLevel + 3;
|
|
||||||
m_out->Print( 0, "\n" );
|
m_out->Print( 0, "\n" );
|
||||||
need_newline = false;
|
need_newline = false;
|
||||||
|
nestLevel = aNestLevel + 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ind = chain.ArcIndex( jj );
|
int ind = chain.ArcIndex( jj );
|
||||||
|
@ -2174,11 +2210,11 @@ void PCB_IO::format( const ZONE* aZone, int aNestLevel ) const
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto& arc = chain.Arc( ind );
|
auto& arc = chain.Arc( ind );
|
||||||
m_out->Print( aNestLevel, "%s(arc (start %s) (mid %s) (end %s))",
|
m_out->Print( nestLevel, "%s(arc (start %s) (mid %s) (end %s))",
|
||||||
nestLevel ? "" : " ",
|
nestLevel ? "" : " ",
|
||||||
FormatInternalUnits( arc.GetP0() ).c_str(),
|
FormatInternalUnits( arc.GetP0() ).c_str(),
|
||||||
FormatInternalUnits( arc.GetArcMid() ).c_str(),
|
FormatInternalUnits( arc.GetArcMid() ).c_str(),
|
||||||
FormatInternalUnits( arc.GetP1() ).c_str() );
|
FormatInternalUnits( arc.GetP1() ).c_str() );
|
||||||
need_newline = true;
|
need_newline = true;
|
||||||
|
|
||||||
do
|
do
|
||||||
|
|
|
@ -4334,7 +4334,7 @@ PAD* PCB_PARSER::parsePAD( FOOTPRINT* aParent )
|
||||||
|
|
||||||
case T_gr_poly:
|
case T_gr_poly:
|
||||||
dummyShape = parsePCB_SHAPE();
|
dummyShape = parsePCB_SHAPE();
|
||||||
pad->AddPrimitivePoly( dummyShape->BuildPolyPointsList(), dummyShape->GetWidth(),
|
pad->AddPrimitivePoly( dummyShape->GetPolyShape(), dummyShape->GetWidth(),
|
||||||
dummyShape->IsFilled() );
|
dummyShape->IsFilled() );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue