59 std::ifstream stream(
path );
60 BOOST_REQUIRE_MESSAGE( stream,
"Unable to open " <<
path );
62 const std::string data( ( std::istreambuf_iterator<char>( stream ) ), {} );
65 for(
int zone = 0; zone <= aZone; ++zone )
67 pos = data.find(
"(zone (layer \"", pos );
68 BOOST_REQUIRE_MESSAGE( pos != std::string::npos,
"Missing zone " << aZone <<
" in " <<
path );
72 pos = data.find(
"polyset ", pos );
73 BOOST_REQUIRE_MESSAGE( pos != std::string::npos,
"Missing polyset for zone " << aZone <<
" in " <<
path );
76 std::stringstream serialized( data.substr( pos ) );
78 BOOST_REQUIRE_MESSAGE(
result.Parse( serialized ),
"Unable to parse zone " << aZone <<
" in " <<
path );
89 for(
int i = 0; i < aSegmentCount; ++i )
109 int closest = std::numeric_limits<int>::max();
122 else if( aClearance >= 0 )
124 std::vector<SEG> aSegments;
125 std::vector<SEG> bSegments;
128 aSegments.push_back( aA.
CSegment( i ) );
131 bSegments.push_back( aB.
CSegment( i ) );
133 auto segmentSort = [](
const SEG& aFirst,
const SEG& aSecond )
135 return aFirst.
A.
x < aSecond.A.x || ( aFirst.
A.
x == aSecond.A.x && aFirst.
A.
y < aSecond.A.y );
138 std::sort( aSegments.begin(), aSegments.end(), segmentSort );
139 std::sort( bSegments.begin(), bSegments.end(), segmentSort );
141 for(
const SEG& a : aSegments )
143 for(
const SEG& b : bSegments )
147 if( a.Collide( b, aClearance, &
distance ) )
151 nearest = a.NearestPoint( b );
164 if( closest == 0 || closest < aClearance )
172 result.location = nearest;
217 const std::vector<CORPUS_CASE> cases = { {
"One-Air-Max.kicad_polys", 18, 0, 3 },
218 {
"issue5093.kicad_polys", 3, 0, 1 },
219 {
"bad_triangulation_case.kicad_polys", 47, 0, 3 } };
228 BOOST_REQUIRE_EQUAL( a.
ArcCount(), 0 );
229 BOOST_REQUIRE_EQUAL( b.
ArcCount(), 0 );
231 for(
int clearance : { -1, 0, 200000, 2000000 } )
247 const std::vector<std::pair<int, int>> sizes = { { 31, 133 }, { 32, 128 }, { 66, 63 }, { 63, 65 }, { 64, 64 } };
251 for(
const auto& [countA, countB] : sizes )
253 for(
int startA : { 0, sourceA.
SegmentCount() - countA } )
258 for(
int clearance : { -1, 0, 200000, 2000000 } )
286 std::vector<SEG> segments;
289 segments.push_back( contour.
CSegment( i ) );
293 BOOST_REQUIRE_GT(
index.size(), 256 );
295 for(
size_t queryIndex = 0; queryIndex < segments.size(); queryIndex += 17 )
297 const SEG& query = segments[queryIndex];
299 for(
int padding : { 0, 200000, 2000000 } )
302 const int64_t minX =
static_cast<int64_t
>( std::min( query.
A.
x, query.
B.
x ) ) - padding;
303 const int64_t minY =
static_cast<int64_t
>( std::min( query.
A.
y, query.
B.
y ) ) - padding;
304 const int64_t maxX =
static_cast<int64_t
>( std::max( query.
A.
x, query.
B.
x ) ) + padding;
305 const int64_t maxY =
static_cast<int64_t
>( std::max( query.
A.
y, query.
B.
y ) ) + padding;
307 for(
size_t i = 0; i < segments.size(); ++i )
309 const SEG& segment = segments[i];
311 if( std::max( segment.
A.
x, segment.
B.
x ) >= minX && std::min( segment.
A.
x, segment.
B.
x ) <= maxX
312 && std::max( segment.
A.
y, segment.
B.
y ) >= minY && std::min( segment.
A.
y, segment.
B.
y ) <= maxY )
314 expected.push_back(
static_cast<int>( i ) );
319 auto visitor = [&](
int aItem )
321 actual.push_back( aItem );
325 index.VisitCandidates( query, padding, visitor );
332 auto stopVisitor = [&]( int )
338 index.VisitCandidates( segments.front(), std::numeric_limits<int>::max(), stopVisitor );
356 BOOST_CHECK( collided );
374 BOOST_CHECK( collided );
391 BOOST_CHECK( collided );
410 BOOST_CHECK( collided );
411 BOOST_CHECK_MESSAGE(
actual == 6,
"Expected: " << 6 <<
" Actual: " <<
actual );
429 BOOST_CHECK( !collided );
430 BOOST_CHECK_MESSAGE(
actual == 0,
"Expected: " << 0 <<
" Actual: " <<
actual );
Immutable owning spatial snapshot of straight segments.
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
bool IsClosed() const override
virtual const VECTOR2I GetPoint(int aIndex) const override
virtual size_t GetPointCount() const override
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
int SegmentCount() const
Return the number of segments in this line chain.
const SEG CSegment(int aIndex) const
Return a constant copy of the aIndex segment in the line chain.
bool PointInside(const VECTOR2I &aPt, int aAccuracy=0, bool aUseBBoxCache=false) const override
Check if point aP lies inside a closed shape.
Represent a set of closed polygons.
int OutlineCount() const
Return the number of outlines in the set.
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
An abstract shape on 2D plane.
std::string GetTestDataRootDir()
static float distance(const SFVEC2UI &a, const SFVEC2UI &b)
static bool Collide(const SHAPE_CIRCLE &aA, const SHAPE_CIRCLE &aB, int aClearance, int *aActual, VECTOR2I *aLocation, VECTOR2I *aMTV)
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
BOOST_AUTO_TEST_SUITE_END()
BOOST_TEST(netlist.find("R_G1 ARM_OUT1 DIE_B R='0.001 / ((SW_STATE)") !=std::string::npos)
VECTOR3I expected(15, 30, 45)
static const VECTOR2I NO_LOCATION(123456789, -123456789)
static constexpr int NO_ACTUAL
BOOST_AUTO_TEST_CASE(Collide_RealContourParity)
static SHAPE_POLY_SET loadZone(const std::string &aFilename, int aZone)
static COLLISION_OUTPUT indexedCollision(const SHAPE_LINE_CHAIN &aA, const SHAPE_LINE_CHAIN &aB, int aClearance, int aOutputs)
static COLLISION_OUTPUT referenceCollision(const SHAPE_LINE_CHAIN &aA, const SHAPE_LINE_CHAIN &aB, int aClearance, int aOutputs)
static SHAPE_LINE_CHAIN extractSubchain(const SHAPE_LINE_CHAIN &aSource, int aStart, int aSegmentCount)
static void checkCollisionParity(const SHAPE_LINE_CHAIN &aA, const SHAPE_LINE_CHAIN &aB, int aClearance)
wxString result
Test unit parsing edge cases and error handling.
BOOST_CHECK_EQUAL(result, "25.4")
VECTOR2< int32_t > VECTOR2I