Remove dead code (SHAPE_LINE_CHAIN::DetectArcs)

This commit is contained in:
Roberto Fernandez Bautista 2021-06-23 18:07:07 +01:00 committed by Jon Evans
parent 778c64de88
commit cee5920d5c
5 changed files with 0 additions and 379 deletions

View File

@ -637,16 +637,6 @@ public:
*/
SHAPE_LINE_CHAIN& Simplify( bool aRemoveColinear = true );
/**
* Detects arcs in a chain and converts them from segments to true arcs by adding an arc
* and the associated references. The original segment points are not changed.
*
* @param aArcs List of possible arcs that might be in this chain
* @param aMargin Maximum acceptable deviation from the found points to the arc (defaults
* to ARC_HIGH_DEF)
*/
void DetectArcs( const std::vector<SHAPE_ARC>& aArcs, int aMargin = PCB_IU_PER_MM * 0.005 );
/**
* Find the segment nearest the given point.
*

View File

@ -1369,16 +1369,6 @@ private:
void booleanOp( ClipperLib::ClipType aType, const SHAPE_POLY_SET& aShape,
const SHAPE_POLY_SET& aOtherShape, POLYGON_MODE aFastMode );
/**
* Detect arcs in a polyset and convert them from segments to true arcs by adding an arc
* and associated references. The original segment points are not changed.
*
* @param aArcs List of possible arcs that might be in this polyset
* @param aMargin Maximum acceptable deviation from the found points to the arc (defaults
* to ARC_HIGH_DEF)
*/
void detectArcs( const std::vector<SHAPE_ARC>& aArcs, int aMargin = PCB_IU_PER_MM * 0.005 );
/**
* Check whether the point \a aP is inside the \a aSubpolyIndex-th polygon of the polyset. If
* the points lies on an edge, the polygon is considered to contain it.

View File

@ -363,118 +363,6 @@ bool SHAPE_LINE_CHAIN_BASE::Collide( const SEG& aSeg, int aClearance, int* aActu
}
void SHAPE_LINE_CHAIN::DetectArcs( const std::vector<SHAPE_ARC>& aArcs, int aMargin )
{
// Remove all arcs
m_arcs.clear();
std::fill( m_shapes.begin(), m_shapes.end(), SHAPES_ARE_PT );
auto emplaceArc =
[&]( point_iter aStart, point_iter aEnd, SHAPE_ARC aReplacementArc )
{
size_t startIndex = aStart - m_points.begin();
size_t endIndex = aEnd - m_points.begin();
for( int ii = startIndex; ii <= endIndex; ++ii )
{
if( m_shapes[ii].first == SHAPE_IS_PT )
{
m_shapes[ii].first = m_arcs.size();
}
else
{
// The point can't be shared with more than two arcs
assert( m_shapes[ii].second == SHAPE_IS_PT );
m_shapes[ii].second = m_arcs.size();
}
}
m_arcs.push_back( aReplacementArc );
};
for( point_iter it = m_points.begin(); it != m_points.end(); ++it )
{
for( const SHAPE_ARC& arc : aArcs )
{
SHAPE_ARC givenArcThin( arc );
givenArcThin.SetWidth( 0 );
// Need at least this point and the next one to be on the arc
point_iter it2 = it;
++it2;
if( it2 == m_points.end() )
return;
if( givenArcThin.Collide( *it, aMargin ) && givenArcThin.Collide( *it2 , aMargin ) )
{
VECTOR2I arcStart = *it;
VECTOR2I arcEnd = *it2;
int numPts = 2;
point_iter it3 = it2;
VECTOR2I arcApproxMid = arcEnd; // Determine arc mid point from found points
// (it might not be exactly in the middle)
while( (++it2 != m_points.end()) && givenArcThin.Collide( *it2, aMargin) )
{
if( ++numPts % 2 )
arcApproxMid = *it3++;
arcEnd = *it2;
}
--it2;
if( arcStart == givenArcThin.GetP0() && arcEnd == givenArcThin.GetP1() )
{
// Simplest case: found arc is equal to given arc
emplaceArc( it, it2, givenArcThin );
}
else if( arcStart == givenArcThin.GetP1() && arcEnd == givenArcThin.GetP0() )
{
// Found arc was just reversed
emplaceArc( it, it2, givenArcThin.Reversed() );
}
else
{
// Some of the points are part of the original arc, but we will need to alter
// the start and end points.
VECTOR2I arcCenter = givenArcThin.GetCenter();
int arcRadius = KiROUND( givenArcThin.GetRadius() );
CIRCLE tempCircle( arcCenter, arcRadius );
if( arcEnd == arcApproxMid )
{
// Only 2 points found of the given arc
// Need to derive the approximate location of the mid point using the
// given arc's centre
VECTOR2I startLine = arcStart - arcCenter;
VECTOR2I endLine = arcEnd - arcCenter;
double angle = RAD2DECIDEG( endLine.Angle() - startLine.Angle() );
RotatePoint( arcApproxMid, arcCenter, angle * 10.0 / 2.0 );
}
// Project all the points so that they sit on the known arc, but don't
// alter the actual points in m_points
arcStart = tempCircle.NearestPoint( arcStart );
arcEnd = tempCircle.NearestPoint( arcEnd );
arcApproxMid = tempCircle.NearestPoint( arcApproxMid );
SHAPE_ARC tempArc( arcStart, arcApproxMid, arcEnd, 0 );
emplaceArc( it, it2, tempArc );
}
it = --it2;
break;
}
}
}
}
const SHAPE_LINE_CHAIN SHAPE_LINE_CHAIN::Reverse() const
{
SHAPE_LINE_CHAIN a( *this );

View File

@ -678,18 +678,6 @@ void SHAPE_POLY_SET::booleanOp( ClipperLib::ClipType aType, const SHAPE_POLY_SET
}
void SHAPE_POLY_SET::detectArcs( const std::vector<SHAPE_ARC>& aArcs, int aMargin )
{
for( POLYGON& poly : m_polys )
{
for( size_t i = 0; i < poly.size(); i++ )
{
poly[i].DetectArcs( aArcs, aMargin );
}
}
}
void SHAPE_POLY_SET::BooleanAdd( const SHAPE_POLY_SET& b, POLYGON_MODE aFastMode )
{
booleanOp( ClipperLib::ctUnion, b, aFastMode );

View File

@ -108,239 +108,4 @@ BOOST_AUTO_TEST_CASE( ArcToPolylineLargeCoords )
}
struct ARC_FOUND_PROPERTIES
{
VECTOR2I m_Start;
VECTOR2I m_End;
VECTOR2I m_Center;
double m_Radius;
ARC_FOUND_PROPERTIES()
{
m_Start = { 0, 0 };
m_End = { 0, 0 };
m_Center = { 0, 0 };
m_Radius = 0.0;
}
ARC_FOUND_PROPERTIES( SHAPE_ARC aArc )
{
m_Start = aArc.GetP0();
m_End = aArc.GetP1();
m_Center = aArc.GetCenter();
m_Radius = aArc.GetRadius();
};
};
struct DETECT_ARCS_CASE
{
/// The text context name
std::string m_ctx_name;
/// Chain with arcs
SHAPE_LINE_CHAIN m_chain;
/// Ars that are used as hints in DetectArcs function
std::vector<SHAPE_ARC> m_arcs_to_find;
/// Expected properties of the arcs found in m_chain
std::vector<ARC_FOUND_PROPERTIES> m_expected_arc_props;
};
static std::vector<DETECT_ARCS_CASE> DetectArcsTestCases( int aTolerance, SHAPE_ARC aArc )
{
std::vector<DETECT_ARCS_CASE> retval;
SHAPE_LINE_CHAIN base_chain(
{ VECTOR2I( 0, 0 ), VECTOR2I( 0, 1000000 ), VECTOR2I( 1000000, 0 ) } );
int num_pts = base_chain.GetPointCount();
SHAPE_ARC appended_arc1 = SHAPE_ARC( VECTOR2I( 0, 0 ), VECTOR2I( 0, -200000 ), 45 );
SHAPE_ARC appended_arc2 = aArc;
// Add the arcs to the chain as individual line segments, ensuring the chain has no knowledge
// of the arcs that were added to it.
SHAPE_LINE_CHAIN poly_arc1 = appended_arc1.ConvertToPolyline( aTolerance );
SHAPE_LINE_CHAIN poly_arc2 = appended_arc2.ConvertToPolyline( aTolerance );
base_chain.Append( poly_arc1 );
base_chain.Append( poly_arc2 );
wxASSERT_MSG( poly_arc2.PointCount() > 3, "Test arc is too small" );
// Simple case: Arcs in the chain are as created by ConvertToPolyline
SHAPE_LINE_CHAIN simple_chain( base_chain );
retval.push_back( { "Simple case",
simple_chain,
{ appended_arc1, appended_arc2 },
{ appended_arc1, appended_arc2 } } );
// Reversed case: Points are reversed
SHAPE_LINE_CHAIN reversed_chain( base_chain.Reverse() );
retval.push_back( { "Reversed case",
reversed_chain,
{ appended_arc1, appended_arc2 },
{ appended_arc2.Reversed(), appended_arc1.Reversed() } } );
// Complex Case 1: Half of the end points of arc 2 removed
{
SHAPE_LINE_CHAIN truncated_chain( base_chain );
int start_index = truncated_chain.GetPointCount()
- std::max( poly_arc2.GetPointCount() / 2, (size_t) 1 );
int end_index = truncated_chain.GetPointCount() - 1;
truncated_chain.Remove( start_index, end_index );
ARC_FOUND_PROPERTIES expected_arc2( appended_arc2 );
expected_arc2.m_End = truncated_chain.GetPoint( truncated_chain.GetPointCount() - 1 );
retval.push_back( { "Complex Case 1: End Point Changed",
truncated_chain,
{ appended_arc1, appended_arc2 },
{ appended_arc1, expected_arc2 } } );
}
// Complex Case 2: Half of the START points of arc 2 removed
{
SHAPE_LINE_CHAIN truncated_chain( base_chain );
int start_index = truncated_chain.GetPointCount() - poly_arc2.GetPointCount();
int end_index = truncated_chain.GetPointCount()
- std::max( poly_arc2.GetPointCount() / 2, (size_t) 1 );
ARC_FOUND_PROPERTIES expected_arc2( appended_arc2 );
expected_arc2.m_Start = truncated_chain.GetPoint( end_index );
truncated_chain.Remove( start_index, end_index - 1 );
retval.push_back( { "Complex Case 2: Start Point Changed",
truncated_chain,
{ appended_arc1, appended_arc2 },
{ appended_arc1, expected_arc2 } } );
}
// Complex Case 3: Start and end points removed
{
SHAPE_LINE_CHAIN truncated_chain( base_chain );
// Remove some points at the start:
int start_index = truncated_chain.GetPointCount() - poly_arc2.GetPointCount();
int end_index = truncated_chain.GetPointCount()
- std::max( ( 3 * poly_arc2.GetPointCount() ) / 4, (size_t) 1 );
ARC_FOUND_PROPERTIES expected_arc2( appended_arc2 );
expected_arc2.m_Start = truncated_chain.GetPoint( end_index );
truncated_chain.Remove( start_index, end_index - 1 );
// Remove some points at the end:
start_index = truncated_chain.GetPointCount()
- std::max( poly_arc2.GetPointCount() / 4, (size_t) 1 );
end_index = truncated_chain.GetPointCount() - 1;
truncated_chain.Remove( start_index, end_index );
expected_arc2.m_End = truncated_chain.GetPoint( truncated_chain.GetPointCount() - 1 );
retval.push_back( { "Complex Case 3: Start and End Points Changed",
truncated_chain,
{ appended_arc1, appended_arc2 },
{ appended_arc1, expected_arc2 } } );
}
return retval;
}
BOOST_AUTO_TEST_CASE( DetectArcs )
{
std::vector<int> tolerance_cases = { 10, 50, 100, 500, 1000, 5000 };
std::vector<std::pair<VECTOR2I, VECTOR2I>> center_start_pts_cases =
{
{ VECTOR2I( 0, 500000 ), VECTOR2I( 0, 400000 ) },
{ VECTOR2I( 0, 40505 ), VECTOR2I( 45205, 4245 ) },
{ VECTOR2I( 47244, 4005 ), VECTOR2I( 94504, 5550 ) },
{ VECTOR2I( 5000, 0 ), VECTOR2I( 0, 4000 ) }
};
std::vector<double> arc_angle_cases = { 15, 45, 90, 135, 180, 225, 270, 305, 360 };
std::vector<SHAPE_ARC> arc_cases;
for( std::pair<VECTOR2I, VECTOR2I> center_start : center_start_pts_cases )
{
for( double angle : arc_angle_cases )
arc_cases.emplace_back( center_start.first, center_start.second, angle );
}
// SHAPE_ARC does not define arc centre and radius. These are calculated parameters based on the
// three points of the arc. We want to ensure the centre and radius are somewhat close to the
// original arc, but accept that there will be rounding errors when calculating.
const int maxTolDerived = 450;
for( int& tol : tolerance_cases )
{
for( SHAPE_ARC& arc_case : arc_cases )
{
std::vector<DETECT_ARCS_CASE> test_cases = DetectArcsTestCases( tol, arc_case );
for( DETECT_ARCS_CASE& tc : test_cases )
{
BOOST_TEST_CONTEXT( tc.m_ctx_name << " -> Tolerance IU: " << tol
<< " -> Arc Tested: { center=" << arc_case.GetCenter()
<< " start=" << arc_case.GetP0()
<< " angle=" << arc_case.GetCentralAngle() << "}" )
{
BOOST_REQUIRE_MESSAGE( tc.m_arcs_to_find.size()
== tc.m_expected_arc_props.size(),
"\nMalformed test case. m_arcs_to_find.size()"
" should equal m_expected_arc_props.size()." );
BOOST_REQUIRE_MESSAGE( tc.m_chain.ArcCount() == 0,
"\nMalformed test case. The SHAPE_LINE_CHAIN to test "
"(m_chain) should have no arcs to start with. I.e. "
"m_chain.ArcCount() should equal 0." );
tc.m_chain.DetectArcs( tc.m_arcs_to_find, tol );
BOOST_CHECK_EQUAL( tc.m_chain.ArcCount(), tc.m_expected_arc_props.size() );
BOOST_REQUIRE_MESSAGE( tc.m_chain.ArcCount() == tc.m_expected_arc_props.size(),
"\nConvertToArcs failed: "
"\n Expected arcs to be found: "
<< tc.m_expected_arc_props.size()
<< "\n Actual number found: "
<< tc.m_chain.ArcCount() );
int i = 0;
int td = maxTolDerived;
for( ARC_FOUND_PROPERTIES& exp : tc.m_expected_arc_props )
{
BOOST_TEST_CONTEXT( "Arc Index: " << i )
{
BOOST_CHECK_PREDICATE(
KI_TEST::IsVecWithinTol<VECTOR2I>,
( tc.m_chain.Arc( i ).GetP0() )( exp.m_Start )( tol / 2 ) );
BOOST_CHECK_PREDICATE(
KI_TEST::IsVecWithinTol<VECTOR2I>,
( tc.m_chain.Arc( i ).GetP1() )( exp.m_End )( tol / 2 ) );
BOOST_CHECK_PREDICATE(
KI_TEST::IsVecWithinTol<VECTOR2I>,
( tc.m_chain.Arc( i ).GetCenter() )( exp.m_Center )( td ) );
BOOST_CHECK_PREDICATE(
KI_TEST::IsWithin<double>,
( tc.m_chain.Arc( i ).GetRadius() )( exp.m_Radius )( td ) );
++i;
}
}
}
}
}
}
}
BOOST_AUTO_TEST_SUITE_END()