@tscircuit/cli 0.1.1643 → 0.1.1645
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -2
- package/dist/cli/main.js +3659 -376
- package/dist/lib/index.js +3 -2
- package/package.json +3 -2
package/dist/cli/main.js
CHANGED
|
@@ -53619,6 +53619,1817 @@ var init_dist_3YR26ALR = __esm(() => {
|
|
|
53619
53619
|
];
|
|
53620
53620
|
});
|
|
53621
53621
|
|
|
53622
|
+
// node_modules/splaytree/dist/splaytree.umd.cjs
|
|
53623
|
+
var require_splaytree_umd = __commonJS((exports2, module2) => {
|
|
53624
|
+
(function(h4, c3) {
|
|
53625
|
+
typeof exports2 == "object" && typeof module2 < "u" ? module2.exports = c3() : typeof define == "function" && define.amd ? define(c3) : (h4 = typeof globalThis < "u" ? globalThis : h4 || self, h4.SplayTree = c3());
|
|
53626
|
+
})(exports2, function() {
|
|
53627
|
+
|
|
53628
|
+
class h4 {
|
|
53629
|
+
constructor(t50, e4) {
|
|
53630
|
+
this.next = null, this.key = t50, this.data = e4, this.left = null, this.right = null;
|
|
53631
|
+
}
|
|
53632
|
+
}
|
|
53633
|
+
function c3(n3, t50) {
|
|
53634
|
+
return n3 > t50 ? 1 : n3 < t50 ? -1 : 0;
|
|
53635
|
+
}
|
|
53636
|
+
function u4(n3, t50, e4) {
|
|
53637
|
+
const r4 = new h4(null, null);
|
|
53638
|
+
let i3 = r4, l3 = r4;
|
|
53639
|
+
for (;; ) {
|
|
53640
|
+
const o3 = e4(n3, t50.key);
|
|
53641
|
+
if (o3 < 0) {
|
|
53642
|
+
if (t50.left === null)
|
|
53643
|
+
break;
|
|
53644
|
+
if (e4(n3, t50.left.key) < 0) {
|
|
53645
|
+
const s3 = t50.left;
|
|
53646
|
+
if (t50.left = s3.right, s3.right = t50, t50 = s3, t50.left === null)
|
|
53647
|
+
break;
|
|
53648
|
+
}
|
|
53649
|
+
l3.left = t50, l3 = t50, t50 = t50.left;
|
|
53650
|
+
} else if (o3 > 0) {
|
|
53651
|
+
if (t50.right === null)
|
|
53652
|
+
break;
|
|
53653
|
+
if (e4(n3, t50.right.key) > 0) {
|
|
53654
|
+
const s3 = t50.right;
|
|
53655
|
+
if (t50.right = s3.left, s3.left = t50, t50 = s3, t50.right === null)
|
|
53656
|
+
break;
|
|
53657
|
+
}
|
|
53658
|
+
i3.right = t50, i3 = t50, t50 = t50.right;
|
|
53659
|
+
} else
|
|
53660
|
+
break;
|
|
53661
|
+
}
|
|
53662
|
+
return i3.right = t50.left, l3.left = t50.right, t50.left = r4.right, t50.right = r4.left, t50;
|
|
53663
|
+
}
|
|
53664
|
+
function _4(n3, t50, e4, r4) {
|
|
53665
|
+
const i3 = new h4(n3, t50);
|
|
53666
|
+
if (e4 === null)
|
|
53667
|
+
return i3.left = i3.right = null, i3;
|
|
53668
|
+
e4 = u4(n3, e4, r4);
|
|
53669
|
+
const l3 = r4(n3, e4.key);
|
|
53670
|
+
return l3 < 0 ? (i3.left = e4.left, i3.right = e4, e4.left = null) : l3 >= 0 && (i3.right = e4.right, i3.left = e4, e4.right = null), i3;
|
|
53671
|
+
}
|
|
53672
|
+
function d3(n3, t50, e4) {
|
|
53673
|
+
let r4 = null, i3 = null;
|
|
53674
|
+
if (t50) {
|
|
53675
|
+
t50 = u4(n3, t50, e4);
|
|
53676
|
+
const l3 = e4(t50.key, n3);
|
|
53677
|
+
l3 === 0 ? (r4 = t50.left, i3 = t50.right) : l3 < 0 ? (i3 = t50.right, t50.right = null, r4 = t50) : (r4 = t50.left, t50.left = null, i3 = t50);
|
|
53678
|
+
}
|
|
53679
|
+
return { left: r4, right: i3 };
|
|
53680
|
+
}
|
|
53681
|
+
function w4(n3, t50, e4) {
|
|
53682
|
+
return t50 === null ? n3 : (n3 === null || (t50 = u4(n3.key, t50, e4), t50.left = n3), t50);
|
|
53683
|
+
}
|
|
53684
|
+
function a3(n3, t50, e4, r4, i3) {
|
|
53685
|
+
if (n3) {
|
|
53686
|
+
r4(`${t50}${e4 ? "└── " : "├── "}${i3(n3)}
|
|
53687
|
+
`);
|
|
53688
|
+
const l3 = t50 + (e4 ? " " : "│ ");
|
|
53689
|
+
n3.left && a3(n3.left, l3, false, r4, i3), n3.right && a3(n3.right, l3, true, r4, i3);
|
|
53690
|
+
}
|
|
53691
|
+
}
|
|
53692
|
+
|
|
53693
|
+
class x4 {
|
|
53694
|
+
constructor(t50 = c3) {
|
|
53695
|
+
this._root = null, this._size = 0, this._comparator = t50;
|
|
53696
|
+
}
|
|
53697
|
+
insert(t50, e4) {
|
|
53698
|
+
return this._size++, this._root = _4(t50, e4, this._root, this._comparator);
|
|
53699
|
+
}
|
|
53700
|
+
add(t50, e4) {
|
|
53701
|
+
const r4 = new h4(t50, e4);
|
|
53702
|
+
this._root === null && (r4.left = r4.right = null, this._size++, this._root = r4);
|
|
53703
|
+
const i3 = this._comparator, l3 = u4(t50, this._root, i3), o3 = i3(t50, l3.key);
|
|
53704
|
+
return o3 === 0 ? this._root = l3 : (o3 < 0 ? (r4.left = l3.left, r4.right = l3, l3.left = null) : o3 > 0 && (r4.right = l3.right, r4.left = l3, l3.right = null), this._size++, this._root = r4), this._root;
|
|
53705
|
+
}
|
|
53706
|
+
remove(t50) {
|
|
53707
|
+
this._root = this._remove(t50, this._root, this._comparator);
|
|
53708
|
+
}
|
|
53709
|
+
_remove(t50, e4, r4) {
|
|
53710
|
+
let i3;
|
|
53711
|
+
return e4 === null ? null : (e4 = u4(t50, e4, r4), r4(t50, e4.key) === 0 ? (e4.left === null ? i3 = e4.right : (i3 = u4(t50, e4.left, r4), i3.right = e4.right), this._size--, i3) : e4);
|
|
53712
|
+
}
|
|
53713
|
+
pop() {
|
|
53714
|
+
let t50 = this._root;
|
|
53715
|
+
if (t50) {
|
|
53716
|
+
for (;t50.left; )
|
|
53717
|
+
t50 = t50.left;
|
|
53718
|
+
return this._root = u4(t50.key, this._root, this._comparator), this._root = this._remove(t50.key, this._root, this._comparator), { key: t50.key, data: t50.data };
|
|
53719
|
+
}
|
|
53720
|
+
return null;
|
|
53721
|
+
}
|
|
53722
|
+
findStatic(t50) {
|
|
53723
|
+
let e4 = this._root;
|
|
53724
|
+
const r4 = this._comparator;
|
|
53725
|
+
for (;e4; ) {
|
|
53726
|
+
const i3 = r4(t50, e4.key);
|
|
53727
|
+
if (i3 === 0)
|
|
53728
|
+
return e4;
|
|
53729
|
+
i3 < 0 ? e4 = e4.left : e4 = e4.right;
|
|
53730
|
+
}
|
|
53731
|
+
return null;
|
|
53732
|
+
}
|
|
53733
|
+
find(t50) {
|
|
53734
|
+
return this._root && (this._root = u4(t50, this._root, this._comparator), this._comparator(t50, this._root.key) !== 0) ? null : this._root;
|
|
53735
|
+
}
|
|
53736
|
+
contains(t50) {
|
|
53737
|
+
let e4 = this._root;
|
|
53738
|
+
const r4 = this._comparator;
|
|
53739
|
+
for (;e4; ) {
|
|
53740
|
+
const i3 = r4(t50, e4.key);
|
|
53741
|
+
if (i3 === 0)
|
|
53742
|
+
return true;
|
|
53743
|
+
i3 < 0 ? e4 = e4.left : e4 = e4.right;
|
|
53744
|
+
}
|
|
53745
|
+
return false;
|
|
53746
|
+
}
|
|
53747
|
+
forEach(t50, e4) {
|
|
53748
|
+
let r4 = this._root;
|
|
53749
|
+
const i3 = [];
|
|
53750
|
+
let l3 = false;
|
|
53751
|
+
for (;!l3; )
|
|
53752
|
+
r4 !== null ? (i3.push(r4), r4 = r4.left) : i3.length !== 0 ? (r4 = i3.pop(), t50.call(e4, r4), r4 = r4.right) : l3 = true;
|
|
53753
|
+
return this;
|
|
53754
|
+
}
|
|
53755
|
+
range(t50, e4, r4, i3) {
|
|
53756
|
+
const l3 = [], o3 = this._comparator;
|
|
53757
|
+
let s3 = this._root, f3;
|
|
53758
|
+
for (;l3.length !== 0 || s3; )
|
|
53759
|
+
if (s3)
|
|
53760
|
+
l3.push(s3), s3 = s3.left;
|
|
53761
|
+
else {
|
|
53762
|
+
if (s3 = l3.pop(), f3 = o3(s3.key, e4), f3 > 0)
|
|
53763
|
+
break;
|
|
53764
|
+
if (o3(s3.key, t50) >= 0 && r4.call(i3, s3))
|
|
53765
|
+
return this;
|
|
53766
|
+
s3 = s3.right;
|
|
53767
|
+
}
|
|
53768
|
+
return this;
|
|
53769
|
+
}
|
|
53770
|
+
keys() {
|
|
53771
|
+
const t50 = [];
|
|
53772
|
+
return this.forEach(({ key: e4 }) => {
|
|
53773
|
+
t50.push(e4);
|
|
53774
|
+
}), t50;
|
|
53775
|
+
}
|
|
53776
|
+
values() {
|
|
53777
|
+
const t50 = [];
|
|
53778
|
+
return this.forEach(({ data: e4 }) => {
|
|
53779
|
+
t50.push(e4);
|
|
53780
|
+
}), t50;
|
|
53781
|
+
}
|
|
53782
|
+
min() {
|
|
53783
|
+
return this._root ? this.minNode(this._root).key : null;
|
|
53784
|
+
}
|
|
53785
|
+
max() {
|
|
53786
|
+
return this._root ? this.maxNode(this._root).key : null;
|
|
53787
|
+
}
|
|
53788
|
+
minNode(t50 = this._root) {
|
|
53789
|
+
if (t50)
|
|
53790
|
+
for (;t50.left; )
|
|
53791
|
+
t50 = t50.left;
|
|
53792
|
+
return t50;
|
|
53793
|
+
}
|
|
53794
|
+
maxNode(t50 = this._root) {
|
|
53795
|
+
if (t50)
|
|
53796
|
+
for (;t50.right; )
|
|
53797
|
+
t50 = t50.right;
|
|
53798
|
+
return t50;
|
|
53799
|
+
}
|
|
53800
|
+
at(t50) {
|
|
53801
|
+
let e4 = this._root, r4 = false, i3 = 0;
|
|
53802
|
+
const l3 = [];
|
|
53803
|
+
for (;!r4; )
|
|
53804
|
+
if (e4)
|
|
53805
|
+
l3.push(e4), e4 = e4.left;
|
|
53806
|
+
else if (l3.length > 0) {
|
|
53807
|
+
if (e4 = l3.pop(), i3 === t50)
|
|
53808
|
+
return e4;
|
|
53809
|
+
i3++, e4 = e4.right;
|
|
53810
|
+
} else
|
|
53811
|
+
r4 = true;
|
|
53812
|
+
return null;
|
|
53813
|
+
}
|
|
53814
|
+
next(t50) {
|
|
53815
|
+
let e4 = this._root, r4 = null;
|
|
53816
|
+
if (t50.right) {
|
|
53817
|
+
for (r4 = t50.right;r4.left; )
|
|
53818
|
+
r4 = r4.left;
|
|
53819
|
+
return r4;
|
|
53820
|
+
}
|
|
53821
|
+
const i3 = this._comparator;
|
|
53822
|
+
for (;e4; ) {
|
|
53823
|
+
const l3 = i3(t50.key, e4.key);
|
|
53824
|
+
if (l3 === 0)
|
|
53825
|
+
break;
|
|
53826
|
+
l3 < 0 ? (r4 = e4, e4 = e4.left) : e4 = e4.right;
|
|
53827
|
+
}
|
|
53828
|
+
return r4;
|
|
53829
|
+
}
|
|
53830
|
+
prev(t50) {
|
|
53831
|
+
let e4 = this._root, r4 = null;
|
|
53832
|
+
if (t50.left !== null) {
|
|
53833
|
+
for (r4 = t50.left;r4.right; )
|
|
53834
|
+
r4 = r4.right;
|
|
53835
|
+
return r4;
|
|
53836
|
+
}
|
|
53837
|
+
const i3 = this._comparator;
|
|
53838
|
+
for (;e4; ) {
|
|
53839
|
+
const l3 = i3(t50.key, e4.key);
|
|
53840
|
+
if (l3 === 0)
|
|
53841
|
+
break;
|
|
53842
|
+
l3 < 0 ? e4 = e4.left : (r4 = e4, e4 = e4.right);
|
|
53843
|
+
}
|
|
53844
|
+
return r4;
|
|
53845
|
+
}
|
|
53846
|
+
clear() {
|
|
53847
|
+
return this._root = null, this._size = 0, this;
|
|
53848
|
+
}
|
|
53849
|
+
toList() {
|
|
53850
|
+
return y4(this._root);
|
|
53851
|
+
}
|
|
53852
|
+
load(t50, e4 = [], r4 = false) {
|
|
53853
|
+
let i3 = t50.length;
|
|
53854
|
+
const l3 = this._comparator;
|
|
53855
|
+
if (r4 && m4(t50, e4, 0, i3 - 1, l3), this._root === null)
|
|
53856
|
+
this._root = p3(t50, e4, 0, i3), this._size = i3;
|
|
53857
|
+
else {
|
|
53858
|
+
const o3 = z4(this.toList(), k4(t50, e4), l3);
|
|
53859
|
+
i3 = this._size + i3, this._root = g6({ head: o3 }, 0, i3);
|
|
53860
|
+
}
|
|
53861
|
+
return this;
|
|
53862
|
+
}
|
|
53863
|
+
isEmpty() {
|
|
53864
|
+
return this._root === null;
|
|
53865
|
+
}
|
|
53866
|
+
get size() {
|
|
53867
|
+
return this._size;
|
|
53868
|
+
}
|
|
53869
|
+
get root() {
|
|
53870
|
+
return this._root;
|
|
53871
|
+
}
|
|
53872
|
+
toString(t50 = (e4) => String(e4.key)) {
|
|
53873
|
+
const e4 = [];
|
|
53874
|
+
return a3(this._root, "", true, (r4) => e4.push(r4), t50), e4.join("");
|
|
53875
|
+
}
|
|
53876
|
+
update(t50, e4, r4) {
|
|
53877
|
+
const i3 = this._comparator;
|
|
53878
|
+
let { left: l3, right: o3 } = d3(t50, this._root, i3);
|
|
53879
|
+
i3(t50, e4) < 0 ? o3 = _4(e4, r4, o3, i3) : l3 = _4(e4, r4, l3, i3), this._root = w4(l3, o3, i3);
|
|
53880
|
+
}
|
|
53881
|
+
split(t50) {
|
|
53882
|
+
return d3(t50, this._root, this._comparator);
|
|
53883
|
+
}
|
|
53884
|
+
*[Symbol.iterator]() {
|
|
53885
|
+
let t50 = this._root;
|
|
53886
|
+
const e4 = [];
|
|
53887
|
+
let r4 = false;
|
|
53888
|
+
for (;!r4; )
|
|
53889
|
+
t50 !== null ? (e4.push(t50), t50 = t50.left) : e4.length !== 0 ? (t50 = e4.pop(), yield t50, t50 = t50.right) : r4 = true;
|
|
53890
|
+
}
|
|
53891
|
+
}
|
|
53892
|
+
function p3(n3, t50, e4, r4) {
|
|
53893
|
+
const i3 = r4 - e4;
|
|
53894
|
+
if (i3 > 0) {
|
|
53895
|
+
const l3 = e4 + Math.floor(i3 / 2), o3 = n3[l3], s3 = t50[l3], f3 = new h4(o3, s3);
|
|
53896
|
+
return f3.left = p3(n3, t50, e4, l3), f3.right = p3(n3, t50, l3 + 1, r4), f3;
|
|
53897
|
+
}
|
|
53898
|
+
return null;
|
|
53899
|
+
}
|
|
53900
|
+
function k4(n3, t50) {
|
|
53901
|
+
const e4 = new h4(null, null);
|
|
53902
|
+
let r4 = e4;
|
|
53903
|
+
for (let i3 = 0;i3 < n3.length; i3++)
|
|
53904
|
+
r4 = r4.next = new h4(n3[i3], t50[i3]);
|
|
53905
|
+
return r4.next = null, e4.next;
|
|
53906
|
+
}
|
|
53907
|
+
function y4(n3) {
|
|
53908
|
+
let t50 = n3;
|
|
53909
|
+
const e4 = [];
|
|
53910
|
+
let r4 = false;
|
|
53911
|
+
const i3 = new h4(null, null);
|
|
53912
|
+
let l3 = i3;
|
|
53913
|
+
for (;!r4; )
|
|
53914
|
+
t50 ? (e4.push(t50), t50 = t50.left) : e4.length > 0 ? (t50 = l3 = l3.next = e4.pop(), t50 = t50.right) : r4 = true;
|
|
53915
|
+
return l3.next = null, i3.next;
|
|
53916
|
+
}
|
|
53917
|
+
function g6(n3, t50, e4) {
|
|
53918
|
+
const r4 = e4 - t50;
|
|
53919
|
+
if (r4 > 0) {
|
|
53920
|
+
const i3 = t50 + Math.floor(r4 / 2), l3 = g6(n3, t50, i3), o3 = n3.head;
|
|
53921
|
+
return o3.left = l3, n3.head = n3.head.next, o3.right = g6(n3, i3 + 1, e4), o3;
|
|
53922
|
+
}
|
|
53923
|
+
return null;
|
|
53924
|
+
}
|
|
53925
|
+
function z4(n3, t50, e4) {
|
|
53926
|
+
const r4 = new h4(null, null);
|
|
53927
|
+
let i3 = r4, l3 = n3, o3 = t50;
|
|
53928
|
+
for (;l3 !== null && o3 !== null; )
|
|
53929
|
+
e4(l3.key, o3.key) < 0 ? (i3.next = l3, l3 = l3.next) : (i3.next = o3, o3 = o3.next), i3 = i3.next;
|
|
53930
|
+
return l3 !== null ? i3.next = l3 : o3 !== null && (i3.next = o3), r4.next;
|
|
53931
|
+
}
|
|
53932
|
+
function m4(n3, t50, e4, r4, i3) {
|
|
53933
|
+
if (e4 >= r4)
|
|
53934
|
+
return;
|
|
53935
|
+
const l3 = n3[e4 + r4 >> 1];
|
|
53936
|
+
let o3 = e4 - 1, s3 = r4 + 1;
|
|
53937
|
+
for (;; ) {
|
|
53938
|
+
do
|
|
53939
|
+
o3++;
|
|
53940
|
+
while (i3(n3[o3], l3) < 0);
|
|
53941
|
+
do
|
|
53942
|
+
s3--;
|
|
53943
|
+
while (i3(n3[s3], l3) > 0);
|
|
53944
|
+
if (o3 >= s3)
|
|
53945
|
+
break;
|
|
53946
|
+
let f3 = n3[o3];
|
|
53947
|
+
n3[o3] = n3[s3], n3[s3] = f3, f3 = t50[o3], t50[o3] = t50[s3], t50[s3] = f3;
|
|
53948
|
+
}
|
|
53949
|
+
m4(n3, t50, e4, s3, i3), m4(n3, t50, s3 + 1, r4, i3);
|
|
53950
|
+
}
|
|
53951
|
+
return x4;
|
|
53952
|
+
});
|
|
53953
|
+
});
|
|
53954
|
+
|
|
53955
|
+
// node_modules/polygon-clipping/dist/polygon-clipping.cjs.js
|
|
53956
|
+
var require_polygon_clipping_cjs = __commonJS((exports2, module2) => {
|
|
53957
|
+
var SplayTree = require_splaytree_umd();
|
|
53958
|
+
function _interopDefaultLegacy(e4) {
|
|
53959
|
+
return e4 && typeof e4 === "object" && "default" in e4 ? e4 : { default: e4 };
|
|
53960
|
+
}
|
|
53961
|
+
var SplayTree__default = /* @__PURE__ */ _interopDefaultLegacy(SplayTree);
|
|
53962
|
+
var isInBbox = (bbox, point9) => {
|
|
53963
|
+
return bbox.ll.x <= point9.x && point9.x <= bbox.ur.x && bbox.ll.y <= point9.y && point9.y <= bbox.ur.y;
|
|
53964
|
+
};
|
|
53965
|
+
var getBboxOverlap = (b12, b22) => {
|
|
53966
|
+
if (b22.ur.x < b12.ll.x || b12.ur.x < b22.ll.x || b22.ur.y < b12.ll.y || b12.ur.y < b22.ll.y)
|
|
53967
|
+
return null;
|
|
53968
|
+
const lowerX = b12.ll.x < b22.ll.x ? b22.ll.x : b12.ll.x;
|
|
53969
|
+
const upperX = b12.ur.x < b22.ur.x ? b12.ur.x : b22.ur.x;
|
|
53970
|
+
const lowerY = b12.ll.y < b22.ll.y ? b22.ll.y : b12.ll.y;
|
|
53971
|
+
const upperY = b12.ur.y < b22.ur.y ? b12.ur.y : b22.ur.y;
|
|
53972
|
+
return {
|
|
53973
|
+
ll: {
|
|
53974
|
+
x: lowerX,
|
|
53975
|
+
y: lowerY
|
|
53976
|
+
},
|
|
53977
|
+
ur: {
|
|
53978
|
+
x: upperX,
|
|
53979
|
+
y: upperY
|
|
53980
|
+
}
|
|
53981
|
+
};
|
|
53982
|
+
};
|
|
53983
|
+
var epsilon$1 = Number.EPSILON;
|
|
53984
|
+
if (epsilon$1 === undefined)
|
|
53985
|
+
epsilon$1 = Math.pow(2, -52);
|
|
53986
|
+
var EPSILON_SQ = epsilon$1 * epsilon$1;
|
|
53987
|
+
var cmp = (a3, b3) => {
|
|
53988
|
+
if (-epsilon$1 < a3 && a3 < epsilon$1) {
|
|
53989
|
+
if (-epsilon$1 < b3 && b3 < epsilon$1) {
|
|
53990
|
+
return 0;
|
|
53991
|
+
}
|
|
53992
|
+
}
|
|
53993
|
+
const ab2 = a3 - b3;
|
|
53994
|
+
if (ab2 * ab2 < EPSILON_SQ * a3 * b3) {
|
|
53995
|
+
return 0;
|
|
53996
|
+
}
|
|
53997
|
+
return a3 < b3 ? -1 : 1;
|
|
53998
|
+
};
|
|
53999
|
+
|
|
54000
|
+
class PtRounder {
|
|
54001
|
+
constructor() {
|
|
54002
|
+
this.reset();
|
|
54003
|
+
}
|
|
54004
|
+
reset() {
|
|
54005
|
+
this.xRounder = new CoordRounder;
|
|
54006
|
+
this.yRounder = new CoordRounder;
|
|
54007
|
+
}
|
|
54008
|
+
round(x4, y4) {
|
|
54009
|
+
return {
|
|
54010
|
+
x: this.xRounder.round(x4),
|
|
54011
|
+
y: this.yRounder.round(y4)
|
|
54012
|
+
};
|
|
54013
|
+
}
|
|
54014
|
+
}
|
|
54015
|
+
|
|
54016
|
+
class CoordRounder {
|
|
54017
|
+
constructor() {
|
|
54018
|
+
this.tree = new SplayTree__default["default"];
|
|
54019
|
+
this.round(0);
|
|
54020
|
+
}
|
|
54021
|
+
round(coord) {
|
|
54022
|
+
const node = this.tree.add(coord);
|
|
54023
|
+
const prevNode = this.tree.prev(node);
|
|
54024
|
+
if (prevNode !== null && cmp(node.key, prevNode.key) === 0) {
|
|
54025
|
+
this.tree.remove(coord);
|
|
54026
|
+
return prevNode.key;
|
|
54027
|
+
}
|
|
54028
|
+
const nextNode = this.tree.next(node);
|
|
54029
|
+
if (nextNode !== null && cmp(node.key, nextNode.key) === 0) {
|
|
54030
|
+
this.tree.remove(coord);
|
|
54031
|
+
return nextNode.key;
|
|
54032
|
+
}
|
|
54033
|
+
return coord;
|
|
54034
|
+
}
|
|
54035
|
+
}
|
|
54036
|
+
var rounder = new PtRounder;
|
|
54037
|
+
var epsilon = 0.00000000000000011102230246251565;
|
|
54038
|
+
var splitter = 134217729;
|
|
54039
|
+
var resulterrbound = (3 + 8 * epsilon) * epsilon;
|
|
54040
|
+
function sum(elen, e4, flen, f3, h4) {
|
|
54041
|
+
let Q4, Qnew, hh3, bvirt;
|
|
54042
|
+
let enow = e4[0];
|
|
54043
|
+
let fnow = f3[0];
|
|
54044
|
+
let eindex = 0;
|
|
54045
|
+
let findex = 0;
|
|
54046
|
+
if (fnow > enow === fnow > -enow) {
|
|
54047
|
+
Q4 = enow;
|
|
54048
|
+
enow = e4[++eindex];
|
|
54049
|
+
} else {
|
|
54050
|
+
Q4 = fnow;
|
|
54051
|
+
fnow = f3[++findex];
|
|
54052
|
+
}
|
|
54053
|
+
let hindex = 0;
|
|
54054
|
+
if (eindex < elen && findex < flen) {
|
|
54055
|
+
if (fnow > enow === fnow > -enow) {
|
|
54056
|
+
Qnew = enow + Q4;
|
|
54057
|
+
hh3 = Q4 - (Qnew - enow);
|
|
54058
|
+
enow = e4[++eindex];
|
|
54059
|
+
} else {
|
|
54060
|
+
Qnew = fnow + Q4;
|
|
54061
|
+
hh3 = Q4 - (Qnew - fnow);
|
|
54062
|
+
fnow = f3[++findex];
|
|
54063
|
+
}
|
|
54064
|
+
Q4 = Qnew;
|
|
54065
|
+
if (hh3 !== 0) {
|
|
54066
|
+
h4[hindex++] = hh3;
|
|
54067
|
+
}
|
|
54068
|
+
while (eindex < elen && findex < flen) {
|
|
54069
|
+
if (fnow > enow === fnow > -enow) {
|
|
54070
|
+
Qnew = Q4 + enow;
|
|
54071
|
+
bvirt = Qnew - Q4;
|
|
54072
|
+
hh3 = Q4 - (Qnew - bvirt) + (enow - bvirt);
|
|
54073
|
+
enow = e4[++eindex];
|
|
54074
|
+
} else {
|
|
54075
|
+
Qnew = Q4 + fnow;
|
|
54076
|
+
bvirt = Qnew - Q4;
|
|
54077
|
+
hh3 = Q4 - (Qnew - bvirt) + (fnow - bvirt);
|
|
54078
|
+
fnow = f3[++findex];
|
|
54079
|
+
}
|
|
54080
|
+
Q4 = Qnew;
|
|
54081
|
+
if (hh3 !== 0) {
|
|
54082
|
+
h4[hindex++] = hh3;
|
|
54083
|
+
}
|
|
54084
|
+
}
|
|
54085
|
+
}
|
|
54086
|
+
while (eindex < elen) {
|
|
54087
|
+
Qnew = Q4 + enow;
|
|
54088
|
+
bvirt = Qnew - Q4;
|
|
54089
|
+
hh3 = Q4 - (Qnew - bvirt) + (enow - bvirt);
|
|
54090
|
+
enow = e4[++eindex];
|
|
54091
|
+
Q4 = Qnew;
|
|
54092
|
+
if (hh3 !== 0) {
|
|
54093
|
+
h4[hindex++] = hh3;
|
|
54094
|
+
}
|
|
54095
|
+
}
|
|
54096
|
+
while (findex < flen) {
|
|
54097
|
+
Qnew = Q4 + fnow;
|
|
54098
|
+
bvirt = Qnew - Q4;
|
|
54099
|
+
hh3 = Q4 - (Qnew - bvirt) + (fnow - bvirt);
|
|
54100
|
+
fnow = f3[++findex];
|
|
54101
|
+
Q4 = Qnew;
|
|
54102
|
+
if (hh3 !== 0) {
|
|
54103
|
+
h4[hindex++] = hh3;
|
|
54104
|
+
}
|
|
54105
|
+
}
|
|
54106
|
+
if (Q4 !== 0 || hindex === 0) {
|
|
54107
|
+
h4[hindex++] = Q4;
|
|
54108
|
+
}
|
|
54109
|
+
return hindex;
|
|
54110
|
+
}
|
|
54111
|
+
function estimate(elen, e4) {
|
|
54112
|
+
let Q4 = e4[0];
|
|
54113
|
+
for (let i3 = 1;i3 < elen; i3++)
|
|
54114
|
+
Q4 += e4[i3];
|
|
54115
|
+
return Q4;
|
|
54116
|
+
}
|
|
54117
|
+
function vec(n3) {
|
|
54118
|
+
return new Float64Array(n3);
|
|
54119
|
+
}
|
|
54120
|
+
var ccwerrboundA = (3 + 16 * epsilon) * epsilon;
|
|
54121
|
+
var ccwerrboundB = (2 + 12 * epsilon) * epsilon;
|
|
54122
|
+
var ccwerrboundC = (9 + 64 * epsilon) * epsilon * epsilon;
|
|
54123
|
+
var B4 = vec(4);
|
|
54124
|
+
var C12 = vec(8);
|
|
54125
|
+
var C22 = vec(12);
|
|
54126
|
+
var D4 = vec(16);
|
|
54127
|
+
var u4 = vec(4);
|
|
54128
|
+
function orient2dadapt(ax3, ay3, bx3, by3, cx3, cy3, detsum) {
|
|
54129
|
+
let acxtail, acytail, bcxtail, bcytail;
|
|
54130
|
+
let bvirt, c3, ahi, alo, bhi, blo, _i3, _j, _02, s12, s02, t110, t02, u32;
|
|
54131
|
+
const acx = ax3 - cx3;
|
|
54132
|
+
const bcx = bx3 - cx3;
|
|
54133
|
+
const acy = ay3 - cy3;
|
|
54134
|
+
const bcy = by3 - cy3;
|
|
54135
|
+
s12 = acx * bcy;
|
|
54136
|
+
c3 = splitter * acx;
|
|
54137
|
+
ahi = c3 - (c3 - acx);
|
|
54138
|
+
alo = acx - ahi;
|
|
54139
|
+
c3 = splitter * bcy;
|
|
54140
|
+
bhi = c3 - (c3 - bcy);
|
|
54141
|
+
blo = bcy - bhi;
|
|
54142
|
+
s02 = alo * blo - (s12 - ahi * bhi - alo * bhi - ahi * blo);
|
|
54143
|
+
t110 = acy * bcx;
|
|
54144
|
+
c3 = splitter * acy;
|
|
54145
|
+
ahi = c3 - (c3 - acy);
|
|
54146
|
+
alo = acy - ahi;
|
|
54147
|
+
c3 = splitter * bcx;
|
|
54148
|
+
bhi = c3 - (c3 - bcx);
|
|
54149
|
+
blo = bcx - bhi;
|
|
54150
|
+
t02 = alo * blo - (t110 - ahi * bhi - alo * bhi - ahi * blo);
|
|
54151
|
+
_i3 = s02 - t02;
|
|
54152
|
+
bvirt = s02 - _i3;
|
|
54153
|
+
B4[0] = s02 - (_i3 + bvirt) + (bvirt - t02);
|
|
54154
|
+
_j = s12 + _i3;
|
|
54155
|
+
bvirt = _j - s12;
|
|
54156
|
+
_02 = s12 - (_j - bvirt) + (_i3 - bvirt);
|
|
54157
|
+
_i3 = _02 - t110;
|
|
54158
|
+
bvirt = _02 - _i3;
|
|
54159
|
+
B4[1] = _02 - (_i3 + bvirt) + (bvirt - t110);
|
|
54160
|
+
u32 = _j + _i3;
|
|
54161
|
+
bvirt = u32 - _j;
|
|
54162
|
+
B4[2] = _j - (u32 - bvirt) + (_i3 - bvirt);
|
|
54163
|
+
B4[3] = u32;
|
|
54164
|
+
let det = estimate(4, B4);
|
|
54165
|
+
let errbound = ccwerrboundB * detsum;
|
|
54166
|
+
if (det >= errbound || -det >= errbound) {
|
|
54167
|
+
return det;
|
|
54168
|
+
}
|
|
54169
|
+
bvirt = ax3 - acx;
|
|
54170
|
+
acxtail = ax3 - (acx + bvirt) + (bvirt - cx3);
|
|
54171
|
+
bvirt = bx3 - bcx;
|
|
54172
|
+
bcxtail = bx3 - (bcx + bvirt) + (bvirt - cx3);
|
|
54173
|
+
bvirt = ay3 - acy;
|
|
54174
|
+
acytail = ay3 - (acy + bvirt) + (bvirt - cy3);
|
|
54175
|
+
bvirt = by3 - bcy;
|
|
54176
|
+
bcytail = by3 - (bcy + bvirt) + (bvirt - cy3);
|
|
54177
|
+
if (acxtail === 0 && acytail === 0 && bcxtail === 0 && bcytail === 0) {
|
|
54178
|
+
return det;
|
|
54179
|
+
}
|
|
54180
|
+
errbound = ccwerrboundC * detsum + resulterrbound * Math.abs(det);
|
|
54181
|
+
det += acx * bcytail + bcy * acxtail - (acy * bcxtail + bcx * acytail);
|
|
54182
|
+
if (det >= errbound || -det >= errbound)
|
|
54183
|
+
return det;
|
|
54184
|
+
s12 = acxtail * bcy;
|
|
54185
|
+
c3 = splitter * acxtail;
|
|
54186
|
+
ahi = c3 - (c3 - acxtail);
|
|
54187
|
+
alo = acxtail - ahi;
|
|
54188
|
+
c3 = splitter * bcy;
|
|
54189
|
+
bhi = c3 - (c3 - bcy);
|
|
54190
|
+
blo = bcy - bhi;
|
|
54191
|
+
s02 = alo * blo - (s12 - ahi * bhi - alo * bhi - ahi * blo);
|
|
54192
|
+
t110 = acytail * bcx;
|
|
54193
|
+
c3 = splitter * acytail;
|
|
54194
|
+
ahi = c3 - (c3 - acytail);
|
|
54195
|
+
alo = acytail - ahi;
|
|
54196
|
+
c3 = splitter * bcx;
|
|
54197
|
+
bhi = c3 - (c3 - bcx);
|
|
54198
|
+
blo = bcx - bhi;
|
|
54199
|
+
t02 = alo * blo - (t110 - ahi * bhi - alo * bhi - ahi * blo);
|
|
54200
|
+
_i3 = s02 - t02;
|
|
54201
|
+
bvirt = s02 - _i3;
|
|
54202
|
+
u4[0] = s02 - (_i3 + bvirt) + (bvirt - t02);
|
|
54203
|
+
_j = s12 + _i3;
|
|
54204
|
+
bvirt = _j - s12;
|
|
54205
|
+
_02 = s12 - (_j - bvirt) + (_i3 - bvirt);
|
|
54206
|
+
_i3 = _02 - t110;
|
|
54207
|
+
bvirt = _02 - _i3;
|
|
54208
|
+
u4[1] = _02 - (_i3 + bvirt) + (bvirt - t110);
|
|
54209
|
+
u32 = _j + _i3;
|
|
54210
|
+
bvirt = u32 - _j;
|
|
54211
|
+
u4[2] = _j - (u32 - bvirt) + (_i3 - bvirt);
|
|
54212
|
+
u4[3] = u32;
|
|
54213
|
+
const C1len = sum(4, B4, 4, u4, C12);
|
|
54214
|
+
s12 = acx * bcytail;
|
|
54215
|
+
c3 = splitter * acx;
|
|
54216
|
+
ahi = c3 - (c3 - acx);
|
|
54217
|
+
alo = acx - ahi;
|
|
54218
|
+
c3 = splitter * bcytail;
|
|
54219
|
+
bhi = c3 - (c3 - bcytail);
|
|
54220
|
+
blo = bcytail - bhi;
|
|
54221
|
+
s02 = alo * blo - (s12 - ahi * bhi - alo * bhi - ahi * blo);
|
|
54222
|
+
t110 = acy * bcxtail;
|
|
54223
|
+
c3 = splitter * acy;
|
|
54224
|
+
ahi = c3 - (c3 - acy);
|
|
54225
|
+
alo = acy - ahi;
|
|
54226
|
+
c3 = splitter * bcxtail;
|
|
54227
|
+
bhi = c3 - (c3 - bcxtail);
|
|
54228
|
+
blo = bcxtail - bhi;
|
|
54229
|
+
t02 = alo * blo - (t110 - ahi * bhi - alo * bhi - ahi * blo);
|
|
54230
|
+
_i3 = s02 - t02;
|
|
54231
|
+
bvirt = s02 - _i3;
|
|
54232
|
+
u4[0] = s02 - (_i3 + bvirt) + (bvirt - t02);
|
|
54233
|
+
_j = s12 + _i3;
|
|
54234
|
+
bvirt = _j - s12;
|
|
54235
|
+
_02 = s12 - (_j - bvirt) + (_i3 - bvirt);
|
|
54236
|
+
_i3 = _02 - t110;
|
|
54237
|
+
bvirt = _02 - _i3;
|
|
54238
|
+
u4[1] = _02 - (_i3 + bvirt) + (bvirt - t110);
|
|
54239
|
+
u32 = _j + _i3;
|
|
54240
|
+
bvirt = u32 - _j;
|
|
54241
|
+
u4[2] = _j - (u32 - bvirt) + (_i3 - bvirt);
|
|
54242
|
+
u4[3] = u32;
|
|
54243
|
+
const C2len = sum(C1len, C12, 4, u4, C22);
|
|
54244
|
+
s12 = acxtail * bcytail;
|
|
54245
|
+
c3 = splitter * acxtail;
|
|
54246
|
+
ahi = c3 - (c3 - acxtail);
|
|
54247
|
+
alo = acxtail - ahi;
|
|
54248
|
+
c3 = splitter * bcytail;
|
|
54249
|
+
bhi = c3 - (c3 - bcytail);
|
|
54250
|
+
blo = bcytail - bhi;
|
|
54251
|
+
s02 = alo * blo - (s12 - ahi * bhi - alo * bhi - ahi * blo);
|
|
54252
|
+
t110 = acytail * bcxtail;
|
|
54253
|
+
c3 = splitter * acytail;
|
|
54254
|
+
ahi = c3 - (c3 - acytail);
|
|
54255
|
+
alo = acytail - ahi;
|
|
54256
|
+
c3 = splitter * bcxtail;
|
|
54257
|
+
bhi = c3 - (c3 - bcxtail);
|
|
54258
|
+
blo = bcxtail - bhi;
|
|
54259
|
+
t02 = alo * blo - (t110 - ahi * bhi - alo * bhi - ahi * blo);
|
|
54260
|
+
_i3 = s02 - t02;
|
|
54261
|
+
bvirt = s02 - _i3;
|
|
54262
|
+
u4[0] = s02 - (_i3 + bvirt) + (bvirt - t02);
|
|
54263
|
+
_j = s12 + _i3;
|
|
54264
|
+
bvirt = _j - s12;
|
|
54265
|
+
_02 = s12 - (_j - bvirt) + (_i3 - bvirt);
|
|
54266
|
+
_i3 = _02 - t110;
|
|
54267
|
+
bvirt = _02 - _i3;
|
|
54268
|
+
u4[1] = _02 - (_i3 + bvirt) + (bvirt - t110);
|
|
54269
|
+
u32 = _j + _i3;
|
|
54270
|
+
bvirt = u32 - _j;
|
|
54271
|
+
u4[2] = _j - (u32 - bvirt) + (_i3 - bvirt);
|
|
54272
|
+
u4[3] = u32;
|
|
54273
|
+
const Dlen = sum(C2len, C22, 4, u4, D4);
|
|
54274
|
+
return D4[Dlen - 1];
|
|
54275
|
+
}
|
|
54276
|
+
function orient2d(ax3, ay3, bx3, by3, cx3, cy3) {
|
|
54277
|
+
const detleft = (ay3 - cy3) * (bx3 - cx3);
|
|
54278
|
+
const detright = (ax3 - cx3) * (by3 - cy3);
|
|
54279
|
+
const det = detleft - detright;
|
|
54280
|
+
const detsum = Math.abs(detleft + detright);
|
|
54281
|
+
if (Math.abs(det) >= ccwerrboundA * detsum)
|
|
54282
|
+
return det;
|
|
54283
|
+
return -orient2dadapt(ax3, ay3, bx3, by3, cx3, cy3, detsum);
|
|
54284
|
+
}
|
|
54285
|
+
var crossProduct = (a3, b3) => a3.x * b3.y - a3.y * b3.x;
|
|
54286
|
+
var dotProduct = (a3, b3) => a3.x * b3.x + a3.y * b3.y;
|
|
54287
|
+
var compareVectorAngles = (basePt, endPt1, endPt2) => {
|
|
54288
|
+
const res2 = orient2d(basePt.x, basePt.y, endPt1.x, endPt1.y, endPt2.x, endPt2.y);
|
|
54289
|
+
if (res2 > 0)
|
|
54290
|
+
return -1;
|
|
54291
|
+
if (res2 < 0)
|
|
54292
|
+
return 1;
|
|
54293
|
+
return 0;
|
|
54294
|
+
};
|
|
54295
|
+
var length67 = (v4) => Math.sqrt(dotProduct(v4, v4));
|
|
54296
|
+
var sineOfAngle = (pShared, pBase, pAngle) => {
|
|
54297
|
+
const vBase = {
|
|
54298
|
+
x: pBase.x - pShared.x,
|
|
54299
|
+
y: pBase.y - pShared.y
|
|
54300
|
+
};
|
|
54301
|
+
const vAngle = {
|
|
54302
|
+
x: pAngle.x - pShared.x,
|
|
54303
|
+
y: pAngle.y - pShared.y
|
|
54304
|
+
};
|
|
54305
|
+
return crossProduct(vAngle, vBase) / length67(vAngle) / length67(vBase);
|
|
54306
|
+
};
|
|
54307
|
+
var cosineOfAngle = (pShared, pBase, pAngle) => {
|
|
54308
|
+
const vBase = {
|
|
54309
|
+
x: pBase.x - pShared.x,
|
|
54310
|
+
y: pBase.y - pShared.y
|
|
54311
|
+
};
|
|
54312
|
+
const vAngle = {
|
|
54313
|
+
x: pAngle.x - pShared.x,
|
|
54314
|
+
y: pAngle.y - pShared.y
|
|
54315
|
+
};
|
|
54316
|
+
return dotProduct(vAngle, vBase) / length67(vAngle) / length67(vBase);
|
|
54317
|
+
};
|
|
54318
|
+
var horizontalIntersection = (pt3, v4, y4) => {
|
|
54319
|
+
if (v4.y === 0)
|
|
54320
|
+
return null;
|
|
54321
|
+
return {
|
|
54322
|
+
x: pt3.x + v4.x / v4.y * (y4 - pt3.y),
|
|
54323
|
+
y: y4
|
|
54324
|
+
};
|
|
54325
|
+
};
|
|
54326
|
+
var verticalIntersection = (pt3, v4, x4) => {
|
|
54327
|
+
if (v4.x === 0)
|
|
54328
|
+
return null;
|
|
54329
|
+
return {
|
|
54330
|
+
x: x4,
|
|
54331
|
+
y: pt3.y + v4.y / v4.x * (x4 - pt3.x)
|
|
54332
|
+
};
|
|
54333
|
+
};
|
|
54334
|
+
var intersection$1 = (pt1, v12, pt22, v22) => {
|
|
54335
|
+
if (v12.x === 0)
|
|
54336
|
+
return verticalIntersection(pt22, v22, pt1.x);
|
|
54337
|
+
if (v22.x === 0)
|
|
54338
|
+
return verticalIntersection(pt1, v12, pt22.x);
|
|
54339
|
+
if (v12.y === 0)
|
|
54340
|
+
return horizontalIntersection(pt22, v22, pt1.y);
|
|
54341
|
+
if (v22.y === 0)
|
|
54342
|
+
return horizontalIntersection(pt1, v12, pt22.y);
|
|
54343
|
+
const kross = crossProduct(v12, v22);
|
|
54344
|
+
if (kross == 0)
|
|
54345
|
+
return null;
|
|
54346
|
+
const ve3 = {
|
|
54347
|
+
x: pt22.x - pt1.x,
|
|
54348
|
+
y: pt22.y - pt1.y
|
|
54349
|
+
};
|
|
54350
|
+
const d12 = crossProduct(ve3, v12) / kross;
|
|
54351
|
+
const d23 = crossProduct(ve3, v22) / kross;
|
|
54352
|
+
const x12 = pt1.x + d23 * v12.x, x22 = pt22.x + d12 * v22.x;
|
|
54353
|
+
const y12 = pt1.y + d23 * v12.y, y22 = pt22.y + d12 * v22.y;
|
|
54354
|
+
const x4 = (x12 + x22) / 2;
|
|
54355
|
+
const y4 = (y12 + y22) / 2;
|
|
54356
|
+
return {
|
|
54357
|
+
x: x4,
|
|
54358
|
+
y: y4
|
|
54359
|
+
};
|
|
54360
|
+
};
|
|
54361
|
+
|
|
54362
|
+
class SweepEvent {
|
|
54363
|
+
static compare(a3, b3) {
|
|
54364
|
+
const ptCmp = SweepEvent.comparePoints(a3.point, b3.point);
|
|
54365
|
+
if (ptCmp !== 0)
|
|
54366
|
+
return ptCmp;
|
|
54367
|
+
if (a3.point !== b3.point)
|
|
54368
|
+
a3.link(b3);
|
|
54369
|
+
if (a3.isLeft !== b3.isLeft)
|
|
54370
|
+
return a3.isLeft ? 1 : -1;
|
|
54371
|
+
return Segment3.compare(a3.segment, b3.segment);
|
|
54372
|
+
}
|
|
54373
|
+
static comparePoints(aPt, bPt) {
|
|
54374
|
+
if (aPt.x < bPt.x)
|
|
54375
|
+
return -1;
|
|
54376
|
+
if (aPt.x > bPt.x)
|
|
54377
|
+
return 1;
|
|
54378
|
+
if (aPt.y < bPt.y)
|
|
54379
|
+
return -1;
|
|
54380
|
+
if (aPt.y > bPt.y)
|
|
54381
|
+
return 1;
|
|
54382
|
+
return 0;
|
|
54383
|
+
}
|
|
54384
|
+
constructor(point9, isLeft) {
|
|
54385
|
+
if (point9.events === undefined)
|
|
54386
|
+
point9.events = [this];
|
|
54387
|
+
else
|
|
54388
|
+
point9.events.push(this);
|
|
54389
|
+
this.point = point9;
|
|
54390
|
+
this.isLeft = isLeft;
|
|
54391
|
+
}
|
|
54392
|
+
link(other) {
|
|
54393
|
+
if (other.point === this.point) {
|
|
54394
|
+
throw new Error("Tried to link already linked events");
|
|
54395
|
+
}
|
|
54396
|
+
const otherEvents = other.point.events;
|
|
54397
|
+
for (let i3 = 0, iMax = otherEvents.length;i3 < iMax; i3++) {
|
|
54398
|
+
const evt = otherEvents[i3];
|
|
54399
|
+
this.point.events.push(evt);
|
|
54400
|
+
evt.point = this.point;
|
|
54401
|
+
}
|
|
54402
|
+
this.checkForConsuming();
|
|
54403
|
+
}
|
|
54404
|
+
checkForConsuming() {
|
|
54405
|
+
const numEvents = this.point.events.length;
|
|
54406
|
+
for (let i3 = 0;i3 < numEvents; i3++) {
|
|
54407
|
+
const evt1 = this.point.events[i3];
|
|
54408
|
+
if (evt1.segment.consumedBy !== undefined)
|
|
54409
|
+
continue;
|
|
54410
|
+
for (let j4 = i3 + 1;j4 < numEvents; j4++) {
|
|
54411
|
+
const evt2 = this.point.events[j4];
|
|
54412
|
+
if (evt2.consumedBy !== undefined)
|
|
54413
|
+
continue;
|
|
54414
|
+
if (evt1.otherSE.point.events !== evt2.otherSE.point.events)
|
|
54415
|
+
continue;
|
|
54416
|
+
evt1.segment.consume(evt2.segment);
|
|
54417
|
+
}
|
|
54418
|
+
}
|
|
54419
|
+
}
|
|
54420
|
+
getAvailableLinkedEvents() {
|
|
54421
|
+
const events = [];
|
|
54422
|
+
for (let i3 = 0, iMax = this.point.events.length;i3 < iMax; i3++) {
|
|
54423
|
+
const evt = this.point.events[i3];
|
|
54424
|
+
if (evt !== this && !evt.segment.ringOut && evt.segment.isInResult()) {
|
|
54425
|
+
events.push(evt);
|
|
54426
|
+
}
|
|
54427
|
+
}
|
|
54428
|
+
return events;
|
|
54429
|
+
}
|
|
54430
|
+
getLeftmostComparator(baseEvent) {
|
|
54431
|
+
const cache = new Map;
|
|
54432
|
+
const fillCache = (linkedEvent) => {
|
|
54433
|
+
const nextEvent = linkedEvent.otherSE;
|
|
54434
|
+
cache.set(linkedEvent, {
|
|
54435
|
+
sine: sineOfAngle(this.point, baseEvent.point, nextEvent.point),
|
|
54436
|
+
cosine: cosineOfAngle(this.point, baseEvent.point, nextEvent.point)
|
|
54437
|
+
});
|
|
54438
|
+
};
|
|
54439
|
+
return (a3, b3) => {
|
|
54440
|
+
if (!cache.has(a3))
|
|
54441
|
+
fillCache(a3);
|
|
54442
|
+
if (!cache.has(b3))
|
|
54443
|
+
fillCache(b3);
|
|
54444
|
+
const {
|
|
54445
|
+
sine: asine,
|
|
54446
|
+
cosine: acosine
|
|
54447
|
+
} = cache.get(a3);
|
|
54448
|
+
const {
|
|
54449
|
+
sine: bsine,
|
|
54450
|
+
cosine: bcosine
|
|
54451
|
+
} = cache.get(b3);
|
|
54452
|
+
if (asine >= 0 && bsine >= 0) {
|
|
54453
|
+
if (acosine < bcosine)
|
|
54454
|
+
return 1;
|
|
54455
|
+
if (acosine > bcosine)
|
|
54456
|
+
return -1;
|
|
54457
|
+
return 0;
|
|
54458
|
+
}
|
|
54459
|
+
if (asine < 0 && bsine < 0) {
|
|
54460
|
+
if (acosine < bcosine)
|
|
54461
|
+
return -1;
|
|
54462
|
+
if (acosine > bcosine)
|
|
54463
|
+
return 1;
|
|
54464
|
+
return 0;
|
|
54465
|
+
}
|
|
54466
|
+
if (bsine < asine)
|
|
54467
|
+
return -1;
|
|
54468
|
+
if (bsine > asine)
|
|
54469
|
+
return 1;
|
|
54470
|
+
return 0;
|
|
54471
|
+
};
|
|
54472
|
+
}
|
|
54473
|
+
}
|
|
54474
|
+
var segmentId = 0;
|
|
54475
|
+
|
|
54476
|
+
class Segment3 {
|
|
54477
|
+
static compare(a3, b3) {
|
|
54478
|
+
const alx = a3.leftSE.point.x;
|
|
54479
|
+
const blx = b3.leftSE.point.x;
|
|
54480
|
+
const arx = a3.rightSE.point.x;
|
|
54481
|
+
const brx = b3.rightSE.point.x;
|
|
54482
|
+
if (brx < alx)
|
|
54483
|
+
return 1;
|
|
54484
|
+
if (arx < blx)
|
|
54485
|
+
return -1;
|
|
54486
|
+
const aly = a3.leftSE.point.y;
|
|
54487
|
+
const bly = b3.leftSE.point.y;
|
|
54488
|
+
const ary = a3.rightSE.point.y;
|
|
54489
|
+
const bry = b3.rightSE.point.y;
|
|
54490
|
+
if (alx < blx) {
|
|
54491
|
+
if (bly < aly && bly < ary)
|
|
54492
|
+
return 1;
|
|
54493
|
+
if (bly > aly && bly > ary)
|
|
54494
|
+
return -1;
|
|
54495
|
+
const aCmpBLeft = a3.comparePoint(b3.leftSE.point);
|
|
54496
|
+
if (aCmpBLeft < 0)
|
|
54497
|
+
return 1;
|
|
54498
|
+
if (aCmpBLeft > 0)
|
|
54499
|
+
return -1;
|
|
54500
|
+
const bCmpARight = b3.comparePoint(a3.rightSE.point);
|
|
54501
|
+
if (bCmpARight !== 0)
|
|
54502
|
+
return bCmpARight;
|
|
54503
|
+
return -1;
|
|
54504
|
+
}
|
|
54505
|
+
if (alx > blx) {
|
|
54506
|
+
if (aly < bly && aly < bry)
|
|
54507
|
+
return -1;
|
|
54508
|
+
if (aly > bly && aly > bry)
|
|
54509
|
+
return 1;
|
|
54510
|
+
const bCmpALeft = b3.comparePoint(a3.leftSE.point);
|
|
54511
|
+
if (bCmpALeft !== 0)
|
|
54512
|
+
return bCmpALeft;
|
|
54513
|
+
const aCmpBRight = a3.comparePoint(b3.rightSE.point);
|
|
54514
|
+
if (aCmpBRight < 0)
|
|
54515
|
+
return 1;
|
|
54516
|
+
if (aCmpBRight > 0)
|
|
54517
|
+
return -1;
|
|
54518
|
+
return 1;
|
|
54519
|
+
}
|
|
54520
|
+
if (aly < bly)
|
|
54521
|
+
return -1;
|
|
54522
|
+
if (aly > bly)
|
|
54523
|
+
return 1;
|
|
54524
|
+
if (arx < brx) {
|
|
54525
|
+
const bCmpARight = b3.comparePoint(a3.rightSE.point);
|
|
54526
|
+
if (bCmpARight !== 0)
|
|
54527
|
+
return bCmpARight;
|
|
54528
|
+
}
|
|
54529
|
+
if (arx > brx) {
|
|
54530
|
+
const aCmpBRight = a3.comparePoint(b3.rightSE.point);
|
|
54531
|
+
if (aCmpBRight < 0)
|
|
54532
|
+
return 1;
|
|
54533
|
+
if (aCmpBRight > 0)
|
|
54534
|
+
return -1;
|
|
54535
|
+
}
|
|
54536
|
+
if (arx !== brx) {
|
|
54537
|
+
const ay3 = ary - aly;
|
|
54538
|
+
const ax3 = arx - alx;
|
|
54539
|
+
const by3 = bry - bly;
|
|
54540
|
+
const bx3 = brx - blx;
|
|
54541
|
+
if (ay3 > ax3 && by3 < bx3)
|
|
54542
|
+
return 1;
|
|
54543
|
+
if (ay3 < ax3 && by3 > bx3)
|
|
54544
|
+
return -1;
|
|
54545
|
+
}
|
|
54546
|
+
if (arx > brx)
|
|
54547
|
+
return 1;
|
|
54548
|
+
if (arx < brx)
|
|
54549
|
+
return -1;
|
|
54550
|
+
if (ary < bry)
|
|
54551
|
+
return -1;
|
|
54552
|
+
if (ary > bry)
|
|
54553
|
+
return 1;
|
|
54554
|
+
if (a3.id < b3.id)
|
|
54555
|
+
return -1;
|
|
54556
|
+
if (a3.id > b3.id)
|
|
54557
|
+
return 1;
|
|
54558
|
+
return 0;
|
|
54559
|
+
}
|
|
54560
|
+
constructor(leftSE, rightSE, rings, windings) {
|
|
54561
|
+
this.id = ++segmentId;
|
|
54562
|
+
this.leftSE = leftSE;
|
|
54563
|
+
leftSE.segment = this;
|
|
54564
|
+
leftSE.otherSE = rightSE;
|
|
54565
|
+
this.rightSE = rightSE;
|
|
54566
|
+
rightSE.segment = this;
|
|
54567
|
+
rightSE.otherSE = leftSE;
|
|
54568
|
+
this.rings = rings;
|
|
54569
|
+
this.windings = windings;
|
|
54570
|
+
}
|
|
54571
|
+
static fromRing(pt1, pt22, ring) {
|
|
54572
|
+
let leftPt, rightPt, winding;
|
|
54573
|
+
const cmpPts = SweepEvent.comparePoints(pt1, pt22);
|
|
54574
|
+
if (cmpPts < 0) {
|
|
54575
|
+
leftPt = pt1;
|
|
54576
|
+
rightPt = pt22;
|
|
54577
|
+
winding = 1;
|
|
54578
|
+
} else if (cmpPts > 0) {
|
|
54579
|
+
leftPt = pt22;
|
|
54580
|
+
rightPt = pt1;
|
|
54581
|
+
winding = -1;
|
|
54582
|
+
} else
|
|
54583
|
+
throw new Error(`Tried to create degenerate segment at [${pt1.x}, ${pt1.y}]`);
|
|
54584
|
+
const leftSE = new SweepEvent(leftPt, true);
|
|
54585
|
+
const rightSE = new SweepEvent(rightPt, false);
|
|
54586
|
+
return new Segment3(leftSE, rightSE, [ring], [winding]);
|
|
54587
|
+
}
|
|
54588
|
+
replaceRightSE(newRightSE) {
|
|
54589
|
+
this.rightSE = newRightSE;
|
|
54590
|
+
this.rightSE.segment = this;
|
|
54591
|
+
this.rightSE.otherSE = this.leftSE;
|
|
54592
|
+
this.leftSE.otherSE = this.rightSE;
|
|
54593
|
+
}
|
|
54594
|
+
bbox() {
|
|
54595
|
+
const y12 = this.leftSE.point.y;
|
|
54596
|
+
const y22 = this.rightSE.point.y;
|
|
54597
|
+
return {
|
|
54598
|
+
ll: {
|
|
54599
|
+
x: this.leftSE.point.x,
|
|
54600
|
+
y: y12 < y22 ? y12 : y22
|
|
54601
|
+
},
|
|
54602
|
+
ur: {
|
|
54603
|
+
x: this.rightSE.point.x,
|
|
54604
|
+
y: y12 > y22 ? y12 : y22
|
|
54605
|
+
}
|
|
54606
|
+
};
|
|
54607
|
+
}
|
|
54608
|
+
vector() {
|
|
54609
|
+
return {
|
|
54610
|
+
x: this.rightSE.point.x - this.leftSE.point.x,
|
|
54611
|
+
y: this.rightSE.point.y - this.leftSE.point.y
|
|
54612
|
+
};
|
|
54613
|
+
}
|
|
54614
|
+
isAnEndpoint(pt3) {
|
|
54615
|
+
return pt3.x === this.leftSE.point.x && pt3.y === this.leftSE.point.y || pt3.x === this.rightSE.point.x && pt3.y === this.rightSE.point.y;
|
|
54616
|
+
}
|
|
54617
|
+
comparePoint(point9) {
|
|
54618
|
+
if (this.isAnEndpoint(point9))
|
|
54619
|
+
return 0;
|
|
54620
|
+
const lPt = this.leftSE.point;
|
|
54621
|
+
const rPt = this.rightSE.point;
|
|
54622
|
+
const v4 = this.vector();
|
|
54623
|
+
if (lPt.x === rPt.x) {
|
|
54624
|
+
if (point9.x === lPt.x)
|
|
54625
|
+
return 0;
|
|
54626
|
+
return point9.x < lPt.x ? 1 : -1;
|
|
54627
|
+
}
|
|
54628
|
+
const yDist = (point9.y - lPt.y) / v4.y;
|
|
54629
|
+
const xFromYDist = lPt.x + yDist * v4.x;
|
|
54630
|
+
if (point9.x === xFromYDist)
|
|
54631
|
+
return 0;
|
|
54632
|
+
const xDist = (point9.x - lPt.x) / v4.x;
|
|
54633
|
+
const yFromXDist = lPt.y + xDist * v4.y;
|
|
54634
|
+
if (point9.y === yFromXDist)
|
|
54635
|
+
return 0;
|
|
54636
|
+
return point9.y < yFromXDist ? -1 : 1;
|
|
54637
|
+
}
|
|
54638
|
+
getIntersection(other) {
|
|
54639
|
+
const tBbox = this.bbox();
|
|
54640
|
+
const oBbox = other.bbox();
|
|
54641
|
+
const bboxOverlap = getBboxOverlap(tBbox, oBbox);
|
|
54642
|
+
if (bboxOverlap === null)
|
|
54643
|
+
return null;
|
|
54644
|
+
const tlp = this.leftSE.point;
|
|
54645
|
+
const trp = this.rightSE.point;
|
|
54646
|
+
const olp = other.leftSE.point;
|
|
54647
|
+
const orp = other.rightSE.point;
|
|
54648
|
+
const touchesOtherLSE = isInBbox(tBbox, olp) && this.comparePoint(olp) === 0;
|
|
54649
|
+
const touchesThisLSE = isInBbox(oBbox, tlp) && other.comparePoint(tlp) === 0;
|
|
54650
|
+
const touchesOtherRSE = isInBbox(tBbox, orp) && this.comparePoint(orp) === 0;
|
|
54651
|
+
const touchesThisRSE = isInBbox(oBbox, trp) && other.comparePoint(trp) === 0;
|
|
54652
|
+
if (touchesThisLSE && touchesOtherLSE) {
|
|
54653
|
+
if (touchesThisRSE && !touchesOtherRSE)
|
|
54654
|
+
return trp;
|
|
54655
|
+
if (!touchesThisRSE && touchesOtherRSE)
|
|
54656
|
+
return orp;
|
|
54657
|
+
return null;
|
|
54658
|
+
}
|
|
54659
|
+
if (touchesThisLSE) {
|
|
54660
|
+
if (touchesOtherRSE) {
|
|
54661
|
+
if (tlp.x === orp.x && tlp.y === orp.y)
|
|
54662
|
+
return null;
|
|
54663
|
+
}
|
|
54664
|
+
return tlp;
|
|
54665
|
+
}
|
|
54666
|
+
if (touchesOtherLSE) {
|
|
54667
|
+
if (touchesThisRSE) {
|
|
54668
|
+
if (trp.x === olp.x && trp.y === olp.y)
|
|
54669
|
+
return null;
|
|
54670
|
+
}
|
|
54671
|
+
return olp;
|
|
54672
|
+
}
|
|
54673
|
+
if (touchesThisRSE && touchesOtherRSE)
|
|
54674
|
+
return null;
|
|
54675
|
+
if (touchesThisRSE)
|
|
54676
|
+
return trp;
|
|
54677
|
+
if (touchesOtherRSE)
|
|
54678
|
+
return orp;
|
|
54679
|
+
const pt3 = intersection$1(tlp, this.vector(), olp, other.vector());
|
|
54680
|
+
if (pt3 === null)
|
|
54681
|
+
return null;
|
|
54682
|
+
if (!isInBbox(bboxOverlap, pt3))
|
|
54683
|
+
return null;
|
|
54684
|
+
return rounder.round(pt3.x, pt3.y);
|
|
54685
|
+
}
|
|
54686
|
+
split(point9) {
|
|
54687
|
+
const newEvents = [];
|
|
54688
|
+
const alreadyLinked = point9.events !== undefined;
|
|
54689
|
+
const newLeftSE = new SweepEvent(point9, true);
|
|
54690
|
+
const newRightSE = new SweepEvent(point9, false);
|
|
54691
|
+
const oldRightSE = this.rightSE;
|
|
54692
|
+
this.replaceRightSE(newRightSE);
|
|
54693
|
+
newEvents.push(newRightSE);
|
|
54694
|
+
newEvents.push(newLeftSE);
|
|
54695
|
+
const newSeg = new Segment3(newLeftSE, oldRightSE, this.rings.slice(), this.windings.slice());
|
|
54696
|
+
if (SweepEvent.comparePoints(newSeg.leftSE.point, newSeg.rightSE.point) > 0) {
|
|
54697
|
+
newSeg.swapEvents();
|
|
54698
|
+
}
|
|
54699
|
+
if (SweepEvent.comparePoints(this.leftSE.point, this.rightSE.point) > 0) {
|
|
54700
|
+
this.swapEvents();
|
|
54701
|
+
}
|
|
54702
|
+
if (alreadyLinked) {
|
|
54703
|
+
newLeftSE.checkForConsuming();
|
|
54704
|
+
newRightSE.checkForConsuming();
|
|
54705
|
+
}
|
|
54706
|
+
return newEvents;
|
|
54707
|
+
}
|
|
54708
|
+
swapEvents() {
|
|
54709
|
+
const tmpEvt = this.rightSE;
|
|
54710
|
+
this.rightSE = this.leftSE;
|
|
54711
|
+
this.leftSE = tmpEvt;
|
|
54712
|
+
this.leftSE.isLeft = true;
|
|
54713
|
+
this.rightSE.isLeft = false;
|
|
54714
|
+
for (let i3 = 0, iMax = this.windings.length;i3 < iMax; i3++) {
|
|
54715
|
+
this.windings[i3] *= -1;
|
|
54716
|
+
}
|
|
54717
|
+
}
|
|
54718
|
+
consume(other) {
|
|
54719
|
+
let consumer = this;
|
|
54720
|
+
let consumee = other;
|
|
54721
|
+
while (consumer.consumedBy)
|
|
54722
|
+
consumer = consumer.consumedBy;
|
|
54723
|
+
while (consumee.consumedBy)
|
|
54724
|
+
consumee = consumee.consumedBy;
|
|
54725
|
+
const cmp2 = Segment3.compare(consumer, consumee);
|
|
54726
|
+
if (cmp2 === 0)
|
|
54727
|
+
return;
|
|
54728
|
+
if (cmp2 > 0) {
|
|
54729
|
+
const tmp = consumer;
|
|
54730
|
+
consumer = consumee;
|
|
54731
|
+
consumee = tmp;
|
|
54732
|
+
}
|
|
54733
|
+
if (consumer.prev === consumee) {
|
|
54734
|
+
const tmp = consumer;
|
|
54735
|
+
consumer = consumee;
|
|
54736
|
+
consumee = tmp;
|
|
54737
|
+
}
|
|
54738
|
+
for (let i3 = 0, iMax = consumee.rings.length;i3 < iMax; i3++) {
|
|
54739
|
+
const ring = consumee.rings[i3];
|
|
54740
|
+
const winding = consumee.windings[i3];
|
|
54741
|
+
const index2 = consumer.rings.indexOf(ring);
|
|
54742
|
+
if (index2 === -1) {
|
|
54743
|
+
consumer.rings.push(ring);
|
|
54744
|
+
consumer.windings.push(winding);
|
|
54745
|
+
} else
|
|
54746
|
+
consumer.windings[index2] += winding;
|
|
54747
|
+
}
|
|
54748
|
+
consumee.rings = null;
|
|
54749
|
+
consumee.windings = null;
|
|
54750
|
+
consumee.consumedBy = consumer;
|
|
54751
|
+
consumee.leftSE.consumedBy = consumer.leftSE;
|
|
54752
|
+
consumee.rightSE.consumedBy = consumer.rightSE;
|
|
54753
|
+
}
|
|
54754
|
+
prevInResult() {
|
|
54755
|
+
if (this._prevInResult !== undefined)
|
|
54756
|
+
return this._prevInResult;
|
|
54757
|
+
if (!this.prev)
|
|
54758
|
+
this._prevInResult = null;
|
|
54759
|
+
else if (this.prev.isInResult())
|
|
54760
|
+
this._prevInResult = this.prev;
|
|
54761
|
+
else
|
|
54762
|
+
this._prevInResult = this.prev.prevInResult();
|
|
54763
|
+
return this._prevInResult;
|
|
54764
|
+
}
|
|
54765
|
+
beforeState() {
|
|
54766
|
+
if (this._beforeState !== undefined)
|
|
54767
|
+
return this._beforeState;
|
|
54768
|
+
if (!this.prev)
|
|
54769
|
+
this._beforeState = {
|
|
54770
|
+
rings: [],
|
|
54771
|
+
windings: [],
|
|
54772
|
+
multiPolys: []
|
|
54773
|
+
};
|
|
54774
|
+
else {
|
|
54775
|
+
const seg = this.prev.consumedBy || this.prev;
|
|
54776
|
+
this._beforeState = seg.afterState();
|
|
54777
|
+
}
|
|
54778
|
+
return this._beforeState;
|
|
54779
|
+
}
|
|
54780
|
+
afterState() {
|
|
54781
|
+
if (this._afterState !== undefined)
|
|
54782
|
+
return this._afterState;
|
|
54783
|
+
const beforeState = this.beforeState();
|
|
54784
|
+
this._afterState = {
|
|
54785
|
+
rings: beforeState.rings.slice(0),
|
|
54786
|
+
windings: beforeState.windings.slice(0),
|
|
54787
|
+
multiPolys: []
|
|
54788
|
+
};
|
|
54789
|
+
const ringsAfter = this._afterState.rings;
|
|
54790
|
+
const windingsAfter = this._afterState.windings;
|
|
54791
|
+
const mpsAfter = this._afterState.multiPolys;
|
|
54792
|
+
for (let i3 = 0, iMax = this.rings.length;i3 < iMax; i3++) {
|
|
54793
|
+
const ring = this.rings[i3];
|
|
54794
|
+
const winding = this.windings[i3];
|
|
54795
|
+
const index2 = ringsAfter.indexOf(ring);
|
|
54796
|
+
if (index2 === -1) {
|
|
54797
|
+
ringsAfter.push(ring);
|
|
54798
|
+
windingsAfter.push(winding);
|
|
54799
|
+
} else
|
|
54800
|
+
windingsAfter[index2] += winding;
|
|
54801
|
+
}
|
|
54802
|
+
const polysAfter = [];
|
|
54803
|
+
const polysExclude = [];
|
|
54804
|
+
for (let i3 = 0, iMax = ringsAfter.length;i3 < iMax; i3++) {
|
|
54805
|
+
if (windingsAfter[i3] === 0)
|
|
54806
|
+
continue;
|
|
54807
|
+
const ring = ringsAfter[i3];
|
|
54808
|
+
const poly = ring.poly;
|
|
54809
|
+
if (polysExclude.indexOf(poly) !== -1)
|
|
54810
|
+
continue;
|
|
54811
|
+
if (ring.isExterior)
|
|
54812
|
+
polysAfter.push(poly);
|
|
54813
|
+
else {
|
|
54814
|
+
if (polysExclude.indexOf(poly) === -1)
|
|
54815
|
+
polysExclude.push(poly);
|
|
54816
|
+
const index2 = polysAfter.indexOf(ring.poly);
|
|
54817
|
+
if (index2 !== -1)
|
|
54818
|
+
polysAfter.splice(index2, 1);
|
|
54819
|
+
}
|
|
54820
|
+
}
|
|
54821
|
+
for (let i3 = 0, iMax = polysAfter.length;i3 < iMax; i3++) {
|
|
54822
|
+
const mp3 = polysAfter[i3].multiPoly;
|
|
54823
|
+
if (mpsAfter.indexOf(mp3) === -1)
|
|
54824
|
+
mpsAfter.push(mp3);
|
|
54825
|
+
}
|
|
54826
|
+
return this._afterState;
|
|
54827
|
+
}
|
|
54828
|
+
isInResult() {
|
|
54829
|
+
if (this.consumedBy)
|
|
54830
|
+
return false;
|
|
54831
|
+
if (this._isInResult !== undefined)
|
|
54832
|
+
return this._isInResult;
|
|
54833
|
+
const mpsBefore = this.beforeState().multiPolys;
|
|
54834
|
+
const mpsAfter = this.afterState().multiPolys;
|
|
54835
|
+
switch (operation.type) {
|
|
54836
|
+
case "union": {
|
|
54837
|
+
const noBefores = mpsBefore.length === 0;
|
|
54838
|
+
const noAfters = mpsAfter.length === 0;
|
|
54839
|
+
this._isInResult = noBefores !== noAfters;
|
|
54840
|
+
break;
|
|
54841
|
+
}
|
|
54842
|
+
case "intersection": {
|
|
54843
|
+
let least;
|
|
54844
|
+
let most;
|
|
54845
|
+
if (mpsBefore.length < mpsAfter.length) {
|
|
54846
|
+
least = mpsBefore.length;
|
|
54847
|
+
most = mpsAfter.length;
|
|
54848
|
+
} else {
|
|
54849
|
+
least = mpsAfter.length;
|
|
54850
|
+
most = mpsBefore.length;
|
|
54851
|
+
}
|
|
54852
|
+
this._isInResult = most === operation.numMultiPolys && least < most;
|
|
54853
|
+
break;
|
|
54854
|
+
}
|
|
54855
|
+
case "xor": {
|
|
54856
|
+
const diff = Math.abs(mpsBefore.length - mpsAfter.length);
|
|
54857
|
+
this._isInResult = diff % 2 === 1;
|
|
54858
|
+
break;
|
|
54859
|
+
}
|
|
54860
|
+
case "difference": {
|
|
54861
|
+
const isJustSubject = (mps) => mps.length === 1 && mps[0].isSubject;
|
|
54862
|
+
this._isInResult = isJustSubject(mpsBefore) !== isJustSubject(mpsAfter);
|
|
54863
|
+
break;
|
|
54864
|
+
}
|
|
54865
|
+
default:
|
|
54866
|
+
throw new Error(`Unrecognized operation type found ${operation.type}`);
|
|
54867
|
+
}
|
|
54868
|
+
return this._isInResult;
|
|
54869
|
+
}
|
|
54870
|
+
}
|
|
54871
|
+
|
|
54872
|
+
class RingIn {
|
|
54873
|
+
constructor(geomRing, poly, isExterior) {
|
|
54874
|
+
if (!Array.isArray(geomRing) || geomRing.length === 0) {
|
|
54875
|
+
throw new Error("Input geometry is not a valid Polygon or MultiPolygon");
|
|
54876
|
+
}
|
|
54877
|
+
this.poly = poly;
|
|
54878
|
+
this.isExterior = isExterior;
|
|
54879
|
+
this.segments = [];
|
|
54880
|
+
if (typeof geomRing[0][0] !== "number" || typeof geomRing[0][1] !== "number") {
|
|
54881
|
+
throw new Error("Input geometry is not a valid Polygon or MultiPolygon");
|
|
54882
|
+
}
|
|
54883
|
+
const firstPoint = rounder.round(geomRing[0][0], geomRing[0][1]);
|
|
54884
|
+
this.bbox = {
|
|
54885
|
+
ll: {
|
|
54886
|
+
x: firstPoint.x,
|
|
54887
|
+
y: firstPoint.y
|
|
54888
|
+
},
|
|
54889
|
+
ur: {
|
|
54890
|
+
x: firstPoint.x,
|
|
54891
|
+
y: firstPoint.y
|
|
54892
|
+
}
|
|
54893
|
+
};
|
|
54894
|
+
let prevPoint = firstPoint;
|
|
54895
|
+
for (let i3 = 1, iMax = geomRing.length;i3 < iMax; i3++) {
|
|
54896
|
+
if (typeof geomRing[i3][0] !== "number" || typeof geomRing[i3][1] !== "number") {
|
|
54897
|
+
throw new Error("Input geometry is not a valid Polygon or MultiPolygon");
|
|
54898
|
+
}
|
|
54899
|
+
let point9 = rounder.round(geomRing[i3][0], geomRing[i3][1]);
|
|
54900
|
+
if (point9.x === prevPoint.x && point9.y === prevPoint.y)
|
|
54901
|
+
continue;
|
|
54902
|
+
this.segments.push(Segment3.fromRing(prevPoint, point9, this));
|
|
54903
|
+
if (point9.x < this.bbox.ll.x)
|
|
54904
|
+
this.bbox.ll.x = point9.x;
|
|
54905
|
+
if (point9.y < this.bbox.ll.y)
|
|
54906
|
+
this.bbox.ll.y = point9.y;
|
|
54907
|
+
if (point9.x > this.bbox.ur.x)
|
|
54908
|
+
this.bbox.ur.x = point9.x;
|
|
54909
|
+
if (point9.y > this.bbox.ur.y)
|
|
54910
|
+
this.bbox.ur.y = point9.y;
|
|
54911
|
+
prevPoint = point9;
|
|
54912
|
+
}
|
|
54913
|
+
if (firstPoint.x !== prevPoint.x || firstPoint.y !== prevPoint.y) {
|
|
54914
|
+
this.segments.push(Segment3.fromRing(prevPoint, firstPoint, this));
|
|
54915
|
+
}
|
|
54916
|
+
}
|
|
54917
|
+
getSweepEvents() {
|
|
54918
|
+
const sweepEvents = [];
|
|
54919
|
+
for (let i3 = 0, iMax = this.segments.length;i3 < iMax; i3++) {
|
|
54920
|
+
const segment2 = this.segments[i3];
|
|
54921
|
+
sweepEvents.push(segment2.leftSE);
|
|
54922
|
+
sweepEvents.push(segment2.rightSE);
|
|
54923
|
+
}
|
|
54924
|
+
return sweepEvents;
|
|
54925
|
+
}
|
|
54926
|
+
}
|
|
54927
|
+
|
|
54928
|
+
class PolyIn {
|
|
54929
|
+
constructor(geomPoly, multiPoly) {
|
|
54930
|
+
if (!Array.isArray(geomPoly)) {
|
|
54931
|
+
throw new Error("Input geometry is not a valid Polygon or MultiPolygon");
|
|
54932
|
+
}
|
|
54933
|
+
this.exteriorRing = new RingIn(geomPoly[0], this, true);
|
|
54934
|
+
this.bbox = {
|
|
54935
|
+
ll: {
|
|
54936
|
+
x: this.exteriorRing.bbox.ll.x,
|
|
54937
|
+
y: this.exteriorRing.bbox.ll.y
|
|
54938
|
+
},
|
|
54939
|
+
ur: {
|
|
54940
|
+
x: this.exteriorRing.bbox.ur.x,
|
|
54941
|
+
y: this.exteriorRing.bbox.ur.y
|
|
54942
|
+
}
|
|
54943
|
+
};
|
|
54944
|
+
this.interiorRings = [];
|
|
54945
|
+
for (let i3 = 1, iMax = geomPoly.length;i3 < iMax; i3++) {
|
|
54946
|
+
const ring = new RingIn(geomPoly[i3], this, false);
|
|
54947
|
+
if (ring.bbox.ll.x < this.bbox.ll.x)
|
|
54948
|
+
this.bbox.ll.x = ring.bbox.ll.x;
|
|
54949
|
+
if (ring.bbox.ll.y < this.bbox.ll.y)
|
|
54950
|
+
this.bbox.ll.y = ring.bbox.ll.y;
|
|
54951
|
+
if (ring.bbox.ur.x > this.bbox.ur.x)
|
|
54952
|
+
this.bbox.ur.x = ring.bbox.ur.x;
|
|
54953
|
+
if (ring.bbox.ur.y > this.bbox.ur.y)
|
|
54954
|
+
this.bbox.ur.y = ring.bbox.ur.y;
|
|
54955
|
+
this.interiorRings.push(ring);
|
|
54956
|
+
}
|
|
54957
|
+
this.multiPoly = multiPoly;
|
|
54958
|
+
}
|
|
54959
|
+
getSweepEvents() {
|
|
54960
|
+
const sweepEvents = this.exteriorRing.getSweepEvents();
|
|
54961
|
+
for (let i3 = 0, iMax = this.interiorRings.length;i3 < iMax; i3++) {
|
|
54962
|
+
const ringSweepEvents = this.interiorRings[i3].getSweepEvents();
|
|
54963
|
+
for (let j4 = 0, jMax = ringSweepEvents.length;j4 < jMax; j4++) {
|
|
54964
|
+
sweepEvents.push(ringSweepEvents[j4]);
|
|
54965
|
+
}
|
|
54966
|
+
}
|
|
54967
|
+
return sweepEvents;
|
|
54968
|
+
}
|
|
54969
|
+
}
|
|
54970
|
+
|
|
54971
|
+
class MultiPolyIn {
|
|
54972
|
+
constructor(geom, isSubject) {
|
|
54973
|
+
if (!Array.isArray(geom)) {
|
|
54974
|
+
throw new Error("Input geometry is not a valid Polygon or MultiPolygon");
|
|
54975
|
+
}
|
|
54976
|
+
try {
|
|
54977
|
+
if (typeof geom[0][0][0] === "number")
|
|
54978
|
+
geom = [geom];
|
|
54979
|
+
} catch (ex3) {}
|
|
54980
|
+
this.polys = [];
|
|
54981
|
+
this.bbox = {
|
|
54982
|
+
ll: {
|
|
54983
|
+
x: Number.POSITIVE_INFINITY,
|
|
54984
|
+
y: Number.POSITIVE_INFINITY
|
|
54985
|
+
},
|
|
54986
|
+
ur: {
|
|
54987
|
+
x: Number.NEGATIVE_INFINITY,
|
|
54988
|
+
y: Number.NEGATIVE_INFINITY
|
|
54989
|
+
}
|
|
54990
|
+
};
|
|
54991
|
+
for (let i3 = 0, iMax = geom.length;i3 < iMax; i3++) {
|
|
54992
|
+
const poly = new PolyIn(geom[i3], this);
|
|
54993
|
+
if (poly.bbox.ll.x < this.bbox.ll.x)
|
|
54994
|
+
this.bbox.ll.x = poly.bbox.ll.x;
|
|
54995
|
+
if (poly.bbox.ll.y < this.bbox.ll.y)
|
|
54996
|
+
this.bbox.ll.y = poly.bbox.ll.y;
|
|
54997
|
+
if (poly.bbox.ur.x > this.bbox.ur.x)
|
|
54998
|
+
this.bbox.ur.x = poly.bbox.ur.x;
|
|
54999
|
+
if (poly.bbox.ur.y > this.bbox.ur.y)
|
|
55000
|
+
this.bbox.ur.y = poly.bbox.ur.y;
|
|
55001
|
+
this.polys.push(poly);
|
|
55002
|
+
}
|
|
55003
|
+
this.isSubject = isSubject;
|
|
55004
|
+
}
|
|
55005
|
+
getSweepEvents() {
|
|
55006
|
+
const sweepEvents = [];
|
|
55007
|
+
for (let i3 = 0, iMax = this.polys.length;i3 < iMax; i3++) {
|
|
55008
|
+
const polySweepEvents = this.polys[i3].getSweepEvents();
|
|
55009
|
+
for (let j4 = 0, jMax = polySweepEvents.length;j4 < jMax; j4++) {
|
|
55010
|
+
sweepEvents.push(polySweepEvents[j4]);
|
|
55011
|
+
}
|
|
55012
|
+
}
|
|
55013
|
+
return sweepEvents;
|
|
55014
|
+
}
|
|
55015
|
+
}
|
|
55016
|
+
|
|
55017
|
+
class RingOut {
|
|
55018
|
+
static factory(allSegments) {
|
|
55019
|
+
const ringsOut = [];
|
|
55020
|
+
for (let i3 = 0, iMax = allSegments.length;i3 < iMax; i3++) {
|
|
55021
|
+
const segment2 = allSegments[i3];
|
|
55022
|
+
if (!segment2.isInResult() || segment2.ringOut)
|
|
55023
|
+
continue;
|
|
55024
|
+
let prevEvent = null;
|
|
55025
|
+
let event = segment2.leftSE;
|
|
55026
|
+
let nextEvent = segment2.rightSE;
|
|
55027
|
+
const events = [event];
|
|
55028
|
+
const startingPoint = event.point;
|
|
55029
|
+
const intersectionLEs = [];
|
|
55030
|
+
while (true) {
|
|
55031
|
+
prevEvent = event;
|
|
55032
|
+
event = nextEvent;
|
|
55033
|
+
events.push(event);
|
|
55034
|
+
if (event.point === startingPoint)
|
|
55035
|
+
break;
|
|
55036
|
+
while (true) {
|
|
55037
|
+
const availableLEs = event.getAvailableLinkedEvents();
|
|
55038
|
+
if (availableLEs.length === 0) {
|
|
55039
|
+
const firstPt = events[0].point;
|
|
55040
|
+
const lastPt = events[events.length - 1].point;
|
|
55041
|
+
throw new Error(`Unable to complete output ring starting at [${firstPt.x},` + ` ${firstPt.y}]. Last matching segment found ends at` + ` [${lastPt.x}, ${lastPt.y}].`);
|
|
55042
|
+
}
|
|
55043
|
+
if (availableLEs.length === 1) {
|
|
55044
|
+
nextEvent = availableLEs[0].otherSE;
|
|
55045
|
+
break;
|
|
55046
|
+
}
|
|
55047
|
+
let indexLE = null;
|
|
55048
|
+
for (let j4 = 0, jMax = intersectionLEs.length;j4 < jMax; j4++) {
|
|
55049
|
+
if (intersectionLEs[j4].point === event.point) {
|
|
55050
|
+
indexLE = j4;
|
|
55051
|
+
break;
|
|
55052
|
+
}
|
|
55053
|
+
}
|
|
55054
|
+
if (indexLE !== null) {
|
|
55055
|
+
const intersectionLE = intersectionLEs.splice(indexLE)[0];
|
|
55056
|
+
const ringEvents = events.splice(intersectionLE.index);
|
|
55057
|
+
ringEvents.unshift(ringEvents[0].otherSE);
|
|
55058
|
+
ringsOut.push(new RingOut(ringEvents.reverse()));
|
|
55059
|
+
continue;
|
|
55060
|
+
}
|
|
55061
|
+
intersectionLEs.push({
|
|
55062
|
+
index: events.length,
|
|
55063
|
+
point: event.point
|
|
55064
|
+
});
|
|
55065
|
+
const comparator = event.getLeftmostComparator(prevEvent);
|
|
55066
|
+
nextEvent = availableLEs.sort(comparator)[0].otherSE;
|
|
55067
|
+
break;
|
|
55068
|
+
}
|
|
55069
|
+
}
|
|
55070
|
+
ringsOut.push(new RingOut(events));
|
|
55071
|
+
}
|
|
55072
|
+
return ringsOut;
|
|
55073
|
+
}
|
|
55074
|
+
constructor(events) {
|
|
55075
|
+
this.events = events;
|
|
55076
|
+
for (let i3 = 0, iMax = events.length;i3 < iMax; i3++) {
|
|
55077
|
+
events[i3].segment.ringOut = this;
|
|
55078
|
+
}
|
|
55079
|
+
this.poly = null;
|
|
55080
|
+
}
|
|
55081
|
+
getGeom() {
|
|
55082
|
+
let prevPt = this.events[0].point;
|
|
55083
|
+
const points = [prevPt];
|
|
55084
|
+
for (let i3 = 1, iMax = this.events.length - 1;i3 < iMax; i3++) {
|
|
55085
|
+
const pt4 = this.events[i3].point;
|
|
55086
|
+
const nextPt2 = this.events[i3 + 1].point;
|
|
55087
|
+
if (compareVectorAngles(pt4, prevPt, nextPt2) === 0)
|
|
55088
|
+
continue;
|
|
55089
|
+
points.push(pt4);
|
|
55090
|
+
prevPt = pt4;
|
|
55091
|
+
}
|
|
55092
|
+
if (points.length === 1)
|
|
55093
|
+
return null;
|
|
55094
|
+
const pt3 = points[0];
|
|
55095
|
+
const nextPt = points[1];
|
|
55096
|
+
if (compareVectorAngles(pt3, prevPt, nextPt) === 0)
|
|
55097
|
+
points.shift();
|
|
55098
|
+
points.push(points[0]);
|
|
55099
|
+
const step = this.isExteriorRing() ? 1 : -1;
|
|
55100
|
+
const iStart = this.isExteriorRing() ? 0 : points.length - 1;
|
|
55101
|
+
const iEnd = this.isExteriorRing() ? points.length : -1;
|
|
55102
|
+
const orderedPoints = [];
|
|
55103
|
+
for (let i3 = iStart;i3 != iEnd; i3 += step)
|
|
55104
|
+
orderedPoints.push([points[i3].x, points[i3].y]);
|
|
55105
|
+
return orderedPoints;
|
|
55106
|
+
}
|
|
55107
|
+
isExteriorRing() {
|
|
55108
|
+
if (this._isExteriorRing === undefined) {
|
|
55109
|
+
const enclosing = this.enclosingRing();
|
|
55110
|
+
this._isExteriorRing = enclosing ? !enclosing.isExteriorRing() : true;
|
|
55111
|
+
}
|
|
55112
|
+
return this._isExteriorRing;
|
|
55113
|
+
}
|
|
55114
|
+
enclosingRing() {
|
|
55115
|
+
if (this._enclosingRing === undefined) {
|
|
55116
|
+
this._enclosingRing = this._calcEnclosingRing();
|
|
55117
|
+
}
|
|
55118
|
+
return this._enclosingRing;
|
|
55119
|
+
}
|
|
55120
|
+
_calcEnclosingRing() {
|
|
55121
|
+
let leftMostEvt = this.events[0];
|
|
55122
|
+
for (let i3 = 1, iMax = this.events.length;i3 < iMax; i3++) {
|
|
55123
|
+
const evt = this.events[i3];
|
|
55124
|
+
if (SweepEvent.compare(leftMostEvt, evt) > 0)
|
|
55125
|
+
leftMostEvt = evt;
|
|
55126
|
+
}
|
|
55127
|
+
let prevSeg = leftMostEvt.segment.prevInResult();
|
|
55128
|
+
let prevPrevSeg = prevSeg ? prevSeg.prevInResult() : null;
|
|
55129
|
+
while (true) {
|
|
55130
|
+
if (!prevSeg)
|
|
55131
|
+
return null;
|
|
55132
|
+
if (!prevPrevSeg)
|
|
55133
|
+
return prevSeg.ringOut;
|
|
55134
|
+
if (prevPrevSeg.ringOut !== prevSeg.ringOut) {
|
|
55135
|
+
if (prevPrevSeg.ringOut.enclosingRing() !== prevSeg.ringOut) {
|
|
55136
|
+
return prevSeg.ringOut;
|
|
55137
|
+
} else
|
|
55138
|
+
return prevSeg.ringOut.enclosingRing();
|
|
55139
|
+
}
|
|
55140
|
+
prevSeg = prevPrevSeg.prevInResult();
|
|
55141
|
+
prevPrevSeg = prevSeg ? prevSeg.prevInResult() : null;
|
|
55142
|
+
}
|
|
55143
|
+
}
|
|
55144
|
+
}
|
|
55145
|
+
|
|
55146
|
+
class PolyOut {
|
|
55147
|
+
constructor(exteriorRing) {
|
|
55148
|
+
this.exteriorRing = exteriorRing;
|
|
55149
|
+
exteriorRing.poly = this;
|
|
55150
|
+
this.interiorRings = [];
|
|
55151
|
+
}
|
|
55152
|
+
addInterior(ring) {
|
|
55153
|
+
this.interiorRings.push(ring);
|
|
55154
|
+
ring.poly = this;
|
|
55155
|
+
}
|
|
55156
|
+
getGeom() {
|
|
55157
|
+
const geom = [this.exteriorRing.getGeom()];
|
|
55158
|
+
if (geom[0] === null)
|
|
55159
|
+
return null;
|
|
55160
|
+
for (let i3 = 0, iMax = this.interiorRings.length;i3 < iMax; i3++) {
|
|
55161
|
+
const ringGeom = this.interiorRings[i3].getGeom();
|
|
55162
|
+
if (ringGeom === null)
|
|
55163
|
+
continue;
|
|
55164
|
+
geom.push(ringGeom);
|
|
55165
|
+
}
|
|
55166
|
+
return geom;
|
|
55167
|
+
}
|
|
55168
|
+
}
|
|
55169
|
+
|
|
55170
|
+
class MultiPolyOut {
|
|
55171
|
+
constructor(rings) {
|
|
55172
|
+
this.rings = rings;
|
|
55173
|
+
this.polys = this._composePolys(rings);
|
|
55174
|
+
}
|
|
55175
|
+
getGeom() {
|
|
55176
|
+
const geom = [];
|
|
55177
|
+
for (let i3 = 0, iMax = this.polys.length;i3 < iMax; i3++) {
|
|
55178
|
+
const polyGeom = this.polys[i3].getGeom();
|
|
55179
|
+
if (polyGeom === null)
|
|
55180
|
+
continue;
|
|
55181
|
+
geom.push(polyGeom);
|
|
55182
|
+
}
|
|
55183
|
+
return geom;
|
|
55184
|
+
}
|
|
55185
|
+
_composePolys(rings) {
|
|
55186
|
+
const polys = [];
|
|
55187
|
+
for (let i3 = 0, iMax = rings.length;i3 < iMax; i3++) {
|
|
55188
|
+
const ring = rings[i3];
|
|
55189
|
+
if (ring.poly)
|
|
55190
|
+
continue;
|
|
55191
|
+
if (ring.isExteriorRing())
|
|
55192
|
+
polys.push(new PolyOut(ring));
|
|
55193
|
+
else {
|
|
55194
|
+
const enclosingRing = ring.enclosingRing();
|
|
55195
|
+
if (!enclosingRing.poly)
|
|
55196
|
+
polys.push(new PolyOut(enclosingRing));
|
|
55197
|
+
enclosingRing.poly.addInterior(ring);
|
|
55198
|
+
}
|
|
55199
|
+
}
|
|
55200
|
+
return polys;
|
|
55201
|
+
}
|
|
55202
|
+
}
|
|
55203
|
+
|
|
55204
|
+
class SweepLine {
|
|
55205
|
+
constructor(queue) {
|
|
55206
|
+
let comparator = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : Segment3.compare;
|
|
55207
|
+
this.queue = queue;
|
|
55208
|
+
this.tree = new SplayTree__default["default"](comparator);
|
|
55209
|
+
this.segments = [];
|
|
55210
|
+
}
|
|
55211
|
+
process(event) {
|
|
55212
|
+
const segment2 = event.segment;
|
|
55213
|
+
const newEvents = [];
|
|
55214
|
+
if (event.consumedBy) {
|
|
55215
|
+
if (event.isLeft)
|
|
55216
|
+
this.queue.remove(event.otherSE);
|
|
55217
|
+
else
|
|
55218
|
+
this.tree.remove(segment2);
|
|
55219
|
+
return newEvents;
|
|
55220
|
+
}
|
|
55221
|
+
const node = event.isLeft ? this.tree.add(segment2) : this.tree.find(segment2);
|
|
55222
|
+
if (!node)
|
|
55223
|
+
throw new Error(`Unable to find segment #${segment2.id} ` + `[${segment2.leftSE.point.x}, ${segment2.leftSE.point.y}] -> ` + `[${segment2.rightSE.point.x}, ${segment2.rightSE.point.y}] ` + "in SweepLine tree.");
|
|
55224
|
+
let prevNode = node;
|
|
55225
|
+
let nextNode = node;
|
|
55226
|
+
let prevSeg = undefined;
|
|
55227
|
+
let nextSeg = undefined;
|
|
55228
|
+
while (prevSeg === undefined) {
|
|
55229
|
+
prevNode = this.tree.prev(prevNode);
|
|
55230
|
+
if (prevNode === null)
|
|
55231
|
+
prevSeg = null;
|
|
55232
|
+
else if (prevNode.key.consumedBy === undefined)
|
|
55233
|
+
prevSeg = prevNode.key;
|
|
55234
|
+
}
|
|
55235
|
+
while (nextSeg === undefined) {
|
|
55236
|
+
nextNode = this.tree.next(nextNode);
|
|
55237
|
+
if (nextNode === null)
|
|
55238
|
+
nextSeg = null;
|
|
55239
|
+
else if (nextNode.key.consumedBy === undefined)
|
|
55240
|
+
nextSeg = nextNode.key;
|
|
55241
|
+
}
|
|
55242
|
+
if (event.isLeft) {
|
|
55243
|
+
let prevMySplitter = null;
|
|
55244
|
+
if (prevSeg) {
|
|
55245
|
+
const prevInter = prevSeg.getIntersection(segment2);
|
|
55246
|
+
if (prevInter !== null) {
|
|
55247
|
+
if (!segment2.isAnEndpoint(prevInter))
|
|
55248
|
+
prevMySplitter = prevInter;
|
|
55249
|
+
if (!prevSeg.isAnEndpoint(prevInter)) {
|
|
55250
|
+
const newEventsFromSplit = this._splitSafely(prevSeg, prevInter);
|
|
55251
|
+
for (let i3 = 0, iMax = newEventsFromSplit.length;i3 < iMax; i3++) {
|
|
55252
|
+
newEvents.push(newEventsFromSplit[i3]);
|
|
55253
|
+
}
|
|
55254
|
+
}
|
|
55255
|
+
}
|
|
55256
|
+
}
|
|
55257
|
+
let nextMySplitter = null;
|
|
55258
|
+
if (nextSeg) {
|
|
55259
|
+
const nextInter = nextSeg.getIntersection(segment2);
|
|
55260
|
+
if (nextInter !== null) {
|
|
55261
|
+
if (!segment2.isAnEndpoint(nextInter))
|
|
55262
|
+
nextMySplitter = nextInter;
|
|
55263
|
+
if (!nextSeg.isAnEndpoint(nextInter)) {
|
|
55264
|
+
const newEventsFromSplit = this._splitSafely(nextSeg, nextInter);
|
|
55265
|
+
for (let i3 = 0, iMax = newEventsFromSplit.length;i3 < iMax; i3++) {
|
|
55266
|
+
newEvents.push(newEventsFromSplit[i3]);
|
|
55267
|
+
}
|
|
55268
|
+
}
|
|
55269
|
+
}
|
|
55270
|
+
}
|
|
55271
|
+
if (prevMySplitter !== null || nextMySplitter !== null) {
|
|
55272
|
+
let mySplitter = null;
|
|
55273
|
+
if (prevMySplitter === null)
|
|
55274
|
+
mySplitter = nextMySplitter;
|
|
55275
|
+
else if (nextMySplitter === null)
|
|
55276
|
+
mySplitter = prevMySplitter;
|
|
55277
|
+
else {
|
|
55278
|
+
const cmpSplitters = SweepEvent.comparePoints(prevMySplitter, nextMySplitter);
|
|
55279
|
+
mySplitter = cmpSplitters <= 0 ? prevMySplitter : nextMySplitter;
|
|
55280
|
+
}
|
|
55281
|
+
this.queue.remove(segment2.rightSE);
|
|
55282
|
+
newEvents.push(segment2.rightSE);
|
|
55283
|
+
const newEventsFromSplit = segment2.split(mySplitter);
|
|
55284
|
+
for (let i3 = 0, iMax = newEventsFromSplit.length;i3 < iMax; i3++) {
|
|
55285
|
+
newEvents.push(newEventsFromSplit[i3]);
|
|
55286
|
+
}
|
|
55287
|
+
}
|
|
55288
|
+
if (newEvents.length > 0) {
|
|
55289
|
+
this.tree.remove(segment2);
|
|
55290
|
+
newEvents.push(event);
|
|
55291
|
+
} else {
|
|
55292
|
+
this.segments.push(segment2);
|
|
55293
|
+
segment2.prev = prevSeg;
|
|
55294
|
+
}
|
|
55295
|
+
} else {
|
|
55296
|
+
if (prevSeg && nextSeg) {
|
|
55297
|
+
const inter = prevSeg.getIntersection(nextSeg);
|
|
55298
|
+
if (inter !== null) {
|
|
55299
|
+
if (!prevSeg.isAnEndpoint(inter)) {
|
|
55300
|
+
const newEventsFromSplit = this._splitSafely(prevSeg, inter);
|
|
55301
|
+
for (let i3 = 0, iMax = newEventsFromSplit.length;i3 < iMax; i3++) {
|
|
55302
|
+
newEvents.push(newEventsFromSplit[i3]);
|
|
55303
|
+
}
|
|
55304
|
+
}
|
|
55305
|
+
if (!nextSeg.isAnEndpoint(inter)) {
|
|
55306
|
+
const newEventsFromSplit = this._splitSafely(nextSeg, inter);
|
|
55307
|
+
for (let i3 = 0, iMax = newEventsFromSplit.length;i3 < iMax; i3++) {
|
|
55308
|
+
newEvents.push(newEventsFromSplit[i3]);
|
|
55309
|
+
}
|
|
55310
|
+
}
|
|
55311
|
+
}
|
|
55312
|
+
}
|
|
55313
|
+
this.tree.remove(segment2);
|
|
55314
|
+
}
|
|
55315
|
+
return newEvents;
|
|
55316
|
+
}
|
|
55317
|
+
_splitSafely(seg, pt3) {
|
|
55318
|
+
this.tree.remove(seg);
|
|
55319
|
+
const rightSE = seg.rightSE;
|
|
55320
|
+
this.queue.remove(rightSE);
|
|
55321
|
+
const newEvents = seg.split(pt3);
|
|
55322
|
+
newEvents.push(rightSE);
|
|
55323
|
+
if (seg.consumedBy === undefined)
|
|
55324
|
+
this.tree.add(seg);
|
|
55325
|
+
return newEvents;
|
|
55326
|
+
}
|
|
55327
|
+
}
|
|
55328
|
+
var POLYGON_CLIPPING_MAX_QUEUE_SIZE = typeof process !== "undefined" && process.env.POLYGON_CLIPPING_MAX_QUEUE_SIZE || 1e6;
|
|
55329
|
+
var POLYGON_CLIPPING_MAX_SWEEPLINE_SEGMENTS = typeof process !== "undefined" && process.env.POLYGON_CLIPPING_MAX_SWEEPLINE_SEGMENTS || 1e6;
|
|
55330
|
+
|
|
55331
|
+
class Operation {
|
|
55332
|
+
run(type, geom, moreGeoms) {
|
|
55333
|
+
operation.type = type;
|
|
55334
|
+
rounder.reset();
|
|
55335
|
+
const multipolys = [new MultiPolyIn(geom, true)];
|
|
55336
|
+
for (let i3 = 0, iMax = moreGeoms.length;i3 < iMax; i3++) {
|
|
55337
|
+
multipolys.push(new MultiPolyIn(moreGeoms[i3], false));
|
|
55338
|
+
}
|
|
55339
|
+
operation.numMultiPolys = multipolys.length;
|
|
55340
|
+
if (operation.type === "difference") {
|
|
55341
|
+
const subject = multipolys[0];
|
|
55342
|
+
let i3 = 1;
|
|
55343
|
+
while (i3 < multipolys.length) {
|
|
55344
|
+
if (getBboxOverlap(multipolys[i3].bbox, subject.bbox) !== null)
|
|
55345
|
+
i3++;
|
|
55346
|
+
else
|
|
55347
|
+
multipolys.splice(i3, 1);
|
|
55348
|
+
}
|
|
55349
|
+
}
|
|
55350
|
+
if (operation.type === "intersection") {
|
|
55351
|
+
for (let i3 = 0, iMax = multipolys.length;i3 < iMax; i3++) {
|
|
55352
|
+
const mpA = multipolys[i3];
|
|
55353
|
+
for (let j4 = i3 + 1, jMax = multipolys.length;j4 < jMax; j4++) {
|
|
55354
|
+
if (getBboxOverlap(mpA.bbox, multipolys[j4].bbox) === null)
|
|
55355
|
+
return [];
|
|
55356
|
+
}
|
|
55357
|
+
}
|
|
55358
|
+
}
|
|
55359
|
+
const queue = new SplayTree__default["default"](SweepEvent.compare);
|
|
55360
|
+
for (let i3 = 0, iMax = multipolys.length;i3 < iMax; i3++) {
|
|
55361
|
+
const sweepEvents = multipolys[i3].getSweepEvents();
|
|
55362
|
+
for (let j4 = 0, jMax = sweepEvents.length;j4 < jMax; j4++) {
|
|
55363
|
+
queue.insert(sweepEvents[j4]);
|
|
55364
|
+
if (queue.size > POLYGON_CLIPPING_MAX_QUEUE_SIZE) {
|
|
55365
|
+
throw new Error("Infinite loop when putting segment endpoints in a priority queue " + "(queue size too big).");
|
|
55366
|
+
}
|
|
55367
|
+
}
|
|
55368
|
+
}
|
|
55369
|
+
const sweepLine = new SweepLine(queue);
|
|
55370
|
+
let prevQueueSize = queue.size;
|
|
55371
|
+
let node = queue.pop();
|
|
55372
|
+
while (node) {
|
|
55373
|
+
const evt = node.key;
|
|
55374
|
+
if (queue.size === prevQueueSize) {
|
|
55375
|
+
const seg = evt.segment;
|
|
55376
|
+
throw new Error(`Unable to pop() ${evt.isLeft ? "left" : "right"} SweepEvent ` + `[${evt.point.x}, ${evt.point.y}] from segment #${seg.id} ` + `[${seg.leftSE.point.x}, ${seg.leftSE.point.y}] -> ` + `[${seg.rightSE.point.x}, ${seg.rightSE.point.y}] from queue.`);
|
|
55377
|
+
}
|
|
55378
|
+
if (queue.size > POLYGON_CLIPPING_MAX_QUEUE_SIZE) {
|
|
55379
|
+
throw new Error("Infinite loop when passing sweep line over endpoints " + "(queue size too big).");
|
|
55380
|
+
}
|
|
55381
|
+
if (sweepLine.segments.length > POLYGON_CLIPPING_MAX_SWEEPLINE_SEGMENTS) {
|
|
55382
|
+
throw new Error("Infinite loop when passing sweep line over endpoints " + "(too many sweep line segments).");
|
|
55383
|
+
}
|
|
55384
|
+
const newEvents = sweepLine.process(evt);
|
|
55385
|
+
for (let i3 = 0, iMax = newEvents.length;i3 < iMax; i3++) {
|
|
55386
|
+
const evt2 = newEvents[i3];
|
|
55387
|
+
if (evt2.consumedBy === undefined)
|
|
55388
|
+
queue.insert(evt2);
|
|
55389
|
+
}
|
|
55390
|
+
prevQueueSize = queue.size;
|
|
55391
|
+
node = queue.pop();
|
|
55392
|
+
}
|
|
55393
|
+
rounder.reset();
|
|
55394
|
+
const ringsOut = RingOut.factory(sweepLine.segments);
|
|
55395
|
+
const result = new MultiPolyOut(ringsOut);
|
|
55396
|
+
return result.getGeom();
|
|
55397
|
+
}
|
|
55398
|
+
}
|
|
55399
|
+
var operation = new Operation;
|
|
55400
|
+
var union = function(geom) {
|
|
55401
|
+
for (var _len = arguments.length, moreGeoms = new Array(_len > 1 ? _len - 1 : 0), _key = 1;_key < _len; _key++) {
|
|
55402
|
+
moreGeoms[_key - 1] = arguments[_key];
|
|
55403
|
+
}
|
|
55404
|
+
return operation.run("union", geom, moreGeoms);
|
|
55405
|
+
};
|
|
55406
|
+
var intersection = function(geom) {
|
|
55407
|
+
for (var _len2 = arguments.length, moreGeoms = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1;_key2 < _len2; _key2++) {
|
|
55408
|
+
moreGeoms[_key2 - 1] = arguments[_key2];
|
|
55409
|
+
}
|
|
55410
|
+
return operation.run("intersection", geom, moreGeoms);
|
|
55411
|
+
};
|
|
55412
|
+
var xor = function(geom) {
|
|
55413
|
+
for (var _len3 = arguments.length, moreGeoms = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1;_key3 < _len3; _key3++) {
|
|
55414
|
+
moreGeoms[_key3 - 1] = arguments[_key3];
|
|
55415
|
+
}
|
|
55416
|
+
return operation.run("xor", geom, moreGeoms);
|
|
55417
|
+
};
|
|
55418
|
+
var difference = function(subjectGeom) {
|
|
55419
|
+
for (var _len4 = arguments.length, clippingGeoms = new Array(_len4 > 1 ? _len4 - 1 : 0), _key4 = 1;_key4 < _len4; _key4++) {
|
|
55420
|
+
clippingGeoms[_key4 - 1] = arguments[_key4];
|
|
55421
|
+
}
|
|
55422
|
+
return operation.run("difference", subjectGeom, clippingGeoms);
|
|
55423
|
+
};
|
|
55424
|
+
var index = {
|
|
55425
|
+
union,
|
|
55426
|
+
intersection,
|
|
55427
|
+
xor,
|
|
55428
|
+
difference
|
|
55429
|
+
};
|
|
55430
|
+
module2.exports = index;
|
|
55431
|
+
});
|
|
55432
|
+
|
|
53622
55433
|
// node_modules/fast-json-stable-stringify/index.js
|
|
53623
55434
|
var require_fast_json_stable_stringify = __commonJS((exports2, module2) => {
|
|
53624
55435
|
module2.exports = function(data, opts) {
|
|
@@ -53682,7 +55493,7 @@ var require_fast_json_stable_stringify = __commonJS((exports2, module2) => {
|
|
|
53682
55493
|
};
|
|
53683
55494
|
});
|
|
53684
55495
|
|
|
53685
|
-
// node_modules/circuit-json-to-gerber/dist/chunk-
|
|
55496
|
+
// node_modules/circuit-json-to-gerber/dist/chunk-46NSLLUV.js
|
|
53686
55497
|
import { z as z4 } from "zod";
|
|
53687
55498
|
import { z as z23 } from "zod";
|
|
53688
55499
|
import { z as z32 } from "zod";
|
|
@@ -53703,6 +55514,7 @@ import { z as z17 } from "zod";
|
|
|
53703
55514
|
import { z as z18 } from "zod";
|
|
53704
55515
|
import { z as z19 } from "zod";
|
|
53705
55516
|
import { z as z20 } from "zod";
|
|
55517
|
+
import { getBoundFromCenteredRect } from "@tscircuit/math-utils";
|
|
53706
55518
|
import { z as z21 } from "zod";
|
|
53707
55519
|
import { z as z222 } from "zod";
|
|
53708
55520
|
import { z as z232 } from "zod";
|
|
@@ -53733,7 +55545,6 @@ import { z as z47 } from "zod";
|
|
|
53733
55545
|
import { z as z48 } from "zod";
|
|
53734
55546
|
import { z as z49 } from "zod";
|
|
53735
55547
|
import { z as z50 } from "zod";
|
|
53736
|
-
import { lineAlphabet as lineAlphabet2 } from "@tscircuit/alphabet";
|
|
53737
55548
|
import {
|
|
53738
55549
|
applyToPoint as applyToPoint26,
|
|
53739
55550
|
compose as compose9,
|
|
@@ -53741,6 +55552,25 @@ import {
|
|
|
53741
55552
|
rotate as rotate12,
|
|
53742
55553
|
translate as translate9
|
|
53743
55554
|
} from "transformation-matrix";
|
|
55555
|
+
import { getBoundFromCenteredRect as getBoundFromCenteredRect2 } from "@tscircuit/math-utils";
|
|
55556
|
+
import { lineAlphabet as lineAlphabet2 } from "@tscircuit/alphabet";
|
|
55557
|
+
import {
|
|
55558
|
+
applyToPoint as applyToPoint42,
|
|
55559
|
+
compose as compose42,
|
|
55560
|
+
identity as identity32,
|
|
55561
|
+
rotate as rotate42,
|
|
55562
|
+
translate as translate42
|
|
55563
|
+
} from "transformation-matrix";
|
|
55564
|
+
import { getBoundFromCenteredRect as getBoundFromCenteredRect3 } from "@tscircuit/math-utils";
|
|
55565
|
+
import { applyToPoint as applyToPoint25, compose as compose22, rotate as rotate22, translate as translate22 } from "transformation-matrix";
|
|
55566
|
+
import { getBoundFromCenteredRect as getBoundFromCenteredRect4 } from "@tscircuit/math-utils";
|
|
55567
|
+
import {
|
|
55568
|
+
applyToPoint as applyToPoint32,
|
|
55569
|
+
compose as compose32,
|
|
55570
|
+
identity as identity22,
|
|
55571
|
+
rotate as rotate32,
|
|
55572
|
+
translate as translate32
|
|
55573
|
+
} from "transformation-matrix";
|
|
53744
55574
|
function pairs3(arr) {
|
|
53745
55575
|
const result = [];
|
|
53746
55576
|
for (let i3 = 0;i3 < arr.length - 1; i3++) {
|
|
@@ -53756,17 +55586,30 @@ function getAllTraceWidths(soup) {
|
|
|
53756
55586
|
if (segment2.route_type === "wire") {
|
|
53757
55587
|
widths[segment2.layer] = widths[segment2.layer] || /* @__PURE__ */ new Set;
|
|
53758
55588
|
widths[segment2.layer].add(segment2.width);
|
|
55589
|
+
} else if (segment2.route_type === "through_pad") {
|
|
55590
|
+
for (const layer of [segment2.start_layer, segment2.end_layer]) {
|
|
55591
|
+
if (typeof layer === "string" && typeof segment2.width === "number") {
|
|
55592
|
+
widths[layer] = widths[layer] || /* @__PURE__ */ new Set;
|
|
55593
|
+
widths[layer].add(segment2.width);
|
|
55594
|
+
}
|
|
55595
|
+
}
|
|
53759
55596
|
}
|
|
53760
55597
|
}
|
|
53761
55598
|
}
|
|
53762
55599
|
return {
|
|
53763
55600
|
top: Array.from(widths.top || []),
|
|
55601
|
+
inner1: Array.from(widths.inner1 || []),
|
|
55602
|
+
inner2: Array.from(widths.inner2 || []),
|
|
55603
|
+
inner3: Array.from(widths.inner3 || []),
|
|
55604
|
+
inner4: Array.from(widths.inner4 || []),
|
|
55605
|
+
inner5: Array.from(widths.inner5 || []),
|
|
55606
|
+
inner6: Array.from(widths.inner6 || []),
|
|
53764
55607
|
bottom: Array.from(widths.bottom || [])
|
|
53765
55608
|
};
|
|
53766
55609
|
}
|
|
53767
55610
|
function defineAperturesForLayer({
|
|
53768
55611
|
glayer,
|
|
53769
|
-
|
|
55612
|
+
circuitJson,
|
|
53770
55613
|
glayer_name
|
|
53771
55614
|
}) {
|
|
53772
55615
|
const getNextApertureNumber = () => {
|
|
@@ -53782,15 +55625,20 @@ function defineAperturesForLayer({
|
|
|
53782
55625
|
return highest_aperture_number + 1;
|
|
53783
55626
|
};
|
|
53784
55627
|
glayer.push(...gerberBuilder().add("comment", { comment: "aperture START LIST" }).build());
|
|
53785
|
-
const traceWidths = getAllTraceWidths(
|
|
53786
|
-
|
|
55628
|
+
const traceWidths = getAllTraceWidths(circuitJson);
|
|
55629
|
+
const layerRef = getLayerRefFromGerberLayerName(glayer_name);
|
|
55630
|
+
for (const width of traceWidths[layerRef]) {
|
|
53787
55631
|
glayer.push(...gerberBuilder().add("define_aperture_template", {
|
|
53788
55632
|
aperture_number: getNextApertureNumber(),
|
|
53789
55633
|
standard_template_code: "C",
|
|
53790
55634
|
diameter: width
|
|
53791
55635
|
}).build());
|
|
53792
55636
|
}
|
|
53793
|
-
const apertureConfigs = getAllApertureTemplateConfigsForLayer(
|
|
55637
|
+
const apertureConfigs = getAllApertureTemplateConfigsForLayer({
|
|
55638
|
+
circuitJson,
|
|
55639
|
+
layer: layerRef,
|
|
55640
|
+
glayer_name
|
|
55641
|
+
});
|
|
53794
55642
|
for (const apertureConfig of apertureConfigs) {
|
|
53795
55643
|
glayer.push(...gerberBuilder().add("define_aperture_template", {
|
|
53796
55644
|
aperture_number: getNextApertureNumber(),
|
|
@@ -53799,9 +55647,16 @@ function defineAperturesForLayer({
|
|
|
53799
55647
|
}
|
|
53800
55648
|
glayer.push(...gerberBuilder().add("delete_attribute", {}).add("comment", { comment: "aperture END LIST" }).build());
|
|
53801
55649
|
}
|
|
53802
|
-
function getAllApertureTemplateConfigsForLayer(
|
|
55650
|
+
function getAllApertureTemplateConfigsForLayer({
|
|
55651
|
+
circuitJson,
|
|
55652
|
+
layer,
|
|
55653
|
+
glayer_name
|
|
55654
|
+
}) {
|
|
53803
55655
|
const configs = [];
|
|
53804
55656
|
const configHashMap = /* @__PURE__ */ new Set;
|
|
55657
|
+
const isSoldermaskLayer = glayer_name.endsWith("_Mask");
|
|
55658
|
+
const isCopperLayer = glayer_name.endsWith("_Cu");
|
|
55659
|
+
const isFabricationLayer = glayer_name.endsWith("_Fab");
|
|
53805
55660
|
const addConfigIfNew = (config) => {
|
|
53806
55661
|
const hash = import_fast_json_stable_stringify.default(config);
|
|
53807
55662
|
if (!configHashMap.has(hash)) {
|
|
@@ -53809,38 +55664,145 @@ function getAllApertureTemplateConfigsForLayer(soup, layer) {
|
|
|
53809
55664
|
configHashMap.add(hash);
|
|
53810
55665
|
}
|
|
53811
55666
|
};
|
|
53812
|
-
for (const elm of
|
|
55667
|
+
for (const elm of circuitJson) {
|
|
53813
55668
|
if (elm.type === "pcb_smtpad") {
|
|
55669
|
+
if (isFabricationLayer)
|
|
55670
|
+
continue;
|
|
53814
55671
|
if (elm.layer === layer && elm.shape !== "polygon") {
|
|
53815
|
-
|
|
55672
|
+
if (isSoldermaskLayer) {
|
|
55673
|
+
addConfigIfNew(getApertureConfigFromPcbSmtpadSoldermask(elm));
|
|
55674
|
+
} else {
|
|
55675
|
+
addConfigIfNew(getApertureConfigFromPcbSmtpad(elm));
|
|
55676
|
+
}
|
|
53816
55677
|
}
|
|
53817
55678
|
} else if (elm.type === "pcb_solder_paste") {
|
|
55679
|
+
if (isFabricationLayer)
|
|
55680
|
+
continue;
|
|
53818
55681
|
if (elm.layer === layer) {
|
|
53819
55682
|
addConfigIfNew(getApertureConfigFromPcbSolderPaste(elm));
|
|
55683
|
+
if (elm.shape === "pill") {
|
|
55684
|
+
addConfigIfNew(getApertureConfigFromPcbSolderPaste({
|
|
55685
|
+
...elm,
|
|
55686
|
+
width: elm.height,
|
|
55687
|
+
height: elm.width
|
|
55688
|
+
}));
|
|
55689
|
+
}
|
|
53820
55690
|
}
|
|
53821
55691
|
} else if (elm.type === "pcb_plated_hole") {
|
|
55692
|
+
if (isFabricationLayer)
|
|
55693
|
+
continue;
|
|
53822
55694
|
if (elm.layers.includes(layer)) {
|
|
53823
|
-
|
|
55695
|
+
if (elm.shape === "hole_with_polygon_pad") {
|
|
55696
|
+
continue;
|
|
55697
|
+
}
|
|
55698
|
+
if (glayer_name.endsWith("_Mask") && elm.is_covered_with_solder_mask === true) {
|
|
55699
|
+
continue;
|
|
55700
|
+
}
|
|
55701
|
+
if (isSoldermaskLayer) {
|
|
55702
|
+
addConfigIfNew(getApertureConfigFromPcbPlatedHoleSoldermask(elm));
|
|
55703
|
+
} else {
|
|
55704
|
+
addConfigIfNew(getApertureConfigFromPcbPlatedHole(elm));
|
|
55705
|
+
}
|
|
53824
55706
|
}
|
|
53825
55707
|
} else if (elm.type === "pcb_hole") {
|
|
53826
|
-
if (
|
|
53827
|
-
|
|
53828
|
-
|
|
55708
|
+
if (!isSoldermaskLayer)
|
|
55709
|
+
continue;
|
|
55710
|
+
if (glayer_name.endsWith("_Mask") && elm.is_covered_with_solder_mask === true) {
|
|
55711
|
+
continue;
|
|
55712
|
+
}
|
|
55713
|
+
if (elm.hole_shape === "circle") {
|
|
55714
|
+
if (isSoldermaskLayer) {
|
|
55715
|
+
addConfigIfNew(getApertureConfigFromCirclePcbHoleSoldermask(elm));
|
|
55716
|
+
} else {
|
|
55717
|
+
addConfigIfNew(getApertureConfigFromCirclePcbHole(elm));
|
|
55718
|
+
}
|
|
55719
|
+
} else
|
|
53829
55720
|
console.warn("NOT IMPLEMENTED: drawing gerber for non circle holes");
|
|
53830
55721
|
} else if (elm.type === "pcb_via") {
|
|
53831
|
-
|
|
53832
|
-
|
|
53833
|
-
addConfigIfNew(
|
|
53834
|
-
else if (elm.type === "
|
|
53835
|
-
|
|
53836
|
-
|
|
55722
|
+
if (isFabricationLayer)
|
|
55723
|
+
continue;
|
|
55724
|
+
addConfigIfNew(getApertureConfigFromOuterDiameter(elm));
|
|
55725
|
+
} else if (elm.type === "pcb_trace") {
|
|
55726
|
+
if (isFabricationLayer)
|
|
55727
|
+
continue;
|
|
55728
|
+
for (const point9 of elm.route) {
|
|
55729
|
+
if (point9.route_type === "via" && typeof point9.outer_diameter === "number" && (point9.from_layer === layer || point9.to_layer === layer)) {
|
|
55730
|
+
addConfigIfNew(getApertureConfigFromOuterDiameter(point9));
|
|
55731
|
+
}
|
|
55732
|
+
}
|
|
55733
|
+
} else if (elm.type === "pcb_silkscreen_path") {
|
|
55734
|
+
if (!isFabricationLayer)
|
|
55735
|
+
addConfigIfNew(getApertureConfigFromPcbSilkscreenPath(elm));
|
|
55736
|
+
} else if (isSilkscreenShape(elm)) {
|
|
55737
|
+
if (!isFabricationLayer) {
|
|
55738
|
+
addConfigIfNew({
|
|
55739
|
+
standard_template_code: "C",
|
|
55740
|
+
diameter: elm.stroke_width ?? 0.1
|
|
55741
|
+
});
|
|
55742
|
+
if (elm.is_filled === true) {
|
|
55743
|
+
addConfigIfNew(REGION_APERTURE_CONFIG);
|
|
55744
|
+
}
|
|
55745
|
+
}
|
|
55746
|
+
} else if (elm.type === "pcb_silkscreen_graphic") {
|
|
55747
|
+
if (glayer_name.endsWith("_SilkScreen")) {
|
|
55748
|
+
addConfigIfNew(REGION_APERTURE_CONFIG);
|
|
55749
|
+
}
|
|
55750
|
+
} else if (elm.type === "pcb_silkscreen_text") {
|
|
55751
|
+
if (!isFabricationLayer)
|
|
55752
|
+
addConfigIfNew(getApertureConfigFromPcbSilkscreenText(elm));
|
|
55753
|
+
} else if (elm.type === "pcb_fabrication_note_text") {
|
|
55754
|
+
if (isFabricationLayer && elm.layer === layer)
|
|
55755
|
+
addConfigIfNew(getApertureConfigFromPcbFabricationNoteText(elm));
|
|
55756
|
+
} else if (elm.type === "pcb_fabrication_note_path") {
|
|
55757
|
+
if (isFabricationLayer && elm.layer === layer)
|
|
55758
|
+
addConfigIfNew(getApertureConfigFromPcbFabricationNotePath(elm));
|
|
55759
|
+
} else if (elm.type === "pcb_fabrication_note_rect") {
|
|
55760
|
+
if (isFabricationLayer && elm.layer === layer) {
|
|
55761
|
+
if (elm.has_stroke !== false)
|
|
55762
|
+
addConfigIfNew(getApertureConfigFromPcbFabricationNotePath(elm));
|
|
55763
|
+
if (elm.is_filled === true)
|
|
55764
|
+
addConfigIfNew(REGION_APERTURE_CONFIG);
|
|
55765
|
+
}
|
|
55766
|
+
} else if (elm.type === "pcb_fabrication_note_dimension") {
|
|
55767
|
+
if (isFabricationLayer && elm.layer === layer) {
|
|
55768
|
+
addConfigIfNew(getApertureConfigFromPcbFabricationNoteDimension(elm));
|
|
55769
|
+
addConfigIfNew(getApertureConfigFromPcbFabricationNoteText(elm));
|
|
55770
|
+
}
|
|
55771
|
+
} else if (elm.type === "pcb_copper_text") {
|
|
53837
55772
|
if (elm.layer === layer)
|
|
53838
55773
|
addConfigIfNew(getApertureConfigFromPcbCopperText(elm));
|
|
53839
55774
|
}
|
|
53840
55775
|
}
|
|
55776
|
+
const needsRegionAperture = circuitJson.some((elm) => {
|
|
55777
|
+
if (elm.type === "pcb_copper_pour") {
|
|
55778
|
+
if (elm.layer !== layer)
|
|
55779
|
+
return false;
|
|
55780
|
+
if (isCopperLayer)
|
|
55781
|
+
return true;
|
|
55782
|
+
return isSoldermaskLayer && elm.covered_with_solder_mask === false;
|
|
55783
|
+
}
|
|
55784
|
+
if (elm.type === "pcb_smtpad" && elm.shape === "polygon") {
|
|
55785
|
+
if (elm.layer !== layer)
|
|
55786
|
+
return false;
|
|
55787
|
+
if (isCopperLayer)
|
|
55788
|
+
return true;
|
|
55789
|
+
return isSoldermaskLayer && elm.is_covered_with_solder_mask !== true;
|
|
55790
|
+
}
|
|
55791
|
+
if (elm.type === "pcb_plated_hole" && elm.shape === "hole_with_polygon_pad") {
|
|
55792
|
+
if (!elm.layers.includes(layer))
|
|
55793
|
+
return false;
|
|
55794
|
+
if (isCopperLayer)
|
|
55795
|
+
return true;
|
|
55796
|
+
return isSoldermaskLayer && elm.is_covered_with_solder_mask !== true;
|
|
55797
|
+
}
|
|
55798
|
+
return false;
|
|
55799
|
+
});
|
|
55800
|
+
if (needsRegionAperture) {
|
|
55801
|
+
addConfigIfNew(REGION_APERTURE_CONFIG);
|
|
55802
|
+
}
|
|
53841
55803
|
return configs;
|
|
53842
55804
|
}
|
|
53843
|
-
var import_fast_json_stable_stringify, defineExcellonDrillCommand = ({
|
|
55805
|
+
var import_polygon_clipping, import_fast_json_stable_stringify, import_polygon_clipping2, import_polygon_clipping3, defineExcellonDrillCommand = ({
|
|
53844
55806
|
command_code,
|
|
53845
55807
|
schema,
|
|
53846
55808
|
stringify: stringify3
|
|
@@ -53873,12 +55835,270 @@ var import_fast_json_stable_stringify, defineExcellonDrillCommand = ({
|
|
|
53873
55835
|
build() {
|
|
53874
55836
|
return this.commands;
|
|
53875
55837
|
}
|
|
53876
|
-
}, excellonDrill = () => new ExcellonDrillBuilder,
|
|
55838
|
+
}, excellonDrill = () => new ExcellonDrillBuilder, getLayerCount = (circuitJson) => {
|
|
55839
|
+
const board = circuitJson.find((element) => element.type === "pcb_board");
|
|
55840
|
+
if (!board || typeof board.num_layers !== "number") {
|
|
55841
|
+
return 2;
|
|
55842
|
+
}
|
|
55843
|
+
return Math.max(2, board.num_layers);
|
|
55844
|
+
}, getLayerNumber = (layer, layerCount) => {
|
|
55845
|
+
if (layer === "top")
|
|
55846
|
+
return 1;
|
|
55847
|
+
if (layer === "bottom")
|
|
55848
|
+
return layerCount;
|
|
55849
|
+
const innerLayerMatch = layer.match(/^inner([1-6])$/);
|
|
55850
|
+
if (innerLayerMatch) {
|
|
55851
|
+
const innerLayerNumber = Number(innerLayerMatch[1]);
|
|
55852
|
+
if (innerLayerNumber >= 1 && innerLayerNumber <= layerCount - 2) {
|
|
55853
|
+
return innerLayerNumber + 1;
|
|
55854
|
+
}
|
|
55855
|
+
}
|
|
55856
|
+
throw new Error(`Invalid layer "${layer}" for ${layerCount}-layer board`);
|
|
55857
|
+
}, normalizeLayerSpan = (span, layerCount) => {
|
|
55858
|
+
const fromLayerNumber = getLayerNumber(span.from_layer, layerCount);
|
|
55859
|
+
const toLayerNumber = getLayerNumber(span.to_layer, layerCount);
|
|
55860
|
+
if (fromLayerNumber <= toLayerNumber) {
|
|
55861
|
+
return span;
|
|
55862
|
+
}
|
|
55863
|
+
return {
|
|
55864
|
+
from_layer: span.to_layer,
|
|
55865
|
+
to_layer: span.from_layer
|
|
55866
|
+
};
|
|
55867
|
+
}, getPlatedElementLayerSpan = (element, layerCount) => {
|
|
55868
|
+
if (element.type !== "pcb_plated_hole" && element.type !== "pcb_via") {
|
|
55869
|
+
return;
|
|
55870
|
+
}
|
|
55871
|
+
if ("from_layer" in element && typeof element.from_layer === "string" && "to_layer" in element && typeof element.to_layer === "string") {
|
|
55872
|
+
return normalizeLayerSpan({
|
|
55873
|
+
from_layer: element.from_layer,
|
|
55874
|
+
to_layer: element.to_layer
|
|
55875
|
+
}, layerCount);
|
|
55876
|
+
}
|
|
55877
|
+
let layers = [];
|
|
55878
|
+
if ("layers" in element && Array.isArray(element.layers)) {
|
|
55879
|
+
layers = element.layers;
|
|
55880
|
+
}
|
|
55881
|
+
if (layers.length > 0) {
|
|
55882
|
+
const sortedLayers = [...layers].sort((a3, b3) => getLayerNumber(a3, layerCount) - getLayerNumber(b3, layerCount));
|
|
55883
|
+
return {
|
|
55884
|
+
from_layer: sortedLayers[0],
|
|
55885
|
+
to_layer: sortedLayers[sortedLayers.length - 1]
|
|
55886
|
+
};
|
|
55887
|
+
}
|
|
55888
|
+
return {
|
|
55889
|
+
from_layer: "top",
|
|
55890
|
+
to_layer: "bottom"
|
|
55891
|
+
};
|
|
55892
|
+
}, getDefaultPlatedDrillLayerSpan = () => ({
|
|
55893
|
+
from_layer: "top",
|
|
55894
|
+
to_layer: "bottom"
|
|
55895
|
+
}), getRequestedLayerSpan = (layer_span) => {
|
|
55896
|
+
if (layer_span) {
|
|
55897
|
+
return layer_span;
|
|
55898
|
+
}
|
|
55899
|
+
return getDefaultPlatedDrillLayerSpan();
|
|
55900
|
+
}, isSameLayerSpan = (a3, b3, layerCount) => {
|
|
55901
|
+
const normalizedA = normalizeLayerSpan(a3, layerCount);
|
|
55902
|
+
const normalizedB = normalizeLayerSpan(b3, layerCount);
|
|
55903
|
+
return normalizedA.from_layer === normalizedB.from_layer && normalizedA.to_layer === normalizedB.to_layer;
|
|
55904
|
+
}, shouldIncludeElement = ({
|
|
55905
|
+
element,
|
|
55906
|
+
is_plated,
|
|
55907
|
+
layer_span,
|
|
55908
|
+
layerCount
|
|
55909
|
+
}) => {
|
|
55910
|
+
if (element.type !== "pcb_plated_hole" && element.type !== "pcb_hole" && element.type !== "pcb_via") {
|
|
55911
|
+
return false;
|
|
55912
|
+
}
|
|
55913
|
+
if (!is_plated)
|
|
55914
|
+
return element.type === "pcb_hole";
|
|
55915
|
+
if (element.type === "pcb_hole")
|
|
55916
|
+
return false;
|
|
55917
|
+
const elementLayerSpan = getPlatedElementLayerSpan(element, layerCount);
|
|
55918
|
+
if (!elementLayerSpan)
|
|
55919
|
+
return false;
|
|
55920
|
+
const requestedLayerSpan = getRequestedLayerSpan(layer_span);
|
|
55921
|
+
return isSameLayerSpan(elementLayerSpan, requestedLayerSpan, layerCount);
|
|
55922
|
+
}, getFileFunctionLayerSpan = ({
|
|
55923
|
+
circuitJson,
|
|
55924
|
+
is_plated,
|
|
55925
|
+
layer_span
|
|
55926
|
+
}) => {
|
|
55927
|
+
const layerCount = getLayerCount(circuitJson);
|
|
55928
|
+
if (!is_plated)
|
|
55929
|
+
return `NonPlated,1,${layerCount},NPTH`;
|
|
55930
|
+
const requestedLayerSpan = getRequestedLayerSpan(layer_span);
|
|
55931
|
+
const span = normalizeLayerSpan(requestedLayerSpan, layerCount);
|
|
55932
|
+
return `Plated,${getLayerNumber(span.from_layer, layerCount)},${getLayerNumber(span.to_layer, layerCount)},PTH`;
|
|
55933
|
+
}, getTraceRouteViaElements = (circuitJson) => {
|
|
55934
|
+
const routeVias = [];
|
|
55935
|
+
for (const element of circuitJson) {
|
|
55936
|
+
if (element.type !== "pcb_trace") {
|
|
55937
|
+
continue;
|
|
55938
|
+
}
|
|
55939
|
+
for (const [index, point9] of element.route.entries()) {
|
|
55940
|
+
if (point9.route_type !== "via" || typeof point9.hole_diameter !== "number" || typeof point9.outer_diameter !== "number" || typeof point9.from_layer !== "string" || typeof point9.to_layer !== "string") {
|
|
55941
|
+
continue;
|
|
55942
|
+
}
|
|
55943
|
+
const fromLayer = point9.from_layer;
|
|
55944
|
+
const toLayer = point9.to_layer;
|
|
55945
|
+
routeVias.push({
|
|
55946
|
+
type: "pcb_via",
|
|
55947
|
+
pcb_via_id: `${element.pcb_trace_id}_route_via_${index}`,
|
|
55948
|
+
x: point9.x,
|
|
55949
|
+
y: point9.y,
|
|
55950
|
+
hole_diameter: point9.hole_diameter,
|
|
55951
|
+
outer_diameter: point9.outer_diameter,
|
|
55952
|
+
from_layer: fromLayer,
|
|
55953
|
+
to_layer: toLayer,
|
|
55954
|
+
layers: [fromLayer, toLayer]
|
|
55955
|
+
});
|
|
55956
|
+
}
|
|
55957
|
+
}
|
|
55958
|
+
return routeVias;
|
|
55959
|
+
}, getDrillableElements = (circuitJson) => [
|
|
55960
|
+
...circuitJson,
|
|
55961
|
+
...getTraceRouteViaElements(circuitJson)
|
|
55962
|
+
], circleCutoutPolygonSegmentCount = 64, getBoardOutlinePolygons = (circuitJson) => {
|
|
55963
|
+
return circuitJson.flatMap((element) => {
|
|
55964
|
+
if (element.type !== "pcb_board") {
|
|
55965
|
+
return [];
|
|
55966
|
+
}
|
|
55967
|
+
if (element.outline && element.outline.length > 2) {
|
|
55968
|
+
return [[element.outline.map((point9) => [point9.x, point9.y])]];
|
|
55969
|
+
}
|
|
55970
|
+
const bounds = getBoundFromCenteredRect({
|
|
55971
|
+
center: element.center,
|
|
55972
|
+
width: element.width,
|
|
55973
|
+
height: element.height
|
|
55974
|
+
});
|
|
55975
|
+
return [
|
|
55976
|
+
[
|
|
55977
|
+
[
|
|
55978
|
+
[bounds.minX, bounds.minY],
|
|
55979
|
+
[bounds.maxX, bounds.minY],
|
|
55980
|
+
[bounds.maxX, bounds.maxY],
|
|
55981
|
+
[bounds.minX, bounds.maxY]
|
|
55982
|
+
]
|
|
55983
|
+
]
|
|
55984
|
+
];
|
|
55985
|
+
});
|
|
55986
|
+
}, getCircleCutoutPolygon = (cutout) => {
|
|
55987
|
+
const points = [];
|
|
55988
|
+
for (let i3 = 0;i3 < circleCutoutPolygonSegmentCount; i3++) {
|
|
55989
|
+
const angle = i3 / circleCutoutPolygonSegmentCount * Math.PI * 2;
|
|
55990
|
+
points.push([
|
|
55991
|
+
cutout.center.x + cutout.radius * Math.cos(angle),
|
|
55992
|
+
cutout.center.y + cutout.radius * Math.sin(angle)
|
|
55993
|
+
]);
|
|
55994
|
+
}
|
|
55995
|
+
return [points];
|
|
55996
|
+
}, isInternalCircularCutout = ({
|
|
55997
|
+
cutout,
|
|
55998
|
+
boardOutlinePolygons
|
|
55999
|
+
}) => {
|
|
56000
|
+
const cutoutPolygon = getCircleCutoutPolygon(cutout);
|
|
56001
|
+
return boardOutlinePolygons.some((boardOutlinePolygon) => {
|
|
56002
|
+
const overlapsBoard = import_polygon_clipping.default.intersection(boardOutlinePolygon, cutoutPolygon).length > 0;
|
|
56003
|
+
const extendsOutsideBoard = import_polygon_clipping.default.difference(cutoutPolygon, boardOutlinePolygon).length > 0;
|
|
56004
|
+
return overlapsBoard && !extendsOutsideBoard;
|
|
56005
|
+
});
|
|
56006
|
+
}, getInternalCircularCutoutDrills = (circuitJson) => {
|
|
56007
|
+
const boardOutlinePolygons = getBoardOutlinePolygons(circuitJson);
|
|
56008
|
+
return circuitJson.filter((element) => {
|
|
56009
|
+
if (element.type !== "pcb_cutout") {
|
|
56010
|
+
return false;
|
|
56011
|
+
}
|
|
56012
|
+
if (element.shape !== "circle") {
|
|
56013
|
+
return false;
|
|
56014
|
+
}
|
|
56015
|
+
return isInternalCircularCutout({
|
|
56016
|
+
cutout: element,
|
|
56017
|
+
boardOutlinePolygons
|
|
56018
|
+
});
|
|
56019
|
+
});
|
|
56020
|
+
}, getDrillElements = ({
|
|
56021
|
+
circuitJson,
|
|
56022
|
+
is_plated
|
|
56023
|
+
}) => {
|
|
56024
|
+
const drillableElements = getDrillableElements(circuitJson).filter((element) => element.type !== "pcb_cutout");
|
|
56025
|
+
if (is_plated) {
|
|
56026
|
+
return drillableElements;
|
|
56027
|
+
}
|
|
56028
|
+
const internalCircularCutoutDrills = getInternalCircularCutoutDrills(circuitJson);
|
|
56029
|
+
return [...drillableElements, ...internalCircularCutoutDrills];
|
|
56030
|
+
}, getHoleDiameter = (element) => {
|
|
56031
|
+
if ("hole_diameter" in element && typeof element.hole_diameter === "number") {
|
|
56032
|
+
return element.hole_diameter;
|
|
56033
|
+
}
|
|
56034
|
+
if (element.type === "pcb_cutout") {
|
|
56035
|
+
return element.radius * 2;
|
|
56036
|
+
}
|
|
56037
|
+
if ("hole_width" in element && typeof element.hole_width === "number" && "hole_height" in element && typeof element.hole_height === "number") {
|
|
56038
|
+
return Math.min(element.hole_width, element.hole_height);
|
|
56039
|
+
}
|
|
56040
|
+
return;
|
|
56041
|
+
}, getDrillCenter = (element) => {
|
|
56042
|
+
if (element.type === "pcb_cutout") {
|
|
56043
|
+
return element.center;
|
|
56044
|
+
}
|
|
56045
|
+
let x4 = 0;
|
|
56046
|
+
let y4 = 0;
|
|
56047
|
+
let holeOffsetX = 0;
|
|
56048
|
+
let holeOffsetY = 0;
|
|
56049
|
+
if ("x" in element && typeof element.x === "number") {
|
|
56050
|
+
x4 = element.x;
|
|
56051
|
+
}
|
|
56052
|
+
if ("y" in element && typeof element.y === "number") {
|
|
56053
|
+
y4 = element.y;
|
|
56054
|
+
}
|
|
56055
|
+
if ("hole_offset_x" in element && typeof element.hole_offset_x === "number") {
|
|
56056
|
+
holeOffsetX = element.hole_offset_x;
|
|
56057
|
+
}
|
|
56058
|
+
if ("hole_offset_y" in element && typeof element.hole_offset_y === "number") {
|
|
56059
|
+
holeOffsetY = element.hole_offset_y;
|
|
56060
|
+
}
|
|
56061
|
+
return {
|
|
56062
|
+
x: x4 + holeOffsetX,
|
|
56063
|
+
y: y4 + holeOffsetY
|
|
56064
|
+
};
|
|
56065
|
+
}, getYMultiplier = (flip_y_axis) => {
|
|
56066
|
+
if (flip_y_axis) {
|
|
56067
|
+
return -1;
|
|
56068
|
+
}
|
|
56069
|
+
return 1;
|
|
56070
|
+
}, getSlotEndpoints = ({
|
|
56071
|
+
holeWidth,
|
|
56072
|
+
holeHeight,
|
|
56073
|
+
slotHalfLength
|
|
56074
|
+
}) => {
|
|
56075
|
+
let startRelative = { x: 0, y: -slotHalfLength };
|
|
56076
|
+
let endRelative = { x: 0, y: slotHalfLength };
|
|
56077
|
+
if (holeWidth >= holeHeight) {
|
|
56078
|
+
startRelative = { x: -slotHalfLength, y: 0 };
|
|
56079
|
+
endRelative = { x: slotHalfLength, y: 0 };
|
|
56080
|
+
}
|
|
56081
|
+
return { startRelative, endRelative };
|
|
56082
|
+
}, getHoleRotationDegrees = (element) => {
|
|
56083
|
+
if ("hole_ccw_rotation" in element && typeof element.hole_ccw_rotation === "number") {
|
|
56084
|
+
return element.hole_ccw_rotation;
|
|
56085
|
+
}
|
|
56086
|
+
if ("ccw_rotation" in element && typeof element.ccw_rotation === "number") {
|
|
56087
|
+
return element.ccw_rotation;
|
|
56088
|
+
}
|
|
56089
|
+
return 0;
|
|
56090
|
+
}, convertSoupToExcellonDrillCommands = ({
|
|
53877
56091
|
circuitJson,
|
|
53878
56092
|
is_plated,
|
|
53879
|
-
flip_y_axis = false
|
|
56093
|
+
flip_y_axis = false,
|
|
56094
|
+
layer_span
|
|
53880
56095
|
}) => {
|
|
53881
56096
|
const builder = excellonDrill();
|
|
56097
|
+
const layerCount = getLayerCount(circuitJson);
|
|
56098
|
+
const drillElements = getDrillElements({
|
|
56099
|
+
circuitJson,
|
|
56100
|
+
is_plated
|
|
56101
|
+
});
|
|
53882
56102
|
builder.add("M48", {});
|
|
53883
56103
|
const date_str = (/* @__PURE__ */ new Date()).toISOString();
|
|
53884
56104
|
builder.add("header_comment", {
|
|
@@ -53893,18 +56113,27 @@ var import_fast_json_stable_stringify, defineExcellonDrillCommand = ({
|
|
|
53893
56113
|
attribute_value: "tscircuit"
|
|
53894
56114
|
}).add("header_attribute", {
|
|
53895
56115
|
attribute_name: "TF.FileFunction",
|
|
53896
|
-
attribute_value:
|
|
56116
|
+
attribute_value: getFileFunctionLayerSpan({
|
|
56117
|
+
circuitJson,
|
|
56118
|
+
is_plated,
|
|
56119
|
+
layer_span
|
|
56120
|
+
})
|
|
53897
56121
|
}).add("FMAT", { format: 2 }).add("unit_format", { unit: "METRIC", lz: null });
|
|
53898
56122
|
let tool_counter = 10;
|
|
53899
56123
|
const diameterToToolNumber = {};
|
|
53900
|
-
for (const element of
|
|
53901
|
-
if (element.type !== "
|
|
56124
|
+
for (const element of drillElements) {
|
|
56125
|
+
if (element.type !== "pcb_cutout" && !shouldIncludeElement({
|
|
56126
|
+
element,
|
|
56127
|
+
is_plated,
|
|
56128
|
+
layer_span,
|
|
56129
|
+
layerCount
|
|
56130
|
+
})) {
|
|
53902
56131
|
continue;
|
|
53903
56132
|
}
|
|
53904
|
-
if (
|
|
56133
|
+
if (is_plated && element.type === "pcb_hole") {
|
|
53905
56134
|
continue;
|
|
53906
56135
|
}
|
|
53907
|
-
const holeDiameter =
|
|
56136
|
+
const holeDiameter = getHoleDiameter(element);
|
|
53908
56137
|
if (!holeDiameter)
|
|
53909
56138
|
continue;
|
|
53910
56139
|
if (!diameterToToolNumber[holeDiameter]) {
|
|
@@ -53924,22 +56153,27 @@ var import_fast_json_stable_stringify, defineExcellonDrillCommand = ({
|
|
|
53924
56153
|
builder.add("G05", {});
|
|
53925
56154
|
for (let i3 = 10;i3 < tool_counter; i3++) {
|
|
53926
56155
|
builder.add("use_tool", { tool_number: i3 });
|
|
53927
|
-
for (const element of
|
|
53928
|
-
if (element.type === "pcb_plated_hole" || element.type === "pcb_hole" || element.type === "pcb_via") {
|
|
53929
|
-
if (
|
|
56156
|
+
for (const element of drillElements) {
|
|
56157
|
+
if (element.type === "pcb_plated_hole" || element.type === "pcb_hole" || element.type === "pcb_via" || element.type === "pcb_cutout") {
|
|
56158
|
+
if (element.type !== "pcb_cutout" && !shouldIncludeElement({
|
|
56159
|
+
element,
|
|
56160
|
+
is_plated,
|
|
56161
|
+
layer_span,
|
|
56162
|
+
layerCount
|
|
56163
|
+
})) {
|
|
56164
|
+
continue;
|
|
56165
|
+
}
|
|
56166
|
+
if (is_plated && element.type === "pcb_hole") {
|
|
53930
56167
|
continue;
|
|
53931
56168
|
}
|
|
53932
|
-
const holeDiameter =
|
|
56169
|
+
const holeDiameter = getHoleDiameter(element);
|
|
53933
56170
|
if (!holeDiameter || diameterToToolNumber[holeDiameter] !== i3) {
|
|
53934
56171
|
continue;
|
|
53935
56172
|
}
|
|
53936
|
-
const
|
|
53937
|
-
const
|
|
53938
|
-
const
|
|
53939
|
-
const
|
|
53940
|
-
const centerX = elementX + offsetX;
|
|
53941
|
-
const centerY = elementY + offsetY;
|
|
53942
|
-
const yMultiplier = flip_y_axis ? -1 : 1;
|
|
56173
|
+
const drillCenter = getDrillCenter(element);
|
|
56174
|
+
const centerX = drillCenter.x;
|
|
56175
|
+
const centerY = drillCenter.y;
|
|
56176
|
+
const yMultiplier = getYMultiplier(flip_y_axis);
|
|
53943
56177
|
if ("hole_width" in element && typeof element.hole_width === "number" && "hole_height" in element && typeof element.hole_height === "number") {
|
|
53944
56178
|
const holeWidth = element.hole_width;
|
|
53945
56179
|
const holeHeight = element.hole_height;
|
|
@@ -53952,14 +56186,16 @@ var import_fast_json_stable_stringify, defineExcellonDrillCommand = ({
|
|
|
53952
56186
|
});
|
|
53953
56187
|
continue;
|
|
53954
56188
|
}
|
|
53955
|
-
const rotationDegrees =
|
|
56189
|
+
const rotationDegrees = getHoleRotationDegrees(element);
|
|
53956
56190
|
const rotationRadians = rotationDegrees * Math.PI / 180;
|
|
53957
56191
|
const cosTheta = Math.cos(rotationRadians);
|
|
53958
56192
|
const sinTheta = Math.sin(rotationRadians);
|
|
53959
|
-
const isWidthMajor = holeWidth >= holeHeight;
|
|
53960
56193
|
const slotHalfLength = (maxDim - minDim) / 2;
|
|
53961
|
-
const
|
|
53962
|
-
|
|
56194
|
+
const { startRelative, endRelative } = getSlotEndpoints({
|
|
56195
|
+
holeWidth,
|
|
56196
|
+
holeHeight,
|
|
56197
|
+
slotHalfLength
|
|
56198
|
+
});
|
|
53963
56199
|
const rotatePoint4 = ({ x: x4, y: y4 }) => ({
|
|
53964
56200
|
x: x4 * cosTheta - y4 * sinTheta,
|
|
53965
56201
|
y: x4 * sinTheta + y4 * cosTheta
|
|
@@ -54061,7 +56297,7 @@ var import_fast_json_stable_stringify, defineExcellonDrillCommand = ({
|
|
|
54061
56297
|
0 $4 = Circle center offset
|
|
54062
56298
|
0 21 = Center Line(Exposure, Width, Height, Center X, Center Y, Rotation)*
|
|
54063
56299
|
0 1 = Circle(Exposure, Diameter, Center X, Center Y, Rotation)*
|
|
54064
|
-
21,1,$1,$2,0.0,0.0,0.0*
|
|
56300
|
+
21,1,$1-$3,$2,0.0,0.0,0.0*
|
|
54065
56301
|
1,1,$3,0.0-$4,0.0*
|
|
54066
56302
|
1,1,$3,$4,0.0*
|
|
54067
56303
|
`.trim()
|
|
@@ -54075,12 +56311,12 @@ var import_fast_json_stable_stringify, defineExcellonDrillCommand = ({
|
|
|
54075
56311
|
0 $3 = Circle diameter (equal to width)*
|
|
54076
56312
|
0 $4 = Circle center offset
|
|
54077
56313
|
0 21 = Center Line(Exposure, Width, Height, Center X, Center Y, Rotation)*
|
|
54078
|
-
21,1,$1,$2,0.0,0.0,0.0*
|
|
56314
|
+
21,1,$1,$2-$3,0.0,0.0,0.0*
|
|
54079
56315
|
1,1,$3,0.0,0.0-$4*
|
|
54080
56316
|
1,1,$3,0.0,$4*
|
|
54081
56317
|
`.trim()
|
|
54082
56318
|
}).add("define_macro_aperture_template", {
|
|
54083
|
-
macro_name: "
|
|
56319
|
+
macro_name: "ROUNDRECT",
|
|
54084
56320
|
template_code: `
|
|
54085
56321
|
0 Rectangle with rounded corners*
|
|
54086
56322
|
0 $1 Corner radius*
|
|
@@ -54099,7 +56335,117 @@ var import_fast_json_stable_stringify, defineExcellonDrillCommand = ({
|
|
|
54099
56335
|
20,1,$1+$1,$8,$9,$2,$3,0*
|
|
54100
56336
|
`.trim()
|
|
54101
56337
|
}).add("comment", { comment: "APERTURE MACROS END" }).build());
|
|
54102
|
-
},
|
|
56338
|
+
}, SILKSCREEN_SHAPE_TYPES, isSilkscreenShape = (element) => SILKSCREEN_SHAPE_TYPES.includes(element.type), DEFAULT_STROKE_WIDTH2 = 0.1, ELLIPSE_SEGMENTS = 48, CORNER_SEGMENTS = 12, rotationAboutCenter = (center2, ccwDegrees) => ccwDegrees ? compose9(translate9(center2.x, center2.y), rotate12(ccwDegrees * Math.PI / 180), translate9(-center2.x, -center2.y)) : identity8(), ellipseRoute = (center2, radiusX, radiusY, ccwDegrees = 0) => {
|
|
56339
|
+
const matrix2 = rotationAboutCenter(center2, ccwDegrees);
|
|
56340
|
+
return Array.from({ length: ELLIPSE_SEGMENTS + 1 }, (_4, i3) => {
|
|
56341
|
+
const angle = i3 / ELLIPSE_SEGMENTS * Math.PI * 2;
|
|
56342
|
+
return applyToPoint26(matrix2, {
|
|
56343
|
+
x: center2.x + radiusX * Math.cos(angle),
|
|
56344
|
+
y: center2.y + radiusY * Math.sin(angle)
|
|
56345
|
+
});
|
|
56346
|
+
});
|
|
56347
|
+
}, rectangleRoute = (center2, width, height, cornerRadius, ccwDegrees = 0) => {
|
|
56348
|
+
const halfW = width / 2;
|
|
56349
|
+
const halfH = height / 2;
|
|
56350
|
+
const route = [];
|
|
56351
|
+
if (cornerRadius <= 0) {
|
|
56352
|
+
const bounds = getBoundFromCenteredRect2({ center: center2, width, height });
|
|
56353
|
+
route.push({ x: bounds.minX, y: bounds.minY }, { x: bounds.maxX, y: bounds.minY }, { x: bounds.maxX, y: bounds.maxY }, { x: bounds.minX, y: bounds.maxY });
|
|
56354
|
+
} else {
|
|
56355
|
+
const insetW = halfW - cornerRadius;
|
|
56356
|
+
const insetH = halfH - cornerRadius;
|
|
56357
|
+
const corners = [
|
|
56358
|
+
{ x: center2.x + insetW, y: center2.y + insetH, start: 0 },
|
|
56359
|
+
{ x: center2.x - insetW, y: center2.y + insetH, start: Math.PI / 2 },
|
|
56360
|
+
{ x: center2.x - insetW, y: center2.y - insetH, start: Math.PI },
|
|
56361
|
+
{ x: center2.x + insetW, y: center2.y - insetH, start: 3 * Math.PI / 2 }
|
|
56362
|
+
];
|
|
56363
|
+
for (const corner of corners) {
|
|
56364
|
+
for (let i3 = 0;i3 <= CORNER_SEGMENTS; i3++) {
|
|
56365
|
+
const angle = corner.start + i3 / CORNER_SEGMENTS * (Math.PI / 2);
|
|
56366
|
+
route.push({
|
|
56367
|
+
x: corner.x + cornerRadius * Math.cos(angle),
|
|
56368
|
+
y: corner.y + cornerRadius * Math.sin(angle)
|
|
56369
|
+
});
|
|
56370
|
+
}
|
|
56371
|
+
}
|
|
56372
|
+
}
|
|
56373
|
+
route.push(route[0]);
|
|
56374
|
+
const matrix2 = rotationAboutCenter(center2, ccwDegrees);
|
|
56375
|
+
return route.map((point9) => applyToPoint26(matrix2, point9));
|
|
56376
|
+
}, clampCornerRadius = (width, height, cornerRadius) => {
|
|
56377
|
+
if (typeof cornerRadius !== "number" || cornerRadius <= 0)
|
|
56378
|
+
return 0;
|
|
56379
|
+
return Math.min(cornerRadius, width / 2, height / 2);
|
|
56380
|
+
}, getSilkscreenShapeStroke = (element) => {
|
|
56381
|
+
const strokeWidth = element.stroke_width ?? DEFAULT_STROKE_WIDTH2;
|
|
56382
|
+
switch (element.type) {
|
|
56383
|
+
case "pcb_silkscreen_line":
|
|
56384
|
+
return {
|
|
56385
|
+
route: [
|
|
56386
|
+
{ x: element.x1, y: element.y1 },
|
|
56387
|
+
{ x: element.x2, y: element.y2 }
|
|
56388
|
+
],
|
|
56389
|
+
strokeWidth
|
|
56390
|
+
};
|
|
56391
|
+
case "pcb_silkscreen_rect":
|
|
56392
|
+
return {
|
|
56393
|
+
route: rectangleRoute(element.center, element.width, element.height, clampCornerRadius(element.width, element.height, element.corner_radius), element.ccw_rotation ?? 0),
|
|
56394
|
+
strokeWidth
|
|
56395
|
+
};
|
|
56396
|
+
case "pcb_silkscreen_circle":
|
|
56397
|
+
return {
|
|
56398
|
+
route: ellipseRoute(element.center, element.radius, element.radius),
|
|
56399
|
+
strokeWidth
|
|
56400
|
+
};
|
|
56401
|
+
case "pcb_silkscreen_oval":
|
|
56402
|
+
return {
|
|
56403
|
+
route: ellipseRoute(element.center, element.radius_x, element.radius_y, element.ccw_rotation ?? 0),
|
|
56404
|
+
strokeWidth
|
|
56405
|
+
};
|
|
56406
|
+
case "pcb_silkscreen_pill":
|
|
56407
|
+
return {
|
|
56408
|
+
route: rectangleRoute(element.center, element.width, element.height, Math.min(element.width, element.height) / 2),
|
|
56409
|
+
strokeWidth
|
|
56410
|
+
};
|
|
56411
|
+
default:
|
|
56412
|
+
return null;
|
|
56413
|
+
}
|
|
56414
|
+
}, getLayerRefFromGerberLayerName = (glayer_name) => {
|
|
56415
|
+
if (glayer_name.startsWith("F_"))
|
|
56416
|
+
return "top";
|
|
56417
|
+
if (glayer_name.startsWith("B_"))
|
|
56418
|
+
return "bottom";
|
|
56419
|
+
const innerLayerMatch = glayer_name.match(/^In([1-6])_/);
|
|
56420
|
+
if (innerLayerMatch)
|
|
56421
|
+
return `inner${innerLayerMatch[1]}`;
|
|
56422
|
+
throw new Error(`Could not infer layer ref from ${glayer_name}`);
|
|
56423
|
+
}, getClampedRoundedRectCornerRadius = (width, height, cornerRadius) => {
|
|
56424
|
+
if (typeof cornerRadius !== "number")
|
|
56425
|
+
return 0;
|
|
56426
|
+
return Math.max(0, Math.min(cornerRadius, width / 2, height / 2));
|
|
56427
|
+
}, getRoundedRectApertureConfig = (width, height, cornerRadius) => {
|
|
56428
|
+
const halfWidth = width / 2;
|
|
56429
|
+
const halfHeight = height / 2;
|
|
56430
|
+
return {
|
|
56431
|
+
macro_name: "ROUNDRECT",
|
|
56432
|
+
corner_radius: cornerRadius,
|
|
56433
|
+
corner_1_x: -halfWidth + cornerRadius,
|
|
56434
|
+
corner_1_y: halfHeight - cornerRadius,
|
|
56435
|
+
corner_2_x: halfWidth - cornerRadius,
|
|
56436
|
+
corner_2_y: halfHeight - cornerRadius,
|
|
56437
|
+
corner_3_x: halfWidth - cornerRadius,
|
|
56438
|
+
corner_3_y: -halfHeight + cornerRadius,
|
|
56439
|
+
corner_4_x: -halfWidth + cornerRadius,
|
|
56440
|
+
corner_4_y: -halfHeight + cornerRadius
|
|
56441
|
+
};
|
|
56442
|
+
}, REGION_APERTURE_CONFIG, getApertureConfigFromPcbSmtpad = (elm) => {
|
|
56443
|
+
if (elm.shape === "rect" || elm.shape === "rotated_rect") {
|
|
56444
|
+
const cornerRadius = getClampedRoundedRectCornerRadius(elm.width, elm.height, "corner_radius" in elm ? elm.corner_radius : undefined);
|
|
56445
|
+
if (cornerRadius > 0) {
|
|
56446
|
+
return getRoundedRectApertureConfig(elm.width, elm.height, cornerRadius);
|
|
56447
|
+
}
|
|
56448
|
+
}
|
|
54103
56449
|
if (elm.shape === "rect") {
|
|
54104
56450
|
return {
|
|
54105
56451
|
standard_template_code: "R",
|
|
@@ -54120,6 +56466,63 @@ var import_fast_json_stable_stringify, defineExcellonDrillCommand = ({
|
|
|
54120
56466
|
y_size: elm.height
|
|
54121
56467
|
};
|
|
54122
56468
|
}
|
|
56469
|
+
if (elm.shape === "pill" || elm.shape === "rotated_pill") {
|
|
56470
|
+
if (!(("width" in elm) && ("height" in elm))) {
|
|
56471
|
+
throw new Error("Invalid pill shape in getApertureConfigFromPcbSmtpad: missing dimensions");
|
|
56472
|
+
}
|
|
56473
|
+
return {
|
|
56474
|
+
standard_template_code: "C",
|
|
56475
|
+
diameter: Math.min(elm.width, elm.height)
|
|
56476
|
+
};
|
|
56477
|
+
}
|
|
56478
|
+
if (elm.shape === "polygon") {
|
|
56479
|
+
throw new Error("Polygon SMT pads are drawn as regions, not apertures");
|
|
56480
|
+
}
|
|
56481
|
+
throw new Error(`Unsupported shape ${elm.shape}`);
|
|
56482
|
+
}, getApertureConfigFromPcbSmtpadSoldermask = (elm) => {
|
|
56483
|
+
let soldermaskMargin = 0;
|
|
56484
|
+
if ("soldermask_margin" in elm && typeof elm.soldermask_margin === "number") {
|
|
56485
|
+
soldermaskMargin = elm.soldermask_margin;
|
|
56486
|
+
}
|
|
56487
|
+
if (elm.shape === "rect" || elm.shape === "rotated_rect") {
|
|
56488
|
+
const width = elm.width + soldermaskMargin * 2;
|
|
56489
|
+
const height = elm.height + soldermaskMargin * 2;
|
|
56490
|
+
const cornerRadius = getClampedRoundedRectCornerRadius(width, height, "corner_radius" in elm && typeof elm.corner_radius === "number" ? elm.corner_radius + soldermaskMargin : undefined);
|
|
56491
|
+
if (cornerRadius > 0) {
|
|
56492
|
+
return getRoundedRectApertureConfig(width, height, cornerRadius);
|
|
56493
|
+
}
|
|
56494
|
+
}
|
|
56495
|
+
if (elm.shape === "rect") {
|
|
56496
|
+
return {
|
|
56497
|
+
standard_template_code: "R",
|
|
56498
|
+
x_size: elm.width + soldermaskMargin * 2,
|
|
56499
|
+
y_size: elm.height + soldermaskMargin * 2
|
|
56500
|
+
};
|
|
56501
|
+
}
|
|
56502
|
+
if (elm.shape === "circle") {
|
|
56503
|
+
return {
|
|
56504
|
+
standard_template_code: "C",
|
|
56505
|
+
diameter: elm.radius * 2 + soldermaskMargin * 2
|
|
56506
|
+
};
|
|
56507
|
+
}
|
|
56508
|
+
if (elm.shape === "rotated_rect") {
|
|
56509
|
+
return {
|
|
56510
|
+
standard_template_code: "R",
|
|
56511
|
+
x_size: elm.width + soldermaskMargin * 2,
|
|
56512
|
+
y_size: elm.height + soldermaskMargin * 2
|
|
56513
|
+
};
|
|
56514
|
+
}
|
|
56515
|
+
if (elm.shape === "pill" || elm.shape === "rotated_pill") {
|
|
56516
|
+
if (!(("width" in elm) && ("height" in elm))) {
|
|
56517
|
+
throw new Error("Invalid pill shape in getApertureConfigFromPcbSmtpadSoldermask: missing dimensions");
|
|
56518
|
+
}
|
|
56519
|
+
const width = elm.width + soldermaskMargin * 2;
|
|
56520
|
+
const height = elm.height + soldermaskMargin * 2;
|
|
56521
|
+
return {
|
|
56522
|
+
standard_template_code: "C",
|
|
56523
|
+
diameter: Math.min(width, height)
|
|
56524
|
+
};
|
|
56525
|
+
}
|
|
54123
56526
|
if (elm.shape === "polygon") {
|
|
54124
56527
|
throw new Error("Polygon SMT pads are drawn as regions, not apertures");
|
|
54125
56528
|
}
|
|
@@ -54148,6 +56551,30 @@ var import_fast_json_stable_stringify, defineExcellonDrillCommand = ({
|
|
|
54148
56551
|
};
|
|
54149
56552
|
}
|
|
54150
56553
|
throw new Error(`Provide font_size for: ${elm}`);
|
|
56554
|
+
}, getApertureConfigFromPcbFabricationNoteText = (elm) => {
|
|
56555
|
+
if ("font_size" in elm) {
|
|
56556
|
+
return {
|
|
56557
|
+
standard_template_code: "C",
|
|
56558
|
+
diameter: elm.font_size / 8
|
|
56559
|
+
};
|
|
56560
|
+
}
|
|
56561
|
+
throw new Error(`Provide font_size for: ${elm}`);
|
|
56562
|
+
}, getApertureConfigFromPcbFabricationNotePath = (elm) => {
|
|
56563
|
+
if (!("stroke_width" in elm) || typeof elm.stroke_width !== "number") {
|
|
56564
|
+
return {
|
|
56565
|
+
standard_template_code: "C",
|
|
56566
|
+
diameter: 0.1
|
|
56567
|
+
};
|
|
56568
|
+
}
|
|
56569
|
+
return {
|
|
56570
|
+
standard_template_code: "C",
|
|
56571
|
+
diameter: elm.stroke_width
|
|
56572
|
+
};
|
|
56573
|
+
}, getApertureConfigFromPcbFabricationNoteDimension = (elm) => {
|
|
56574
|
+
return {
|
|
56575
|
+
standard_template_code: "C",
|
|
56576
|
+
diameter: Math.max(0.05, elm.font_size / 10)
|
|
56577
|
+
};
|
|
54151
56578
|
}, getApertureConfigFromPcbSolderPaste = (elm) => {
|
|
54152
56579
|
if (elm.shape === "rect") {
|
|
54153
56580
|
return {
|
|
@@ -54179,7 +56606,7 @@ var import_fast_json_stable_stringify, defineExcellonDrillCommand = ({
|
|
|
54179
56606
|
x_size: elm.width,
|
|
54180
56607
|
y_size: elm.height,
|
|
54181
56608
|
circle_diameter: Math.min(elm.width, elm.height),
|
|
54182
|
-
circle_center_offset: elm.width / 2
|
|
56609
|
+
circle_center_offset: (elm.width - elm.height) / 2
|
|
54183
56610
|
};
|
|
54184
56611
|
}
|
|
54185
56612
|
return {
|
|
@@ -54187,7 +56614,7 @@ var import_fast_json_stable_stringify, defineExcellonDrillCommand = ({
|
|
|
54187
56614
|
x_size: elm.width,
|
|
54188
56615
|
y_size: elm.height,
|
|
54189
56616
|
circle_diameter: Math.min(elm.width, elm.height),
|
|
54190
|
-
circle_center_offset: elm.height / 2
|
|
56617
|
+
circle_center_offset: (elm.height - elm.width) / 2
|
|
54191
56618
|
};
|
|
54192
56619
|
}
|
|
54193
56620
|
throw new Error(`Unsupported shape ${elm.shape}`);
|
|
@@ -54211,7 +56638,7 @@ var import_fast_json_stable_stringify, defineExcellonDrillCommand = ({
|
|
|
54211
56638
|
x_size: elm.outer_width,
|
|
54212
56639
|
y_size: elm.outer_height,
|
|
54213
56640
|
circle_diameter: Math.min(elm.outer_width, elm.outer_height),
|
|
54214
|
-
circle_center_offset: elm.outer_width / 2
|
|
56641
|
+
circle_center_offset: (elm.outer_width - elm.outer_height) / 2
|
|
54215
56642
|
};
|
|
54216
56643
|
}
|
|
54217
56644
|
return {
|
|
@@ -54219,7 +56646,7 @@ var import_fast_json_stable_stringify, defineExcellonDrillCommand = ({
|
|
|
54219
56646
|
x_size: elm.outer_width,
|
|
54220
56647
|
y_size: elm.outer_height,
|
|
54221
56648
|
circle_diameter: Math.min(elm.outer_width, elm.outer_height),
|
|
54222
|
-
circle_center_offset: elm.outer_height / 2
|
|
56649
|
+
circle_center_offset: (elm.outer_height - elm.outer_width) / 2
|
|
54223
56650
|
};
|
|
54224
56651
|
}
|
|
54225
56652
|
const shape = elm.shape;
|
|
@@ -54234,6 +56661,55 @@ var import_fast_json_stable_stringify, defineExcellonDrillCommand = ({
|
|
|
54234
56661
|
};
|
|
54235
56662
|
}
|
|
54236
56663
|
throw new Error(`Unsupported shape in getApertureConfigFromPcbPlatedHole: ${elm.shape}`);
|
|
56664
|
+
}, getApertureConfigFromPcbPlatedHoleSoldermask = (elm) => {
|
|
56665
|
+
let soldermaskMargin = 0;
|
|
56666
|
+
if ("soldermask_margin" in elm && typeof elm.soldermask_margin === "number") {
|
|
56667
|
+
soldermaskMargin = elm.soldermask_margin;
|
|
56668
|
+
}
|
|
56669
|
+
if (elm.shape === "circle") {
|
|
56670
|
+
if (!(("outer_diameter" in elm) && ("hole_diameter" in elm))) {
|
|
56671
|
+
throw new Error("Invalid circle shape in getApertureConfigFromPcbPlatedHoleSoldermask: missing diameters");
|
|
56672
|
+
}
|
|
56673
|
+
return {
|
|
56674
|
+
standard_template_code: "C",
|
|
56675
|
+
diameter: elm.outer_diameter + soldermaskMargin * 2
|
|
56676
|
+
};
|
|
56677
|
+
}
|
|
56678
|
+
if (elm.shape === "pill") {
|
|
56679
|
+
if (!(("outer_width" in elm) && ("outer_height" in elm))) {
|
|
56680
|
+
throw new Error("Invalid pill shape in getApertureConfigFromPcbPlatedHoleSoldermask: missing dimensions");
|
|
56681
|
+
}
|
|
56682
|
+
const outerWidth = elm.outer_width + soldermaskMargin * 2;
|
|
56683
|
+
const outerHeight = elm.outer_height + soldermaskMargin * 2;
|
|
56684
|
+
if (outerWidth > outerHeight) {
|
|
56685
|
+
return {
|
|
56686
|
+
macro_name: "HORZPILL",
|
|
56687
|
+
x_size: outerWidth,
|
|
56688
|
+
y_size: outerHeight,
|
|
56689
|
+
circle_diameter: Math.min(outerWidth, outerHeight),
|
|
56690
|
+
circle_center_offset: (outerWidth - outerHeight) / 2
|
|
56691
|
+
};
|
|
56692
|
+
}
|
|
56693
|
+
return {
|
|
56694
|
+
macro_name: "VERTPILL",
|
|
56695
|
+
x_size: outerWidth,
|
|
56696
|
+
y_size: outerHeight,
|
|
56697
|
+
circle_diameter: Math.min(outerWidth, outerHeight),
|
|
56698
|
+
circle_center_offset: (outerHeight - outerWidth) / 2
|
|
56699
|
+
};
|
|
56700
|
+
}
|
|
56701
|
+
const shape = elm.shape;
|
|
56702
|
+
if (shape === "circular_hole_with_rect_pad" || shape === "pill_hole_with_rect_pad" || shape === "rotated_pill_hole_with_rect_pad") {
|
|
56703
|
+
if (!(("rect_pad_width" in elm) && ("rect_pad_height" in elm))) {
|
|
56704
|
+
throw new Error(`Invalid ${shape} shape in getApertureConfigFromPcbPlatedHoleSoldermask: missing dimensions`);
|
|
56705
|
+
}
|
|
56706
|
+
return {
|
|
56707
|
+
standard_template_code: "R",
|
|
56708
|
+
x_size: elm.rect_pad_width + soldermaskMargin * 2,
|
|
56709
|
+
y_size: elm.rect_pad_height + soldermaskMargin * 2
|
|
56710
|
+
};
|
|
56711
|
+
}
|
|
56712
|
+
throw new Error(`Unsupported shape in getApertureConfigFromPcbPlatedHoleSoldermask: ${elm.shape}`);
|
|
54237
56713
|
}, getApertureConfigFromCirclePcbHole = (elm) => {
|
|
54238
56714
|
if (!("hole_diameter" in elm)) {
|
|
54239
56715
|
throw new Error(`Invalid shape called in getApertureConfigFromCirclePcbHole: ${elm.hole_shape}`);
|
|
@@ -54242,9 +56718,21 @@ var import_fast_json_stable_stringify, defineExcellonDrillCommand = ({
|
|
|
54242
56718
|
standard_template_code: "C",
|
|
54243
56719
|
diameter: elm.hole_diameter
|
|
54244
56720
|
};
|
|
54245
|
-
},
|
|
54246
|
-
if (!("
|
|
54247
|
-
throw new Error(
|
|
56721
|
+
}, getApertureConfigFromCirclePcbHoleSoldermask = (elm) => {
|
|
56722
|
+
if (!("hole_diameter" in elm)) {
|
|
56723
|
+
throw new Error(`Invalid shape called in getApertureConfigFromCirclePcbHoleSoldermask: ${elm.hole_shape}`);
|
|
56724
|
+
}
|
|
56725
|
+
let soldermaskMargin = 0;
|
|
56726
|
+
if ("soldermask_margin" in elm && typeof elm.soldermask_margin === "number") {
|
|
56727
|
+
soldermaskMargin = elm.soldermask_margin;
|
|
56728
|
+
}
|
|
56729
|
+
return {
|
|
56730
|
+
standard_template_code: "C",
|
|
56731
|
+
diameter: elm.hole_diameter + soldermaskMargin * 2
|
|
56732
|
+
};
|
|
56733
|
+
}, getApertureConfigFromOuterDiameter = (elm) => {
|
|
56734
|
+
if (typeof elm.outer_diameter !== "number") {
|
|
56735
|
+
throw new Error("outer_diameter not specified in getApertureConfigFromOuterDiameter");
|
|
54248
56736
|
}
|
|
54249
56737
|
return {
|
|
54250
56738
|
standard_template_code: "C",
|
|
@@ -54262,8 +56750,22 @@ var import_fast_json_stable_stringify, defineExcellonDrillCommand = ({
|
|
|
54262
56750
|
throw new Error(`Aperture not found for search params ${JSON.stringify(search_params)}`);
|
|
54263
56751
|
}
|
|
54264
56752
|
return aperture.aperture_number;
|
|
54265
|
-
}, package_default5, layerAndTypeToFileFunction,
|
|
54266
|
-
|
|
56753
|
+
}, package_default5, layerAndTypeToFileFunction, getCopperLayerNumber = (layer, total_layer_count) => {
|
|
56754
|
+
if (layer === "top")
|
|
56755
|
+
return 1;
|
|
56756
|
+
if (layer === "bottom")
|
|
56757
|
+
return total_layer_count;
|
|
56758
|
+
return Number(layer.replace("inner", "")) + 1;
|
|
56759
|
+
}, getCommandHeaders = (opts) => {
|
|
56760
|
+
const total_layer_count = opts.total_layer_count ?? 2;
|
|
56761
|
+
let file_function;
|
|
56762
|
+
if (opts.layer_type === "copper" && opts.layer !== "edgecut") {
|
|
56763
|
+
const layerNumber = getCopperLayerNumber(opts.layer, total_layer_count);
|
|
56764
|
+
const layerPosition = opts.layer === "top" ? "Top" : opts.layer === "bottom" ? "Bot" : "Inr";
|
|
56765
|
+
file_function = `Copper,L${layerNumber},${layerPosition}`;
|
|
56766
|
+
} else {
|
|
56767
|
+
file_function = layerAndTypeToFileFunction[opts.layer_type ? `${opts.layer}-${opts.layer_type}` : opts.layer];
|
|
56768
|
+
}
|
|
54267
56769
|
return gerberBuilder().add("add_attribute_on_file", {
|
|
54268
56770
|
attribute_name: "GenerationSoftware",
|
|
54269
56771
|
attribute_value: `tscircuit,circuit-json-to-gerber,${package_default5.version}`
|
|
@@ -54291,14 +56793,564 @@ var import_fast_json_stable_stringify, defineExcellonDrillCommand = ({
|
|
|
54291
56793
|
}, layerRefToGerberPrefix, layerTypeToGerberSuffix, getGerberLayerName = (layer_ref2, layer_type) => {
|
|
54292
56794
|
if (layer_ref2 === "edgecut")
|
|
54293
56795
|
return "Edge_Cuts";
|
|
56796
|
+
if (layer_ref2.startsWith("inner") && layer_type !== "copper") {
|
|
56797
|
+
throw new Error(`Inner layer ${layer_ref2} only supports copper gerbers`);
|
|
56798
|
+
}
|
|
54294
56799
|
return `${layerRefToGerberPrefix[layer_ref2]}${layerTypeToGerberSuffix[layer_type]}`;
|
|
54295
|
-
},
|
|
56800
|
+
}, getSignedPolygonArea = (points) => {
|
|
56801
|
+
let area2 = 0;
|
|
56802
|
+
for (let i3 = 0;i3 < points.length; i3++) {
|
|
56803
|
+
const current2 = points[i3];
|
|
56804
|
+
const next = points[(i3 + 1) % points.length];
|
|
56805
|
+
area2 += current2.x * next.y - next.x * current2.y;
|
|
56806
|
+
}
|
|
56807
|
+
return area2 / 2;
|
|
56808
|
+
}, getLineIntersection = (lineA, lineB) => {
|
|
56809
|
+
const ax3 = lineA.end.x - lineA.start.x;
|
|
56810
|
+
const ay3 = lineA.end.y - lineA.start.y;
|
|
56811
|
+
const bx3 = lineB.end.x - lineB.start.x;
|
|
56812
|
+
const by3 = lineB.end.y - lineB.start.y;
|
|
56813
|
+
const denominator = ax3 * by3 - ay3 * bx3;
|
|
56814
|
+
if (Math.abs(denominator) < 0.000000001) {
|
|
56815
|
+
return null;
|
|
56816
|
+
}
|
|
56817
|
+
const cx3 = lineB.start.x - lineA.start.x;
|
|
56818
|
+
const cy3 = lineB.start.y - lineA.start.y;
|
|
56819
|
+
const t50 = (cx3 * by3 - cy3 * bx3) / denominator;
|
|
56820
|
+
return {
|
|
56821
|
+
x: lineA.start.x + ax3 * t50,
|
|
56822
|
+
y: lineA.start.y + ay3 * t50
|
|
56823
|
+
};
|
|
56824
|
+
}, offsetPolygonOutline = (points, offset) => {
|
|
56825
|
+
if (points.length < 3 || offset === 0) {
|
|
56826
|
+
return points;
|
|
56827
|
+
}
|
|
56828
|
+
const isCounterClockwise = getSignedPolygonArea(points) > 0;
|
|
56829
|
+
const shiftedEdges = [];
|
|
56830
|
+
for (let i3 = 0;i3 < points.length; i3++) {
|
|
56831
|
+
const start = points[i3];
|
|
56832
|
+
const end = points[(i3 + 1) % points.length];
|
|
56833
|
+
const dx3 = end.x - start.x;
|
|
56834
|
+
const dy3 = end.y - start.y;
|
|
56835
|
+
const length67 = Math.sqrt(dx3 * dx3 + dy3 * dy3);
|
|
56836
|
+
if (length67 < 0.000000001) {
|
|
56837
|
+
continue;
|
|
56838
|
+
}
|
|
56839
|
+
let normalX = -dy3 / length67;
|
|
56840
|
+
let normalY = dx3 / length67;
|
|
56841
|
+
if (isCounterClockwise) {
|
|
56842
|
+
normalX = dy3 / length67;
|
|
56843
|
+
normalY = -dx3 / length67;
|
|
56844
|
+
}
|
|
56845
|
+
shiftedEdges.push({
|
|
56846
|
+
start: {
|
|
56847
|
+
x: start.x + normalX * offset,
|
|
56848
|
+
y: start.y + normalY * offset
|
|
56849
|
+
},
|
|
56850
|
+
end: {
|
|
56851
|
+
x: end.x + normalX * offset,
|
|
56852
|
+
y: end.y + normalY * offset
|
|
56853
|
+
}
|
|
56854
|
+
});
|
|
56855
|
+
}
|
|
56856
|
+
if (shiftedEdges.length < 3) {
|
|
56857
|
+
return points;
|
|
56858
|
+
}
|
|
56859
|
+
const offsetPoints = [];
|
|
56860
|
+
for (let i3 = 0;i3 < shiftedEdges.length; i3++) {
|
|
56861
|
+
const previousEdge = shiftedEdges[(i3 - 1 + shiftedEdges.length) % shiftedEdges.length];
|
|
56862
|
+
const currentEdge = shiftedEdges[i3];
|
|
56863
|
+
const intersection = getLineIntersection(previousEdge, currentEdge);
|
|
56864
|
+
if (intersection) {
|
|
56865
|
+
offsetPoints.push(intersection);
|
|
56866
|
+
} else {
|
|
56867
|
+
offsetPoints.push(currentEdge.start);
|
|
56868
|
+
}
|
|
56869
|
+
}
|
|
56870
|
+
return offsetPoints;
|
|
56871
|
+
}, outerLayerRefs, isOuterLayerRef = (layerRef) => layerRef === "top" || layerRef === "bottom", isFabricationElementOnLayer = (element, layerRef) => (element.type === "pcb_fabrication_note_text" || element.type === "pcb_fabrication_note_path" || element.type === "pcb_fabrication_note_rect" || element.type === "pcb_fabrication_note_dimension") && element.layer === layerRef, getFabricationLayerRefs = (circuitJson) => outerLayerRefs.filter((layerRef) => circuitJson.some((element) => isFabricationElementOnLayer(element, layerRef))), getFabRectPoints = (element) => {
|
|
56872
|
+
const bounds = getBoundFromCenteredRect3({
|
|
56873
|
+
center: element.center,
|
|
56874
|
+
width: element.width,
|
|
56875
|
+
height: element.height
|
|
56876
|
+
});
|
|
56877
|
+
return [
|
|
56878
|
+
{ x: bounds.minX, y: bounds.minY },
|
|
56879
|
+
{ x: bounds.maxX, y: bounds.minY },
|
|
56880
|
+
{ x: bounds.maxX, y: bounds.maxY },
|
|
56881
|
+
{ x: bounds.minX, y: bounds.maxY }
|
|
56882
|
+
];
|
|
56883
|
+
}, renderOpenPath = ({
|
|
56884
|
+
element,
|
|
56885
|
+
glayer,
|
|
56886
|
+
apertureConfig,
|
|
56887
|
+
route,
|
|
56888
|
+
mapY
|
|
56889
|
+
}) => {
|
|
56890
|
+
if (route.length === 0)
|
|
56891
|
+
return;
|
|
56892
|
+
const gerber = gerberBuilder().add("select_aperture", {
|
|
56893
|
+
aperture_number: findApertureNumber(glayer, apertureConfig)
|
|
56894
|
+
});
|
|
56895
|
+
gerber.add("move_operation", {
|
|
56896
|
+
x: route[0].x,
|
|
56897
|
+
y: mapY(route[0].y)
|
|
56898
|
+
});
|
|
56899
|
+
const isDashed = element.is_stroke_dashed === true;
|
|
56900
|
+
if (!isDashed) {
|
|
56901
|
+
for (let i3 = 1;i3 < route.length; i3++) {
|
|
56902
|
+
gerber.add("plot_operation", {
|
|
56903
|
+
x: route[i3].x,
|
|
56904
|
+
y: mapY(route[i3].y)
|
|
56905
|
+
});
|
|
56906
|
+
}
|
|
56907
|
+
glayer.push(...gerber.build());
|
|
56908
|
+
return;
|
|
56909
|
+
}
|
|
56910
|
+
const dashLength = Math.max(0.2, (element.stroke_width ?? 0.1) * 4);
|
|
56911
|
+
const gapLength = dashLength;
|
|
56912
|
+
for (const [start, end] of pairs3(route)) {
|
|
56913
|
+
const dx3 = end.x - start.x;
|
|
56914
|
+
const dy3 = end.y - start.y;
|
|
56915
|
+
const length67 = Math.hypot(dx3, dy3);
|
|
56916
|
+
if (length67 <= 0.000000001)
|
|
56917
|
+
continue;
|
|
56918
|
+
const ux3 = dx3 / length67;
|
|
56919
|
+
const uy3 = dy3 / length67;
|
|
56920
|
+
let distance49 = 0;
|
|
56921
|
+
while (distance49 < length67) {
|
|
56922
|
+
const dashEndDistance = Math.min(distance49 + dashLength, length67);
|
|
56923
|
+
const dashStart = {
|
|
56924
|
+
x: start.x + ux3 * distance49,
|
|
56925
|
+
y: start.y + uy3 * distance49
|
|
56926
|
+
};
|
|
56927
|
+
const dashEnd = {
|
|
56928
|
+
x: start.x + ux3 * dashEndDistance,
|
|
56929
|
+
y: start.y + uy3 * dashEndDistance
|
|
56930
|
+
};
|
|
56931
|
+
gerber.add("move_operation", {
|
|
56932
|
+
x: dashStart.x,
|
|
56933
|
+
y: mapY(dashStart.y)
|
|
56934
|
+
});
|
|
56935
|
+
gerber.add("plot_operation", {
|
|
56936
|
+
x: dashEnd.x,
|
|
56937
|
+
y: mapY(dashEnd.y)
|
|
56938
|
+
});
|
|
56939
|
+
distance49 += dashLength + gapLength;
|
|
56940
|
+
}
|
|
56941
|
+
}
|
|
56942
|
+
glayer.push(...gerber.build());
|
|
56943
|
+
}, renderFabricationDimension = ({
|
|
56944
|
+
element,
|
|
56945
|
+
glayer,
|
|
56946
|
+
mapY,
|
|
56947
|
+
renderText: renderText2
|
|
56948
|
+
}) => {
|
|
56949
|
+
const from = element.from;
|
|
56950
|
+
const to3 = element.to;
|
|
56951
|
+
const dx3 = to3.x - from.x;
|
|
56952
|
+
const dy3 = to3.y - from.y;
|
|
56953
|
+
const length67 = Math.hypot(dx3, dy3);
|
|
56954
|
+
if (length67 <= 0.000000001)
|
|
56955
|
+
return;
|
|
56956
|
+
const offsetDistance = element.offset_distance ?? element.offset ?? 0;
|
|
56957
|
+
const defaultOffsetDirection = { x: -dy3 / length67, y: dx3 / length67 };
|
|
56958
|
+
const offsetDirection = element.offset_direction ?? defaultOffsetDirection;
|
|
56959
|
+
const offsetMagnitude = Math.hypot(offsetDirection.x, offsetDirection.y) || 1;
|
|
56960
|
+
const offsetVector = {
|
|
56961
|
+
x: offsetDirection.x / offsetMagnitude * offsetDistance,
|
|
56962
|
+
y: offsetDirection.y / offsetMagnitude * offsetDistance
|
|
56963
|
+
};
|
|
56964
|
+
const dimStart = { x: from.x + offsetVector.x, y: from.y + offsetVector.y };
|
|
56965
|
+
const dimEnd = { x: to3.x + offsetVector.x, y: to3.y + offsetVector.y };
|
|
56966
|
+
const arrowSize = element.arrow_size ?? 1;
|
|
56967
|
+
const ux3 = dx3 / length67;
|
|
56968
|
+
const uy3 = dy3 / length67;
|
|
56969
|
+
const px3 = -uy3;
|
|
56970
|
+
const py3 = ux3;
|
|
56971
|
+
const arrowHalfWidth = arrowSize * 0.35;
|
|
56972
|
+
const lineConfig = getApertureConfigFromPcbFabricationNoteDimension(element);
|
|
56973
|
+
renderOpenPath({
|
|
56974
|
+
element,
|
|
56975
|
+
glayer,
|
|
56976
|
+
apertureConfig: lineConfig,
|
|
56977
|
+
route: [from, dimStart, dimEnd, to3],
|
|
56978
|
+
mapY
|
|
56979
|
+
});
|
|
56980
|
+
renderOpenPath({
|
|
56981
|
+
element,
|
|
56982
|
+
glayer,
|
|
56983
|
+
apertureConfig: lineConfig,
|
|
56984
|
+
route: [
|
|
56985
|
+
{
|
|
56986
|
+
x: dimStart.x + ux3 * arrowSize + px3 * arrowHalfWidth,
|
|
56987
|
+
y: dimStart.y + uy3 * arrowSize + py3 * arrowHalfWidth
|
|
56988
|
+
},
|
|
56989
|
+
dimStart,
|
|
56990
|
+
{
|
|
56991
|
+
x: dimStart.x + ux3 * arrowSize - px3 * arrowHalfWidth,
|
|
56992
|
+
y: dimStart.y + uy3 * arrowSize - py3 * arrowHalfWidth
|
|
56993
|
+
}
|
|
56994
|
+
],
|
|
56995
|
+
mapY
|
|
56996
|
+
});
|
|
56997
|
+
renderOpenPath({
|
|
56998
|
+
element,
|
|
56999
|
+
glayer,
|
|
57000
|
+
apertureConfig: lineConfig,
|
|
57001
|
+
route: [
|
|
57002
|
+
{
|
|
57003
|
+
x: dimEnd.x - ux3 * arrowSize + px3 * arrowHalfWidth,
|
|
57004
|
+
y: dimEnd.y - uy3 * arrowSize + py3 * arrowHalfWidth
|
|
57005
|
+
},
|
|
57006
|
+
dimEnd,
|
|
57007
|
+
{
|
|
57008
|
+
x: dimEnd.x - ux3 * arrowSize - px3 * arrowHalfWidth,
|
|
57009
|
+
y: dimEnd.y - uy3 * arrowSize - py3 * arrowHalfWidth
|
|
57010
|
+
}
|
|
57011
|
+
],
|
|
57012
|
+
mapY
|
|
57013
|
+
});
|
|
57014
|
+
if (element.text) {
|
|
57015
|
+
renderText2({
|
|
57016
|
+
...element,
|
|
57017
|
+
anchor_position: {
|
|
57018
|
+
x: (dimStart.x + dimEnd.x) / 2,
|
|
57019
|
+
y: (dimStart.y + dimEnd.y) / 2
|
|
57020
|
+
},
|
|
57021
|
+
anchor_alignment: "center",
|
|
57022
|
+
ccw_rotation: element.text_ccw_rotation ?? Math.atan2(dy3, dx3) * 180 / Math.PI
|
|
57023
|
+
});
|
|
57024
|
+
}
|
|
57025
|
+
}, roundedRectCornerArcSegmentCount = 8, circleCutoutPolygonSegmentCount2 = 64, getBoardOutlinePolygon = (board) => {
|
|
57026
|
+
if (board.outline && board.outline.length > 2) {
|
|
57027
|
+
return [board.outline.map((point9) => [point9.x, point9.y])];
|
|
57028
|
+
}
|
|
57029
|
+
const bounds = getBoundFromCenteredRect4({
|
|
57030
|
+
center: board.center,
|
|
57031
|
+
width: board.width,
|
|
57032
|
+
height: board.height
|
|
57033
|
+
});
|
|
57034
|
+
return [
|
|
57035
|
+
[
|
|
57036
|
+
[bounds.minX, bounds.minY],
|
|
57037
|
+
[bounds.maxX, bounds.minY],
|
|
57038
|
+
[bounds.maxX, bounds.maxY],
|
|
57039
|
+
[bounds.minX, bounds.maxY]
|
|
57040
|
+
]
|
|
57041
|
+
];
|
|
57042
|
+
}, getBoardOutlinePolygons2 = (circuitJson) => circuitJson.filter((element) => element.type === "pcb_board").map(getBoardOutlinePolygon), getRectCutoutOutlinePoints = (cutout) => {
|
|
57043
|
+
const { center: center2, width, height, rotation: rotation11, corner_radius } = cutout;
|
|
57044
|
+
const w4 = width / 2;
|
|
57045
|
+
const h4 = height / 2;
|
|
57046
|
+
const r4 = Math.max(0, Math.min(corner_radius ?? 0, Math.abs(w4), Math.abs(h4)));
|
|
57047
|
+
let transformMatrix = translate22(center2.x, center2.y);
|
|
57048
|
+
if (rotation11) {
|
|
57049
|
+
transformMatrix = compose22(transformMatrix, rotate22(rotation11 * Math.PI / 180));
|
|
57050
|
+
}
|
|
57051
|
+
if (r4 === 0) {
|
|
57052
|
+
return [
|
|
57053
|
+
{ x: -w4, y: h4 },
|
|
57054
|
+
{ x: w4, y: h4 },
|
|
57055
|
+
{ x: w4, y: -h4 },
|
|
57056
|
+
{ x: -w4, y: -h4 }
|
|
57057
|
+
].map((point9) => applyToPoint25(transformMatrix, point9));
|
|
57058
|
+
}
|
|
57059
|
+
const points = [];
|
|
57060
|
+
const corners = [
|
|
57061
|
+
{ center: { x: w4 - r4, y: h4 - r4 }, start: Math.PI / 2, end: 0 },
|
|
57062
|
+
{ center: { x: w4 - r4, y: -h4 + r4 }, start: 0, end: -Math.PI / 2 },
|
|
57063
|
+
{ center: { x: -w4 + r4, y: -h4 + r4 }, start: -Math.PI / 2, end: -Math.PI },
|
|
57064
|
+
{ center: { x: -w4 + r4, y: h4 - r4 }, start: Math.PI, end: Math.PI / 2 }
|
|
57065
|
+
];
|
|
57066
|
+
for (const corner of corners) {
|
|
57067
|
+
for (let i3 = 0;i3 <= roundedRectCornerArcSegmentCount; i3++) {
|
|
57068
|
+
const t50 = i3 / roundedRectCornerArcSegmentCount;
|
|
57069
|
+
const angle = corner.start + (corner.end - corner.start) * t50;
|
|
57070
|
+
points.push({
|
|
57071
|
+
x: corner.center.x + r4 * Math.cos(angle),
|
|
57072
|
+
y: corner.center.y + r4 * Math.sin(angle)
|
|
57073
|
+
});
|
|
57074
|
+
}
|
|
57075
|
+
}
|
|
57076
|
+
return points.map((point9) => applyToPoint25(transformMatrix, point9));
|
|
57077
|
+
}, getCircleCutoutOutlinePolygon = (cutout) => {
|
|
57078
|
+
const points = [];
|
|
57079
|
+
for (let i3 = 0;i3 < circleCutoutPolygonSegmentCount2; i3++) {
|
|
57080
|
+
const angle = i3 / circleCutoutPolygonSegmentCount2 * Math.PI * 2;
|
|
57081
|
+
points.push([
|
|
57082
|
+
cutout.center.x + cutout.radius * Math.cos(angle),
|
|
57083
|
+
cutout.center.y + cutout.radius * Math.sin(angle)
|
|
57084
|
+
]);
|
|
57085
|
+
}
|
|
57086
|
+
return [points];
|
|
57087
|
+
}, getSolidCutoutOutlinePolygon = (cutout) => {
|
|
57088
|
+
if (cutout.shape === "rect") {
|
|
57089
|
+
return [
|
|
57090
|
+
getRectCutoutOutlinePoints(cutout).map((point9) => [point9.x, point9.y])
|
|
57091
|
+
];
|
|
57092
|
+
}
|
|
57093
|
+
if (cutout.shape === "circle") {
|
|
57094
|
+
return getCircleCutoutOutlinePolygon(cutout);
|
|
57095
|
+
}
|
|
57096
|
+
if (cutout.shape === "polygon") {
|
|
57097
|
+
return [cutout.points.map((point9) => [point9.x, point9.y])];
|
|
57098
|
+
}
|
|
57099
|
+
return null;
|
|
57100
|
+
}, doesSolidCutoutOverlapBoardEdge = ({
|
|
57101
|
+
cutout,
|
|
57102
|
+
boardOutlinePolygons
|
|
57103
|
+
}) => {
|
|
57104
|
+
const cutoutOutlinePolygon = getSolidCutoutOutlinePolygon(cutout);
|
|
57105
|
+
if (!cutoutOutlinePolygon)
|
|
57106
|
+
return false;
|
|
57107
|
+
return boardOutlinePolygons.some((boardOutlinePolygon) => {
|
|
57108
|
+
const overlapsBoard = import_polygon_clipping3.default.intersection(boardOutlinePolygon, cutoutOutlinePolygon).length > 0;
|
|
57109
|
+
const extendsOutsideBoard = import_polygon_clipping3.default.difference(cutoutOutlinePolygon, boardOutlinePolygon).length > 0;
|
|
57110
|
+
return overlapsBoard && extendsOutsideBoard;
|
|
57111
|
+
});
|
|
57112
|
+
}, isCutoutFullyInternal = ({
|
|
57113
|
+
cutout,
|
|
57114
|
+
boardOutlinePolygons
|
|
57115
|
+
}) => {
|
|
57116
|
+
const cutoutOutlinePolygon = getSolidCutoutOutlinePolygon(cutout);
|
|
57117
|
+
if (!cutoutOutlinePolygon)
|
|
57118
|
+
return false;
|
|
57119
|
+
return boardOutlinePolygons.some((boardOutlinePolygon) => import_polygon_clipping3.default.intersection(boardOutlinePolygon, cutoutOutlinePolygon).length > 0 && import_polygon_clipping3.default.difference(cutoutOutlinePolygon, boardOutlinePolygon).length === 0);
|
|
57120
|
+
}, emitCutoutEdgeCuts = ({
|
|
57121
|
+
cutout,
|
|
57122
|
+
builder,
|
|
57123
|
+
mfy,
|
|
57124
|
+
drawCw
|
|
57125
|
+
}) => {
|
|
57126
|
+
if (cutout.shape === "circle") {
|
|
57127
|
+
emitCircle({ cutout, builder, mfy, drawCw });
|
|
57128
|
+
} else if (cutout.shape === "rect") {
|
|
57129
|
+
emitRect({ cutout, builder, mfy, drawCw });
|
|
57130
|
+
} else if (cutout.shape === "polygon") {
|
|
57131
|
+
emitPolygon({ cutout, builder, mfy, drawCw });
|
|
57132
|
+
}
|
|
57133
|
+
}, emitCircle = ({
|
|
57134
|
+
cutout,
|
|
57135
|
+
builder,
|
|
57136
|
+
mfy,
|
|
57137
|
+
drawCw
|
|
57138
|
+
}) => {
|
|
57139
|
+
const { center: center2, radius } = cutout;
|
|
57140
|
+
const p12 = { x: center2.x + radius, y: center2.y };
|
|
57141
|
+
const p23 = { x: center2.x - radius, y: center2.y };
|
|
57142
|
+
const isYFlipped = mfy(1) < 0;
|
|
57143
|
+
let isClockwise = drawCw;
|
|
57144
|
+
if (isYFlipped) {
|
|
57145
|
+
isClockwise = !isClockwise;
|
|
57146
|
+
}
|
|
57147
|
+
let arcMode = "set_movement_mode_to_counterclockwise_circular";
|
|
57148
|
+
if (isClockwise) {
|
|
57149
|
+
arcMode = "set_movement_mode_to_clockwise_circular";
|
|
57150
|
+
}
|
|
57151
|
+
builder.add("move_operation", { x: p12.x, y: mfy(p12.y) }).add(arcMode, {}).add("plot_operation", { x: p23.x, y: mfy(p23.y), i: -radius, j: 0 }).add("plot_operation", { x: p12.x, y: mfy(p12.y), i: radius, j: 0 }).add("set_movement_mode_to_linear", {});
|
|
57152
|
+
}, emitRect = ({
|
|
57153
|
+
cutout,
|
|
57154
|
+
builder,
|
|
57155
|
+
mfy,
|
|
57156
|
+
drawCw
|
|
57157
|
+
}) => {
|
|
57158
|
+
const { center: center2, width, height, rotation: rotation11, corner_radius } = cutout;
|
|
57159
|
+
const w4 = width / 2;
|
|
57160
|
+
const h4 = height / 2;
|
|
57161
|
+
let cr3 = 0;
|
|
57162
|
+
if (corner_radius !== undefined) {
|
|
57163
|
+
cr3 = corner_radius;
|
|
57164
|
+
}
|
|
57165
|
+
const r4 = Math.max(0, Math.min(cr3, Math.abs(w4), Math.abs(h4)));
|
|
57166
|
+
let rotationTransform = identity22();
|
|
57167
|
+
if (rotation11) {
|
|
57168
|
+
rotationTransform = rotate32(rotation11 * Math.PI / 180);
|
|
57169
|
+
}
|
|
57170
|
+
const transformMatrix = compose32(translate32(center2.x, center2.y), rotationTransform);
|
|
57171
|
+
if (r4 > 0) {
|
|
57172
|
+
emitRoundedRect({ w: w4, h: h4, r: r4, transformMatrix, builder, mfy, drawCw });
|
|
57173
|
+
} else {
|
|
57174
|
+
emitSharpRect({ w: w4, h: h4, transformMatrix, builder, mfy, drawCw });
|
|
57175
|
+
}
|
|
57176
|
+
}, emitSharpRect = ({
|
|
57177
|
+
w: w4,
|
|
57178
|
+
h: h4,
|
|
57179
|
+
transformMatrix,
|
|
57180
|
+
builder,
|
|
57181
|
+
mfy,
|
|
57182
|
+
drawCw
|
|
57183
|
+
}) => {
|
|
57184
|
+
const cwPoints = [
|
|
57185
|
+
{ x: -w4, y: h4 },
|
|
57186
|
+
{ x: w4, y: h4 },
|
|
57187
|
+
{ x: w4, y: -h4 },
|
|
57188
|
+
{ x: -w4, y: -h4 }
|
|
57189
|
+
];
|
|
57190
|
+
const isYFlipped = mfy(1) < 0;
|
|
57191
|
+
let shouldReverse = !drawCw;
|
|
57192
|
+
if (isYFlipped) {
|
|
57193
|
+
shouldReverse = !shouldReverse;
|
|
57194
|
+
}
|
|
57195
|
+
let pts = cwPoints;
|
|
57196
|
+
if (shouldReverse) {
|
|
57197
|
+
pts = [...cwPoints].reverse();
|
|
57198
|
+
}
|
|
57199
|
+
const tpts = pts.map((p3) => applyToPoint32(transformMatrix, p3));
|
|
57200
|
+
builder.add("move_operation", { x: tpts[0].x, y: mfy(tpts[0].y) });
|
|
57201
|
+
for (let i3 = 1;i3 < tpts.length; i3++) {
|
|
57202
|
+
builder.add("plot_operation", { x: tpts[i3].x, y: mfy(tpts[i3].y) });
|
|
57203
|
+
}
|
|
57204
|
+
builder.add("plot_operation", { x: tpts[0].x, y: mfy(tpts[0].y) });
|
|
57205
|
+
}, emitRoundedRect = ({
|
|
57206
|
+
w: w4,
|
|
57207
|
+
h: h4,
|
|
57208
|
+
r: r4,
|
|
57209
|
+
transformMatrix,
|
|
57210
|
+
builder,
|
|
57211
|
+
mfy,
|
|
57212
|
+
drawCw
|
|
57213
|
+
}) => {
|
|
57214
|
+
const isYFlipped = mfy(1) < 0;
|
|
57215
|
+
let isClockwise = drawCw;
|
|
57216
|
+
if (isYFlipped) {
|
|
57217
|
+
isClockwise = !isClockwise;
|
|
57218
|
+
}
|
|
57219
|
+
let arcMode = "set_movement_mode_to_counterclockwise_circular";
|
|
57220
|
+
if (isClockwise) {
|
|
57221
|
+
arcMode = "set_movement_mode_to_clockwise_circular";
|
|
57222
|
+
}
|
|
57223
|
+
let currentPoint;
|
|
57224
|
+
const addLine = (pt3) => {
|
|
57225
|
+
const tpt = applyToPoint32(transformMatrix, pt3);
|
|
57226
|
+
builder.add("plot_operation", { x: tpt.x, y: mfy(tpt.y) });
|
|
57227
|
+
currentPoint = tpt;
|
|
57228
|
+
};
|
|
57229
|
+
const addArc = (endPt, centerPt) => {
|
|
57230
|
+
const tEnd = applyToPoint32(transformMatrix, endPt);
|
|
57231
|
+
const tCenter = applyToPoint32(transformMatrix, centerPt);
|
|
57232
|
+
builder.add(arcMode, {}).add("plot_operation", {
|
|
57233
|
+
x: tEnd.x,
|
|
57234
|
+
y: mfy(tEnd.y),
|
|
57235
|
+
i: tCenter.x - currentPoint.x,
|
|
57236
|
+
j: mfy(tCenter.y) - mfy(currentPoint.y)
|
|
57237
|
+
}).add("set_movement_mode_to_linear", {});
|
|
57238
|
+
currentPoint = tEnd;
|
|
57239
|
+
};
|
|
57240
|
+
if (isClockwise) {
|
|
57241
|
+
const cwSegments = [
|
|
57242
|
+
{
|
|
57243
|
+
lineTo: { x: w4 - r4, y: h4 },
|
|
57244
|
+
arcEnd: { x: w4, y: h4 - r4 },
|
|
57245
|
+
arcCenter: { x: w4 - r4, y: h4 - r4 }
|
|
57246
|
+
},
|
|
57247
|
+
{
|
|
57248
|
+
lineTo: { x: w4, y: -h4 + r4 },
|
|
57249
|
+
arcEnd: { x: w4 - r4, y: -h4 },
|
|
57250
|
+
arcCenter: { x: w4 - r4, y: -h4 + r4 }
|
|
57251
|
+
},
|
|
57252
|
+
{
|
|
57253
|
+
lineTo: { x: -w4 + r4, y: -h4 },
|
|
57254
|
+
arcEnd: { x: -w4, y: -h4 + r4 },
|
|
57255
|
+
arcCenter: { x: -w4 + r4, y: -h4 + r4 }
|
|
57256
|
+
},
|
|
57257
|
+
{
|
|
57258
|
+
lineTo: { x: -w4, y: h4 - r4 },
|
|
57259
|
+
arcEnd: { x: -w4 + r4, y: h4 },
|
|
57260
|
+
arcCenter: { x: -w4 + r4, y: h4 - r4 }
|
|
57261
|
+
}
|
|
57262
|
+
];
|
|
57263
|
+
const startPt = { x: -w4 + r4, y: h4 };
|
|
57264
|
+
const tStart = applyToPoint32(transformMatrix, startPt);
|
|
57265
|
+
builder.add("move_operation", { x: tStart.x, y: mfy(tStart.y) });
|
|
57266
|
+
currentPoint = tStart;
|
|
57267
|
+
for (const seg of cwSegments) {
|
|
57268
|
+
addLine(seg.lineTo);
|
|
57269
|
+
addArc(seg.arcEnd, seg.arcCenter);
|
|
57270
|
+
}
|
|
57271
|
+
} else {
|
|
57272
|
+
const startPt = { x: w4 - r4, y: h4 };
|
|
57273
|
+
const tStart = applyToPoint32(transformMatrix, startPt);
|
|
57274
|
+
builder.add("move_operation", { x: tStart.x, y: mfy(tStart.y) });
|
|
57275
|
+
currentPoint = tStart;
|
|
57276
|
+
addLine({ x: -w4 + r4, y: h4 });
|
|
57277
|
+
addArc({ x: -w4, y: h4 - r4 }, { x: -w4 + r4, y: h4 - r4 });
|
|
57278
|
+
addLine({ x: -w4, y: -h4 + r4 });
|
|
57279
|
+
addArc({ x: -w4 + r4, y: -h4 }, { x: -w4 + r4, y: -h4 + r4 });
|
|
57280
|
+
addLine({ x: w4 - r4, y: -h4 });
|
|
57281
|
+
addArc({ x: w4, y: -h4 + r4 }, { x: w4 - r4, y: -h4 + r4 });
|
|
57282
|
+
addLine({ x: w4, y: h4 - r4 });
|
|
57283
|
+
addArc({ x: w4 - r4, y: h4 }, { x: w4 - r4, y: h4 - r4 });
|
|
57284
|
+
}
|
|
57285
|
+
}, emitPolygon = ({
|
|
57286
|
+
cutout,
|
|
57287
|
+
builder,
|
|
57288
|
+
mfy,
|
|
57289
|
+
drawCw
|
|
57290
|
+
}) => {
|
|
57291
|
+
const points = cutout.points;
|
|
57292
|
+
if (points.length === 0)
|
|
57293
|
+
return;
|
|
57294
|
+
const isYFlipped = mfy(1) < 0;
|
|
57295
|
+
let shouldReverse = !drawCw;
|
|
57296
|
+
if (isYFlipped) {
|
|
57297
|
+
shouldReverse = !shouldReverse;
|
|
57298
|
+
}
|
|
57299
|
+
let ordered = points;
|
|
57300
|
+
if (shouldReverse) {
|
|
57301
|
+
ordered = [...points].reverse();
|
|
57302
|
+
}
|
|
57303
|
+
builder.add("move_operation", { x: ordered[0].x, y: mfy(ordered[0].y) });
|
|
57304
|
+
for (let i3 = 1;i3 < ordered.length; i3++) {
|
|
57305
|
+
builder.add("plot_operation", { x: ordered[i3].x, y: mfy(ordered[i3].y) });
|
|
57306
|
+
}
|
|
57307
|
+
builder.add("plot_operation", { x: ordered[0].x, y: mfy(ordered[0].y) });
|
|
57308
|
+
}, closeRing = (ring) => {
|
|
57309
|
+
const first = ring[0];
|
|
57310
|
+
const last = ring[ring.length - 1];
|
|
57311
|
+
if (!first || !last)
|
|
57312
|
+
return ring;
|
|
57313
|
+
if (first[0] === last[0] && first[1] === last[1])
|
|
57314
|
+
return ring;
|
|
57315
|
+
return [...ring, first];
|
|
57316
|
+
}, emitEdgeCutRing = (gerberBuild, ring, mfy) => {
|
|
57317
|
+
const closedRing = closeRing(ring);
|
|
57318
|
+
const firstPoint = closedRing[0];
|
|
57319
|
+
if (!firstPoint || closedRing.length < 4)
|
|
57320
|
+
return;
|
|
57321
|
+
gerberBuild.add("move_operation", {
|
|
57322
|
+
x: firstPoint[0],
|
|
57323
|
+
y: mfy(firstPoint[1])
|
|
57324
|
+
});
|
|
57325
|
+
for (let i3 = 1;i3 < closedRing.length; i3++) {
|
|
57326
|
+
const point9 = closedRing[i3];
|
|
57327
|
+
gerberBuild.add("plot_operation", {
|
|
57328
|
+
x: point9[0],
|
|
57329
|
+
y: mfy(point9[1])
|
|
57330
|
+
});
|
|
57331
|
+
}
|
|
57332
|
+
}, getLayerCount2 = (circuitJson) => {
|
|
57333
|
+
const board = circuitJson.find((element) => element.type === "pcb_board");
|
|
57334
|
+
const numLayers = board?.num_layers ?? 2;
|
|
57335
|
+
return Math.max(2, Math.min(8, numLayers));
|
|
57336
|
+
}, getInnerLayerRefs = (layerCount) => Array.from({ length: layerCount - 2 }, (_4, i3) => `inner${i3 + 1}`), getGerberInnerLayerName = (layerRef) => {
|
|
57337
|
+
if (!layerRef.startsWith("inner")) {
|
|
57338
|
+
throw new Error(`Expected inner layer, got ${layerRef}`);
|
|
57339
|
+
}
|
|
57340
|
+
return `In${layerRef.replace("inner", "")}_Cu`;
|
|
57341
|
+
}, convertSoupToGerberCommands = (circuitJson, opts = {}) => {
|
|
54296
57342
|
opts.flip_y_axis ??= false;
|
|
54297
|
-
const hasPanel =
|
|
57343
|
+
const hasPanel = circuitJson.some((e4) => e4.type === "pcb_panel");
|
|
57344
|
+
const hasBoard = circuitJson.some((e4) => e4.type === "pcb_board");
|
|
57345
|
+
const layerCount = getLayerCount2(circuitJson);
|
|
57346
|
+
const innerLayerRefs = getInnerLayerRefs(layerCount);
|
|
57347
|
+
const copperLayerRefs = ["top", ...innerLayerRefs, "bottom"];
|
|
57348
|
+
const fabricationLayerRefs = getFabricationLayerRefs(circuitJson);
|
|
54298
57349
|
const glayers = {
|
|
54299
57350
|
F_Cu: getCommandHeaders({
|
|
54300
57351
|
layer: "top",
|
|
54301
|
-
layer_type: "copper"
|
|
57352
|
+
layer_type: "copper",
|
|
57353
|
+
total_layer_count: layerCount
|
|
54302
57354
|
}),
|
|
54303
57355
|
F_SilkScreen: getCommandHeaders({
|
|
54304
57356
|
layer: "top",
|
|
@@ -54314,7 +57366,8 @@ var import_fast_json_stable_stringify, defineExcellonDrillCommand = ({
|
|
|
54314
57366
|
}),
|
|
54315
57367
|
B_Cu: getCommandHeaders({
|
|
54316
57368
|
layer: "bottom",
|
|
54317
|
-
layer_type: "copper"
|
|
57369
|
+
layer_type: "copper",
|
|
57370
|
+
total_layer_count: layerCount
|
|
54318
57371
|
}),
|
|
54319
57372
|
B_SilkScreen: getCommandHeaders({
|
|
54320
57373
|
layer: "bottom",
|
|
@@ -54332,20 +57385,36 @@ var import_fast_json_stable_stringify, defineExcellonDrillCommand = ({
|
|
|
54332
57385
|
layer: "edgecut"
|
|
54333
57386
|
})
|
|
54334
57387
|
};
|
|
57388
|
+
for (const innerLayerRef of innerLayerRefs) {
|
|
57389
|
+
glayers[getGerberInnerLayerName(innerLayerRef)] = getCommandHeaders({
|
|
57390
|
+
layer: innerLayerRef,
|
|
57391
|
+
layer_type: "copper",
|
|
57392
|
+
total_layer_count: layerCount
|
|
57393
|
+
});
|
|
57394
|
+
}
|
|
57395
|
+
for (const layerRef of fabricationLayerRefs) {
|
|
57396
|
+
glayers[getGerberLayerName(layerRef, "fabrication")] = getCommandHeaders({
|
|
57397
|
+
layer: layerRef,
|
|
57398
|
+
layer_type: "fabrication"
|
|
57399
|
+
});
|
|
57400
|
+
}
|
|
57401
|
+
const copperGerberLayerNames = copperLayerRefs.map((layerRef) => getGerberLayerName(layerRef, "copper"));
|
|
57402
|
+
const fabricationGerberLayerNames = fabricationLayerRefs.map((layerRef) => getGerberLayerName(layerRef, "fabrication"));
|
|
57403
|
+
const outerGerberLayerNames = outerLayerRefs.flatMap((layerRef) => [
|
|
57404
|
+
getGerberLayerName(layerRef, "soldermask"),
|
|
57405
|
+
getGerberLayerName(layerRef, "paste"),
|
|
57406
|
+
getGerberLayerName(layerRef, "silkscreen")
|
|
57407
|
+
]);
|
|
54335
57408
|
for (const glayer_name of [
|
|
54336
57409
|
"F_Cu",
|
|
54337
|
-
"
|
|
54338
|
-
|
|
54339
|
-
|
|
54340
|
-
"F_Paste",
|
|
54341
|
-
"B_Paste",
|
|
54342
|
-
"F_SilkScreen",
|
|
54343
|
-
"B_SilkScreen"
|
|
57410
|
+
...copperGerberLayerNames.filter((name) => name !== "F_Cu"),
|
|
57411
|
+
...fabricationGerberLayerNames,
|
|
57412
|
+
...outerGerberLayerNames
|
|
54344
57413
|
]) {
|
|
54345
57414
|
const glayer = glayers[glayer_name];
|
|
54346
57415
|
defineCommonMacros(glayer);
|
|
54347
57416
|
defineAperturesForLayer({
|
|
54348
|
-
|
|
57417
|
+
circuitJson,
|
|
54349
57418
|
glayer,
|
|
54350
57419
|
glayer_name
|
|
54351
57420
|
});
|
|
@@ -54355,14 +57424,92 @@ var import_fast_json_stable_stringify, defineExcellonDrillCommand = ({
|
|
|
54355
57424
|
standard_template_code: "C",
|
|
54356
57425
|
diameter: 0.05
|
|
54357
57426
|
}).build());
|
|
54358
|
-
const mfy = (y4) =>
|
|
54359
|
-
|
|
54360
|
-
|
|
54361
|
-
if (element.type === "pcb_plated_hole" && "x" in element && typeof element.x === "number" && "y" in element && typeof element.y === "number") {
|
|
54362
|
-
const rotation11 = "ccw_rotation" in element && typeof element.ccw_rotation === "number" ? element.ccw_rotation : 0;
|
|
54363
|
-
rotationLookup.set(`${element.x}:${element.y}`, rotation11);
|
|
57427
|
+
const mfy = (y4) => {
|
|
57428
|
+
if (opts.flip_y_axis) {
|
|
57429
|
+
return -y4;
|
|
54364
57430
|
}
|
|
54365
|
-
|
|
57431
|
+
return y4;
|
|
57432
|
+
};
|
|
57433
|
+
const boardOutlinePolygons = getBoardOutlinePolygons2(circuitJson);
|
|
57434
|
+
const solidCutoutPolygons = circuitJson.filter((element) => element.type === "pcb_cutout").filter((cutout) => doesSolidCutoutOverlapBoardEdge({ cutout, boardOutlinePolygons })).map(getSolidCutoutOutlinePolygon).filter((polygon2) => polygon2 !== null);
|
|
57435
|
+
const renderPillFlash = ({
|
|
57436
|
+
glayer,
|
|
57437
|
+
x: x4,
|
|
57438
|
+
y: y4,
|
|
57439
|
+
width,
|
|
57440
|
+
height,
|
|
57441
|
+
rotationDegrees = 0
|
|
57442
|
+
}) => {
|
|
57443
|
+
const circleApertureConfig = {
|
|
57444
|
+
standard_template_code: "C",
|
|
57445
|
+
diameter: Math.min(width, height)
|
|
57446
|
+
};
|
|
57447
|
+
const apertureNumber = findApertureNumber(glayer, circleApertureConfig);
|
|
57448
|
+
const gb3 = gerberBuilder().add("select_aperture", {
|
|
57449
|
+
aperture_number: apertureNumber
|
|
57450
|
+
});
|
|
57451
|
+
const offset = Math.abs(width - height) / 2;
|
|
57452
|
+
const rotationRadians = rotationDegrees * Math.PI / 180;
|
|
57453
|
+
const cosTheta = Math.cos(rotationRadians);
|
|
57454
|
+
const sinTheta = Math.sin(rotationRadians);
|
|
57455
|
+
const rotateAndTranslate = (dx3, dy3) => ({
|
|
57456
|
+
x: x4 + dx3 * cosTheta - dy3 * sinTheta,
|
|
57457
|
+
y: y4 + dx3 * sinTheta + dy3 * cosTheta
|
|
57458
|
+
});
|
|
57459
|
+
if (offset <= 0.000000001) {
|
|
57460
|
+
gb3.add("flash_operation", { x: x4, y: mfy(y4) });
|
|
57461
|
+
glayer.push(...gb3.build());
|
|
57462
|
+
return;
|
|
57463
|
+
}
|
|
57464
|
+
const isHorizontal2 = width >= height;
|
|
57465
|
+
const startRelative = isHorizontal2 ? { x: -offset, y: 0 } : { x: 0, y: -offset };
|
|
57466
|
+
const endRelative = isHorizontal2 ? { x: offset, y: 0 } : { x: 0, y: offset };
|
|
57467
|
+
const startPoint = rotateAndTranslate(startRelative.x, startRelative.y);
|
|
57468
|
+
const endPoint = rotateAndTranslate(endRelative.x, endRelative.y);
|
|
57469
|
+
gb3.add("flash_operation", {
|
|
57470
|
+
x: startPoint.x,
|
|
57471
|
+
y: mfy(startPoint.y)
|
|
57472
|
+
}).add("move_operation", {
|
|
57473
|
+
x: startPoint.x,
|
|
57474
|
+
y: mfy(startPoint.y)
|
|
57475
|
+
}).add("plot_operation", {
|
|
57476
|
+
x: endPoint.x,
|
|
57477
|
+
y: mfy(endPoint.y)
|
|
57478
|
+
}).add("flash_operation", {
|
|
57479
|
+
x: endPoint.x,
|
|
57480
|
+
y: mfy(endPoint.y)
|
|
57481
|
+
});
|
|
57482
|
+
glayer.push(...gb3.build());
|
|
57483
|
+
};
|
|
57484
|
+
const getRegionApertureNumber = (glayer) => findApertureNumber(glayer, REGION_APERTURE_CONFIG);
|
|
57485
|
+
const addClosedRegionFromPoints = ({
|
|
57486
|
+
target,
|
|
57487
|
+
apertureSource,
|
|
57488
|
+
points
|
|
57489
|
+
}) => {
|
|
57490
|
+
if (points.length === 0)
|
|
57491
|
+
return;
|
|
57492
|
+
const regionApertureNumber = getRegionApertureNumber(apertureSource);
|
|
57493
|
+
const regionBuilder = gerberBuilder().add("select_aperture", {
|
|
57494
|
+
aperture_number: regionApertureNumber
|
|
57495
|
+
}).add("start_region_statement", {});
|
|
57496
|
+
regionBuilder.add("move_operation", {
|
|
57497
|
+
x: points[0].x,
|
|
57498
|
+
y: mfy(points[0].y)
|
|
57499
|
+
});
|
|
57500
|
+
for (let i3 = 1;i3 < points.length; i3++) {
|
|
57501
|
+
regionBuilder.add("plot_operation", {
|
|
57502
|
+
x: points[i3].x,
|
|
57503
|
+
y: mfy(points[i3].y)
|
|
57504
|
+
});
|
|
57505
|
+
}
|
|
57506
|
+
regionBuilder.add("plot_operation", {
|
|
57507
|
+
x: points[0].x,
|
|
57508
|
+
y: mfy(points[0].y)
|
|
57509
|
+
});
|
|
57510
|
+
regionBuilder.add("end_region_statement", {});
|
|
57511
|
+
target.push(...regionBuilder.build());
|
|
57512
|
+
};
|
|
54366
57513
|
const renderVectorText = (element, layer, layerType, getApertureConfig) => {
|
|
54367
57514
|
if (element.layer !== layer)
|
|
54368
57515
|
return;
|
|
@@ -54439,16 +57586,16 @@ var import_fast_json_stable_stringify, defineExcellonDrillCommand = ({
|
|
|
54439
57586
|
const transforms = [];
|
|
54440
57587
|
const shouldMirror = element.is_mirrored !== undefined ? element.is_mirrored : element.layer === "bottom";
|
|
54441
57588
|
if (shouldMirror) {
|
|
54442
|
-
transforms.push(
|
|
57589
|
+
transforms.push(translate42(cx3, cy3), { a: -1, b: 0, c: 0, d: 1, e: 0, f: 0 }, translate42(-cx3, -cy3));
|
|
54443
57590
|
rotation11 = -rotation11;
|
|
54444
57591
|
}
|
|
54445
57592
|
if (rotation11) {
|
|
54446
57593
|
const rad = rotation11 * Math.PI / 180;
|
|
54447
|
-
transforms.push(
|
|
57594
|
+
transforms.push(translate42(cx3, cy3), rotate42(rad), translate42(-cx3, -cy3));
|
|
54448
57595
|
}
|
|
54449
|
-
const transformMatrix = transforms.length > 0 ?
|
|
54450
|
-
const applyTransform = (point9) => transformMatrix ?
|
|
54451
|
-
if (
|
|
57596
|
+
const transformMatrix = transforms.length > 0 ? compose42(...transforms) : undefined;
|
|
57597
|
+
const applyTransform = (point9) => transformMatrix ? applyToPoint42(transformMatrix, point9) : point9;
|
|
57598
|
+
if (element.is_knockout) {
|
|
54452
57599
|
const padding = element.knockout_padding ?? {
|
|
54453
57600
|
left: 0.2,
|
|
54454
57601
|
right: 0.2,
|
|
@@ -54490,7 +57637,7 @@ var import_fast_json_stable_stringify, defineExcellonDrillCommand = ({
|
|
|
54490
57637
|
}).add("end_region_statement", {}).build());
|
|
54491
57638
|
glayer.push(...gerberBuilder().add("set_layer_polarity", { polarity: "C" }).build());
|
|
54492
57639
|
}
|
|
54493
|
-
for (const char of element.text
|
|
57640
|
+
for (const char of element.text) {
|
|
54494
57641
|
if (char === " ") {
|
|
54495
57642
|
anchoredX += spaceWidth + letterSpacing;
|
|
54496
57643
|
continue;
|
|
@@ -54509,7 +57656,7 @@ var import_fast_json_stable_stringify, defineExcellonDrillCommand = ({
|
|
|
54509
57656
|
anchoredX += fontSize + letterSpacing;
|
|
54510
57657
|
}
|
|
54511
57658
|
glayer.push(...gerber.build());
|
|
54512
|
-
if (
|
|
57659
|
+
if (element.is_knockout) {
|
|
54513
57660
|
glayer.push(...gerberBuilder().add("set_layer_polarity", { polarity: "D" }).build());
|
|
54514
57661
|
}
|
|
54515
57662
|
};
|
|
@@ -54588,8 +57735,8 @@ var import_fast_json_stable_stringify, defineExcellonDrillCommand = ({
|
|
|
54588
57735
|
});
|
|
54589
57736
|
return { vertices: new_vertices };
|
|
54590
57737
|
};
|
|
54591
|
-
for (const layer of
|
|
54592
|
-
for (const element of
|
|
57738
|
+
for (const layer of copperLayerRefs) {
|
|
57739
|
+
for (const element of circuitJson) {
|
|
54593
57740
|
if (element.type === "pcb_copper_pour" && layer === element.layer) {
|
|
54594
57741
|
const copper_glayer = glayers[getGerberLayerName(layer, "copper")];
|
|
54595
57742
|
const all_pour_commands = [];
|
|
@@ -54598,14 +57745,17 @@ var import_fast_json_stable_stringify, defineExcellonDrillCommand = ({
|
|
|
54598
57745
|
if (!brep_shape)
|
|
54599
57746
|
continue;
|
|
54600
57747
|
const { outer_ring, inner_rings } = brep_shape;
|
|
54601
|
-
const
|
|
57748
|
+
const regionApertureNumber = getRegionApertureNumber(copper_glayer);
|
|
57749
|
+
const outer_builder = gerberBuilder().add("select_aperture", { aperture_number: regionApertureNumber }).add("start_region_statement", {});
|
|
54602
57750
|
drawRingToBuilder(outer_builder, reverseRing(outer_ring));
|
|
54603
57751
|
outer_builder.add("end_region_statement", {});
|
|
54604
57752
|
all_pour_commands.push(...outer_builder.build());
|
|
54605
57753
|
if (inner_rings && inner_rings.length > 0) {
|
|
54606
57754
|
all_pour_commands.push(...gerberBuilder().add("set_layer_polarity", { polarity: "C" }).build());
|
|
54607
57755
|
for (const inner_ring of inner_rings) {
|
|
54608
|
-
const inner_builder = gerberBuilder().add("select_aperture", {
|
|
57756
|
+
const inner_builder = gerberBuilder().add("select_aperture", {
|
|
57757
|
+
aperture_number: regionApertureNumber
|
|
57758
|
+
}).add("start_region_statement", {});
|
|
54609
57759
|
drawRingToBuilder(inner_builder, inner_ring);
|
|
54610
57760
|
inner_builder.add("end_region_statement", {});
|
|
54611
57761
|
all_pour_commands.push(...inner_builder.build());
|
|
@@ -54622,14 +57772,15 @@ var import_fast_json_stable_stringify, defineExcellonDrillCommand = ({
|
|
|
54622
57772
|
{ x: w4, y: -h4 },
|
|
54623
57773
|
{ x: -w4, y: -h4 }
|
|
54624
57774
|
];
|
|
54625
|
-
let transformMatrix =
|
|
57775
|
+
let transformMatrix = identity32();
|
|
54626
57776
|
if (rotation11) {
|
|
54627
57777
|
const angle_rad = rotation11 * Math.PI / 180;
|
|
54628
|
-
transformMatrix =
|
|
57778
|
+
transformMatrix = rotate42(angle_rad);
|
|
54629
57779
|
}
|
|
54630
|
-
transformMatrix =
|
|
54631
|
-
const transformedPoints = points.map((p3) =>
|
|
54632
|
-
const
|
|
57780
|
+
transformMatrix = compose42(translate42(center2.x, center2.y), transformMatrix);
|
|
57781
|
+
const transformedPoints = points.map((p3) => applyToPoint42(transformMatrix, p3));
|
|
57782
|
+
const regionApertureNumber = getRegionApertureNumber(copper_glayer);
|
|
57783
|
+
const rect_builder = gerberBuilder().add("select_aperture", { aperture_number: regionApertureNumber }).add("start_region_statement", {});
|
|
54633
57784
|
rect_builder.add("move_operation", {
|
|
54634
57785
|
x: transformedPoints[0].x,
|
|
54635
57786
|
y: mfy(transformedPoints[0].y)
|
|
@@ -54648,25 +57799,11 @@ var import_fast_json_stable_stringify, defineExcellonDrillCommand = ({
|
|
|
54648
57799
|
all_pour_commands.push(...rect_builder.build());
|
|
54649
57800
|
} else if (element.shape === "polygon") {
|
|
54650
57801
|
const { points } = element;
|
|
54651
|
-
|
|
54652
|
-
|
|
54653
|
-
|
|
54654
|
-
|
|
54655
|
-
|
|
54656
|
-
});
|
|
54657
|
-
for (let i3 = 1;i3 < points.length; i3++) {
|
|
54658
|
-
poly_builder.add("plot_operation", {
|
|
54659
|
-
x: points[i3].x,
|
|
54660
|
-
y: mfy(points[i3].y)
|
|
54661
|
-
});
|
|
54662
|
-
}
|
|
54663
|
-
poly_builder.add("plot_operation", {
|
|
54664
|
-
x: points[0].x,
|
|
54665
|
-
y: mfy(points[0].y)
|
|
54666
|
-
});
|
|
54667
|
-
poly_builder.add("end_region_statement", {});
|
|
54668
|
-
all_pour_commands.push(...poly_builder.build());
|
|
54669
|
-
}
|
|
57802
|
+
addClosedRegionFromPoints({
|
|
57803
|
+
target: all_pour_commands,
|
|
57804
|
+
apertureSource: copper_glayer,
|
|
57805
|
+
points
|
|
57806
|
+
});
|
|
54670
57807
|
}
|
|
54671
57808
|
copper_glayer.push(...all_pour_commands);
|
|
54672
57809
|
if (element.covered_with_solder_mask === false) {
|
|
@@ -54676,23 +57813,66 @@ var import_fast_json_stable_stringify, defineExcellonDrillCommand = ({
|
|
|
54676
57813
|
}
|
|
54677
57814
|
}
|
|
54678
57815
|
}
|
|
54679
|
-
for (const layer of [
|
|
54680
|
-
for (const element of
|
|
57816
|
+
for (const layer of [...copperLayerRefs, "edgecut"]) {
|
|
57817
|
+
for (const element of circuitJson) {
|
|
54681
57818
|
if (element.type === "pcb_trace") {
|
|
54682
|
-
|
|
57819
|
+
if (layer === "edgecut")
|
|
57820
|
+
continue;
|
|
57821
|
+
const route = element.route;
|
|
54683
57822
|
for (const [a3, b3] of pairs3(route)) {
|
|
54684
57823
|
if (a3.route_type === "wire") {
|
|
54685
57824
|
if (a3.layer === layer) {
|
|
57825
|
+
let bPoint = null;
|
|
57826
|
+
if (b3.route_type === "wire" || b3.route_type === "via") {
|
|
57827
|
+
bPoint = b3;
|
|
57828
|
+
} else if (b3.route_type === "through_pad") {
|
|
57829
|
+
if (b3.start_layer === layer) {
|
|
57830
|
+
bPoint = b3.start;
|
|
57831
|
+
} else if (b3.end_layer === layer) {
|
|
57832
|
+
bPoint = b3.end;
|
|
57833
|
+
}
|
|
57834
|
+
}
|
|
57835
|
+
if (!bPoint)
|
|
57836
|
+
continue;
|
|
54686
57837
|
const glayer = glayers[getGerberLayerName(layer, "copper")];
|
|
54687
57838
|
glayer.push(...gerberBuilder().add("select_aperture", {
|
|
54688
57839
|
aperture_number: findApertureNumber(glayer, {
|
|
54689
57840
|
trace_width: a3.width
|
|
54690
57841
|
})
|
|
57842
|
+
}).add("move_operation", { x: a3.x, y: mfy(a3.y) }).add("plot_operation", { x: bPoint.x, y: mfy(bPoint.y) }).build());
|
|
57843
|
+
}
|
|
57844
|
+
} else if (a3.route_type === "via" && b3.route_type === "wire") {
|
|
57845
|
+
if (b3.layer === layer) {
|
|
57846
|
+
const glayer = glayers[getGerberLayerName(layer, "copper")];
|
|
57847
|
+
glayer.push(...gerberBuilder().add("select_aperture", {
|
|
57848
|
+
aperture_number: findApertureNumber(glayer, {
|
|
57849
|
+
trace_width: b3.width
|
|
57850
|
+
})
|
|
54691
57851
|
}).add("move_operation", { x: a3.x, y: mfy(a3.y) }).add("plot_operation", { x: b3.x, y: mfy(b3.y) }).build());
|
|
54692
57852
|
}
|
|
57853
|
+
} else if (a3.route_type === "through_pad" && b3.route_type === "wire") {
|
|
57854
|
+
if (b3.layer === layer) {
|
|
57855
|
+
const aPoint = a3.end_layer === layer ? a3.end : a3.start_layer === layer ? a3.start : null;
|
|
57856
|
+
if (!aPoint)
|
|
57857
|
+
continue;
|
|
57858
|
+
const glayer = glayers[getGerberLayerName(layer, "copper")];
|
|
57859
|
+
glayer.push(...gerberBuilder().add("select_aperture", {
|
|
57860
|
+
aperture_number: findApertureNumber(glayer, {
|
|
57861
|
+
trace_width: b3.width
|
|
57862
|
+
})
|
|
57863
|
+
}).add("move_operation", { x: aPoint.x, y: mfy(aPoint.y) }).add("plot_operation", { x: b3.x, y: mfy(b3.y) }).build());
|
|
57864
|
+
}
|
|
57865
|
+
}
|
|
57866
|
+
}
|
|
57867
|
+
for (const point9 of route) {
|
|
57868
|
+
if (point9.route_type === "via" && typeof point9.outer_diameter === "number" && (point9.from_layer === layer || point9.to_layer === layer)) {
|
|
57869
|
+
const glayer = glayers[getGerberLayerName(layer, "copper")];
|
|
57870
|
+
glayer.push(...gerberBuilder().add("select_aperture", {
|
|
57871
|
+
aperture_number: findApertureNumber(glayer, getApertureConfigFromOuterDiameter(point9))
|
|
57872
|
+
}).add("flash_operation", { x: point9.x, y: mfy(point9.y) }).build());
|
|
54693
57873
|
}
|
|
54694
57874
|
}
|
|
54695
|
-
} else if (element.type === "pcb_silkscreen_path") {
|
|
57875
|
+
} else if (element.type === "pcb_silkscreen_path" && isOuterLayerRef(layer)) {
|
|
54696
57876
|
if (element.layer === layer) {
|
|
54697
57877
|
const glayer = glayers[getGerberLayerName(layer, "silkscreen")];
|
|
54698
57878
|
const apertureConfig = getApertureConfigFromPcbSilkscreenPath(element);
|
|
@@ -54713,74 +57893,205 @@ var import_fast_json_stable_stringify, defineExcellonDrillCommand = ({
|
|
|
54713
57893
|
}
|
|
54714
57894
|
glayer.push(...gerber.build());
|
|
54715
57895
|
}
|
|
54716
|
-
} else if (element
|
|
57896
|
+
} else if (isSilkscreenShape(element) && isOuterLayerRef(layer)) {
|
|
57897
|
+
if (element.layer === layer) {
|
|
57898
|
+
const stroke = getSilkscreenShapeStroke(element);
|
|
57899
|
+
if (stroke) {
|
|
57900
|
+
const glayer = glayers[getGerberLayerName(layer, "silkscreen")];
|
|
57901
|
+
const isFilled = element.is_filled === true;
|
|
57902
|
+
const isStroked = element.has_stroke !== false;
|
|
57903
|
+
if (isFilled) {
|
|
57904
|
+
addClosedRegionFromPoints({
|
|
57905
|
+
target: glayer,
|
|
57906
|
+
apertureSource: glayer,
|
|
57907
|
+
points: stroke.route
|
|
57908
|
+
});
|
|
57909
|
+
}
|
|
57910
|
+
if (isStroked) {
|
|
57911
|
+
renderOpenPath({
|
|
57912
|
+
element: {
|
|
57913
|
+
type: element.type,
|
|
57914
|
+
stroke_width: stroke.strokeWidth,
|
|
57915
|
+
is_stroke_dashed: element.is_stroke_dashed
|
|
57916
|
+
},
|
|
57917
|
+
glayer,
|
|
57918
|
+
apertureConfig: {
|
|
57919
|
+
standard_template_code: "C",
|
|
57920
|
+
diameter: stroke.strokeWidth
|
|
57921
|
+
},
|
|
57922
|
+
route: stroke.route,
|
|
57923
|
+
mapY: mfy
|
|
57924
|
+
});
|
|
57925
|
+
}
|
|
57926
|
+
}
|
|
57927
|
+
}
|
|
57928
|
+
} else if (element.type === "pcb_silkscreen_graphic" && isOuterLayerRef(layer)) {
|
|
57929
|
+
const graphic = element;
|
|
57930
|
+
if (graphic.layer === layer && graphic.brep_shape) {
|
|
57931
|
+
const glayer = glayers[getGerberLayerName(layer, "silkscreen")];
|
|
57932
|
+
const { outer_ring, inner_rings } = graphic.brep_shape;
|
|
57933
|
+
const regionApertureNumber = getRegionApertureNumber(glayer);
|
|
57934
|
+
const outerBuilder = gerberBuilder().add("select_aperture", { aperture_number: regionApertureNumber }).add("start_region_statement", {});
|
|
57935
|
+
drawRingToBuilder(outerBuilder, reverseRing(outer_ring));
|
|
57936
|
+
outerBuilder.add("end_region_statement", {});
|
|
57937
|
+
glayer.push(...outerBuilder.build());
|
|
57938
|
+
if (inner_rings && inner_rings.length > 0) {
|
|
57939
|
+
glayer.push(...gerberBuilder().add("set_layer_polarity", { polarity: "C" }).build());
|
|
57940
|
+
for (const inner_ring of inner_rings) {
|
|
57941
|
+
const innerBuilder = gerberBuilder().add("select_aperture", {
|
|
57942
|
+
aperture_number: regionApertureNumber
|
|
57943
|
+
}).add("start_region_statement", {});
|
|
57944
|
+
drawRingToBuilder(innerBuilder, inner_ring);
|
|
57945
|
+
innerBuilder.add("end_region_statement", {});
|
|
57946
|
+
glayer.push(...innerBuilder.build());
|
|
57947
|
+
}
|
|
57948
|
+
glayer.push(...gerberBuilder().add("set_layer_polarity", { polarity: "D" }).build());
|
|
57949
|
+
}
|
|
57950
|
+
}
|
|
57951
|
+
} else if (element.type === "pcb_silkscreen_text" && isOuterLayerRef(layer)) {
|
|
54717
57952
|
renderVectorText(element, layer, "silkscreen", getApertureConfigFromPcbSilkscreenText);
|
|
57953
|
+
} else if (element.type === "pcb_fabrication_note_path" && isOuterLayerRef(layer)) {
|
|
57954
|
+
if (element.layer === layer) {
|
|
57955
|
+
renderOpenPath({
|
|
57956
|
+
element,
|
|
57957
|
+
glayer: glayers[getGerberLayerName(layer, "fabrication")],
|
|
57958
|
+
apertureConfig: getApertureConfigFromPcbFabricationNotePath(element),
|
|
57959
|
+
route: element.route,
|
|
57960
|
+
mapY: mfy
|
|
57961
|
+
});
|
|
57962
|
+
}
|
|
57963
|
+
} else if (element.type === "pcb_fabrication_note_rect" && isOuterLayerRef(layer)) {
|
|
57964
|
+
if (element.layer === layer) {
|
|
57965
|
+
const glayer = glayers[getGerberLayerName(layer, "fabrication")];
|
|
57966
|
+
const points = getFabRectPoints(element);
|
|
57967
|
+
if (element.is_filled === true) {
|
|
57968
|
+
addClosedRegionFromPoints({
|
|
57969
|
+
target: glayer,
|
|
57970
|
+
apertureSource: glayer,
|
|
57971
|
+
points
|
|
57972
|
+
});
|
|
57973
|
+
}
|
|
57974
|
+
if (element.has_stroke !== false) {
|
|
57975
|
+
renderOpenPath({
|
|
57976
|
+
element,
|
|
57977
|
+
glayer,
|
|
57978
|
+
apertureConfig: getApertureConfigFromPcbFabricationNotePath(element),
|
|
57979
|
+
route: [...points, points[0]],
|
|
57980
|
+
mapY: mfy
|
|
57981
|
+
});
|
|
57982
|
+
}
|
|
57983
|
+
}
|
|
57984
|
+
} else if (element.type === "pcb_fabrication_note_dimension" && isOuterLayerRef(layer)) {
|
|
57985
|
+
if (element.layer === layer) {
|
|
57986
|
+
renderFabricationDimension({
|
|
57987
|
+
element,
|
|
57988
|
+
glayer: glayers[getGerberLayerName(layer, "fabrication")],
|
|
57989
|
+
mapY: mfy,
|
|
57990
|
+
renderText: (textElement) => renderVectorText(textElement, layer, "fabrication", getApertureConfigFromPcbFabricationNoteText)
|
|
57991
|
+
});
|
|
57992
|
+
}
|
|
57993
|
+
} else if (element.type === "pcb_fabrication_note_text" && isOuterLayerRef(layer)) {
|
|
57994
|
+
renderVectorText(element, layer, "fabrication", getApertureConfigFromPcbFabricationNoteText);
|
|
54718
57995
|
} else if (element.type === "pcb_copper_text" && layer !== "edgecut") {
|
|
54719
57996
|
renderVectorText(element, layer, "copper", getApertureConfigFromPcbCopperText);
|
|
54720
57997
|
} else if (element.type === "pcb_smtpad" && element.shape !== "polygon") {
|
|
54721
|
-
if (element.layer === layer) {
|
|
54722
|
-
|
|
54723
|
-
|
|
54724
|
-
|
|
57998
|
+
if (element.layer === layer && isOuterLayerRef(layer)) {
|
|
57999
|
+
if (element.shape === "pill" || element.shape === "rotated_pill") {
|
|
58000
|
+
const soldermaskMargin = typeof element.soldermask_margin === "number" ? element.soldermask_margin : 0;
|
|
58001
|
+
const rotation23 = element.shape === "rotated_pill" && typeof element.ccw_rotation === "number" ? element.ccw_rotation : 0;
|
|
58002
|
+
renderPillFlash({
|
|
58003
|
+
glayer: glayers[getGerberLayerName(layer, "copper")],
|
|
58004
|
+
x: element.x,
|
|
58005
|
+
y: element.y,
|
|
58006
|
+
width: element.width,
|
|
58007
|
+
height: element.height,
|
|
58008
|
+
rotationDegrees: rotation23
|
|
58009
|
+
});
|
|
58010
|
+
renderPillFlash({
|
|
58011
|
+
glayer: glayers[getGerberLayerName(layer, "soldermask")],
|
|
58012
|
+
x: element.x,
|
|
58013
|
+
y: element.y,
|
|
58014
|
+
width: element.width + soldermaskMargin * 2,
|
|
58015
|
+
height: element.height + soldermaskMargin * 2,
|
|
58016
|
+
rotationDegrees: rotation23
|
|
58017
|
+
});
|
|
58018
|
+
continue;
|
|
58019
|
+
}
|
|
58020
|
+
const rotation11 = element.shape === "rotated_rect" && typeof element.ccw_rotation === "number" ? element.ccw_rotation : 0;
|
|
58021
|
+
for (const { glayer, apertureConfig } of [
|
|
58022
|
+
{
|
|
58023
|
+
glayer: glayers[getGerberLayerName(layer, "copper")],
|
|
58024
|
+
apertureConfig: getApertureConfigFromPcbSmtpad(element)
|
|
58025
|
+
},
|
|
58026
|
+
{
|
|
58027
|
+
glayer: glayers[getGerberLayerName(layer, "soldermask")],
|
|
58028
|
+
apertureConfig: getApertureConfigFromPcbSmtpadSoldermask(element)
|
|
58029
|
+
}
|
|
54725
58030
|
]) {
|
|
54726
|
-
const apertureConfig = getApertureConfigFromPcbSmtpad(element);
|
|
54727
58031
|
const apertureNumber = findApertureNumber(glayer, apertureConfig);
|
|
54728
58032
|
const gb3 = gerberBuilder().add("select_aperture", {
|
|
54729
58033
|
aperture_number: apertureNumber
|
|
54730
58034
|
});
|
|
54731
|
-
if (
|
|
58035
|
+
if (rotation11) {
|
|
54732
58036
|
gb3.add("load_rotation", {
|
|
54733
|
-
rotation_degrees:
|
|
58037
|
+
rotation_degrees: rotation11
|
|
54734
58038
|
});
|
|
54735
58039
|
}
|
|
54736
58040
|
gb3.add("flash_operation", { x: element.x, y: mfy(element.y) });
|
|
54737
|
-
if (
|
|
58041
|
+
if (rotation11) {
|
|
54738
58042
|
gb3.add("load_rotation", { rotation_degrees: 0 });
|
|
54739
58043
|
}
|
|
54740
58044
|
glayer.push(...gb3.build());
|
|
54741
58045
|
}
|
|
54742
58046
|
}
|
|
54743
58047
|
} else if (element.type === "pcb_smtpad" && element.shape === "polygon") {
|
|
54744
|
-
if (element.layer === layer) {
|
|
58048
|
+
if (element.layer === layer && isOuterLayerRef(layer)) {
|
|
54745
58049
|
const layers_to_add_to = [
|
|
54746
58050
|
glayers[getGerberLayerName(layer, "copper")]
|
|
54747
58051
|
];
|
|
54748
|
-
if (
|
|
58052
|
+
if (element.is_covered_with_solder_mask !== true) {
|
|
54749
58053
|
layers_to_add_to.push(glayers[getGerberLayerName(layer, "soldermask")]);
|
|
54750
58054
|
}
|
|
54751
58055
|
for (const glayer of layers_to_add_to) {
|
|
54752
|
-
const pad_builder = gerberBuilder().add("select_aperture", { aperture_number: 10 }).add("start_region_statement", {});
|
|
54753
58056
|
const { points } = element;
|
|
54754
|
-
if (points
|
|
54755
|
-
|
|
54756
|
-
|
|
54757
|
-
|
|
54758
|
-
|
|
54759
|
-
|
|
54760
|
-
|
|
54761
|
-
x: points[i3].x,
|
|
54762
|
-
y: mfy(points[i3].y)
|
|
54763
|
-
});
|
|
54764
|
-
}
|
|
54765
|
-
pad_builder.add("plot_operation", {
|
|
54766
|
-
x: points[0].x,
|
|
54767
|
-
y: mfy(points[0].y)
|
|
54768
|
-
});
|
|
54769
|
-
}
|
|
54770
|
-
pad_builder.add("end_region_statement", {});
|
|
54771
|
-
glayer.push(...pad_builder.build());
|
|
58057
|
+
if (!points)
|
|
58058
|
+
continue;
|
|
58059
|
+
addClosedRegionFromPoints({
|
|
58060
|
+
target: glayer,
|
|
58061
|
+
apertureSource: glayer,
|
|
58062
|
+
points
|
|
58063
|
+
});
|
|
54772
58064
|
}
|
|
54773
58065
|
}
|
|
54774
58066
|
} else if (element.type === "pcb_solder_paste") {
|
|
54775
|
-
if (element.layer === layer) {
|
|
58067
|
+
if (element.layer === layer && isOuterLayerRef(layer)) {
|
|
54776
58068
|
const glayer = glayers[getGerberLayerName(layer, "paste")];
|
|
54777
|
-
|
|
54778
|
-
|
|
58069
|
+
let rotation11 = 0;
|
|
58070
|
+
if ("ccw_rotation" in element && typeof element.ccw_rotation === "number") {
|
|
58071
|
+
rotation11 = element.ccw_rotation;
|
|
58072
|
+
} else {
|
|
58073
|
+
const platedHole = circuitJson.find((candidate) => candidate.type === "pcb_plated_hole" && candidate.x === element.x && candidate.y === element.y && ("ccw_rotation" in candidate) && typeof candidate.ccw_rotation === "number");
|
|
58074
|
+
if (platedHole) {
|
|
58075
|
+
rotation11 = platedHole.ccw_rotation;
|
|
58076
|
+
}
|
|
58077
|
+
}
|
|
58078
|
+
let apertureConfig = getApertureConfigFromPcbSolderPaste(element);
|
|
58079
|
+
if (element.shape === "pill" && (rotation11 === 90 || rotation11 === 270)) {
|
|
58080
|
+
apertureConfig = getApertureConfigFromPcbSolderPaste({
|
|
58081
|
+
...element,
|
|
58082
|
+
width: element.height,
|
|
58083
|
+
height: element.width
|
|
58084
|
+
});
|
|
58085
|
+
rotation11 = 0;
|
|
58086
|
+
}
|
|
58087
|
+
const aperture_number = findApertureNumber(glayer, apertureConfig);
|
|
54779
58088
|
const gb3 = gerberBuilder().add("select_aperture", {
|
|
54780
58089
|
aperture_number
|
|
54781
58090
|
});
|
|
54782
58091
|
if (rotation11) {
|
|
54783
|
-
gb3.add("load_rotation", {
|
|
58092
|
+
gb3.add("load_rotation", {
|
|
58093
|
+
rotation_degrees: rotation11
|
|
58094
|
+
});
|
|
54784
58095
|
}
|
|
54785
58096
|
gb3.add("flash_operation", { x: element.x, y: mfy(element.y) });
|
|
54786
58097
|
if (rotation11) {
|
|
@@ -54790,10 +58101,33 @@ var import_fast_json_stable_stringify, defineExcellonDrillCommand = ({
|
|
|
54790
58101
|
}
|
|
54791
58102
|
} else if (element.type === "pcb_plated_hole") {
|
|
54792
58103
|
if (element.layers.includes(layer)) {
|
|
54793
|
-
|
|
54794
|
-
glayers[getGerberLayerName(layer, "copper")]
|
|
54795
|
-
|
|
54796
|
-
|
|
58104
|
+
const layersToAddTo = [
|
|
58105
|
+
glayers[getGerberLayerName(layer, "copper")]
|
|
58106
|
+
];
|
|
58107
|
+
if (isOuterLayerRef(layer) && element.is_covered_with_solder_mask !== true) {
|
|
58108
|
+
layersToAddTo.push(glayers[getGerberLayerName(layer, "soldermask")]);
|
|
58109
|
+
}
|
|
58110
|
+
for (const glayer of layersToAddTo) {
|
|
58111
|
+
if (element.shape === "hole_with_polygon_pad") {
|
|
58112
|
+
const { pad_outline } = element;
|
|
58113
|
+
if (!pad_outline?.length)
|
|
58114
|
+
continue;
|
|
58115
|
+
const soldermaskGlayer2 = glayers[getGerberLayerName(layer, "soldermask")];
|
|
58116
|
+
let points = pad_outline;
|
|
58117
|
+
if (glayer === soldermaskGlayer2 && "soldermask_margin" in element && typeof element.soldermask_margin === "number") {
|
|
58118
|
+
points = offsetPolygonOutline(pad_outline, element.soldermask_margin);
|
|
58119
|
+
}
|
|
58120
|
+
const translatedPoints = points.map((point9) => ({
|
|
58121
|
+
x: point9.x + element.x,
|
|
58122
|
+
y: point9.y + element.y
|
|
58123
|
+
}));
|
|
58124
|
+
addClosedRegionFromPoints({
|
|
58125
|
+
target: glayer,
|
|
58126
|
+
apertureSource: glayer,
|
|
58127
|
+
points: translatedPoints
|
|
58128
|
+
});
|
|
58129
|
+
continue;
|
|
58130
|
+
}
|
|
54797
58131
|
const holeW = "hole_width" in element && typeof element.hole_width === "number" ? element.hole_width : 0;
|
|
54798
58132
|
const holeH = "hole_height" in element && typeof element.hole_height === "number" ? element.hole_height : 0;
|
|
54799
58133
|
const padWidthCandidates = [holeW];
|
|
@@ -54812,10 +58146,17 @@ var import_fast_json_stable_stringify, defineExcellonDrillCommand = ({
|
|
|
54812
58146
|
padHeightCandidates.push(element.rect_pad_height);
|
|
54813
58147
|
}
|
|
54814
58148
|
const padH = Math.max(...padHeightCandidates);
|
|
58149
|
+
const soldermaskGlayer = glayers[getGerberLayerName(layer, "soldermask")];
|
|
58150
|
+
let soldermaskMargin = 0;
|
|
58151
|
+
if (glayer === soldermaskGlayer && "soldermask_margin" in element && typeof element.soldermask_margin === "number") {
|
|
58152
|
+
soldermaskMargin = element.soldermask_margin;
|
|
58153
|
+
}
|
|
58154
|
+
const aperturePadW = padW + soldermaskMargin * 2;
|
|
58155
|
+
const aperturePadH = padH + soldermaskMargin * 2;
|
|
54815
58156
|
if (element.shape === "pill") {
|
|
54816
58157
|
const circleApertureConfig = {
|
|
54817
58158
|
standard_template_code: "C",
|
|
54818
|
-
diameter: Math.min(
|
|
58159
|
+
diameter: Math.min(aperturePadW, aperturePadH)
|
|
54819
58160
|
};
|
|
54820
58161
|
let aperture_number;
|
|
54821
58162
|
try {
|
|
@@ -54841,8 +58182,8 @@ var import_fast_json_stable_stringify, defineExcellonDrillCommand = ({
|
|
|
54841
58182
|
y: element.y + rotatedY
|
|
54842
58183
|
};
|
|
54843
58184
|
};
|
|
54844
|
-
const isHorizontal2 =
|
|
54845
|
-
const offset = isHorizontal2 ? (
|
|
58185
|
+
const isHorizontal2 = aperturePadW >= aperturePadH;
|
|
58186
|
+
const offset = isHorizontal2 ? (aperturePadW - aperturePadH) / 2 : (aperturePadH - aperturePadW) / 2;
|
|
54846
58187
|
if (offset <= 0) {
|
|
54847
58188
|
const center2 = rotateAndTranslate(0, 0);
|
|
54848
58189
|
gb3.add("flash_operation", { x: center2.x, y: mfy(center2.y) });
|
|
@@ -54867,10 +58208,16 @@ var import_fast_json_stable_stringify, defineExcellonDrillCommand = ({
|
|
|
54867
58208
|
}
|
|
54868
58209
|
glayer.push(...gb3.build());
|
|
54869
58210
|
} else {
|
|
54870
|
-
|
|
58211
|
+
let apertureConfig = getApertureConfigFromPcbPlatedHole({
|
|
54871
58212
|
...element,
|
|
54872
58213
|
...element.shape !== "circle" ? { outer_width: padW, outer_height: padH } : {}
|
|
54873
58214
|
});
|
|
58215
|
+
if (glayer === soldermaskGlayer) {
|
|
58216
|
+
apertureConfig = getApertureConfigFromPcbPlatedHoleSoldermask({
|
|
58217
|
+
...element,
|
|
58218
|
+
...element.shape !== "circle" ? { outer_width: padW, outer_height: padH } : {}
|
|
58219
|
+
});
|
|
58220
|
+
}
|
|
54874
58221
|
const rotation11 = "rect_ccw_rotation" in element && typeof element.rect_ccw_rotation === "number" && Math.abs(padW - padH) > 0.000000001 ? element.rect_ccw_rotation : undefined;
|
|
54875
58222
|
const gb3 = gerberBuilder().add("select_aperture", {
|
|
54876
58223
|
aperture_number: findApertureNumber(glayer, apertureConfig)
|
|
@@ -54885,7 +58232,7 @@ var import_fast_json_stable_stringify, defineExcellonDrillCommand = ({
|
|
|
54885
58232
|
}
|
|
54886
58233
|
}
|
|
54887
58234
|
} else if (element.type === "pcb_hole") {
|
|
54888
|
-
if (layer !==
|
|
58235
|
+
if (isOuterLayerRef(layer) && element.is_covered_with_solder_mask !== true) {
|
|
54889
58236
|
for (const glayer of [
|
|
54890
58237
|
glayers[getGerberLayerName(layer, "soldermask")]
|
|
54891
58238
|
]) {
|
|
@@ -54894,15 +58241,21 @@ var import_fast_json_stable_stringify, defineExcellonDrillCommand = ({
|
|
|
54894
58241
|
continue;
|
|
54895
58242
|
}
|
|
54896
58243
|
glayer.push(...gerberBuilder().add("select_aperture", {
|
|
54897
|
-
aperture_number: findApertureNumber(glayer,
|
|
58244
|
+
aperture_number: findApertureNumber(glayer, getApertureConfigFromCirclePcbHoleSoldermask(element))
|
|
54898
58245
|
}).add("flash_operation", { x: element.x, y: mfy(element.y) }).build());
|
|
54899
58246
|
}
|
|
54900
58247
|
}
|
|
54901
58248
|
} else if (element.type === "pcb_via") {
|
|
54902
58249
|
if (element.layers.includes(layer)) {
|
|
54903
|
-
|
|
58250
|
+
const layersToAddTo = [
|
|
58251
|
+
glayers[getGerberLayerName(layer, "copper")]
|
|
58252
|
+
];
|
|
58253
|
+
if (element.is_tented === false && isOuterLayerRef(layer)) {
|
|
58254
|
+
layersToAddTo.push(glayers[getGerberLayerName(layer, "soldermask")]);
|
|
58255
|
+
}
|
|
58256
|
+
for (const glayer of layersToAddTo) {
|
|
54904
58257
|
glayer.push(...gerberBuilder().add("select_aperture", {
|
|
54905
|
-
aperture_number: findApertureNumber(glayer,
|
|
58258
|
+
aperture_number: findApertureNumber(glayer, getApertureConfigFromOuterDiameter(element))
|
|
54906
58259
|
}).add("flash_operation", { x: element.x, y: mfy(element.y) }).build());
|
|
54907
58260
|
}
|
|
54908
58261
|
}
|
|
@@ -54915,36 +58268,36 @@ var import_fast_json_stable_stringify, defineExcellonDrillCommand = ({
|
|
|
54915
58268
|
aperture_number: 10
|
|
54916
58269
|
});
|
|
54917
58270
|
if (outline && outline.length > 2) {
|
|
54918
|
-
const
|
|
54919
|
-
|
|
54920
|
-
|
|
54921
|
-
|
|
54922
|
-
|
|
54923
|
-
|
|
54924
|
-
for (let i3 = 1;i3 < outlinePoints.length; i3++) {
|
|
54925
|
-
gerberBuild.add("plot_operation", outlinePoints[i3]);
|
|
58271
|
+
const boardPolygon = [
|
|
58272
|
+
outline.map((point9) => [point9.x, point9.y])
|
|
58273
|
+
];
|
|
58274
|
+
let boardGeometry = [boardPolygon];
|
|
58275
|
+
if (solidCutoutPolygons.length > 0) {
|
|
58276
|
+
boardGeometry = import_polygon_clipping2.default.difference(boardPolygon, ...solidCutoutPolygons);
|
|
54926
58277
|
}
|
|
54927
|
-
const
|
|
54928
|
-
|
|
54929
|
-
|
|
58278
|
+
for (const polygon2 of boardGeometry) {
|
|
58279
|
+
for (const ring of polygon2) {
|
|
58280
|
+
emitEdgeCutRing(gerberBuild, ring, mfy);
|
|
58281
|
+
}
|
|
54930
58282
|
}
|
|
54931
58283
|
} else {
|
|
54932
|
-
|
|
54933
|
-
|
|
54934
|
-
|
|
54935
|
-
|
|
54936
|
-
|
|
54937
|
-
|
|
54938
|
-
|
|
54939
|
-
|
|
54940
|
-
|
|
54941
|
-
|
|
54942
|
-
|
|
54943
|
-
|
|
54944
|
-
|
|
54945
|
-
|
|
54946
|
-
|
|
54947
|
-
|
|
58284
|
+
const boardPolygon = [
|
|
58285
|
+
[
|
|
58286
|
+
[center2.x - width / 2, center2.y - height / 2],
|
|
58287
|
+
[center2.x + width / 2, center2.y - height / 2],
|
|
58288
|
+
[center2.x + width / 2, center2.y + height / 2],
|
|
58289
|
+
[center2.x - width / 2, center2.y + height / 2]
|
|
58290
|
+
]
|
|
58291
|
+
];
|
|
58292
|
+
let boardGeometry = [boardPolygon];
|
|
58293
|
+
if (solidCutoutPolygons.length > 0) {
|
|
58294
|
+
boardGeometry = import_polygon_clipping2.default.difference(boardPolygon, ...solidCutoutPolygons);
|
|
58295
|
+
}
|
|
58296
|
+
for (const polygon2 of boardGeometry) {
|
|
58297
|
+
for (const ring of polygon2) {
|
|
58298
|
+
emitEdgeCutRing(gerberBuild, ring, mfy);
|
|
58299
|
+
}
|
|
58300
|
+
}
|
|
54948
58301
|
}
|
|
54949
58302
|
glayer.push(...gerberBuild.build());
|
|
54950
58303
|
} else if (element.type === "pcb_panel" && layer === "edgecut") {
|
|
@@ -54972,131 +58325,26 @@ var import_fast_json_stable_stringify, defineExcellonDrillCommand = ({
|
|
|
54972
58325
|
glayer.push(...gerberBuild.build());
|
|
54973
58326
|
} else if (element.type === "pcb_cutout") {
|
|
54974
58327
|
if (layer === "edgecut") {
|
|
58328
|
+
if (hasBoard && !hasPanel && doesSolidCutoutOverlapBoardEdge({
|
|
58329
|
+
cutout: element,
|
|
58330
|
+
boardOutlinePolygons
|
|
58331
|
+
})) {
|
|
58332
|
+
continue;
|
|
58333
|
+
}
|
|
54975
58334
|
const ec_layer = glayers.Edge_Cuts;
|
|
54976
58335
|
const cutout_builder = gerberBuilder().add("select_aperture", {
|
|
54977
58336
|
aperture_number: 10
|
|
54978
58337
|
});
|
|
54979
|
-
const
|
|
54980
|
-
|
|
54981
|
-
|
|
54982
|
-
|
|
54983
|
-
|
|
54984
|
-
|
|
54985
|
-
|
|
54986
|
-
|
|
54987
|
-
|
|
54988
|
-
|
|
54989
|
-
transformMatrix2 = rotate12(angle_rad);
|
|
54990
|
-
}
|
|
54991
|
-
return compose9(translate9(center2.x, center2.y), transformMatrix2);
|
|
54992
|
-
};
|
|
54993
|
-
const transformMatrix = makeTransformMatrix();
|
|
54994
|
-
if (r4 > 0) {
|
|
54995
|
-
const startPoint = { x: -w4 + r4, y: h4 };
|
|
54996
|
-
let currentPoint = applyToPoint26(transformMatrix, startPoint);
|
|
54997
|
-
cutout_builder.add("move_operation", {
|
|
54998
|
-
x: currentPoint.x,
|
|
54999
|
-
y: mfy(currentPoint.y)
|
|
55000
|
-
});
|
|
55001
|
-
const addLine = (point9) => {
|
|
55002
|
-
const transformedPoint = applyToPoint26(transformMatrix, point9);
|
|
55003
|
-
cutout_builder.add("plot_operation", {
|
|
55004
|
-
x: transformedPoint.x,
|
|
55005
|
-
y: mfy(transformedPoint.y)
|
|
55006
|
-
});
|
|
55007
|
-
currentPoint = transformedPoint;
|
|
55008
|
-
};
|
|
55009
|
-
const addArc = (options) => {
|
|
55010
|
-
const transformedPoint = applyToPoint26(transformMatrix, options.point);
|
|
55011
|
-
const transformedCenter = applyToPoint26(transformMatrix, options.center);
|
|
55012
|
-
cutout_builder.add("set_movement_mode_to_clockwise_circular", {}).add("plot_operation", {
|
|
55013
|
-
x: transformedPoint.x,
|
|
55014
|
-
y: mfy(transformedPoint.y),
|
|
55015
|
-
i: transformedCenter.x - currentPoint.x,
|
|
55016
|
-
j: mfy(transformedCenter.y) - mfy(currentPoint.y)
|
|
55017
|
-
}).add("set_movement_mode_to_linear", {});
|
|
55018
|
-
currentPoint = transformedPoint;
|
|
55019
|
-
};
|
|
55020
|
-
addLine({ x: w4 - r4, y: h4 });
|
|
55021
|
-
addArc({
|
|
55022
|
-
point: { x: w4, y: h4 - r4 },
|
|
55023
|
-
center: { x: w4 - r4, y: h4 - r4 }
|
|
55024
|
-
});
|
|
55025
|
-
addLine({ x: w4, y: -h4 + r4 });
|
|
55026
|
-
addArc({
|
|
55027
|
-
point: { x: w4 - r4, y: -h4 },
|
|
55028
|
-
center: { x: w4 - r4, y: -h4 + r4 }
|
|
55029
|
-
});
|
|
55030
|
-
addLine({ x: -w4 + r4, y: -h4 });
|
|
55031
|
-
addArc({
|
|
55032
|
-
point: { x: -w4, y: -h4 + r4 },
|
|
55033
|
-
center: { x: -w4 + r4, y: -h4 + r4 }
|
|
55034
|
-
});
|
|
55035
|
-
addLine({ x: -w4, y: h4 - r4 });
|
|
55036
|
-
addArc({
|
|
55037
|
-
point: { x: -w4 + r4, y: h4 },
|
|
55038
|
-
center: { x: -w4 + r4, y: h4 - r4 }
|
|
55039
|
-
});
|
|
55040
|
-
} else {
|
|
55041
|
-
const points = [
|
|
55042
|
-
{ x: -w4, y: h4 },
|
|
55043
|
-
{ x: w4, y: h4 },
|
|
55044
|
-
{ x: w4, y: -h4 },
|
|
55045
|
-
{ x: -w4, y: -h4 }
|
|
55046
|
-
];
|
|
55047
|
-
const transformedPoints = points.map((p3) => applyToPoint26(transformMatrix, p3));
|
|
55048
|
-
cutout_builder.add("move_operation", {
|
|
55049
|
-
x: transformedPoints[0].x,
|
|
55050
|
-
y: mfy(transformedPoints[0].y)
|
|
55051
|
-
});
|
|
55052
|
-
for (let i3 = 1;i3 < transformedPoints.length; i3++) {
|
|
55053
|
-
cutout_builder.add("plot_operation", {
|
|
55054
|
-
x: transformedPoints[i3].x,
|
|
55055
|
-
y: mfy(transformedPoints[i3].y)
|
|
55056
|
-
});
|
|
55057
|
-
}
|
|
55058
|
-
cutout_builder.add("plot_operation", {
|
|
55059
|
-
x: transformedPoints[0].x,
|
|
55060
|
-
y: mfy(transformedPoints[0].y)
|
|
55061
|
-
});
|
|
55062
|
-
}
|
|
55063
|
-
} else if (el3.shape === "circle") {
|
|
55064
|
-
const { center: center2, radius } = el3;
|
|
55065
|
-
const p12 = { x: center2.x + radius, y: center2.y };
|
|
55066
|
-
const p23 = { x: center2.x - radius, y: center2.y };
|
|
55067
|
-
cutout_builder.add("move_operation", {
|
|
55068
|
-
x: p12.x,
|
|
55069
|
-
y: mfy(p12.y)
|
|
55070
|
-
}).add("set_movement_mode_to_counterclockwise_circular", {}).add("plot_operation", {
|
|
55071
|
-
x: p23.x,
|
|
55072
|
-
y: mfy(p23.y),
|
|
55073
|
-
i: -radius,
|
|
55074
|
-
j: 0
|
|
55075
|
-
}).add("plot_operation", {
|
|
55076
|
-
x: p12.x,
|
|
55077
|
-
y: mfy(p12.y),
|
|
55078
|
-
i: radius,
|
|
55079
|
-
j: 0
|
|
55080
|
-
}).add("set_movement_mode_to_linear", {});
|
|
55081
|
-
} else if (el3.shape === "polygon") {
|
|
55082
|
-
const { points } = el3;
|
|
55083
|
-
if (points.length > 0) {
|
|
55084
|
-
cutout_builder.add("move_operation", {
|
|
55085
|
-
x: points[0].x,
|
|
55086
|
-
y: mfy(points[0].y)
|
|
55087
|
-
});
|
|
55088
|
-
for (let i3 = 1;i3 < points.length; i3++) {
|
|
55089
|
-
cutout_builder.add("plot_operation", {
|
|
55090
|
-
x: points[i3].x,
|
|
55091
|
-
y: mfy(points[i3].y)
|
|
55092
|
-
});
|
|
55093
|
-
}
|
|
55094
|
-
cutout_builder.add("plot_operation", {
|
|
55095
|
-
x: points[0].x,
|
|
55096
|
-
y: mfy(points[0].y)
|
|
55097
|
-
});
|
|
55098
|
-
}
|
|
55099
|
-
}
|
|
58338
|
+
const drawCw = hasBoard && !hasPanel && isCutoutFullyInternal({
|
|
58339
|
+
cutout: element,
|
|
58340
|
+
boardOutlinePolygons
|
|
58341
|
+
});
|
|
58342
|
+
emitCutoutEdgeCuts({
|
|
58343
|
+
cutout: element,
|
|
58344
|
+
builder: cutout_builder,
|
|
58345
|
+
mfy,
|
|
58346
|
+
drawCw
|
|
58347
|
+
});
|
|
55100
58348
|
ec_layer.push(...cutout_builder.build());
|
|
55101
58349
|
}
|
|
55102
58350
|
}
|
|
@@ -55107,8 +58355,11 @@ var import_fast_json_stable_stringify, defineExcellonDrillCommand = ({
|
|
|
55107
58355
|
}
|
|
55108
58356
|
return glayers;
|
|
55109
58357
|
};
|
|
55110
|
-
var
|
|
58358
|
+
var init_chunk_46NSLLUV = __esm(() => {
|
|
58359
|
+
import_polygon_clipping = __toESM2(require_polygon_clipping_cjs(), 1);
|
|
55111
58360
|
import_fast_json_stable_stringify = __toESM2(require_fast_json_stable_stringify(), 1);
|
|
58361
|
+
import_polygon_clipping2 = __toESM2(require_polygon_clipping_cjs(), 1);
|
|
58362
|
+
import_polygon_clipping3 = __toESM2(require_polygon_clipping_cjs(), 1);
|
|
55112
58363
|
FMAT = defineExcellonDrillCommand({
|
|
55113
58364
|
command_code: "FMAT",
|
|
55114
58365
|
schema: z4.object({
|
|
@@ -55636,7 +58887,17 @@ ${template_code}%`;
|
|
|
55636
58887
|
if (macro_name === "HORZPILL" || macro_name === "VERTPILL") {
|
|
55637
58888
|
commandString += `${props.x_size.toFixed(6)}X${props.y_size.toFixed(6)}X${props.circle_diameter.toFixed(6)}X${props.circle_center_offset.toFixed(6)}`;
|
|
55638
58889
|
} else if (macro_name === "ROUNDRECT") {
|
|
55639
|
-
|
|
58890
|
+
commandString += [
|
|
58891
|
+
props.corner_radius,
|
|
58892
|
+
props.corner_1_x,
|
|
58893
|
+
props.corner_1_y,
|
|
58894
|
+
props.corner_2_x,
|
|
58895
|
+
props.corner_2_y,
|
|
58896
|
+
props.corner_3_x,
|
|
58897
|
+
props.corner_3_y,
|
|
58898
|
+
props.corner_4_x,
|
|
58899
|
+
props.corner_4_y
|
|
58900
|
+
].map((value) => value.toFixed(6)).join("X");
|
|
55640
58901
|
}
|
|
55641
58902
|
commandString += "*%";
|
|
55642
58903
|
return commandString;
|
|
@@ -55696,9 +58957,20 @@ ${template_code}%`;
|
|
|
55696
58957
|
set_layer_polarity,
|
|
55697
58958
|
start_region_statement
|
|
55698
58959
|
};
|
|
58960
|
+
SILKSCREEN_SHAPE_TYPES = [
|
|
58961
|
+
"pcb_silkscreen_line",
|
|
58962
|
+
"pcb_silkscreen_rect",
|
|
58963
|
+
"pcb_silkscreen_circle",
|
|
58964
|
+
"pcb_silkscreen_oval",
|
|
58965
|
+
"pcb_silkscreen_pill"
|
|
58966
|
+
];
|
|
58967
|
+
REGION_APERTURE_CONFIG = {
|
|
58968
|
+
standard_template_code: "C",
|
|
58969
|
+
diameter: 0.001
|
|
58970
|
+
};
|
|
55699
58971
|
package_default5 = {
|
|
55700
58972
|
name: "circuit-json-to-gerber",
|
|
55701
|
-
version: "0.0.
|
|
58973
|
+
version: "0.0.82",
|
|
55702
58974
|
main: "dist/index.js",
|
|
55703
58975
|
type: "module",
|
|
55704
58976
|
scripts: {
|
|
@@ -55723,15 +58995,16 @@ ${template_code}%`;
|
|
|
55723
58995
|
"@types/react-dom": "^19.1.5",
|
|
55724
58996
|
archiver: "^7.0.1",
|
|
55725
58997
|
"bun-match-svg": "^0.0.13",
|
|
55726
|
-
"circuit-json": "^0.0.
|
|
58998
|
+
"circuit-json": "^0.0.426",
|
|
55727
58999
|
commander: "^12.1.0",
|
|
55728
59000
|
"gerber-to-svg": "^4.2.8",
|
|
55729
59001
|
gerberts: "^0.0.3",
|
|
55730
59002
|
jszip: "^3.10.1",
|
|
55731
59003
|
"pcb-stackup": "^4.2.8",
|
|
59004
|
+
"polygon-clipping": "^0.15.7",
|
|
55732
59005
|
react: "^19.2.1",
|
|
55733
59006
|
"react-dom": "^19.2.1",
|
|
55734
|
-
tscircuit: "^0.0.
|
|
59007
|
+
tscircuit: "^0.0.1776",
|
|
55735
59008
|
tsup: "^8.2.4"
|
|
55736
59009
|
},
|
|
55737
59010
|
peerDependencies: {
|
|
@@ -55747,31 +59020,40 @@ ${template_code}%`;
|
|
|
55747
59020
|
};
|
|
55748
59021
|
layerAndTypeToFileFunction = {
|
|
55749
59022
|
"top-copper": "Copper,L1,Top",
|
|
55750
|
-
"bottom-copper": "Copper,L2,Bot",
|
|
55751
59023
|
"top-soldermask": "Soldermask,Top",
|
|
55752
59024
|
"bottom-soldermask": "Soldermask,Bot",
|
|
55753
59025
|
"top-silkscreen": "Legend,Top",
|
|
55754
59026
|
"bottom-silkscreen": "Legend,Bot",
|
|
59027
|
+
"top-fabrication": "Other,Fab,Top",
|
|
59028
|
+
"bottom-fabrication": "Other,Fab,Bot",
|
|
55755
59029
|
"top-paste": "Paste,Top",
|
|
55756
59030
|
"bottom-paste": "Paste,Bot",
|
|
55757
59031
|
edgecut: "Profile,NP"
|
|
55758
59032
|
};
|
|
55759
59033
|
layerRefToGerberPrefix = {
|
|
55760
59034
|
top: "F_",
|
|
55761
|
-
bottom: "B_"
|
|
59035
|
+
bottom: "B_",
|
|
59036
|
+
inner1: "In1_",
|
|
59037
|
+
inner2: "In2_",
|
|
59038
|
+
inner3: "In3_",
|
|
59039
|
+
inner4: "In4_",
|
|
59040
|
+
inner5: "In5_",
|
|
59041
|
+
inner6: "In6_"
|
|
55762
59042
|
};
|
|
55763
59043
|
layerTypeToGerberSuffix = {
|
|
55764
59044
|
copper: "Cu",
|
|
55765
59045
|
silkscreen: "SilkScreen",
|
|
59046
|
+
fabrication: "Fab",
|
|
55766
59047
|
soldermask: "Mask",
|
|
55767
59048
|
mask: "Mask",
|
|
55768
59049
|
paste: "Paste"
|
|
55769
59050
|
};
|
|
59051
|
+
outerLayerRefs = ["top", "bottom"];
|
|
55770
59052
|
});
|
|
55771
59053
|
|
|
55772
59054
|
// node_modules/circuit-json-to-gerber/dist/index.js
|
|
55773
59055
|
var init_dist = __esm(() => {
|
|
55774
|
-
|
|
59056
|
+
init_chunk_46NSLLUV();
|
|
55775
59057
|
});
|
|
55776
59058
|
|
|
55777
59059
|
// node_modules/@tracespace/xml-id/index.js
|
|
@@ -68645,11 +71927,11 @@ var init_lib = __esm(() => {
|
|
|
68645
71927
|
});
|
|
68646
71928
|
|
|
68647
71929
|
// node_modules/circuit-to-canvas/dist/index.js
|
|
68648
|
-
import { compose as
|
|
71930
|
+
import { compose as compose33, identity as identity9, scale as scale7, translate as translate33 } from "transformation-matrix";
|
|
68649
71931
|
import { applyToPoint as applyToPoint27 } from "transformation-matrix";
|
|
68650
|
-
import { applyToPoint as
|
|
68651
|
-
import { applyToPoint as
|
|
68652
|
-
import { applyToPoint as
|
|
71932
|
+
import { applyToPoint as applyToPoint28 } from "transformation-matrix";
|
|
71933
|
+
import { applyToPoint as applyToPoint43 } from "transformation-matrix";
|
|
71934
|
+
import { applyToPoint as applyToPoint33 } from "transformation-matrix";
|
|
68653
71935
|
import { glyphLineAlphabet } from "@tscircuit/alphabet";
|
|
68654
71936
|
import { applyToPoint as applyToPoint52 } from "transformation-matrix";
|
|
68655
71937
|
import {
|
|
@@ -68666,7 +71948,7 @@ import { applyToPoint as applyToPoint102 } from "transformation-matrix";
|
|
|
68666
71948
|
import { applyToPoint as applyToPoint112 } from "transformation-matrix";
|
|
68667
71949
|
import { applyToPoint as applyToPoint152 } from "transformation-matrix";
|
|
68668
71950
|
import { applyToPoint as applyToPoint122, compose as compose10, rotate as rotate13, translate as translate10 } from "transformation-matrix";
|
|
68669
|
-
import { applyToPoint as applyToPoint132, compose as
|
|
71951
|
+
import { applyToPoint as applyToPoint132, compose as compose23, rotate as rotate23, translate as translate23 } from "transformation-matrix";
|
|
68670
71952
|
import { applyToPoint as applyToPoint142 } from "transformation-matrix";
|
|
68671
71953
|
import { applyToPoint as applyToPoint162 } from "transformation-matrix";
|
|
68672
71954
|
import { applyToPoint as applyToPoint172 } from "transformation-matrix";
|
|
@@ -68738,7 +72020,7 @@ function drawRect(params2) {
|
|
|
68738
72020
|
isStrokeDashed = false,
|
|
68739
72021
|
lineJoin
|
|
68740
72022
|
} = params2;
|
|
68741
|
-
const [cx3, cy3] =
|
|
72023
|
+
const [cx3, cy3] = applyToPoint28(realToCanvasMat, [center2.x, center2.y]);
|
|
68742
72024
|
const scaledWidth = width * Math.abs(realToCanvasMat.a);
|
|
68743
72025
|
const scaledHeight = height * Math.abs(realToCanvasMat.a);
|
|
68744
72026
|
const scaledRadius = borderRadius * Math.abs(realToCanvasMat.a);
|
|
@@ -68850,7 +72132,7 @@ function drawPolygon(params2) {
|
|
|
68850
72132
|
if (points.length < 3)
|
|
68851
72133
|
return;
|
|
68852
72134
|
ctx.beginPath();
|
|
68853
|
-
const canvasPoints = points.map((p3) =>
|
|
72135
|
+
const canvasPoints = points.map((p3) => applyToPoint33(realToCanvasMat, [p3.x, p3.y]));
|
|
68854
72136
|
const firstPoint = canvasPoints[0];
|
|
68855
72137
|
if (!firstPoint)
|
|
68856
72138
|
return;
|
|
@@ -68895,25 +72177,25 @@ function computeArcFromBulge(startX, startY, endX, endY, bulge) {
|
|
|
68895
72177
|
}
|
|
68896
72178
|
function drawArcFromBulge(ctx, realStartX, realStartY, realEndX, realEndY, bulge, realToCanvasMat) {
|
|
68897
72179
|
if (Math.abs(bulge) < 0.0000000001) {
|
|
68898
|
-
const [endX, endY] =
|
|
72180
|
+
const [endX, endY] = applyToPoint43(realToCanvasMat, [realEndX, realEndY]);
|
|
68899
72181
|
ctx.lineTo(endX, endY);
|
|
68900
72182
|
return;
|
|
68901
72183
|
}
|
|
68902
72184
|
const arc2 = computeArcFromBulge(realStartX, realStartY, realEndX, realEndY, bulge);
|
|
68903
72185
|
if (!arc2) {
|
|
68904
|
-
const [endX, endY] =
|
|
72186
|
+
const [endX, endY] = applyToPoint43(realToCanvasMat, [realEndX, realEndY]);
|
|
68905
72187
|
ctx.lineTo(endX, endY);
|
|
68906
72188
|
return;
|
|
68907
72189
|
}
|
|
68908
|
-
const [canvasStartX, canvasStartY] =
|
|
72190
|
+
const [canvasStartX, canvasStartY] = applyToPoint43(realToCanvasMat, [
|
|
68909
72191
|
realStartX,
|
|
68910
72192
|
realStartY
|
|
68911
72193
|
]);
|
|
68912
|
-
const [canvasEndX, canvasEndY] =
|
|
72194
|
+
const [canvasEndX, canvasEndY] = applyToPoint43(realToCanvasMat, [
|
|
68913
72195
|
realEndX,
|
|
68914
72196
|
realEndY
|
|
68915
72197
|
]);
|
|
68916
|
-
const [canvasCenterX, canvasCenterY] =
|
|
72198
|
+
const [canvasCenterX, canvasCenterY] = applyToPoint43(realToCanvasMat, [
|
|
68917
72199
|
arc2.centerX,
|
|
68918
72200
|
arc2.centerY
|
|
68919
72201
|
]);
|
|
@@ -68932,7 +72214,7 @@ function drawRing(ctx, ring, realToCanvasMat) {
|
|
|
68932
72214
|
const v02 = ring.vertices[0];
|
|
68933
72215
|
const v12 = ring.vertices[1];
|
|
68934
72216
|
if (v02 && v12 && Math.abs((v02.bulge ?? 0) - 1) < 0.0000000001 && Math.abs((v12.bulge ?? 0) - 1) < 0.0000000001) {
|
|
68935
|
-
const [x02, y02] =
|
|
72217
|
+
const [x02, y02] = applyToPoint43(realToCanvasMat, [v02.x, v02.y]);
|
|
68936
72218
|
ctx.moveTo(x02, y02);
|
|
68937
72219
|
drawArcFromBulge(ctx, v02.x, v02.y, v12.x, v12.y, 1, realToCanvasMat);
|
|
68938
72220
|
drawArcFromBulge(ctx, v12.x, v12.y, v02.x, v02.y, 1, realToCanvasMat);
|
|
@@ -68942,7 +72224,7 @@ function drawRing(ctx, ring, realToCanvasMat) {
|
|
|
68942
72224
|
const firstVertex = ring.vertices[0];
|
|
68943
72225
|
if (!firstVertex)
|
|
68944
72226
|
return;
|
|
68945
|
-
const [firstX, firstY] =
|
|
72227
|
+
const [firstX, firstY] = applyToPoint43(realToCanvasMat, [
|
|
68946
72228
|
firstVertex.x,
|
|
68947
72229
|
firstVertex.y
|
|
68948
72230
|
]);
|
|
@@ -68955,7 +72237,7 @@ function drawRing(ctx, ring, realToCanvasMat) {
|
|
|
68955
72237
|
continue;
|
|
68956
72238
|
const bulge = currentVertex.bulge ?? 0;
|
|
68957
72239
|
if (Math.abs(bulge) < 0.0000000001) {
|
|
68958
|
-
const [nextX, nextY] =
|
|
72240
|
+
const [nextX, nextY] = applyToPoint43(realToCanvasMat, [
|
|
68959
72241
|
nextVertex.x,
|
|
68960
72242
|
nextVertex.y
|
|
68961
72243
|
]);
|
|
@@ -68972,7 +72254,7 @@ function drawPcbCopperPour(params2) {
|
|
|
68972
72254
|
ctx.save();
|
|
68973
72255
|
ctx.globalAlpha = opacity;
|
|
68974
72256
|
if (pour.shape === "rect") {
|
|
68975
|
-
const [cx3, cy3] =
|
|
72257
|
+
const [cx3, cy3] = applyToPoint43(realToCanvasMat, [
|
|
68976
72258
|
pour.center.x,
|
|
68977
72259
|
pour.center.y
|
|
68978
72260
|
]);
|
|
@@ -68991,7 +72273,7 @@ function drawPcbCopperPour(params2) {
|
|
|
68991
72273
|
}
|
|
68992
72274
|
if (pour.shape === "polygon") {
|
|
68993
72275
|
if (pour.points && pour.points.length >= 3) {
|
|
68994
|
-
const canvasPoints = pour.points.map((p3) =>
|
|
72276
|
+
const canvasPoints = pour.points.map((p3) => applyToPoint43(realToCanvasMat, [p3.x, p3.y]));
|
|
68995
72277
|
const firstPoint = canvasPoints[0];
|
|
68996
72278
|
if (!firstPoint) {
|
|
68997
72279
|
ctx.restore();
|
|
@@ -70016,7 +73298,7 @@ function drawRoundedRectPath(params2) {
|
|
|
70016
73298
|
ccwRotationDegrees = 0
|
|
70017
73299
|
} = params2;
|
|
70018
73300
|
const ccwRotationRadians = ccwRotationDegrees * Math.PI / 180;
|
|
70019
|
-
const realToPxTransform =
|
|
73301
|
+
const realToPxTransform = compose23(translate23(centerX, centerY), rotate23(-ccwRotationRadians));
|
|
70020
73302
|
const rectHalfWidth = width / 2;
|
|
70021
73303
|
const rectHalfHeight = height / 2;
|
|
70022
73304
|
const rectCornerRadius = Math.min(radius, rectHalfWidth, rectHalfHeight);
|
|
@@ -73371,7 +76653,7 @@ var getAdvanceRatio = (char) => glyphAdvanceRatio[char] ?? (char === " " ? textM
|
|
|
73371
76653
|
const uniformScale = Math.min(scaleX, scaleY);
|
|
73372
76654
|
const offsetX = (canvasWidth - realWidth * uniformScale) / 2;
|
|
73373
76655
|
const offsetY = (canvasHeight - realHeight * uniformScale) / 2;
|
|
73374
|
-
this.realToCanvasMat =
|
|
76656
|
+
this.realToCanvasMat = compose33(translate33(offsetX, offsetY), scale7(uniformScale, -uniformScale), translate33(-bounds.minX, -bounds.maxY));
|
|
73375
76657
|
}
|
|
73376
76658
|
drawElements(elements, options = {}) {
|
|
73377
76659
|
const layer = getCopperLayer(options.layers);
|
|
@@ -73830,7 +77112,7 @@ import {
|
|
|
73830
77112
|
isPointInsidePolygon as isPointInsidePolygon2,
|
|
73831
77113
|
pointToSegmentDistance as pointToSegmentDistance3
|
|
73832
77114
|
} from "@tscircuit/math-utils";
|
|
73833
|
-
import { applyToPoint as
|
|
77115
|
+
import { applyToPoint as applyToPoint29, identity as identity10 } from "transformation-matrix";
|
|
73834
77116
|
import { convertCircuitJsonToPcbSvg as convertCircuitJsonToPcbSvg22 } from "circuit-to-svg";
|
|
73835
77117
|
import { deflateSync } from "node:zlib";
|
|
73836
77118
|
|
|
@@ -74450,7 +77732,7 @@ var import_gerber_to_svg, renderTscircuitRepro = async (tsx, options = {}) => {
|
|
|
74450
77732
|
const svg = await renderGerberToSvg(gerber);
|
|
74451
77733
|
const boardSvg = forceSvgViewport({ svg, bounds, width, height });
|
|
74452
77734
|
return getMaskFromPng(renderSvgToPng(boardSvg));
|
|
74453
|
-
}, transformPoint = (matrix2, point9) =>
|
|
77735
|
+
}, transformPoint = (matrix2, point9) => applyToPoint29(matrix2, point9), getBounds2 = (parts) => {
|
|
74454
77736
|
let minX = Number.POSITIVE_INFINITY;
|
|
74455
77737
|
let minY = Number.POSITIVE_INFINITY;
|
|
74456
77738
|
let maxX = Number.NEGATIVE_INFINITY;
|
|
@@ -115063,7 +118345,7 @@ var import_perfect_cli = __toESM2(require_dist2(), 1);
|
|
|
115063
118345
|
// lib/getVersion.ts
|
|
115064
118346
|
import { createRequire as createRequire2 } from "node:module";
|
|
115065
118347
|
// package.json
|
|
115066
|
-
var version = "0.1.
|
|
118348
|
+
var version = "0.1.1644";
|
|
115067
118349
|
var package_default = {
|
|
115068
118350
|
name: "@tscircuit/cli",
|
|
115069
118351
|
version,
|
|
@@ -115103,7 +118385,7 @@ var package_default = {
|
|
|
115103
118385
|
"circuit-json-to-3d-png": "^0.0.6",
|
|
115104
118386
|
"circuit-json-to-bom-csv": "^0.0.7",
|
|
115105
118387
|
"circuit-json-to-connectivity-map": "^0.0.25",
|
|
115106
|
-
"circuit-json-to-gerber": "^0.0.
|
|
118388
|
+
"circuit-json-to-gerber": "^0.0.83",
|
|
115107
118389
|
"circuit-json-to-kicad": "0.0.157",
|
|
115108
118390
|
"circuit-json-to-pnp-csv": "^0.0.7",
|
|
115109
118391
|
"circuit-json-to-readable-netlist": "^0.0.15",
|
|
@@ -115136,6 +118418,7 @@ var package_default = {
|
|
|
115136
118418
|
md5: "^2.3.0",
|
|
115137
118419
|
"perfect-cli": "^1.0.21",
|
|
115138
118420
|
playwright: "^1.57.0",
|
|
118421
|
+
"polygon-clipping": "^0.15.7",
|
|
115139
118422
|
poppygl: "^0.0.24",
|
|
115140
118423
|
prompts: "^2.4.2",
|
|
115141
118424
|
redaxios: "^0.5.1",
|
|
@@ -287233,7 +290516,7 @@ import {
|
|
|
287233
290516
|
// node_modules/dsn-converter/dist/index.js
|
|
287234
290517
|
import { su as su14 } from "@tscircuit/soup-util";
|
|
287235
290518
|
import { getBoundsFromPoints as getBoundsFromPoints4 } from "@tscircuit/math-utils";
|
|
287236
|
-
import { applyToPoint as
|
|
290519
|
+
import { applyToPoint as applyToPoint31, scale as scale8 } from "transformation-matrix";
|
|
287237
290520
|
import { su as su24 } from "@tscircuit/soup-util";
|
|
287238
290521
|
import { su as su34 } from "@tscircuit/soup-util";
|
|
287239
290522
|
import Debug4 from "debug";
|
|
@@ -287242,9 +290525,9 @@ import { applyToPoint as applyToPoint210, scale as scale22 } from "transformatio
|
|
|
287242
290525
|
import Debug22 from "debug";
|
|
287243
290526
|
import { applyToPoint as applyToPoint93, scale as scale32 } from "transformation-matrix";
|
|
287244
290527
|
import { su as su52 } from "@tscircuit/soup-util";
|
|
287245
|
-
import { applyToPoint as
|
|
290528
|
+
import { applyToPoint as applyToPoint34 } from "transformation-matrix";
|
|
287246
290529
|
import Debug32 from "debug";
|
|
287247
|
-
import { applyToPoint as
|
|
290530
|
+
import { applyToPoint as applyToPoint44 } from "transformation-matrix";
|
|
287248
290531
|
import Debug6 from "debug";
|
|
287249
290532
|
import"transformation-matrix";
|
|
287250
290533
|
import { applyToPoint as applyToPoint53 } from "transformation-matrix";
|
|
@@ -287644,7 +290927,7 @@ function processComponentsAndPads(componentGroups, circuitElements, pcb) {
|
|
|
287644
290927
|
const sourceComponent = su14(circuitElements).source_component.list().find((e4) => e4.source_component_id === pcbComponent?.source_component_id);
|
|
287645
290928
|
const footprintName = getFootprintName(sourceComponent, pcbComponent);
|
|
287646
290929
|
const componentName = sourceComponent?.name || "Unknown";
|
|
287647
|
-
const circuitSpaceCoordinates =
|
|
290930
|
+
const circuitSpaceCoordinates = applyToPoint31(transformMmToUm, pcbComponent.center);
|
|
287648
290931
|
if (!componentsByFootprint.has(footprintName)) {
|
|
287649
290932
|
componentsByFootprint.set(footprintName, []);
|
|
287650
290933
|
}
|
|
@@ -296329,7 +299612,7 @@ var any_circuit_element = external_exports2.union([
|
|
|
296329
299612
|
var any_soup_element4 = any_circuit_element;
|
|
296330
299613
|
expectTypesMatch2(true);
|
|
296331
299614
|
expectStringUnionsMatch(true);
|
|
296332
|
-
function
|
|
299615
|
+
function applyToPoint35(matrix2, point22) {
|
|
296333
299616
|
return Array.isArray(point22) ? [
|
|
296334
299617
|
matrix2.a * point22[0] + matrix2.c * point22[1] + matrix2.e,
|
|
296335
299618
|
matrix2.b * point22[0] + matrix2.d * point22[1] + matrix2.f
|
|
@@ -297293,7 +300576,7 @@ var transformPCBElement2 = (elm, matrix2) => {
|
|
|
297293
300576
|
const tsr = decomposeTSR2(matrix2);
|
|
297294
300577
|
const flipPadWidthHeight = Math.round(tsr.rotation.angle / (Math.PI / 2)) % 2 === 1;
|
|
297295
300578
|
if (elm.type === "pcb_plated_hole" || elm.type === "pcb_hole" || elm.type === "pcb_via" || elm.type === "pcb_smtpad" || elm.type === "pcb_port") {
|
|
297296
|
-
const { x: x4, y: y4 } =
|
|
300579
|
+
const { x: x4, y: y4 } = applyToPoint35(matrix2, {
|
|
297297
300580
|
x: Number(elm.x),
|
|
297298
300581
|
y: Number(elm.y)
|
|
297299
300582
|
});
|
|
@@ -297301,7 +300584,7 @@ var transformPCBElement2 = (elm, matrix2) => {
|
|
|
297301
300584
|
elm.y = y4;
|
|
297302
300585
|
if (elm.type === "pcb_smtpad" && elm.shape === "polygon" && Array.isArray(elm.points)) {
|
|
297303
300586
|
elm.points = elm.points.map((point22) => {
|
|
297304
|
-
const tp3 =
|
|
300587
|
+
const tp3 = applyToPoint35(matrix2, { x: point22.x, y: point22.y });
|
|
297305
300588
|
return {
|
|
297306
300589
|
x: tp3.x,
|
|
297307
300590
|
y: tp3.y
|
|
@@ -297309,13 +300592,13 @@ var transformPCBElement2 = (elm, matrix2) => {
|
|
|
297309
300592
|
});
|
|
297310
300593
|
}
|
|
297311
300594
|
} else if (elm.type === "pcb_keepout" || elm.type === "pcb_board") {
|
|
297312
|
-
elm.center =
|
|
300595
|
+
elm.center = applyToPoint35(matrix2, elm.center);
|
|
297313
300596
|
} else if (elm.type === "pcb_silkscreen_text" || elm.type === "pcb_fabrication_note_text" || elm.type === "pcb_note_text") {
|
|
297314
|
-
elm.anchor_position =
|
|
300597
|
+
elm.anchor_position = applyToPoint35(matrix2, elm.anchor_position);
|
|
297315
300598
|
} else if (elm.type === "pcb_silkscreen_circle" || elm.type === "pcb_silkscreen_rect" || elm.type === "pcb_note_rect" || elm.type === "pcb_courtyard_rect" || elm.type === "pcb_courtyard_circle") {
|
|
297316
|
-
elm.center =
|
|
300599
|
+
elm.center = applyToPoint35(matrix2, elm.center);
|
|
297317
300600
|
} else if (elm.type === "pcb_component") {
|
|
297318
|
-
elm.center =
|
|
300601
|
+
elm.center = applyToPoint35(matrix2, elm.center);
|
|
297319
300602
|
elm.rotation = elm.rotation + tsr.rotation.angle / Math.PI * 180;
|
|
297320
300603
|
elm.rotation = elm.rotation % 360;
|
|
297321
300604
|
if (flipPadWidthHeight) {
|
|
@@ -297323,21 +300606,21 @@ var transformPCBElement2 = (elm, matrix2) => {
|
|
|
297323
300606
|
}
|
|
297324
300607
|
} else if (elm.type === "pcb_courtyard_outline") {
|
|
297325
300608
|
elm.outline = elm.outline.map((p3) => {
|
|
297326
|
-
const tp3 =
|
|
300609
|
+
const tp3 = applyToPoint35(matrix2, p3);
|
|
297327
300610
|
p3.x = tp3.x;
|
|
297328
300611
|
p3.y = tp3.y;
|
|
297329
300612
|
return p3;
|
|
297330
300613
|
});
|
|
297331
300614
|
} else if (elm.type === "pcb_courtyard_polygon") {
|
|
297332
300615
|
elm.points = elm.points.map((p3) => {
|
|
297333
|
-
const tp3 =
|
|
300616
|
+
const tp3 = applyToPoint35(matrix2, p3);
|
|
297334
300617
|
p3.x = tp3.x;
|
|
297335
300618
|
p3.y = tp3.y;
|
|
297336
300619
|
return p3;
|
|
297337
300620
|
});
|
|
297338
300621
|
} else if (elm.type === "pcb_silkscreen_path" || elm.type === "pcb_trace" || elm.type === "pcb_fabrication_note_path" || elm.type === "pcb_note_path") {
|
|
297339
300622
|
elm.route = elm.route.map((rp3) => {
|
|
297340
|
-
const tp3 =
|
|
300623
|
+
const tp3 = applyToPoint35(matrix2, rp3);
|
|
297341
300624
|
rp3.x = tp3.x;
|
|
297342
300625
|
rp3.y = tp3.y;
|
|
297343
300626
|
return rp3;
|
|
@@ -297345,14 +300628,14 @@ var transformPCBElement2 = (elm, matrix2) => {
|
|
|
297345
300628
|
} else if (elm.type === "pcb_silkscreen_line" || elm.type === "pcb_note_line") {
|
|
297346
300629
|
const p12 = { x: elm.x1, y: elm.y1 };
|
|
297347
300630
|
const p23 = { x: elm.x2, y: elm.y2 };
|
|
297348
|
-
const p1t =
|
|
297349
|
-
const p2t =
|
|
300631
|
+
const p1t = applyToPoint35(matrix2, p12);
|
|
300632
|
+
const p2t = applyToPoint35(matrix2, p23);
|
|
297350
300633
|
elm.x1 = p1t.x;
|
|
297351
300634
|
elm.y1 = p1t.y;
|
|
297352
300635
|
elm.x2 = p2t.x;
|
|
297353
300636
|
elm.y2 = p2t.y;
|
|
297354
300637
|
} else if (elm.type === "cad_component") {
|
|
297355
|
-
const newPos =
|
|
300638
|
+
const newPos = applyToPoint35(matrix2, {
|
|
297356
300639
|
x: elm.position.x,
|
|
297357
300640
|
y: elm.position.y
|
|
297358
300641
|
});
|
|
@@ -298315,15 +301598,15 @@ var convertEasyEdaJsonToCircuitJson = (easyEdaJson, {
|
|
|
298315
301598
|
for (const e4 of circuitElements) {
|
|
298316
301599
|
if (e4.type === "pcb_cutout") {
|
|
298317
301600
|
if (e4.shape === "polygon") {
|
|
298318
|
-
e4.points = e4.points.map((p3) =>
|
|
301601
|
+
e4.points = e4.points.map((p3) => applyToPoint35(matrix2, p3));
|
|
298319
301602
|
} else if (e4.shape === "circle" || e4.shape === "rect") {
|
|
298320
|
-
e4.center =
|
|
301603
|
+
e4.center = applyToPoint35(matrix2, e4.center);
|
|
298321
301604
|
} else if ("route" in e4) {
|
|
298322
301605
|
const cutoutPath = e4;
|
|
298323
|
-
cutoutPath.route = cutoutPath.route.map((p3) =>
|
|
301606
|
+
cutoutPath.route = cutoutPath.route.map((p3) => applyToPoint35(matrix2, p3));
|
|
298324
301607
|
}
|
|
298325
301608
|
} else if (e4.type === "pcb_smtpad" && e4.shape === "polygon") {
|
|
298326
|
-
e4.points = e4.points.map((p3) =>
|
|
301609
|
+
e4.points = e4.points.map((p3) => applyToPoint35(matrix2, p3));
|
|
298327
301610
|
}
|
|
298328
301611
|
}
|
|
298329
301612
|
const cad = circuitElements.find((e4) => e4.type === "cad_component");
|
|
@@ -303116,7 +306399,7 @@ var any_circuit_element2 = z160.union([
|
|
|
303116
306399
|
var any_soup_element5 = any_circuit_element2;
|
|
303117
306400
|
expectTypesMatch3(true);
|
|
303118
306401
|
expectStringUnionsMatch2(true);
|
|
303119
|
-
function
|
|
306402
|
+
function applyToPoint37(matrix2, point22) {
|
|
303120
306403
|
return Array.isArray(point22) ? [
|
|
303121
306404
|
matrix2.a * point22[0] + matrix2.c * point22[1] + matrix2.e,
|
|
303122
306405
|
matrix2.b * point22[0] + matrix2.d * point22[1] + matrix2.f
|
|
@@ -304079,7 +307362,7 @@ var transformPCBElement3 = (elm, matrix2) => {
|
|
|
304079
307362
|
const tsr = decomposeTSR3(matrix2);
|
|
304080
307363
|
const flipPadWidthHeight = Math.round(tsr.rotation.angle / (Math.PI / 2)) % 2 === 1;
|
|
304081
307364
|
if (elm.type === "pcb_plated_hole" || elm.type === "pcb_hole" || elm.type === "pcb_via" || elm.type === "pcb_smtpad" || elm.type === "pcb_port") {
|
|
304082
|
-
const { x: x4, y: y4 } =
|
|
307365
|
+
const { x: x4, y: y4 } = applyToPoint37(matrix2, {
|
|
304083
307366
|
x: Number(elm.x),
|
|
304084
307367
|
y: Number(elm.y)
|
|
304085
307368
|
});
|
|
@@ -304087,7 +307370,7 @@ var transformPCBElement3 = (elm, matrix2) => {
|
|
|
304087
307370
|
elm.y = y4;
|
|
304088
307371
|
if (elm.type === "pcb_smtpad" && elm.shape === "polygon" && Array.isArray(elm.points)) {
|
|
304089
307372
|
elm.points = elm.points.map((point22) => {
|
|
304090
|
-
const tp3 =
|
|
307373
|
+
const tp3 = applyToPoint37(matrix2, { x: point22.x, y: point22.y });
|
|
304091
307374
|
return {
|
|
304092
307375
|
x: tp3.x,
|
|
304093
307376
|
y: tp3.y
|
|
@@ -304095,13 +307378,13 @@ var transformPCBElement3 = (elm, matrix2) => {
|
|
|
304095
307378
|
});
|
|
304096
307379
|
}
|
|
304097
307380
|
} else if (elm.type === "pcb_keepout" || elm.type === "pcb_board") {
|
|
304098
|
-
elm.center =
|
|
307381
|
+
elm.center = applyToPoint37(matrix2, elm.center);
|
|
304099
307382
|
} else if (elm.type === "pcb_silkscreen_text" || elm.type === "pcb_fabrication_note_text" || elm.type === "pcb_note_text") {
|
|
304100
|
-
elm.anchor_position =
|
|
307383
|
+
elm.anchor_position = applyToPoint37(matrix2, elm.anchor_position);
|
|
304101
307384
|
} else if (elm.type === "pcb_silkscreen_circle" || elm.type === "pcb_silkscreen_rect" || elm.type === "pcb_note_rect" || elm.type === "pcb_courtyard_rect" || elm.type === "pcb_courtyard_circle") {
|
|
304102
|
-
elm.center =
|
|
307385
|
+
elm.center = applyToPoint37(matrix2, elm.center);
|
|
304103
307386
|
} else if (elm.type === "pcb_component") {
|
|
304104
|
-
elm.center =
|
|
307387
|
+
elm.center = applyToPoint37(matrix2, elm.center);
|
|
304105
307388
|
elm.rotation = elm.rotation + tsr.rotation.angle / Math.PI * 180;
|
|
304106
307389
|
elm.rotation = elm.rotation % 360;
|
|
304107
307390
|
if (flipPadWidthHeight) {
|
|
@@ -304109,21 +307392,21 @@ var transformPCBElement3 = (elm, matrix2) => {
|
|
|
304109
307392
|
}
|
|
304110
307393
|
} else if (elm.type === "pcb_courtyard_outline") {
|
|
304111
307394
|
elm.outline = elm.outline.map((p3) => {
|
|
304112
|
-
const tp3 =
|
|
307395
|
+
const tp3 = applyToPoint37(matrix2, p3);
|
|
304113
307396
|
p3.x = tp3.x;
|
|
304114
307397
|
p3.y = tp3.y;
|
|
304115
307398
|
return p3;
|
|
304116
307399
|
});
|
|
304117
307400
|
} else if (elm.type === "pcb_courtyard_polygon") {
|
|
304118
307401
|
elm.points = elm.points.map((p3) => {
|
|
304119
|
-
const tp3 =
|
|
307402
|
+
const tp3 = applyToPoint37(matrix2, p3);
|
|
304120
307403
|
p3.x = tp3.x;
|
|
304121
307404
|
p3.y = tp3.y;
|
|
304122
307405
|
return p3;
|
|
304123
307406
|
});
|
|
304124
307407
|
} else if (elm.type === "pcb_silkscreen_path" || elm.type === "pcb_trace" || elm.type === "pcb_fabrication_note_path" || elm.type === "pcb_note_path") {
|
|
304125
307408
|
elm.route = elm.route.map((rp3) => {
|
|
304126
|
-
const tp3 =
|
|
307409
|
+
const tp3 = applyToPoint37(matrix2, rp3);
|
|
304127
307410
|
rp3.x = tp3.x;
|
|
304128
307411
|
rp3.y = tp3.y;
|
|
304129
307412
|
return rp3;
|
|
@@ -304131,14 +307414,14 @@ var transformPCBElement3 = (elm, matrix2) => {
|
|
|
304131
307414
|
} else if (elm.type === "pcb_silkscreen_line" || elm.type === "pcb_note_line") {
|
|
304132
307415
|
const p12 = { x: elm.x1, y: elm.y1 };
|
|
304133
307416
|
const p23 = { x: elm.x2, y: elm.y2 };
|
|
304134
|
-
const p1t =
|
|
304135
|
-
const p2t =
|
|
307417
|
+
const p1t = applyToPoint37(matrix2, p12);
|
|
307418
|
+
const p2t = applyToPoint37(matrix2, p23);
|
|
304136
307419
|
elm.x1 = p1t.x;
|
|
304137
307420
|
elm.y1 = p1t.y;
|
|
304138
307421
|
elm.x2 = p2t.x;
|
|
304139
307422
|
elm.y2 = p2t.y;
|
|
304140
307423
|
} else if (elm.type === "cad_component") {
|
|
304141
|
-
const newPos =
|
|
307424
|
+
const newPos = applyToPoint37(matrix2, {
|
|
304142
307425
|
x: elm.position.x,
|
|
304143
307426
|
y: elm.position.y
|
|
304144
307427
|
});
|
|
@@ -305084,15 +308367,15 @@ var convertEasyEdaJsonToCircuitJson2 = (easyEdaJson, {
|
|
|
305084
308367
|
for (const e4 of circuitElements) {
|
|
305085
308368
|
if (e4.type === "pcb_cutout") {
|
|
305086
308369
|
if (e4.shape === "polygon") {
|
|
305087
|
-
e4.points = e4.points.map((p3) =>
|
|
308370
|
+
e4.points = e4.points.map((p3) => applyToPoint37(matrix2, p3));
|
|
305088
308371
|
} else if (e4.shape === "circle" || e4.shape === "rect") {
|
|
305089
|
-
e4.center =
|
|
308372
|
+
e4.center = applyToPoint37(matrix2, e4.center);
|
|
305090
308373
|
} else if ("route" in e4) {
|
|
305091
308374
|
const cutoutPath = e4;
|
|
305092
|
-
cutoutPath.route = cutoutPath.route.map((p3) =>
|
|
308375
|
+
cutoutPath.route = cutoutPath.route.map((p3) => applyToPoint37(matrix2, p3));
|
|
305093
308376
|
}
|
|
305094
308377
|
} else if (e4.type === "pcb_smtpad" && e4.shape === "polygon") {
|
|
305095
|
-
e4.points = e4.points.map((p3) =>
|
|
308378
|
+
e4.points = e4.points.map((p3) => applyToPoint37(matrix2, p3));
|
|
305096
308379
|
}
|
|
305097
308380
|
}
|
|
305098
308381
|
const cad = circuitElements.find((e4) => e4.type === "cad_component");
|