1 | srecord noeq G22MeshMapper_v2(G22Mesh mesh1, G22Mesh mesh2) { |
2 | // import the important classes |
3 | delegate Anchor, Curve to G22Mesh. |
4 | delegate mapAnchor, unmapAnchor, tempMapAnchor to mm. |
5 | |
6 | // params |
7 | |
8 | settable bool chooseAnchor1AtRandom; |
9 | |
10 | // output |
11 | |
12 | G22MeshMapping mm; |
13 | |
14 | // index structures |
15 | |
16 | MultiMap<Int, Anchor> anchorsByArity2; |
17 | |
18 | // EXCEPTIONS (e.g. meshes don't match in signature) |
19 | |
20 | // set to the reason why when a mapping is deemed impossible |
21 | settable O rejectedBecause; |
22 | |
23 | bool rejected() { ret rejectedBecause != null; } |
24 | |
25 | // INTERNAL VARS |
26 | |
27 | bool prechecksDone; |
28 | S sig1, sig2; |
29 | Anchor anchor1; // first anchor to map |
30 | |
31 | G22MeshMapping get() { ret mm; } |
32 | |
33 | // Do the whole search, but in "random" mode (may fail) |
34 | void run_random { |
35 | search_step1(); |
36 | while (search_step2()); |
37 | } |
38 | |
39 | // random mode |
40 | void search_step1() { |
41 | prechecks(); if (rejected()) ret; |
42 | |
43 | // make empty mapping |
44 | mm = new G22MeshMapping(mesh1, mesh2); |
45 | |
46 | anchorsByArity2 = multiMapIndex(mesh2.anchors(), a -> a.arity()); |
47 | |
48 | // Choose first anchor to map - this is arbitrary |
49 | // (not a backtracking point) |
50 | Anchor anchor1 = chooseAnchor1AtRandom ? random(mesh1.anchors()) : first(mesh1.anchors()); |
51 | |
52 | // Choose which anchor to map it to |
53 | // (first backtracking point) |
54 | L<Anchor> options = anchorsByArity2.get(anchor1.arity()); |
55 | // ret BacktrackingOptions(options, ...); ??? |
56 | |
57 | Anchor anchor2 = random(options); |
58 | print("G22MeshMapper_v2 step1: Connecting " + anchor1 + " to " + anchor2); |
59 | mapAnchor(anchor1, anchor2); |
60 | } |
61 | |
62 | // random mode |
63 | bool search_step2() { |
64 | bool change; |
65 | for (curve1 : mesh1.curves()) { |
66 | // skip if curve is already mapped |
67 | if (mm.isMapped(curve1)) |
68 | continue; // with print("Curve is mapped: " + curve1); |
69 | |
70 | print("Looking to match " + curve1); |
71 | |
72 | // check if anchors are mapped |
73 | Anchor start2 = mm.get(curve1.start); |
74 | Anchor end2 = mm.get(curve1.end); |
75 | |
76 | // If neither anchor is mapped, postpone this curve |
77 | if (start2 == null && end2 == null) |
78 | continue; // with print("Curve is not discovered yet: " + curve1); |
79 | |
80 | // Start at the mapped anchor, choose a viable curve in mesh2 to map to |
81 | bool startAtEnd = end2 != null; |
82 | Anchor a1 = curve1.anchor(startAtEnd); |
83 | Anchor a1other = curve1.anchor(!startAtEnd); |
84 | Anchor a2 = mm.get(curve1.anchor(startAtEnd)); |
85 | |
86 | print(+a1); |
87 | print(+a2); |
88 | print(+a1other); |
89 | |
90 | new L<Curve> possibleCurves; |
91 | for (c2 : a2.curves()) { |
92 | if (mm.isMapped(c2)) |
93 | continue; // with print("Curve already mapped: " + c2); |
94 | |
95 | // check for arity match |
96 | Anchor a3 = c2.anchorOpposite(a2); |
97 | print(+a3); |
98 | int arity1 = a3.arity(), arity2 = a1other.arity(); |
99 | if (arity1 != arity2) |
100 | continue with print("Arity mismatch (" + arity1 + "/" + arity2 + ") for curve " + c2); |
101 | |
102 | // This curve is viable as a mapping target |
103 | possibleCurves.add(c2); |
104 | } |
105 | |
106 | print(l(possibleCurves) + "/" + l(a2.curves()) |
107 | + " possible curve(s) to map " + curve1 + " to:"); |
108 | pnl(possibleCurves); |
109 | if (empty(possibleCurves)) |
110 | ret false with rejectedBecause("Could not map curve " + curve1); |
111 | |
112 | // Map the curve |
113 | Curve c2 = random(possibleCurves); |
114 | bool flipped = c2.start() != a2; |
115 | print("Mapping curve " + curve1 + " to " + c2); |
116 | mm.mapCurve(curve1, c2, flipped); |
117 | set change; |
118 | } |
119 | |
120 | ret change; |
121 | } |
122 | |
123 | Search newSearch() { |
124 | ret new Search; |
125 | } |
126 | |
127 | // backtracking version |
128 | class Search extends VStackComputableWithStep<Void> is IMakeEmptyClone { |
129 | Anchor anchor2; |
130 | |
131 | public selfType makeEmptyClone() { ret new selfType; } |
132 | |
133 | void step(VStack stack) { |
134 | cast stack to BStack<?>; |
135 | |
136 | if (step == 0) { |
137 | prechecks(); |
138 | if (rejected()) stack.ret(); |
139 | step = 1; |
140 | } else if (step == 1) { |
141 | // make empty mapping |
142 | mm = new G22MeshMapping(mesh1, mesh2); |
143 | |
144 | anchorsByArity2 = multiMapIndex(mesh2.anchors(), a -> a.arity()); |
145 | |
146 | // Choose first anchor to map - this is arbitrary |
147 | // (not a backtracking point) |
148 | anchor1 = chooseAnchor1AtRandom ? random(mesh1.anchors()) : first(mesh1.anchors()); |
149 | |
150 | // Choose which anchor to map it to (first backtracking point). |
151 | // List should never be empty because we checked the signatures first. |
152 | L<Anchor> anchor2options = anchorsByArity2.get(anchor1.arity()); |
153 | |
154 | step = 2; |
155 | stack.options(this, map(anchor2options, anchor2 |
156 | -> instance -> instance.anchor2 = anchor2)); |
157 | } else if (step == 2) { |
158 | print("G22MeshMapper_v2 step1: Connecting " + anchor1 + " to " + anchor2); |
159 | stack.temp(tempMapAnchor(anchor1, anchor2)); |
160 | step = 3; |
161 | } else if (step == 3) { |
162 | stack.call(new Step2); |
163 | step = 4; |
164 | } else { |
165 | if (isTrue(stack.subResult())) |
166 | step = 3; |
167 | else |
168 | stack.return(); |
169 | } |
170 | } |
171 | } |
172 | |
173 | class Step2 extends VStackComputableWithStep<Bool> is IMakeEmptyClone { |
174 | bool change; |
175 | Iterator<Curve> curve1iterator; |
176 | Curve curve1, c2; |
177 | Anchor a2; |
178 | |
179 | public selfType makeEmptyClone() { ret new selfType; } |
180 | |
181 | void step(VStack stack) { |
182 | cast stack to BStack<?>; |
183 | |
184 | if (step == 0) { |
185 | curve1iterator = iterator(mesh1.curves()); |
186 | step++; |
187 | } else if (step == 1) { |
188 | if (!curve1iterator.hasNext()) |
189 | ret with stack.return(change); |
190 | |
191 | curve1 = curve1iterator.next(); |
192 | |
193 | print("Looking to match " + curve1); |
194 | |
195 | // skip if curve is already mapped |
196 | if (mm.isMapped(curve1)) { |
197 | print("Curve is mapped: " + curve1); |
198 | ret; // continue loop |
199 | } |
200 | |
201 | // check if anchors are mapped |
202 | Anchor start2 = mm.get(curve1.start); |
203 | Anchor end2 = mm.get(curve1.end); |
204 | |
205 | // If neither anchor is mapped, postpone this curve |
206 | if (start2 == null && end2 == null) { |
207 | //print("Curve is not discovered yet: " + curve1); |
208 | ret; // continue loop; |
209 | } |
210 | |
211 | // Start at the mapped anchor, choose a viable curve in mesh2 to map to |
212 | bool startAtEnd = end2 != null; |
213 | Anchor a1 = curve1.anchor(startAtEnd); |
214 | Anchor a1other = curve1.anchor(!startAtEnd); |
215 | a2 = mm.get(curve1.anchor(startAtEnd)); |
216 | |
217 | print(+a1); |
218 | print(+a2); |
219 | print(+a1other); |
220 | |
221 | new L<Curve> possibleCurves; |
222 | for (c2 : a2.curves()) { |
223 | if (mm.isMapped(c2)) { |
224 | //print("Curve already mapped: " + c2); |
225 | continue; // continue loop |
226 | } |
227 | |
228 | // check for arity match |
229 | Anchor a3 = c2.anchorOpposite(a2); |
230 | print(+a3); |
231 | int arity1 = a3.arity(), arity2 = a1other.arity(); |
232 | if (arity1 != arity2) { |
233 | print("Arity mismatch (" + arity1 + "/" + arity2 + ") for curve " + c2); |
234 | continue; // continue loop |
235 | } |
236 | |
237 | // This curve is viable as a mapping target |
238 | possibleCurves.add(c2); |
239 | print("Possible curve!"); |
240 | } |
241 | |
242 | print(l(possibleCurves) + "/" + l(a2.curves()) |
243 | + " possible curve(s) to map " + curve1 + " to: "); |
244 | pnl(possibleCurves); |
245 | if (empty(possibleCurves)) { |
246 | stack.temp(tempRejectedBecause("Could not map curve " + curve1)); |
247 | ret with stack.ret(false); |
248 | } |
249 | |
250 | // Go through all curve mappings |
251 | step = 2; |
252 | stack.options(this, map(possibleCurves, |
253 | c2 -> instance -> instance.c2 = c2)); |
254 | ret; |
255 | } else { |
256 | bool flipped = c2.start() != a2; |
257 | print("Mapping curve " + curve1 + " to " + c2); |
258 | stack.temp(mm.tempMapCurve(curve1, c2, flipped)); |
259 | set change; |
260 | |
261 | // continue loop |
262 | step = 1; |
263 | } |
264 | } |
265 | } |
266 | |
267 | protected void prechecks { |
268 | set prechecksDone; |
269 | sig1 = mesh1.signature(); |
270 | sig2 = mesh1.signature(); |
271 | if (!eq(sig1, sig2)) |
272 | ret with rejectedBecause(G22SignatureMismatch(mesh1, mesh2)); |
273 | } |
274 | |
275 | AutoCloseable tempRejectedBecause(O reason) { |
276 | rejectedBecause(reason); |
277 | ret -> rejectedBecause(null); |
278 | } |
279 | } |
Began life as a copy of #1035369
download show line numbers debug dex old transpilations
Travelled to 2 computer(s): mowyntqkapby, mqqgnosmbjvj
No comments. add comment
Snippet ID: | #1035416 |
Snippet name: | G22MeshMapper_v2 backup with random mode |
Eternal ID of this version: | #1035416/1 |
Text MD5: | 07ff84641ac01b2f724ce478d2647398 |
Author: | stefan |
Category: | javax |
Type: | JavaX fragment (include) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2022-05-06 18:43:02 |
Source code size: | 8706 bytes / 279 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 102 / 118 |
Referenced in: | [show references] |