flo-mat 4.0.2 → 4.0.3

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.
Files changed (101) hide show
  1. package/__tests__/specific-cases/specific-cases.spec.ts +6 -0
  2. package/browser/index.js +4511 -7115
  3. package/browser/index.min.js +1 -1
  4. package/node/cp-node/fs/is-on-same-loop.d.ts +3 -0
  5. package/node/cp-node/fs/is-on-same-loop.js +6 -0
  6. package/node/cp-node/fs/is-on-same-loop.js.map +1 -0
  7. package/node/debug/debug.d.ts +10 -15
  8. package/node/debug/debug.js +35 -46
  9. package/node/debug/debug.js.map +1 -1
  10. package/node/find-2-prong/add-1-prong.js +1 -4
  11. package/node/find-2-prong/add-1-prong.js.map +1 -1
  12. package/node/find-mat/find-mat.js +1 -2
  13. package/node/find-mat/find-mat.js.map +1 -1
  14. package/node/find-mat/get-meta.d.ts +1 -6
  15. package/node/find-mat/get-meta.js +4 -26
  16. package/node/find-mat/get-meta.js.map +1 -1
  17. package/node/index.d.ts +4 -2
  18. package/node/index.js +3 -1
  19. package/node/index.js.map +1 -1
  20. package/node/reconstruct-from-mat/filter-zero-length.d.ts +10 -0
  21. package/node/reconstruct-from-mat/filter-zero-length.js +14 -0
  22. package/node/reconstruct-from-mat/filter-zero-length.js.map +1 -0
  23. package/node/reconstruct-from-mat/get-all-on-loop-by-loop.d.ts +7 -0
  24. package/node/reconstruct-from-mat/get-all-on-loop-by-loop.js +38 -0
  25. package/node/reconstruct-from-mat/get-all-on-loop-by-loop.js.map +1 -0
  26. package/node/reconstruct-from-mat/get-bezier-piece-length.d.ts +3 -0
  27. package/node/reconstruct-from-mat/get-bezier-piece-length.js +6 -0
  28. package/node/reconstruct-from-mat/get-bezier-piece-length.js.map +1 -0
  29. package/node/reconstruct-from-mat/get-boundary.d.ts +7 -0
  30. package/node/reconstruct-from-mat/get-boundary.js +18 -0
  31. package/node/reconstruct-from-mat/get-boundary.js.map +1 -0
  32. package/node/reconstruct-from-mat/get-cp-nodess-for-sat.d.ts +4 -0
  33. package/node/reconstruct-from-mat/get-cp-nodess-for-sat.js +15 -0
  34. package/node/reconstruct-from-mat/get-cp-nodess-for-sat.js.map +1 -0
  35. package/node/reconstruct-from-mat/get-matching-beziers.d.ts +10 -0
  36. package/node/reconstruct-from-mat/get-matching-beziers.js +29 -0
  37. package/node/reconstruct-from-mat/get-matching-beziers.js.map +1 -0
  38. package/node/reconstruct-from-mat/get-mbss-by-loop-per-sat.d.ts +6 -0
  39. package/node/reconstruct-from-mat/get-mbss-by-loop-per-sat.js +10 -0
  40. package/node/reconstruct-from-mat/get-mbss-by-loop-per-sat.js.map +1 -0
  41. package/node/reconstruct-from-mat/get-mbss-by-loop-with-opp-arr.d.ts +7 -0
  42. package/node/reconstruct-from-mat/get-mbss-by-loop-with-opp-arr.js +47 -0
  43. package/node/reconstruct-from-mat/get-mbss-by-loop-with-opp-arr.js.map +1 -0
  44. package/node/reconstruct-from-mat/get-sats2.d.ts +10 -0
  45. package/node/reconstruct-from-mat/get-sats2.js +16 -0
  46. package/node/reconstruct-from-mat/get-sats2.js.map +1 -0
  47. package/node/reconstruct-from-mat/is-fully-terminating.d.ts +3 -0
  48. package/node/reconstruct-from-mat/is-fully-terminating.js +19 -0
  49. package/node/reconstruct-from-mat/is-fully-terminating.js.map +1 -0
  50. package/node/reconstruct-from-mat/matched-beziers.d.ts +10 -0
  51. package/node/reconstruct-from-mat/matched-beziers.js +2 -0
  52. package/node/reconstruct-from-mat/matched-beziers.js.map +1 -0
  53. package/node/reconstruct-from-mat/reconstruct-from-mat.d.ts +4 -0
  54. package/node/reconstruct-from-mat/reconstruct-from-mat.js +28 -0
  55. package/node/reconstruct-from-mat/reconstruct-from-mat.js.map +1 -0
  56. package/node/reconstruct-from-mat/remove-sat-induced-trivial-3prongs.d.ts +12 -0
  57. package/node/reconstruct-from-mat/remove-sat-induced-trivial-3prongs.js +46 -0
  58. package/node/reconstruct-from-mat/remove-sat-induced-trivial-3prongs.js.map +1 -0
  59. package/node/reconstruct-from-mat/split-tri-path.d.ts +5 -0
  60. package/node/reconstruct-from-mat/split-tri-path.js +209 -0
  61. package/node/reconstruct-from-mat/split-tri-path.js.map +1 -0
  62. package/node/sat/add-debug-info.js +1 -2
  63. package/node/sat/add-debug-info.js.map +1 -1
  64. package/node/utils/clip.d.ts +2 -0
  65. package/node/utils/clip.js +6 -0
  66. package/node/utils/clip.js.map +1 -0
  67. package/package.json +2 -2
  68. package/src/cp-node/fs/is-on-same-loop.ts +15 -0
  69. package/src/debug/debug.ts +54 -72
  70. package/src/find-2-prong/add-1-prong.ts +1 -5
  71. package/src/find-mat/find-mat.ts +1 -2
  72. package/src/find-mat/get-meta.ts +3 -38
  73. package/src/index.ts +5 -3
  74. package/src/reconstruct-from-mat/filter-zero-length.ts +23 -0
  75. package/src/reconstruct-from-mat/get-all-on-loop-by-loop.ts +52 -0
  76. package/src/reconstruct-from-mat/get-bezier-piece-length.ts +12 -0
  77. package/src/reconstruct-from-mat/get-boundary.ts +32 -0
  78. package/src/reconstruct-from-mat/get-cp-nodess-for-sat.ts +24 -0
  79. package/src/reconstruct-from-mat/get-matching-beziers.ts +46 -0
  80. package/src/reconstruct-from-mat/get-mbss-by-loop-per-sat.ts +19 -0
  81. package/src/reconstruct-from-mat/get-mbss-by-loop-with-opp-arr.ts +69 -0
  82. package/src/reconstruct-from-mat/get-sats2.ts +25 -0
  83. package/src/reconstruct-from-mat/is-fully-terminating.ts +27 -0
  84. package/src/reconstruct-from-mat/matched-beziers.ts +14 -0
  85. package/src/reconstruct-from-mat/reconstruct-from-mat.ts +45 -0
  86. package/src/reconstruct-from-mat/remove-sat-induced-trivial-3prongs.ts +62 -0
  87. package/src/reconstruct-from-mat/split-tri-path.ts +280 -0
  88. package/src/sat/add-debug-info.ts +1 -2
  89. package/src/utils/clip.ts +13 -0
  90. package/node/debug/functions/general.d.ts +0 -48
  91. package/node/debug/functions/general.js +0 -53
  92. package/node/debug/functions/general.js.map +0 -1
  93. package/node/point-on-shape/pos-to-human-string.d.ts +0 -8
  94. package/node/point-on-shape/pos-to-human-string.js +0 -12
  95. package/node/point-on-shape/pos-to-human-string.js.map +0 -1
  96. package/src/debug/elem-type-two-prong.ts +0 -8
  97. package/src/debug/functions/cmp-cp-on-delta.ts +0 -54
  98. package/src/debug/functions/general.ts +0 -79
  99. package/src/debug/functions/three-prong.ts +0 -249
  100. package/src/debug/functions/two-prong.ts +0 -203
  101. package/src/find-2-prong/add-debug-info.ts +0 -45
@@ -1,20 +1,20 @@
1
- import { generalDebugFunctions } from './functions/general.js';
2
- import { IGeneralDebugFunctions } from './functions/general.js';
3
- import { DrawElemFunctions } from './functions/draw-elem/draw-elem.js';
4
- import { DebugElems } from './debug-elem-types.js';
1
+ import type { DrawElemFunctions } from './functions/draw-elem/draw-elem.js';
2
+ import type { DebugElems } from './debug-elem-types.js';
5
3
  import { drawElemFs } from './functions/draw-elem/draw-elem.js';
6
4
 
7
5
 
8
6
  /** @internal */
9
7
  interface Debug {
10
8
  /** Generated by debug object for later inspection */
11
- generated: Generated;
9
+ elems: GeneratedElems;
10
+ timing: Timing;
11
+
12
12
  /**
13
13
  * These functions are meant to be used in the console, e.g. in the
14
14
  * console try typing d.fs.twoProng.traceConvergence(0);
15
15
  */
16
- fs: IDebugFunctions;
17
- directives: IDirectives;
16
+ fs: DebugFunctions;
17
+ directives: Directives;
18
18
  }
19
19
 
20
20
 
@@ -23,32 +23,23 @@ type GeneratedElems = { [T in keyof DebugElems]: DebugElems[T][] };
23
23
 
24
24
 
25
25
  /** @internal */
26
- interface ITiming {
27
- //normalize : number;
28
- //simplifyPaths : number;
29
- holeClosers : number;
30
- oneAnd2Prongs : number;
31
- threeProngs : number;
32
- sats : number;
33
- simplifyMat : number;
34
- }
35
-
36
-
37
- /** @internal */
38
- interface Generated {
39
- elems: GeneratedElems;
40
- timing: ITiming;
26
+ interface Timing {
27
+ holeClosers: number;
28
+ oneAnd2Prongs: number;
29
+ threeProngs: number;
30
+ sats: number;
31
+ simplifyMat: number;
41
32
  }
42
33
 
43
34
 
44
35
  /** @internal */
45
- interface IDebugFunctions extends IGeneralDebugFunctions {
46
- drawElem : DrawElemFunctions,
36
+ interface DebugFunctions {
37
+ drawElem: DrawElemFunctions,
47
38
  }
48
39
 
49
40
 
50
41
  /** @internal */
51
- interface IDirectives {
42
+ interface Directives {
52
43
  stopAfterHoleClosers: boolean,
53
44
  stopAfterHoleClosersNum: number,
54
45
  stopAfterTwoProngs: boolean,
@@ -68,59 +59,50 @@ function enableDebugForMat(debugOn: boolean) {
68
59
 
69
60
  debug = {
70
61
  ...debug,
71
- generated: {
72
- //...debug?.generated,
73
- ...(!debug ? {} : !debug.generated ? {} : debug.generated),
62
+ elems: {
63
+ ...debug?.elems,
74
64
  // @ts-ignore
75
- elems: {
76
- //...debug?.generated?.elems,
77
- ...(!debug ? {} : !debug.generated ? {} : !debug.generated.elems ? {} : debug.generated.elems),
78
- oneProng : [],
79
- // oneProngAtDullCorner : [],
80
- twoProng : [],
81
- // twoProng_regular : [],
82
- // twoProng_failed : [],
83
- // twoProng_notAdded : [],
84
- // twoProng_deleted : [],
85
- // twoProng_holeClosing : [],
86
- looseBoundingBox : [],
87
- tightBoundingBox : [],
88
- // sharpCorner : [],
89
- // dullCorner : [],
90
- vertex : [],
91
- threeProng : [],
92
- boundingHull : [],
93
- mat : [],
94
- // sat : [],
95
- cpNode : [],
96
- maxVertex : [],
97
- leaves : [],
98
- // culls : [],
99
- },
100
- timing: {
101
- //...debug?.generated?.timing,
102
- ...(!debug ? {} : !debug.generated ? {} : !debug.generated.timing ? {} : debug.generated.timing),
103
- holeClosers : 0,
104
- oneAnd2Prongs : 0,
105
- threeProngs : 0,
106
- sats : 0,
107
- simplifyMat : 0,
108
- }
65
+
66
+ oneProng : [],
67
+ // oneProngAtDullCorner : [],
68
+ twoProng : [],
69
+ // twoProng_regular : [],
70
+ // twoProng_failed : [],
71
+ // twoProng_notAdded : [],
72
+ // twoProng_deleted : [],
73
+ // twoProng_holeClosing : [],
74
+ looseBoundingBox : [],
75
+ tightBoundingBox : [],
76
+ // sharpCorner : [],
77
+ // dullCorner : [],
78
+ vertex : [],
79
+ threeProng : [],
80
+ boundingHull : [],
81
+ mat : [],
82
+ // sat : [],
83
+ cpNode : [],
84
+ maxVertex : [],
85
+ leaves : [],
86
+ // culls : [],
87
+ },
88
+ timing: {
89
+ ...debug?.timing,
90
+ holeClosers: 0,
91
+ oneAnd2Prongs: 0,
92
+ threeProngs: 0,
93
+ sats: 0,
94
+ simplifyMat: 0,
109
95
  },
110
96
  fs: {
111
- //...debug?.fs,
112
- ...(!debug ? {} : !debug.fs ? {} : debug.fs),
113
- // @ts-ignore
97
+ ...debug?.fs,
114
98
  drawElem: {
115
- //...debug?.fs?.drawElem,
116
- ...(!debug ? {} : !debug.fs ? {} : !debug.fs.drawElem ? {} : debug.fs.drawElem),
99
+ ...debug?.fs?.drawElem,
117
100
  ...drawElemFs
118
- },
119
- ...generalDebugFunctions
101
+ }
120
102
  },
121
103
  directives: {
122
104
  //...debug?.directives,
123
- ...(!debug ? {} : !debug.directives ? {} : debug.directives),
105
+ ...debug?.directives,
124
106
  stopAfterHoleClosers: false,
125
107
  stopAfterHoleClosersNum: undefined!,
126
108
  stopAfterTwoProngs: false,
@@ -135,6 +117,6 @@ function enableDebugForMat(debugOn: boolean) {
135
117
 
136
118
 
137
119
  export {
138
- Debug, GeneratedElems, ITiming, Generated,
139
- IDebugFunctions, IDirectives, enableDebugForMat
120
+ Debug, GeneratedElems, Timing,
121
+ DebugFunctions, Directives, enableDebugForMat
140
122
  }
@@ -50,11 +50,7 @@ function add1Prong(
50
50
  return;
51
51
  }
52
52
 
53
- const { anyFailed, cpNodes } = addToCpTree(false, false, circle, [-0.5, +0.5], meta, [pos, pos]);
54
-
55
- // if (typeof _debug_ !== 'undefined') {
56
- // _debug_.generated.elems.oneProng.push(cpNodes);
57
- // }
53
+ addToCpTree(false, false, circle, [-0.5, +0.5], meta, [pos, pos]);
58
54
  }
59
55
 
60
56
 
@@ -8,7 +8,7 @@ import type { MatOptions } from './mat-options.js';
8
8
  import type { MatMeta } from '../mat/mat-meta.js';
9
9
  import { findAndAdd3ProngsOnLoop } from '../find-3-prong/find-and-add-3-prongs-on-loop.js';
10
10
  import { createInitialCpTree } from './create-initial-cp-tree.js';
11
- import { /*getPointToCpNode,*/ getPartialMeta, addDebugInfo2, addDebugInfo3, addDebugInfo4, getPointToCpNode } from './get-meta.js';
11
+ import { getPartialMeta, addDebugInfo2, addDebugInfo3, addDebugInfo4 } from './get-meta.js';
12
12
  import { getSharpCornersOnLoop } from './get-sharp-corners.js';
13
13
  import { getDullCornersOnLoop } from './get-dull-corners-on-loop.js';
14
14
  import { findAndAdd2ProngsOnAllLoops } from '../find-2-prong/find-and-add-2-prongs-on-all-loops.js';
@@ -49,7 +49,6 @@ function findMat(
49
49
  const cpTrees = createInitialCpTree(loops, sharpCornersPerLoop, lastInsertId);
50
50
 
51
51
  const _meta = getPartialMeta(loops);
52
- const pointToCpNode = getPointToCpNode(loops, cpTrees);
53
52
  const meta: MatMeta = {
54
53
  maxCoordPowerOf2, squaredDiagonalLength, loops, cpTrees,// pointToCpNode,
55
54
  lastInsertId, ..._meta
@@ -1,13 +1,9 @@
1
1
  import type { Debug } from '../debug/debug.js';
2
2
  import type { Loop } from 'flo-boolean';
3
3
  import type { Curve } from 'flo-boolean';
4
- import type { CpNode } from '../cp-node/cp-node.js';
5
- import type { TriMap } from '../utils/tri-map.js';
6
4
  import type { MatMeta } from '../mat/mat-meta.js';
7
- // import { TriMapFs } from '../utils/tri-map.js';
8
5
  import { getBoundingHull, getBoundingBoxTight } from 'flo-bezier3';
9
6
  import { getBoundingBox$ } from '../geometry/get-bounding-box-.js';
10
- import { RbTree } from 'flo-ll-rb-tree';
11
7
  import { getCorner } from '../corner/get-corner.js';
12
8
 
13
9
 
@@ -18,30 +14,6 @@ declare const _debug_: Debug;
18
14
  let timingStart: number;
19
15
 
20
16
 
21
- /** @internal */
22
- function getPointToCpNode(
23
- loops: Loop[],
24
- cpTrees: Map<Loop, RbTree<CpNode>>): TriMap<Loop,number,number,CpNode> {
25
-
26
- timingStart = performance.now();
27
-
28
- // const pointToCpNode: TriMap<Loop,number,number,CpNode> = new Map();
29
-
30
- // for (const loop of loops) {
31
- // // Populate `posMap`
32
- // const cpTree = cpTrees.get(loop)!;
33
- // const cpNodes = cpTree.toArrayInOrder();
34
- // for (const cpNode of cpNodes) {
35
- // const { p, t } = cpNode.pointOnShape;
36
- // TriMapFs.set(pointToCpNode,loop,p[0],p[1],cpNode);
37
- // }
38
- // }
39
-
40
- // return pointToCpNode;
41
- return undefined!
42
- }
43
-
44
-
45
17
  /** @internal */
46
18
  function getPartialMeta(
47
19
  loops: Loop[]): Omit<
@@ -96,9 +68,8 @@ function getPartialMeta(
96
68
  function addDebugInfo2() {
97
69
  if (typeof _debug_ === 'undefined') { return; }
98
70
 
99
- const timing = _debug_.generated.timing;
100
71
  const now = performance.now();
101
- timing.holeClosers += now - timingStart;
72
+ _debug_.timing.holeClosers += now - timingStart;
102
73
  timingStart = now;
103
74
  }
104
75
 
@@ -106,11 +77,9 @@ function addDebugInfo2() {
106
77
  function addDebugInfo3() {
107
78
  if (typeof _debug_ === 'undefined') { return; }
108
79
 
109
- const generated = _debug_.generated;
110
- const timing = generated.timing;
111
80
  const now = performance.now();
112
81
 
113
- timing.oneAnd2Prongs += now - timingStart;
82
+ _debug_.timing.oneAnd2Prongs += now - timingStart;
114
83
  timingStart = now;
115
84
  }
116
85
 
@@ -118,15 +87,11 @@ function addDebugInfo3() {
118
87
  function addDebugInfo4() {
119
88
  if (typeof _debug_ === 'undefined') { return; }
120
89
 
121
- const generated = _debug_.generated;
122
- const timing = generated.timing;
123
-
124
- timing.threeProngs += performance.now() - timingStart;
90
+ _debug_.timing.threeProngs += performance.now() - timingStart;
125
91
  }
126
92
 
127
93
 
128
94
  export {
129
- getPointToCpNode,
130
95
  getPartialMeta,
131
96
  addDebugInfo2,
132
97
  addDebugInfo3,
package/src/index.ts CHANGED
@@ -8,7 +8,7 @@ export type { PointOnShape } from './point-on-shape/point-on-shape.js';
8
8
  export type { Circle } from './geometry/circle.js';
9
9
  export type { CurvePiece } from './mat/curve-piece.js';
10
10
  export type { DrawElemFunctions } from './debug/functions/draw-elem/draw-elem.js';
11
- export type { ITiming } from './debug/debug.js';
11
+ export type { Timing as ITiming } from './debug/debug.js';
12
12
  export type { DebugElems } from './debug/debug-elem-types.js';
13
13
  export type { Debug } from './debug/debug.js';
14
14
  export type { DebugElemKey } from './debug/debug-elem-types.js';
@@ -41,7 +41,7 @@ export { getSharpCornersOnLoop } from './find-mat/get-sharp-corners.js';
41
41
  export { getFor2ProngsOnLoop } from './find-mat/get-for-2-prongs-on-loop.js';
42
42
  export { getPotentialClosestPointsOnCurveCertified } from './closest-boundary-point/get-potential-closest-points-on-curve-certified.js';
43
43
  export { getCloseBoundaryPointsCertified } from './closest-boundary-point/get-close-boundary-points-certified.js';
44
- export { getPartialMeta, getPointToCpNode } from './find-mat/get-meta.js';
44
+ export { getPartialMeta } from './find-mat/get-meta.js';
45
45
  export { findAndAddHoleClosing2Prongs } from './find-2-prong/find-and-add-hole-closing-2-prongs.js';
46
46
 
47
47
 
@@ -80,4 +80,6 @@ export { getHoleClosers } from './cp-node/fs/get-hole-closers.js';
80
80
  export { getInitialDegAngleBetweenMatCurves } from './cp-node/fs/get-angle-between-mat-curves.js';
81
81
  export { getAllVertices } from './cp-node/fs/get-all-vertices.js';
82
82
  export { isTrivial } from './cp-node/fs/is-trivial.js';
83
- export { scaleCircle } from './geometry/circle.js';
83
+ export { scaleCircle } from './geometry/circle.js';
84
+ export { isOnSameLoop } from './cp-node/fs/is-on-same-loop.js';
85
+ export { reconstructFromMats } from './reconstruct-from-mat/reconstruct-from-mat.js';
@@ -0,0 +1,23 @@
1
+ import type { BezierPiece } from "flo-bezier3";
2
+ import { isBezierPieceZeroLength } from "flo-bezier3";
3
+
4
+
5
+ /**
6
+ * Filters out zero-length bezier pieces.
7
+ *
8
+ * * **note** will return at least one bezier piece, even if all pieces are zero-length.
9
+ *
10
+ * @param bezierPieces
11
+ */
12
+ function filterZeroLength(
13
+ bezierPieces: BezierPiece[]): BezierPiece[] {
14
+
15
+ const bezierPieces_ = bezierPieces.filter(
16
+ bezierPiece => !isBezierPieceZeroLength(bezierPiece)
17
+ );
18
+
19
+ return bezierPieces_.length > 0 ? bezierPieces_ : [bezierPieces[0]];
20
+ }
21
+
22
+
23
+ export { filterZeroLength }
@@ -0,0 +1,52 @@
1
+ import type { CpNode } from '../cp-node/cp-node.js';
2
+
3
+
4
+ /**
5
+ * Returns all `CpNode`s on the MAT that this `CpNode` is part of
6
+ * starting from the current one and going anti-clockwise around the shape.
7
+ */
8
+ function getAllOnLoop_ByLoop(
9
+ cpNode: CpNode) {
10
+
11
+ const cpNodess: CpNode[][] = [];
12
+
13
+ const cpStarts: CpNode[] = [cpNode];
14
+ const cpStartSet = new Set(cpStarts);
15
+ if (cpNode.isHoleClosing) {
16
+ cpStartSet.add(cpNode.prevOnCircle.holeCloserTwin!);
17
+ }
18
+ cpStartSet.add(cpNode);
19
+
20
+ while (cpStarts.length > 0) {
21
+ const cpNodes: CpNode[] = [];
22
+
23
+ const cpStart = cpStarts.pop()!;
24
+ const _loop = cpStart.pointOnShape.curve.loop;
25
+ let cpNode = cpStart;
26
+
27
+ do {
28
+ const loop = cpNode.pointOnShape.curve.loop;
29
+ if (_loop === loop) {
30
+ cpNodes.push(cpNode);
31
+ cpNode = cpNode.next;
32
+ continue;
33
+ }
34
+
35
+ const twin = cpNode.holeCloserTwin!;
36
+ if (!cpStartSet.has(twin)) {
37
+ cpStartSet.add(twin);
38
+ cpStartSet.add(twin.prevOnCircle.holeCloserTwin!);
39
+ cpStarts.push(twin);
40
+ }
41
+
42
+ cpNode = cpNode.prev.holeCloserTwin!;
43
+ } while (cpNode !== cpStart);
44
+
45
+ cpNodess.push(cpNodes);
46
+ }
47
+
48
+ return cpNodess;
49
+ }
50
+
51
+
52
+ export { getAllOnLoop_ByLoop }
@@ -0,0 +1,12 @@
1
+ import type { BezierPiece } from "flo-bezier3";
2
+ import { length } from 'flo-bezier3';
3
+
4
+
5
+ function getBezierPieceLength(
6
+ bezierPiece: BezierPiece): number {
7
+
8
+ return length(bezierPiece.ts, bezierPiece.ps);
9
+ }
10
+
11
+
12
+ export { getBezierPieceLength }
@@ -0,0 +1,32 @@
1
+ import type { BezierPiece } from 'flo-bezier3';
2
+ import type { CpNode } from '../cp-node/cp-node.js';
3
+ import { getBoundaryBezierPartsToNext } from '../cp-node/fs/get-boundary-bezier-parts-to-next.js';
4
+ import { filterZeroLength } from "./filter-zero-length.js";
5
+ import { isFullyTerminating } from './is-fully-terminating.js';
6
+
7
+
8
+ function getBoundary(
9
+ cpNode: CpNode): {
10
+ boundaryBeziers: BezierPiece[];
11
+ boundaryBeziersOpp: BezierPiece[] | undefined;
12
+ } {
13
+
14
+ const cpNodeOpp = isFullyTerminating(cpNode)
15
+ ? undefined // no opposite boundary
16
+ : cpNode.next.prevOnCircle;
17
+
18
+ const boundaryBeziers =
19
+ filterZeroLength(getBoundaryBezierPartsToNext(cpNode));
20
+
21
+ const boundaryBeziersOpp = cpNodeOpp === undefined
22
+ ? undefined
23
+ : filterZeroLength(getBoundaryBezierPartsToNext(cpNodeOpp));
24
+
25
+ return {
26
+ boundaryBeziers,
27
+ boundaryBeziersOpp
28
+ };
29
+ }
30
+
31
+
32
+ export { getBoundary }
@@ -0,0 +1,24 @@
1
+ import type { CpNode } from "../cp-node/cp-node.js";
2
+ import type { Mat } from '../mat/mat.js';
3
+ import { isOnSameLoop } from "../cp-node/fs/is-on-same-loop.js";
4
+ import { isFullyTerminating } from "./is-fully-terminating.js";
5
+ import { getAllOnLoop_ByLoop } from "./get-all-on-loop-by-loop.js";
6
+
7
+
8
+ function getCpNodessForSat(
9
+ sat: Mat): CpNode[][] {
10
+
11
+ let { cpNode } = sat;
12
+
13
+ while (!isFullyTerminating(cpNode)) {
14
+ cpNode = cpNode.next;
15
+ }
16
+ if (!isOnSameLoop(cpNode, cpNode.next)) {
17
+ cpNode = cpNode.holeCloserTwin!;
18
+ }
19
+
20
+ return getAllOnLoop_ByLoop(cpNode);
21
+ }
22
+
23
+
24
+ export { getCpNodessForSat }
@@ -0,0 +1,46 @@
1
+ import type { BezierPiece } from 'flo-bezier3';
2
+ import type { CpNode } from '../cp-node/cp-node.js';
3
+ import type { MatchedBeziers } from './matched-beziers.js';
4
+ import { getMatCurveToNext } from '../cp-node/fs/get-mat-curve-to-next.js'
5
+ import { splitTriPath } from './split-tri-path.js';
6
+ import { getBoundary } from './get-boundary.js';
7
+ import { isOnSameLoop } from '../cp-node/fs/is-on-same-loop.js';
8
+
9
+
10
+ /**
11
+ * Returns a correspondence between boundary bezier curves and a medial axis
12
+ * bezier curve. They will later be interpolated.
13
+ *
14
+ * @param cpNode the start `CpNode`
15
+ */
16
+ function getMatchingBeziers(
17
+ cpNode: CpNode): MatchedBeziers[] | undefined {
18
+
19
+ const medialBezier: BezierPiece = {
20
+ ps: getMatCurveToNext(cpNode),
21
+ ts: [0,1]
22
+ };
23
+
24
+ if (cpNode.isHoleClosing && // short-circuit
25
+ !isOnSameLoop(cpNode, cpNode.next)) {
26
+
27
+ // We get here for half of hole-closers, as only half of hole-closers are on a different loop.
28
+ // This cpNode indicates we should connect the hole
29
+ // console.log('hole-closing dummy case');
30
+ return undefined;
31
+ }
32
+
33
+ const r = getBoundary(cpNode);
34
+ const { boundaryBeziers, boundaryBeziersOpp } = r;
35
+
36
+ const matchedBezierss: MatchedBeziers[] = splitTriPath(
37
+ boundaryBeziers,
38
+ medialBezier,
39
+ boundaryBeziersOpp ?? []
40
+ );
41
+
42
+ return matchedBezierss;
43
+ }
44
+
45
+
46
+ export { getMatchingBeziers }
@@ -0,0 +1,19 @@
1
+ import type { Mat } from "../mat/mat.js";
2
+ import { getSats2 } from "./get-sats2.js";
3
+ import { getMbssByLoopWithOppArr } from "./get-mbss-by-loop-with-opp-arr.js";
4
+ import { getCpNodessForSat } from "./get-cp-nodess-for-sat.js";
5
+
6
+
7
+ function getMbssByLoopPerSat(
8
+ mats: Mat[],
9
+ satScale: number) {
10
+
11
+ const sats = getSats2(mats, satScale);
12
+
13
+ const cpNodessPerSat = sats.map(getCpNodessForSat);
14
+
15
+ return cpNodessPerSat.map(getMbssByLoopWithOppArr);
16
+ }
17
+
18
+
19
+ export { getMbssByLoopPerSat }
@@ -0,0 +1,69 @@
1
+ import type { CpNode } from "../cp-node/cp-node.js";
2
+ import type { MatchedBeziers } from "./matched-beziers.js";
3
+ import { getMatchingBeziers } from "./get-matching-beziers.js";
4
+ import { isFullyTerminating } from "./is-fully-terminating.js";
5
+
6
+
7
+ function getMbssByLoopWithOppArr(
8
+ cpNodess: CpNode[][]) {
9
+
10
+ const mbssByLoop: (MatchedBeziers[] | undefined)[][] = [];
11
+
12
+ /**
13
+ * An array with each entry being a pair of indices mapping from
14
+ * `MatchedBeziers[]` on one side to `MatchedBeziers[]` on the other side
15
+ */
16
+ const mbMap: Map<CpNode, [number,number]> = new Map();
17
+
18
+ for (let l=0; l<cpNodess.length; l++) {
19
+ const cpNodes = cpNodess[l];
20
+
21
+ const mbss: (MatchedBeziers[] | undefined)[] = [];
22
+ for (let i=0; i<cpNodes.length; i++) {
23
+ const cpNode = cpNodes[i];
24
+
25
+ mbMap.set(cpNode, [l,i]);
26
+
27
+ const mbs = getMatchingBeziers(cpNode);
28
+
29
+ mbss.push(mbs);
30
+ }
31
+
32
+ mbssByLoop.push(mbss);
33
+ }
34
+
35
+
36
+ const oppArr: [[number,number],[number,number]][] = [];
37
+
38
+ for (let l=0; l<cpNodess.length; l++) {
39
+ const cpNodes = cpNodess[l];
40
+
41
+ for (let i=0; i<cpNodes.length; i++) {
42
+ const cpNode = cpNodes[i];
43
+
44
+ const cpNodeOpp = isFullyTerminating(cpNode)
45
+ ? undefined // no opposite boundary
46
+ : cpNode.next.prevOnCircle;
47
+
48
+ // if (cpNodeOpp === undefined) {
49
+ // continue;
50
+ // }
51
+
52
+ const oppIdxs = cpNodeOpp === undefined
53
+ ? [255,65535] as [number,number]
54
+ : mbMap.get(cpNodeOpp);
55
+
56
+ const mbs = mbssByLoop[l][i];
57
+ if (oppIdxs !== undefined && mbs !== undefined) {
58
+ oppArr.push([[l,i], oppIdxs]);
59
+ } else {
60
+ oppArr.push([[l,i], [255,65535]]);
61
+ }
62
+ }
63
+ }
64
+
65
+ return { mbssByLoop, oppArr };
66
+ }
67
+
68
+
69
+ export { getMbssByLoopWithOppArr }
@@ -0,0 +1,25 @@
1
+ import type { Mat } from '../mat/mat.js';
2
+ import { findMats } from '../find-mat/find-mats.js';
3
+ import { removeSatInducedTrivial3Prongs } from "./remove-sat-induced-trivial-3prongs.js";
4
+ import { toScaleAxis } from '../sat/to-scale-axis.js';
5
+
6
+
7
+ /**
8
+ * Returns the shape information.
9
+ *
10
+ * @param font$$ the font from which the glyph outlines will be retrieved
11
+ * @param glyphId the glyph id for which the shape is to be retrieved
12
+ * @param options the options for SAT computation
13
+ */
14
+ // TODO
15
+ function getSats2(
16
+ mats: Mat[],
17
+ satScale: number): Mat[] {
18
+
19
+ const sats = mats.map(mat => toScaleAxis(mat, satScale));
20
+
21
+ return sats.map(removeSatInducedTrivial3Prongs);
22
+ }
23
+
24
+
25
+ export { getSats2 }
@@ -0,0 +1,27 @@
1
+ import type { CpNode } from '../cp-node/cp-node.js';
2
+ import { getAllOnCircle } from '../cp-node/fs/get-all-on-circle.js';
3
+ import { isTerminating } from '../cp-node/fs/is-terminating.js';
4
+ import { isTrivial } from '../cp-node/fs/is-trivial.js';
5
+
6
+
7
+ // TODO - DUPLICATE! -> likely other version needs fixing
8
+ function isFullyTerminating(cpNode: CpNode) {
9
+ if (!isTerminating(cpNode)) {
10
+ return false;
11
+ }
12
+
13
+ if (isTrivial(cpNode)) {
14
+ return true;
15
+ }
16
+
17
+ while (cpNode.prev === cpNode.prevOnCircle) {
18
+ cpNode = cpNode.prev;
19
+ }
20
+
21
+ const otherOnCircle = getAllOnCircle(cpNode.prevOnCircle, true);
22
+
23
+ return otherOnCircle.every(isTerminating);
24
+ }
25
+
26
+
27
+ export { isFullyTerminating }
@@ -0,0 +1,14 @@
1
+ import type { BezierPiece } from 'flo-bezier3';
2
+
3
+
4
+ /**
5
+ * A type representing a correspondence between 3 bezier curves (one on the
6
+ * boundary, one on the medial axis and one on the opposite boundary)
7
+ */
8
+ interface MatchedBeziers {
9
+ readonly medialBezier: BezierPiece;
10
+ readonly boundaryBezier: BezierPiece;
11
+ }
12
+
13
+
14
+ export type { MatchedBeziers }