Moved special handling of intersection to ClipperUtils

translation1
Marius Kintel 2014-01-27 23:25:33 -05:00
parent c25ead11ff
commit 0600d80046
5 changed files with 104 additions and 21 deletions

View File

@ -367,26 +367,7 @@ Polygon2d *GeometryEvaluator::applyToChildren2D(const AbstractNode &node, OpenSC
break;
}
if (clipType == ClipperLib::ctIntersection && !children.empty()) {
// intersection operations must be split into a sequence of binary operations
std::vector<const Polygon2d *> operands(2);
operands[0] = children[0];
for (int i = 1; i < children.size(); i++) {
operands[1] = children[i];
Polygon2d * result = ClipperUtils::apply(operands, clipType);
if (operands[0] != children[0]) delete operands[0];
operands[0] = result;
}
assert(children.size() >= 2);
// We know that this is ok
return const_cast<Polygon2d *>(operands[0]);
}
else {
return ClipperUtils::apply(children, clipType);
}
return ClipperUtils::apply(children, clipType);
}
/*!

View File

@ -34,7 +34,13 @@ namespace ClipperUtils {
clipper.Execute(ClipperLib::ctUnion, result, ClipperLib::pftEvenOdd);
return result;
}
/*!
We want to use a PolyTree to convert to Polygon2d, since only PolyTrees
have an explicit notion of holes.
We could use a Paths structure, but we'd have to check the orientation of each
path before adding it to the Polygon2d.
*/
Polygon2d *toPolygon2d(const ClipperLib::PolyTree &poly) {
Polygon2d *result = new Polygon2d;
const ClipperLib::PolyNode *node = poly.GetFirst();
@ -71,6 +77,23 @@ namespace ClipperUtils {
ClipperLib::ClipType clipType)
{
ClipperLib::Clipper clipper;
if (clipType == ClipperLib::ctIntersection && pathsvector.size() > 2) {
// intersection operations must be split into a sequence of binary operations
ClipperLib::Paths source = pathsvector[0];
ClipperLib::PolyTree result;
for (int i = 1; i < pathsvector.size(); i++) {
clipper.AddPaths(source, ClipperLib::ptSubject, true);
clipper.AddPaths(pathsvector[i], ClipperLib::ptClip, true);
clipper.Execute(clipType, result, ClipperLib::pftNonZero, ClipperLib::pftNonZero);
if (i != pathsvector.size()-1) {
ClipperLib::PolyTreeToPaths(result, source);
clipper.Clear();
}
}
return ClipperUtils::toPolygon2d(result);
}
bool first = true;
BOOST_FOREACH(const ClipperLib::Paths &paths, pathsvector) {
clipper.AddPaths(paths, first ? ClipperLib::ptSubject : ClipperLib::ptClip, true);

View File

@ -0,0 +1,79 @@
group() {
multmatrix([[1, 0, 0, 0], [0, 1, 0, -20], [0, 0, 1, 0], [0, 0, 0, 1]]) {
intersection() {
circle($fn = 0, $fa = 12, $fs = 2, r = 5);
square(size = [8, 8], center = true);
}
}
multmatrix([[1, 0, 0, -10], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) {
intersection() {
circle($fn = 0, $fa = 12, $fs = 2, r = 5);
square(size = [0, 0], center = true);
}
}
multmatrix([[1, 0, 0, 0], [0, 1, 0, 20], [0, 0, 1, 0], [0, 0, 0, 1]]) {
intersection() {
group();
circle($fn = 0, $fa = 12, $fs = 2, r = 5);
square(size = [8, 8], center = true);
}
}
multmatrix([[1, 0, 0, 20], [0, 1, 0, -20], [0, 0, 1, 0], [0, 0, 0, 1]]) {
intersection() {
multmatrix([[1, 0, 0, 10], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) {
circle($fn = 0, $fa = 12, $fs = 2, r = 15);
}
}
}
multmatrix([[1, 0, 0, 20], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) {
intersection() {
multmatrix([[1, 0, 0, 10], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) {
circle($fn = 0, $fa = 12, $fs = 2, r = 15);
}
multmatrix([[-0.5, -0.86602540378, 0, 0], [0.86602540378, -0.5, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) {
multmatrix([[1, 0, 0, 10], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) {
circle($fn = 0, $fa = 12, $fs = 2, r = 15);
}
}
}
}
multmatrix([[1, 0, 0, 20], [0, 1, 0, 20], [0, 0, 1, 0], [0, 0, 0, 1]]) {
intersection() {
multmatrix([[1, 0, 0, 10], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) {
circle($fn = 0, $fa = 12, $fs = 2, r = 15);
}
multmatrix([[-0.5, -0.86602540378, 0, 0], [0.86602540378, -0.5, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) {
multmatrix([[1, 0, 0, 10], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) {
circle($fn = 0, $fa = 12, $fs = 2, r = 15);
}
}
multmatrix([[-0.5, 0.86602540378, 0, 0], [-0.86602540378, -0.5, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) {
multmatrix([[1, 0, 0, 10], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) {
circle($fn = 0, $fa = 12, $fs = 2, r = 15);
}
}
}
}
multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) {
intersection() {
multmatrix([[1, 0, 0, 10], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) {
circle($fn = 0, $fa = 12, $fs = 2, r = 15);
}
multmatrix([[1, 0, 0, 5], [0, 1, 0, 8.66025403784], [0, 0, 1, 0], [0, 0, 0, 1]]) {
circle($fn = 0, $fa = 12, $fs = 2, r = 15);
}
multmatrix([[1, 0, 0, -5], [0, 1, 0, 8.66025403784], [0, 0, 1, 0], [0, 0, 0, 1]]) {
circle($fn = 0, $fa = 12, $fs = 2, r = 15);
}
multmatrix([[1, 0, 0, -10], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) {
circle($fn = 0, $fa = 12, $fs = 2, r = 15);
}
multmatrix([[1, 0, 0, -5], [0, 1, 0, -8.66025403784], [0, 0, 1, 0], [0, 0, 0, 1]]) {
circle($fn = 0, $fa = 12, $fs = 2, r = 15);
}
multmatrix([[1, 0, 0, 5], [0, 1, 0, -8.66025403784], [0, 0, 1, 0], [0, 0, 0, 1]]) {
circle($fn = 0, $fa = 12, $fs = 2, r = 15);
}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB