make clipper calls a little more readable, compact when packaged
This commit is contained in:
parent
f4889d3c8f
commit
fd86b9b93a
2 changed files with 122 additions and 114 deletions
|
|
@ -17,11 +17,24 @@ const { config, util, polygons, newBounds, newPoint } = base;
|
||||||
const POLY = polygons,
|
const POLY = polygons,
|
||||||
XAXIS = new THREE.Vector3(1,0,0),
|
XAXIS = new THREE.Vector3(1,0,0),
|
||||||
DEG2RAD = Math.PI / 180,
|
DEG2RAD = Math.PI / 180,
|
||||||
clib = self.ClipperLib,
|
ClipperLib = self.ClipperLib,
|
||||||
clip = clib.Clipper,
|
Clipper = ClipperLib.Clipper,
|
||||||
ctyp = clib.ClipType,
|
ClipType = ClipperLib.ClipType,
|
||||||
ptyp = clib.PolyType,
|
PolyType = ClipperLib.PolyType,
|
||||||
cfil = clib.PolyFillType;
|
PolyFillType = ClipperLib.PolyFillType,
|
||||||
|
CleanPolygon = Clipper.CleanPolygon,
|
||||||
|
FillNonZero = PolyFillType.pftNonZero,
|
||||||
|
FillEvenOdd = PolyFillType.pftEvenOdd,
|
||||||
|
PathSubject = PolyType.ptSubject,
|
||||||
|
PathClip = PolyType.ptClip,
|
||||||
|
EndType = ClipperLib.EndType,
|
||||||
|
JoinType = ClipperLib.JoinType,
|
||||||
|
PolyTree = ClipperLib.PolyTree,
|
||||||
|
ClipDiff = ClipType.ctDifference,
|
||||||
|
ClipUnion = ClipType.ctUnion,
|
||||||
|
ClipIntersect = ClipType.ctIntersection,
|
||||||
|
ClipperOffset = ClipperLib.ClipperOffset
|
||||||
|
;
|
||||||
|
|
||||||
let seqid = Math.round(Math.random() * 0xffffffff);
|
let seqid = Math.round(Math.random() * 0xffffffff);
|
||||||
|
|
||||||
|
|
@ -1519,7 +1532,7 @@ class Polygon {
|
||||||
* non-nested polygons. used primarily in slicer/connectLines.
|
* non-nested polygons. used primarily in slicer/connectLines.
|
||||||
*/
|
*/
|
||||||
clean(deep, parent, merge = config.clipperClean) {
|
clean(deep, parent, merge = config.clipperClean) {
|
||||||
let clean = clip.CleanPolygon(this.toClipper()[0], merge),
|
let clean = CleanPolygon(this.toClipper()[0], merge),
|
||||||
poly = fromClipperPath(clean, this.getZ());
|
poly = fromClipperPath(clean, this.getZ());
|
||||||
if (poly.length === 0) return this;
|
if (poly.length === 0) return this;
|
||||||
if (deep && this.inner) {
|
if (deep && this.inner) {
|
||||||
|
|
@ -1590,23 +1603,21 @@ class Polygon {
|
||||||
*/
|
*/
|
||||||
offset_open(distance, type = 'miter') {
|
offset_open(distance, type = 'miter') {
|
||||||
if (this.isOpen()) {
|
if (this.isOpen()) {
|
||||||
let cjnt = clib.JoinType,
|
let coff = new ClipperOffset(),
|
||||||
cety = clib.EndType,
|
tree = new PolyTree(),
|
||||||
coff = new clib.ClipperOffset(),
|
|
||||||
ctre = new clib.PolyTree(),
|
|
||||||
entt = {
|
entt = {
|
||||||
'square' : cety.etOpenSquare,
|
'square' : EndType.etOpenSquare,
|
||||||
'round' : cety.etOpenRound,
|
'round' : EndType.etOpenRound,
|
||||||
'miter' : cety.etOpenSquare
|
'miter' : EndType.etOpenSquare
|
||||||
}[type] || cety.etOpenSquare,
|
}[type] || EndType.etOpenSquare,
|
||||||
jntt = {
|
jntt = {
|
||||||
'square': cjnt.jtSquare,
|
'square': JoinType.jtSquare,
|
||||||
'round': cjnt.jtRound,
|
'round': JoinType.jtRound,
|
||||||
'miter': cjnt.jtMiter
|
'miter': JoinType.jtMiter
|
||||||
}[type] || cjnt.jtMiter;
|
}[type] || JoinType.jtMiter;
|
||||||
coff.AddPaths(this.toClipper(), jntt, entt);
|
coff.AddPaths(this.toClipper(), jntt, entt);
|
||||||
coff.Execute(ctre, distance * config.clipper);
|
coff.Execute(tree, distance * config.clipper);
|
||||||
return POLY.fromClipperTree(ctre, this.getZ(), null, null, 0);
|
return POLY.fromClipperTree(tree, this.getZ(), null, null, 0);
|
||||||
} else {
|
} else {
|
||||||
return this.offset(distance);
|
return this.offset(distance);
|
||||||
}
|
}
|
||||||
|
|
@ -1748,16 +1759,16 @@ class Polygon {
|
||||||
*/
|
*/
|
||||||
diff(poly) {
|
diff(poly) {
|
||||||
let fillang = this.fillang && this.area() > poly.area() ? this.fillang : poly.fillang,
|
let fillang = this.fillang && this.area() > poly.area() ? this.fillang : poly.fillang,
|
||||||
clip = new clib.Clipper(),
|
clip = new Clipper(),
|
||||||
ctre = new clib.PolyTree(),
|
tree = new PolyTree(),
|
||||||
sp1 = this.toClipper(),
|
sp1 = this.toClipper(),
|
||||||
sp2 = poly.toClipper();
|
sp2 = poly.toClipper();
|
||||||
|
|
||||||
clip.AddPaths(sp1, ptyp.ptSubject, true);
|
clip.AddPaths(sp1, PathSubject, true);
|
||||||
clip.AddPaths(sp2, ptyp.ptClip, true);
|
clip.AddPaths(sp2, PathClip, true);
|
||||||
|
|
||||||
if (clip.Execute(ctyp.ctDifference, ctre, cfil.pftEvenOdd, cfil.pftEvenOdd)) {
|
if (clip.Execute(ClipDiff, tree, FillEvenOdd, FillEvenOdd)) {
|
||||||
poly = POLY.fromClipperTree(ctre, poly.getZ());
|
poly = POLY.fromClipperTree(tree, poly.getZ());
|
||||||
poly.forEach(p => {
|
poly.forEach(p => {
|
||||||
p.fillang = fillang;
|
p.fillang = fillang;
|
||||||
})
|
})
|
||||||
|
|
@ -1773,15 +1784,15 @@ class Polygon {
|
||||||
*/
|
*/
|
||||||
mask(poly, nullOnEquiv, minarea) {
|
mask(poly, nullOnEquiv, minarea) {
|
||||||
let fillang = this.fillang && this.area() > poly.area() ? this.fillang : poly.fillang,
|
let fillang = this.fillang && this.area() > poly.area() ? this.fillang : poly.fillang,
|
||||||
clip = new clib.Clipper(),
|
clip = new Clipper(),
|
||||||
ctre = new clib.PolyTree(),
|
tree = new PolyTree(),
|
||||||
sp1 = this.toClipper(),
|
sp1 = this.toClipper(),
|
||||||
sp2 = poly.toClipper();
|
sp2 = poly.toClipper();
|
||||||
clip.AddPaths(sp1, ptyp.ptSubject, true);
|
clip.AddPaths(sp1, PathSubject, true);
|
||||||
clip.AddPaths(sp2, ptyp.ptClip, true);
|
clip.AddPaths(sp2, PathClip, true);
|
||||||
|
|
||||||
if (clip.Execute(ctyp.ctIntersection, ctre, cfil.pftEvenOdd, cfil.pftEvenOdd)) {
|
if (clip.Execute(ClipIntersect, tree, FillEvenOdd, FillEvenOdd)) {
|
||||||
poly = POLY.fromClipperTree(ctre, this.getZ(), undefined, undefined, minarea);
|
poly = POLY.fromClipperTree(tree, this.getZ(), undefined, undefined, minarea);
|
||||||
poly.forEach(p => {
|
poly.forEach(p => {
|
||||||
p.fillang = fillang;
|
p.fillang = fillang;
|
||||||
})
|
})
|
||||||
|
|
@ -1810,17 +1821,17 @@ class Polygon {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let clip = new clib.Clipper(),
|
let clip = new Clipper(),
|
||||||
ctre = new clib.PolyTree(),
|
tree = new PolyTree(),
|
||||||
type = inter ? ctyp.ctIntersection : ctyp.ctDifference,
|
type = inter ? ClipIntersect : ClipDiff,
|
||||||
sp1 = target.toClipper(),
|
sp1 = target.toClipper(),
|
||||||
sp2 = POLY.toClipper(polys);
|
sp2 = POLY.toClipper(polys);
|
||||||
|
|
||||||
clip.AddPaths(sp1, ptyp.ptSubject, false);
|
clip.AddPaths(sp1, PathSubject, false);
|
||||||
clip.AddPaths(sp2, ptyp.ptClip, true);
|
clip.AddPaths(sp2, PathClip, true);
|
||||||
|
|
||||||
if (clip.Execute(type, ctre, cfil.pftEvenOdd, cfil.pftEvenOdd)) {
|
if (clip.Execute(type, tree, FillEvenOdd, FillEvenOdd)) {
|
||||||
let cuts = POLY.fromClipperTree(ctre, target.getZ(), null, null, 0);
|
let cuts = POLY.fromClipperTree(tree, target.getZ(), null, null, 0);
|
||||||
cuts.forEach(no => {
|
cuts.forEach(no => {
|
||||||
// heal open but really closed polygons because cutting
|
// heal open but really closed polygons because cutting
|
||||||
// has to open the poly to perform the cut. but the result
|
// has to open the poly to perform the cut. but the result
|
||||||
|
|
@ -1841,22 +1852,22 @@ class Polygon {
|
||||||
intersect(poly, min) {
|
intersect(poly, min) {
|
||||||
if (!this.overlaps(poly)) return null;
|
if (!this.overlaps(poly)) return null;
|
||||||
|
|
||||||
let clip = new clib.Clipper(),
|
|
||||||
ctre = new clib.PolyTree(),
|
|
||||||
sp1 = this.toClipper(),
|
|
||||||
sp2 = poly.toClipper(),
|
|
||||||
minarea = min >= 0 ? min : 0.1;
|
|
||||||
|
|
||||||
if (this.isInside(poly)) {
|
if (this.isInside(poly)) {
|
||||||
return [this];
|
return [this];
|
||||||
}
|
}
|
||||||
|
|
||||||
clip.AddPaths(sp1, ptyp.ptSubject, true);
|
let clip = new Clipper(),
|
||||||
clip.AddPaths(sp2, ptyp.ptClip, true);
|
tree = new PolyTree(),
|
||||||
|
sp1 = this.toClipper(),
|
||||||
|
sp2 = poly.toClipper(),
|
||||||
|
minarea = min >= 0 ? min : 0.1;
|
||||||
|
|
||||||
if (clip.Execute(ctyp.ctIntersection, ctre, cfil.pftNonZero, cfil.pftNonZero)) {
|
clip.AddPaths(sp1, PathSubject, true);
|
||||||
|
clip.AddPaths(sp2, PathClip, true);
|
||||||
|
|
||||||
|
if (clip.Execute(ClipIntersect, tree, FillNonZero, FillNonZero)) {
|
||||||
let inter = POLY
|
let inter = POLY
|
||||||
.fromClipperTreeUnion(ctre, poly.getZ(), minarea)
|
.fromClipperTreeUnion(tree, poly.getZ(), minarea)
|
||||||
// .filter(p => p.isEquivalent(this) || p.isInside(this))
|
// .filter(p => p.isEquivalent(this) || p.isInside(this))
|
||||||
.filter(p => p.isInside(this));
|
.filter(p => p.isInside(this));
|
||||||
return inter;
|
return inter;
|
||||||
|
|
@ -1890,7 +1901,7 @@ class Polygon {
|
||||||
}
|
}
|
||||||
|
|
||||||
let clip = this.toClipper(),
|
let clip = this.toClipper(),
|
||||||
res = clib.Clipper.SimplifyPolygons(clip, cfil.pftNonZero);
|
res = CLIB.Clipper.SimplifyPolygons(clip, FillNonZero);
|
||||||
|
|
||||||
if (!(res && res.length)) {
|
if (!(res && res.length)) {
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -1919,17 +1930,17 @@ class Polygon {
|
||||||
if (!this.overlaps(poly)) return null;
|
if (!this.overlaps(poly)) return null;
|
||||||
|
|
||||||
let fillang = this.fillang && this.area() > poly.area() ? this.fillang : poly.fillang,
|
let fillang = this.fillang && this.area() > poly.area() ? this.fillang : poly.fillang,
|
||||||
clip = new clib.Clipper(),
|
clip = new Clipper(),
|
||||||
ctre = new clib.PolyTree(),
|
tree = new PolyTree(),
|
||||||
sp1 = this.toClipper(),
|
sp1 = this.toClipper(),
|
||||||
sp2 = poly.toClipper(),
|
sp2 = poly.toClipper(),
|
||||||
minarea = min >= 0 ? min : 0.1;
|
minarea = min >= 0 ? min : 0.1;
|
||||||
|
|
||||||
clip.AddPaths(sp1, ptyp.ptSubject, true);
|
clip.AddPaths(sp1, PathSubject, true);
|
||||||
clip.AddPaths(sp2, ptyp.ptClip, true);
|
clip.AddPaths(sp2, PathClip, true);
|
||||||
|
|
||||||
if (clip.Execute(ctyp.ctUnion, ctre, cfil.pftEvenOdd, cfil.pftEvenOdd)) {
|
if (clip.Execute(ClipUnion, tree, FillEvenOdd, FillEvenOdd)) {
|
||||||
let union = POLY.fromClipperTreeUnion(ctre, poly.getZ(), minarea);
|
let union = POLY.fromClipperTreeUnion(tree, poly.getZ(), minarea);
|
||||||
if (all) {
|
if (all) {
|
||||||
if (union.length === 2) {
|
if (union.length === 2) {
|
||||||
return null;
|
return null;
|
||||||
|
|
|
||||||
|
|
@ -18,11 +18,26 @@ const DEG2RAD = Math.PI / 180,
|
||||||
SQR = util.sqr,
|
SQR = util.sqr,
|
||||||
ABS = Math.abs;
|
ABS = Math.abs;
|
||||||
|
|
||||||
const clib = self.ClipperLib,
|
const ClipperLib = self.ClipperLib,
|
||||||
clip = clib.Clipper,
|
Clipper = ClipperLib.Clipper,
|
||||||
ctyp = clib.ClipType,
|
ClipType = ClipperLib.ClipType,
|
||||||
ptyp = clib.PolyType,
|
PolyType = ClipperLib.PolyType,
|
||||||
cfil = clib.PolyFillType;
|
PolyFillType = ClipperLib.PolyFillType,
|
||||||
|
CleanPolygon = Clipper.CleanPolygon,
|
||||||
|
CleanPolygons = Clipper.CleanPolygons,
|
||||||
|
SimplifyPolygons = Clipper.SimplifyPolygons,
|
||||||
|
FillNonZero = PolyFillType.pftNonZero,
|
||||||
|
FillEvenOdd = PolyFillType.pftEvenOdd,
|
||||||
|
PathSubject = PolyType.ptSubject,
|
||||||
|
PathClip = PolyType.ptClip,
|
||||||
|
EndType = ClipperLib.EndType,
|
||||||
|
JoinType = ClipperLib.JoinType,
|
||||||
|
PolyTree = ClipperLib.PolyTree,
|
||||||
|
ClipDiff = ClipType.ctDifference,
|
||||||
|
ClipUnion = ClipType.ctUnion,
|
||||||
|
ClipIntersect = ClipType.ctIntersection,
|
||||||
|
ClipperOffset = ClipperLib.ClipperOffset
|
||||||
|
;
|
||||||
|
|
||||||
const POLYS = base.polygons = {
|
const POLYS = base.polygons = {
|
||||||
rayIntersect,
|
rayIntersect,
|
||||||
|
|
@ -152,7 +167,7 @@ function fromClipperTreeUnion(tnode, z, minarea, tops, parent) {
|
||||||
function cleanClipperTree(tree) {
|
function cleanClipperTree(tree) {
|
||||||
if (tree.m_Childs)
|
if (tree.m_Childs)
|
||||||
for (let child of tree.m_Childs) {
|
for (let child of tree.m_Childs) {
|
||||||
child.m_polygon = clip.CleanPolygon(child.m_polygon, config.clipperClean);
|
child.m_polygon = CleanPolygon(child.m_polygon, config.clipperClean);
|
||||||
cleanClipperTree(child.m_Childs);
|
cleanClipperTree(child.m_Childs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -354,31 +369,31 @@ function subtract(setA, setB, outA, outB, z, minArea, opt = {}) {
|
||||||
outB.appendAll(filter(oB));
|
outB.appendAll(filter(oB));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let clip = new clib.Clipper(),
|
let clip = new Clipper(),
|
||||||
ctre = new clib.PolyTree(),
|
tree = new PolyTree(),
|
||||||
sp1 = toClipper(setA),
|
sp1 = toClipper(setA),
|
||||||
sp2 = toClipper(setB);
|
sp2 = toClipper(setB);
|
||||||
|
|
||||||
// more expensive? worth it?
|
// more expensive? worth it?
|
||||||
clip.StrictlySimple = true;
|
clip.StrictlySimple = true;
|
||||||
if (outA) {
|
if (outA) {
|
||||||
clip.AddPaths(sp1, ptyp.ptSubject, true);
|
clip.AddPaths(sp1, PathSubject, true);
|
||||||
clip.AddPaths(sp2, ptyp.ptClip, true);
|
clip.AddPaths(sp2, PathClip, true);
|
||||||
if (clip.Execute(ctyp.ctDifference, ctre, cfil.pftEvenOdd, cfil.pftEvenOdd)) {
|
if (clip.Execute(ClipDiff, tree, FillEvenOdd, FillEvenOdd)) {
|
||||||
cleanClipperTree(ctre);
|
cleanClipperTree(tree);
|
||||||
filter(fromClipperTree(ctre, z, null, null, min), outA);
|
filter(fromClipperTree(tree, z, null, null, min), outA);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (outB) {
|
if (outB) {
|
||||||
if (outA) {
|
if (outA) {
|
||||||
ctre.Clear();
|
tree.Clear();
|
||||||
clip.Clear();
|
clip.Clear();
|
||||||
}
|
}
|
||||||
clip.AddPaths(sp2, ptyp.ptSubject, true);
|
clip.AddPaths(sp2, PathSubject, true);
|
||||||
clip.AddPaths(sp1, ptyp.ptClip, true);
|
clip.AddPaths(sp1, PathClip, true);
|
||||||
if (clip.Execute(ctyp.ctDifference, ctre, cfil.pftEvenOdd, cfil.pftEvenOdd)) {
|
if (clip.Execute(ClipDiff, tree, FillEvenOdd, FillEvenOdd)) {
|
||||||
cleanClipperTree(ctre);
|
cleanClipperTree(tree);
|
||||||
filter(fromClipperTree(ctre, z, null, null, min), outB);
|
filter(fromClipperTree(tree, z, null, null, min), outB);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -459,16 +474,16 @@ function subtract(setA, setB, outA, outB, z, minArea, opt = {}) {
|
||||||
* @returns {?Polygon[]}
|
* @returns {?Polygon[]}
|
||||||
*/
|
*/
|
||||||
function diff(setA, setB, z) {
|
function diff(setA, setB, z) {
|
||||||
let clip = new clib.Clipper(),
|
let clip = new Clipper(),
|
||||||
ctre = new clib.PolyTree(),
|
tree = new PolyTree(),
|
||||||
sp1 = toClipper(setA),
|
sp1 = toClipper(setA),
|
||||||
sp2 = toClipper(setB);
|
sp2 = toClipper(setB);
|
||||||
|
|
||||||
clip.AddPaths(sp1, ptyp.ptSubject, true);
|
clip.AddPaths(sp1, PathSubject, true);
|
||||||
clip.AddPaths(sp2, ptyp.ptClip, true);
|
clip.AddPaths(sp2, PathClip, true);
|
||||||
|
|
||||||
if (clip.Execute(ctyp.ctDifference, ctre, cfil.pftEvenOdd, cfil.pftEvenOdd)) {
|
if (clip.Execute(ClipDiff, tree, FillEvenOdd, FillEvenOdd)) {
|
||||||
return fromClipperTree(ctre, z);
|
return fromClipperTree(tree, z);
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
@ -503,24 +518,6 @@ function sumCirc(polys) {
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Polygon[]} polys
|
|
||||||
* @param {number} distance offset
|
|
||||||
* @param {number} [z] defaults to 0
|
|
||||||
*/
|
|
||||||
// function expand_lines(poly, distance, z) {
|
|
||||||
// let fact = config.clipper,
|
|
||||||
// cjnt = clib.JoinType,
|
|
||||||
// cety = clib.EndType,
|
|
||||||
// coff = new clib.ClipperOffset(),
|
|
||||||
// ctre = new clib.PolyTree();
|
|
||||||
|
|
||||||
// coff.AddPaths(poly.toClipper(), cjnt.jtMiter, cety.etOpenSquare);
|
|
||||||
// coff.Execute(ctre, distance * fact);
|
|
||||||
|
|
||||||
// return fromClipperTree(ctre, z, null, null, 0);
|
|
||||||
// }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Polygon[]} polys
|
* @param {Polygon[]} polys
|
||||||
* @param {number} distance offset
|
* @param {number} distance offset
|
||||||
|
|
@ -565,9 +562,9 @@ function offset(polys, dist, opts = {}) {
|
||||||
depth = numOrDefault(opts.depth, 0),
|
depth = numOrDefault(opts.depth, 0),
|
||||||
clean = opts.clean !== false,
|
clean = opts.clean !== false,
|
||||||
simple = opts.simple !== false,
|
simple = opts.simple !== false,
|
||||||
fill = numOrDefault(opts.fill, clib.PolyFillType.pftNonZero),
|
fill = numOrDefault(opts.fill, FillNonZero),
|
||||||
join = numOrDefault(opts.join, clib.JoinType.jtMiter),
|
join = numOrDefault(opts.join, JoinType.jtMiter),
|
||||||
type = numOrDefault(opts.type, clib.EndType.etClosedPolygon),
|
type = numOrDefault(opts.type, EndType.etClosedPolygon),
|
||||||
// if dist is array with values, shift out next offset
|
// if dist is array with values, shift out next offset
|
||||||
offs = Array.isArray(dist) ? (dist.length > 1 ? dist.shift() : dist[0]) : dist,
|
offs = Array.isArray(dist) ? (dist.length > 1 ? dist.shift() : dist[0]) : dist,
|
||||||
mina = numOrDefault(opts.minArea, 0.1),
|
mina = numOrDefault(opts.minArea, 0.1),
|
||||||
|
|
@ -583,21 +580,21 @@ function offset(polys, dist, opts = {}) {
|
||||||
return offset(polys, dist, opts);
|
return offset(polys, dist, opts);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let coff = new clib.ClipperOffset(opts.miter, opts.arc),
|
let coff = new ClipperOffset(opts.miter, opts.arc),
|
||||||
ctre = new clib.PolyTree();
|
tree = new PolyTree();
|
||||||
|
|
||||||
// setup offset
|
// setup offset
|
||||||
for (let poly of polys) {
|
for (let poly of polys) {
|
||||||
// convert to clipper format
|
// convert to clipper format
|
||||||
poly = poly.toClipper();
|
poly = poly.toClipper();
|
||||||
if (clean) poly = clib.Clipper.CleanPolygons(poly, config.clipperClean);
|
if (clean) poly = CleanPolygons(poly, config.clipperClean);
|
||||||
if (simple) poly = clib.Clipper.SimplifyPolygons(poly, fill);
|
if (simple) poly = SimplifyPolygons(poly, fill);
|
||||||
coff.AddPaths(poly, join, type);
|
coff.AddPaths(poly, join, type);
|
||||||
}
|
}
|
||||||
// perform offset
|
// perform offset
|
||||||
coff.Execute(ctre, offs * config.clipper);
|
coff.Execute(tree, offs * config.clipper);
|
||||||
// convert back from clipper output format
|
// convert back from clipper output format
|
||||||
polys = fromClipperTree(ctre, zed, null, null, mina);
|
polys = fromClipperTree(tree, zed, null, null, mina);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -748,8 +745,8 @@ function fillArea(polys, angle, spacing, output, minLen, maxLen) {
|
||||||
step = SQRT(SQR(stepX) + SQR(stepY)),
|
step = SQRT(SQR(stepX) + SQR(stepY)),
|
||||||
steps = dist / step,
|
steps = dist / step,
|
||||||
start = angle < 0 ? { x:bounds.minx, y:bounds.miny, z:zpos } : { x:bounds.maxx, y:bounds.miny, z:zpos },
|
start = angle < 0 ? { x:bounds.minx, y:bounds.miny, z:zpos } : { x:bounds.maxx, y:bounds.miny, z:zpos },
|
||||||
clip = new clib.Clipper(),
|
clip = new Clipper(),
|
||||||
ctre = new clib.PolyTree(),
|
tree = new PolyTree(),
|
||||||
minlen = base.config.clipper * (minLen || 0),
|
minlen = base.config.clipper * (minLen || 0),
|
||||||
maxlen = base.config.clipper * (maxLen || 0),
|
maxlen = base.config.clipper * (maxLen || 0),
|
||||||
lines = [];
|
lines = [];
|
||||||
|
|
@ -771,13 +768,13 @@ function fillArea(polys, angle, spacing, output, minLen, maxLen) {
|
||||||
start.y += stepY;
|
start.y += stepY;
|
||||||
}
|
}
|
||||||
|
|
||||||
clip.AddPaths(lines, ptyp.ptSubject, false);
|
clip.AddPaths(lines, PathSubject, false);
|
||||||
clip.AddPaths(toClipper(polys), ptyp.ptClip, true);
|
clip.AddPaths(toClipper(polys), PathClip, true);
|
||||||
|
|
||||||
lines = [];
|
lines = [];
|
||||||
|
|
||||||
if (clip.Execute(ctyp.ctIntersection, ctre, cfil.pftNonZero, cfil.pftEvenOdd)) {
|
if (clip.Execute(ClipIntersect, tree, FillNonZero, FillEvenOdd)) {
|
||||||
for (let poly of ctre.m_AllPolys) {
|
for (let poly of tree.m_AllPolys) {
|
||||||
if (minlen || maxlen) {
|
if (minlen || maxlen) {
|
||||||
let plen = clib.JS.PerimeterOfPath(poly.m_polygon, false, 1);
|
let plen = clib.JS.PerimeterOfPath(poly.m_polygon, false, 1);
|
||||||
if (minlen && plen < minlen) continue;
|
if (minlen && plen < minlen) continue;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue