Skip to content

Commit d7c76f8

Browse files
committed
checkpoint boundary selection work
1 parent 1674b8e commit d7c76f8

1 file changed

Lines changed: 40 additions & 1 deletion

File tree

src/void/sketch/geometry.js

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ function resolveDerivedEdgeCandidate(event, intersections, feature) {
265265
const edgeHit = resolvedPrimary.hit || null;
266266
const edgeKey = String(edgeHit?.key || '');
267267
if (!edgeKey) return null;
268-
const edge = api.solids?.getEdgeByKey?.(edgeKey) || edgeHit;
268+
let edge = api.solids?.getEdgeByKey?.(edgeKey) || edgeHit;
269269
if (!edge) return null;
270270

271271
let solidId = String(edge?.solidId || edgeHit?.solidId || '');
@@ -283,6 +283,45 @@ function resolveDerivedEdgeCandidate(event, intersections, feature) {
283283
if (!solidId) return null;
284284
const faceKey = Number.isFinite(faceId) ? `${solidId}:${faceId}` : null;
285285

286+
// Promote dense closed loops (typically circles) to full-loop edge derive.
287+
if (!edge?.pathWorld && edgeKey.startsWith('faceedge:')) {
288+
const parts = edgeKey.split(':');
289+
const segIndex = Number(parts[parts.length - 1]);
290+
const fid = Number(parts[parts.length - 2]);
291+
const sid = parts.slice(1, -2).join(':');
292+
if (sid && Number.isFinite(fid) && Number.isFinite(segIndex)) {
293+
const loops = api.solids?.getFaceBoundaryLoops?.(`${sid}:${fid}`) || [];
294+
const loop = loops.find(lp => Array.isArray(lp?.segmentIndices) && lp.segmentIndices.includes(segIndex) && lp?.closed);
295+
if (loop && Array.isArray(loop.points) && loop.points.length >= 8) {
296+
const center = new THREE.Vector3();
297+
for (const p of loop.points) center.add(p);
298+
center.multiplyScalar(1 / loop.points.length);
299+
let mean = 0;
300+
const rr = [];
301+
for (const p of loop.points) {
302+
const r = p.distanceTo(center);
303+
rr.push(r);
304+
mean += r;
305+
}
306+
mean /= Math.max(1, rr.length);
307+
let varR = 0;
308+
for (const r of rr) {
309+
const d = r - mean;
310+
varR += d * d;
311+
}
312+
const rel = mean > 1e-8 ? Math.sqrt(varR / Math.max(1, rr.length)) / mean : 1;
313+
if (rel <= 0.12) {
314+
edge = {
315+
...edge,
316+
key: `faceedgeloop:${sid}:${fid}:${loops.indexOf(loop)}`,
317+
pathWorld: loop.points.map(p => p.clone()),
318+
loop: true
319+
};
320+
}
321+
}
322+
}
323+
}
324+
286325
let a = edge?.aWorld || null;
287326
let b = edge?.bWorld || null;
288327
if ((!a || !b) && Array.isArray(edge?.pathWorld) && edge.pathWorld.length >= 2) {

0 commit comments

Comments
 (0)