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.
- package/__tests__/specific-cases/specific-cases.spec.ts +6 -0
- package/browser/index.js +4511 -7115
- package/browser/index.min.js +1 -1
- package/node/cp-node/fs/is-on-same-loop.d.ts +3 -0
- package/node/cp-node/fs/is-on-same-loop.js +6 -0
- package/node/cp-node/fs/is-on-same-loop.js.map +1 -0
- package/node/debug/debug.d.ts +10 -15
- package/node/debug/debug.js +35 -46
- package/node/debug/debug.js.map +1 -1
- package/node/find-2-prong/add-1-prong.js +1 -4
- package/node/find-2-prong/add-1-prong.js.map +1 -1
- package/node/find-mat/find-mat.js +1 -2
- package/node/find-mat/find-mat.js.map +1 -1
- package/node/find-mat/get-meta.d.ts +1 -6
- package/node/find-mat/get-meta.js +4 -26
- package/node/find-mat/get-meta.js.map +1 -1
- package/node/index.d.ts +4 -2
- package/node/index.js +3 -1
- package/node/index.js.map +1 -1
- package/node/reconstruct-from-mat/filter-zero-length.d.ts +10 -0
- package/node/reconstruct-from-mat/filter-zero-length.js +14 -0
- package/node/reconstruct-from-mat/filter-zero-length.js.map +1 -0
- package/node/reconstruct-from-mat/get-all-on-loop-by-loop.d.ts +7 -0
- package/node/reconstruct-from-mat/get-all-on-loop-by-loop.js +38 -0
- package/node/reconstruct-from-mat/get-all-on-loop-by-loop.js.map +1 -0
- package/node/reconstruct-from-mat/get-bezier-piece-length.d.ts +3 -0
- package/node/reconstruct-from-mat/get-bezier-piece-length.js +6 -0
- package/node/reconstruct-from-mat/get-bezier-piece-length.js.map +1 -0
- package/node/reconstruct-from-mat/get-boundary.d.ts +7 -0
- package/node/reconstruct-from-mat/get-boundary.js +18 -0
- package/node/reconstruct-from-mat/get-boundary.js.map +1 -0
- package/node/reconstruct-from-mat/get-cp-nodess-for-sat.d.ts +4 -0
- package/node/reconstruct-from-mat/get-cp-nodess-for-sat.js +15 -0
- package/node/reconstruct-from-mat/get-cp-nodess-for-sat.js.map +1 -0
- package/node/reconstruct-from-mat/get-matching-beziers.d.ts +10 -0
- package/node/reconstruct-from-mat/get-matching-beziers.js +29 -0
- package/node/reconstruct-from-mat/get-matching-beziers.js.map +1 -0
- package/node/reconstruct-from-mat/get-mbss-by-loop-per-sat.d.ts +6 -0
- package/node/reconstruct-from-mat/get-mbss-by-loop-per-sat.js +10 -0
- package/node/reconstruct-from-mat/get-mbss-by-loop-per-sat.js.map +1 -0
- package/node/reconstruct-from-mat/get-mbss-by-loop-with-opp-arr.d.ts +7 -0
- package/node/reconstruct-from-mat/get-mbss-by-loop-with-opp-arr.js +47 -0
- package/node/reconstruct-from-mat/get-mbss-by-loop-with-opp-arr.js.map +1 -0
- package/node/reconstruct-from-mat/get-sats2.d.ts +10 -0
- package/node/reconstruct-from-mat/get-sats2.js +16 -0
- package/node/reconstruct-from-mat/get-sats2.js.map +1 -0
- package/node/reconstruct-from-mat/is-fully-terminating.d.ts +3 -0
- package/node/reconstruct-from-mat/is-fully-terminating.js +19 -0
- package/node/reconstruct-from-mat/is-fully-terminating.js.map +1 -0
- package/node/reconstruct-from-mat/matched-beziers.d.ts +10 -0
- package/node/reconstruct-from-mat/matched-beziers.js +2 -0
- package/node/reconstruct-from-mat/matched-beziers.js.map +1 -0
- package/node/reconstruct-from-mat/reconstruct-from-mat.d.ts +4 -0
- package/node/reconstruct-from-mat/reconstruct-from-mat.js +28 -0
- package/node/reconstruct-from-mat/reconstruct-from-mat.js.map +1 -0
- package/node/reconstruct-from-mat/remove-sat-induced-trivial-3prongs.d.ts +12 -0
- package/node/reconstruct-from-mat/remove-sat-induced-trivial-3prongs.js +46 -0
- package/node/reconstruct-from-mat/remove-sat-induced-trivial-3prongs.js.map +1 -0
- package/node/reconstruct-from-mat/split-tri-path.d.ts +5 -0
- package/node/reconstruct-from-mat/split-tri-path.js +209 -0
- package/node/reconstruct-from-mat/split-tri-path.js.map +1 -0
- package/node/sat/add-debug-info.js +1 -2
- package/node/sat/add-debug-info.js.map +1 -1
- package/node/utils/clip.d.ts +2 -0
- package/node/utils/clip.js +6 -0
- package/node/utils/clip.js.map +1 -0
- package/package.json +2 -2
- package/src/cp-node/fs/is-on-same-loop.ts +15 -0
- package/src/debug/debug.ts +54 -72
- package/src/find-2-prong/add-1-prong.ts +1 -5
- package/src/find-mat/find-mat.ts +1 -2
- package/src/find-mat/get-meta.ts +3 -38
- package/src/index.ts +5 -3
- package/src/reconstruct-from-mat/filter-zero-length.ts +23 -0
- package/src/reconstruct-from-mat/get-all-on-loop-by-loop.ts +52 -0
- package/src/reconstruct-from-mat/get-bezier-piece-length.ts +12 -0
- package/src/reconstruct-from-mat/get-boundary.ts +32 -0
- package/src/reconstruct-from-mat/get-cp-nodess-for-sat.ts +24 -0
- package/src/reconstruct-from-mat/get-matching-beziers.ts +46 -0
- package/src/reconstruct-from-mat/get-mbss-by-loop-per-sat.ts +19 -0
- package/src/reconstruct-from-mat/get-mbss-by-loop-with-opp-arr.ts +69 -0
- package/src/reconstruct-from-mat/get-sats2.ts +25 -0
- package/src/reconstruct-from-mat/is-fully-terminating.ts +27 -0
- package/src/reconstruct-from-mat/matched-beziers.ts +14 -0
- package/src/reconstruct-from-mat/reconstruct-from-mat.ts +45 -0
- package/src/reconstruct-from-mat/remove-sat-induced-trivial-3prongs.ts +62 -0
- package/src/reconstruct-from-mat/split-tri-path.ts +280 -0
- package/src/sat/add-debug-info.ts +1 -2
- package/src/utils/clip.ts +13 -0
- package/node/debug/functions/general.d.ts +0 -48
- package/node/debug/functions/general.js +0 -53
- package/node/debug/functions/general.js.map +0 -1
- package/node/point-on-shape/pos-to-human-string.d.ts +0 -8
- package/node/point-on-shape/pos-to-human-string.js +0 -12
- package/node/point-on-shape/pos-to-human-string.js.map +0 -1
- package/src/debug/elem-type-two-prong.ts +0 -8
- package/src/debug/functions/cmp-cp-on-delta.ts +0 -54
- package/src/debug/functions/general.ts +0 -79
- package/src/debug/functions/three-prong.ts +0 -249
- package/src/debug/functions/two-prong.ts +0 -203
- package/src/find-2-prong/add-debug-info.ts +0 -45
package/src/debug/debug.ts
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
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
|
-
|
|
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:
|
|
17
|
-
directives:
|
|
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
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
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
|
|
46
|
-
drawElem
|
|
36
|
+
interface DebugFunctions {
|
|
37
|
+
drawElem: DrawElemFunctions,
|
|
47
38
|
}
|
|
48
39
|
|
|
49
40
|
|
|
50
41
|
/** @internal */
|
|
51
|
-
interface
|
|
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
|
-
|
|
72
|
-
|
|
73
|
-
...(!debug ? {} : !debug.generated ? {} : debug.generated),
|
|
62
|
+
elems: {
|
|
63
|
+
...debug?.elems,
|
|
74
64
|
// @ts-ignore
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
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
|
-
|
|
112
|
-
...(!debug ? {} : !debug.fs ? {} : debug.fs),
|
|
113
|
-
// @ts-ignore
|
|
97
|
+
...debug?.fs,
|
|
114
98
|
drawElem: {
|
|
115
|
-
|
|
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
|
-
...
|
|
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,
|
|
139
|
-
|
|
120
|
+
Debug, GeneratedElems, Timing,
|
|
121
|
+
DebugFunctions, Directives, enableDebugForMat
|
|
140
122
|
}
|
|
@@ -50,11 +50,7 @@ function add1Prong(
|
|
|
50
50
|
return;
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
|
|
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
|
|
package/src/find-mat/find-mat.ts
CHANGED
|
@@ -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 {
|
|
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
|
package/src/find-mat/get-meta.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
|
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 }
|