diff --git a/pcbnew/router/pns_dp_meander_placer.cpp b/pcbnew/router/pns_dp_meander_placer.cpp index d56aff44b1..f9675d55e6 100644 --- a/pcbnew/router/pns_dp_meander_placer.cpp +++ b/pcbnew/router/pns_dp_meander_placer.cpp @@ -222,26 +222,72 @@ bool DP_MEANDER_PLACER::Move( const VECTOR2I& aP, ITEM* aEndItem ) PNS_DBG( Dbg(), AddSegment, base, GREEN, "dp-baseline" ); - while( sp.indexP >= curIndexP ) + while( sp.indexP >= curIndexP && curIndexP != -1 ) { - m_result.AddCorner( tunedP.CPoint( curIndexP ), tunedN.CPoint( curIndexN ) ); - curIndexP++; + if( tunedP.IsArcSegment( curIndexP ) ) + { + ssize_t arcIndex = tunedP.ArcIndex( curIndexP ); + + m_result.AddArcAndPt( tunedP.Arc( arcIndex ), tunedN.CPoint( curIndexN ) ); + } + else + { + m_result.AddCorner( tunedP.CPoint( curIndexP ), tunedN.CPoint( curIndexN ) ); + } + + curIndexP = tunedP.NextShape( curIndexP ); } - while( sp.indexN >= curIndexN ) + while( sp.indexN >= curIndexN && curIndexN != -1 ) { - m_result.AddCorner( tunedP.CPoint( sp.indexP ), tunedN.CPoint( curIndexN ) ); - curIndexN++; + if( tunedN.IsArcSegment( curIndexN ) ) + { + ssize_t arcIndex = tunedN.ArcIndex( curIndexN ); + + m_result.AddPtAndArc( tunedP.CPoint( sp.indexP ), tunedN.Arc( arcIndex ) ); + } + else + { + m_result.AddCorner( tunedP.CPoint( sp.indexP ), tunedN.CPoint( curIndexN ) ); + } + + curIndexN = tunedN.NextShape( curIndexN ); } m_result.MeanderSegment( base ); } - while( curIndexP < tunedP.PointCount() ) - m_result.AddCorner( tunedP.CPoint( curIndexP++ ), tunedN.CPoint( curIndexN ) ); + while( curIndexP < tunedP.PointCount() && curIndexP != -1 ) + { + if( tunedP.IsArcSegment( curIndexP ) ) + { + ssize_t arcIndex = tunedP.ArcIndex( curIndexP ); - while( curIndexN < tunedN.PointCount() ) - m_result.AddCorner( tunedP.CPoint( -1 ), tunedN.CPoint( curIndexN++ ) ); + m_result.AddArcAndPt( tunedP.Arc( arcIndex ), tunedN.CPoint( curIndexN ) ); + } + else + { + m_result.AddCorner( tunedP.CPoint( curIndexP ), tunedN.CPoint( curIndexN ) ); + } + + curIndexP = tunedP.NextShape( curIndexP ); + } + + while( curIndexN < tunedN.PointCount() && curIndexN != -1 ) + { + if( tunedN.IsArcSegment( curIndexN ) ) + { + ssize_t arcIndex = tunedN.ArcIndex( curIndexN ); + + m_result.AddPtAndArc( tunedP.CPoint( -1 ), tunedN.Arc( arcIndex ) ); + } + else + { + m_result.AddCorner( tunedP.CPoint( -1 ), tunedN.CPoint( curIndexN ) ); + } + + curIndexN = tunedN.NextShape( curIndexN ); + } long long int dpLen = origPathLength(); diff --git a/pcbnew/router/pns_meander.cpp b/pcbnew/router/pns_meander.cpp index 4a15bf4e77..af1ca02fe3 100644 --- a/pcbnew/router/pns_meander.cpp +++ b/pcbnew/router/pns_meander.cpp @@ -563,6 +563,33 @@ void MEANDERED_LINE::AddCorner( const VECTOR2I& aA, const VECTOR2I& aB ) } +void MEANDERED_LINE::AddArc( const SHAPE_ARC& aArc1, const SHAPE_ARC& aArc2 ) +{ + MEANDER_SHAPE* m = new MEANDER_SHAPE( m_placer, m_width, m_dual ); + + m->MakeArc( aArc1, aArc2 ); + m_last = aArc1.GetP1(); + + m_meanders.push_back( m ); +} + + +void MEANDERED_LINE::AddArcAndPt( const SHAPE_ARC& aArc1, const VECTOR2I& aPt2 ) +{ + SHAPE_ARC arc2( aPt2, aPt2, aPt2, 0 ); + + AddArc( aArc1, arc2 ); +} + + +void MEANDERED_LINE::AddPtAndArc( const VECTOR2I& aPt1, const SHAPE_ARC& aArc2 ) +{ + SHAPE_ARC arc1( aPt1, aPt1, aPt1, 0 ); + + AddArc( arc1, aArc2 ); +} + + void MEANDER_SHAPE::MakeCorner( const VECTOR2I& aP1, const VECTOR2I& aP2 ) { SetType( MT_CORNER ); @@ -575,6 +602,18 @@ void MEANDER_SHAPE::MakeCorner( const VECTOR2I& aP1, const VECTOR2I& aP2 ) } +void MEANDER_SHAPE::MakeArc( const SHAPE_ARC& aArc1, const SHAPE_ARC& aArc2 ) +{ + SetType( MT_CORNER ); + m_shapes[0].Clear(); + m_shapes[1].Clear(); + m_shapes[0].Append( aArc1 ); + m_shapes[1].Append( aArc2 ); + m_clippedBaseSeg.A = aArc1.GetP1(); + m_clippedBaseSeg.B = aArc1.GetP1(); +} + + void MEANDERED_LINE::AddMeander( MEANDER_SHAPE* aShape ) { m_last = aShape->BaseSegment().B; diff --git a/pcbnew/router/pns_meander.h b/pcbnew/router/pns_meander.h index 20b3e78c87..63d305c504 100644 --- a/pcbnew/router/pns_meander.h +++ b/pcbnew/router/pns_meander.h @@ -42,6 +42,7 @@ enum MEANDER_TYPE { MT_CHECK_START, // try fitting a start type, but don't produce a line MT_CHECK_FINISH, // try fitting a finish type, but don't produce a line MT_CORNER, // line corner + MT_ARC, // arc corner MT_EMPTY // no meander (straight line) }; @@ -179,6 +180,15 @@ public: */ void MakeCorner( const VECTOR2I& aP1, const VECTOR2I& aP2 = VECTOR2I( 0, 0 ) ); + /** + * Create a dummy meander shape representing an arc corner. Allows representing existing + * arc tracks so they can be reconstructed after length tuning. + * + * @param aArc1 Arc shape on the 1st line. + * @param aArc2 Arc shape on the 2nd line (if m_dual == true). + */ + void MakeArc( const SHAPE_ARC& aArc1, const SHAPE_ARC& aArc2 = SHAPE_ARC() ); + /** * Change the amplitude of the meander shape to aAmpl and recalculates the resulting * line chain. @@ -411,6 +421,33 @@ public: */ void AddCorner( const VECTOR2I& aA, const VECTOR2I& aB = VECTOR2I( 0, 0 ) ); + /** + * Create a dummy meander shape representing an arc corner. Allows representing existing + * arc tracks so they can be reconstructed after length tuning. + * + * @param aArc1 Arc shape on the 1st line. + * @param aArc2 Arc shape on the 2nd line (if m_dual == true). + */ + void AddArc( const SHAPE_ARC& aArc1, const SHAPE_ARC& aArc2 = SHAPE_ARC() ); + + /** + * Create a dummy meander shape representing an arc corner. Allows representing existing + * arc tracks so they can be reconstructed after length tuning. + * + * @param aArc1 Arc shape on the 1st line. + * @param aPt2 corner point of the 2nd line (if m_dual == true). + */ + void AddArcAndPt( const SHAPE_ARC& aArc1, const VECTOR2I& aPt2 ); + + /** + * Create a dummy meander shape representing an arc corner. Allows representing existing + * arc tracks so they can be reconstructed after length tuning. + * + * @param aPt1 corner point of the 1st line. + * @param aArc2 Arc shape on the 2nd line (if m_dual == true). + */ + void AddPtAndArc( const VECTOR2I& aPt1, const SHAPE_ARC& aArc2 ); + /** * Add a new meander shape to the meandered line. * diff --git a/pcbnew/router/pns_meander_placer.cpp b/pcbnew/router/pns_meander_placer.cpp index 27e72b955c..0a7ac3e464 100644 --- a/pcbnew/router/pns_meander_placer.cpp +++ b/pcbnew/router/pns_meander_placer.cpp @@ -125,7 +125,17 @@ bool MEANDER_PLACER::doMove( const VECTOR2I& aP, ITEM* aEndItem, long long int a for( int i = 0; i < tuned.SegmentCount(); i++ ) { if( tuned.IsArcSegment( i ) ) + { + ssize_t arcIndex = tuned.ArcIndex( i ); + m_result.AddArc( tuned.Arc( arcIndex ) ); + i = tuned.NextShape( i ); + + // NextShape will return -1 if last shape + if( i < 0 ) + i = tuned.SegmentCount(); + continue; + } const SEG s = tuned.CSegment( i ); m_result.AddCorner( s.A ); diff --git a/pcbnew/router/pns_meander_placer_base.cpp b/pcbnew/router/pns_meander_placer_base.cpp index 9c15fa9438..581358dabf 100644 --- a/pcbnew/router/pns_meander_placer_base.cpp +++ b/pcbnew/router/pns_meander_placer_base.cpp @@ -135,7 +135,7 @@ void MEANDER_PLACER_BASE::tuneLineLength( MEANDERED_LINE& aTuned, long long int for( MEANDER_SHAPE* m : aTuned.Meanders() ) { - if( m->Type() != MT_CORNER ) + if( m->Type() != MT_CORNER && m->Type() != MT_ARC ) { if( remaining >= 0 ) remaining -= m->MaxTunableLength() - m->BaselineLength(); @@ -169,7 +169,7 @@ void MEANDER_PLACER_BASE::tuneLineLength( MEANDERED_LINE& aTuned, long long int for( MEANDER_SHAPE* m : aTuned.Meanders() ) { - if( m->Type() != MT_CORNER && m->Type() != MT_EMPTY ) + if( m->Type() != MT_CORNER && m->Type() != MT_ARC && m->Type() != MT_EMPTY ) { if(remaining >= 0) { @@ -188,7 +188,7 @@ void MEANDER_PLACER_BASE::tuneLineLength( MEANDERED_LINE& aTuned, long long int { for( MEANDER_SHAPE* m : aTuned.Meanders() ) { - if( m->Type() != MT_CORNER && m->Type() != MT_EMPTY ) + if( m->Type() != MT_CORNER && m->Type() != MT_ARC && m->Type() != MT_EMPTY ) { m->Resize( std::max( m->Amplitude() - balance / 2, (long long int) m_settings.m_minAmplitude ) );