← Back to team overview

kicad-developers team mailing list archive

on incorrect polygon behavior

 

Hi all,

I did a small investigation of the polygon-related
segfaults/miscalculations. It looks like Boost.polygon badly handles
cases where intersection points of the edges of the polygons lie close
to each other or overlap, causing the 'snap rounding' algorithm used in
boost to go haywire. This is the case for complex zones, with a lot of
thermal holes or via patterns (i.e. a thermal pad under a QFN with a via
field).

See last comment from https://svn.boost.org/trac/boost/ticket/10642.

There's a variety of effects I observed.
- a segfault.
- an incorrect or empty resulting polygon: merging the holes before
subtraction from the main outline (polyset_holes in
AddClearanceAreasPolygonsToPolysList) using boost::assign or subtracting
the holes one-by-one (instead of the whole set) fixes the segfault, but
I know at least one case where the resulting zone is incorrectly
calculated. I'll attach the test cases to the bug report on Launchpad
later in the evening.

For the reasons above, I would strongly consider dropping
boost::polygon. There are also non-technical issues:
- It hasn't been maintained for ~1.5 years. The last activity of the
official maintainer was 3 years ago.
- the code is a mess (look at example below).



@Jean Pierre: do you think Clipper is stable enough for our use? (at
least in case of a bug, it's actively developed and the author offers
support). I'm not asking about speed, it's not important if Kicad
crashes or produces incorrect polygons.

Tom







-- snip --

   if(solid) {
            //we are closing a solid figure, write to output
            //std::cout << "test1\n";
            at1->copyHoles(*(at1->otherTailp_));
            typename PolyLineArbitraryByConcept<Unit, typename
geometry_concept<typename cT::value_type>::type>::type polyData(at1);
            //poly_line_arbitrary_polygon_data polyData(at1);
            //std::cout << "test2\n";
            //std::cout << poly << "\n";
            //std::cout << "test3\n";
            typedef typename cT::value_type result_type;
            typedef typename geometry_concept<result_type>::type
result_concept;
            output.push_back(result_type());
            assign(output.back(), polyData);
            //std::cout << "test4\n";
            //std::cout << "delete " << at1->otherTailp_ << "\n";
            //at1->print();
            //at1->otherTailp_->print();
            delete at1->otherTailp_;
            //at1->print();
            //at1->otherTailp_->print();
            //std::cout << "test5\n";
            //std::cout << "delete " << at1 << "\n";
            delete at1;
            //std::cout << "test6\n";
            return 0;


Follow ups