muitas melhorias pra descrever
This commit is contained in:
1 parent
89b08a19ef
commit
c8fba4d240
21 files changed
+971
-17
No files matched your search
@@ -103,23 +103,37 @@ const LEADER_LINE_SOURCE_KEYS = new Set(["nervous", "regions"]);
|
||||
|
||||
function isLeaderLineMesh(mesh) {
|
||||
try {
|
||||
const prims = mesh.listPrimitives();
|
||||
if (prims.length === 0) return false;
|
||||
return prims.every((prim) => isLeaderLinePrimitive(prim));
|
||||
// Antes, cada primitivo era julgado sozinho ("every"). Isso deixava
|
||||
// passar batido linhas de chamada com um pequeno "gancho"/marcador na
|
||||
// ponta (comum no app original, pra indicar o ponto exato) — esse
|
||||
// gancho é um primitivo à parte que não é colinear, então "every"
|
||||
// reprovava a malha inteira. Agora juntamos os vértices de TODOS os
|
||||
// primitivos da malha num só cálculo e usamos o percentil 90 do desvio
|
||||
// (em vez do máximo), assim uma pontinha que afeta só uma minoria dos
|
||||
// vértices não derruba a classificação, mas uma estrutura real (curva,
|
||||
// ramificada, com volume) continua reprovando.
|
||||
const points = [];
|
||||
for (const prim of mesh.listPrimitives()) {
|
||||
const accessor = prim.getAttribute("POSITION");
|
||||
if (!accessor) continue;
|
||||
const count = accessor.getCount();
|
||||
const arr = accessor.getArray();
|
||||
if (!arr) continue;
|
||||
for (let i = 0; i < count; i++) {
|
||||
points.push([arr[i * 3], arr[i * 3 + 1], arr[i * 3 + 2]]);
|
||||
}
|
||||
}
|
||||
return isLeaderLinePointCloud(points);
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function isLeaderLinePrimitive(prim) {
|
||||
const accessor = prim.getAttribute("POSITION");
|
||||
if (!accessor) return false;
|
||||
const count = accessor.getCount();
|
||||
function isLeaderLinePointCloud(points) {
|
||||
const count = points.length;
|
||||
if (count < 2) return false;
|
||||
const arr = accessor.getArray();
|
||||
if (!arr) return false;
|
||||
|
||||
const at = (i) => [arr[i * 3], arr[i * 3 + 1], arr[i * 3 + 2]];
|
||||
const at = (i) => points[i];
|
||||
const dist2 = (a, b) => {
|
||||
const dx = a[0] - b[0], dy = a[1] - b[1], dz = a[2] - b[2];
|
||||
return dx * dx + dy * dy + dz * dz;
|
||||
@@ -144,18 +158,21 @@ function isLeaderLinePrimitive(prim) {
|
||||
if (axisLen < 0.02) return false; // curto demais pra ser uma linha de chamada (poste real de âncora)
|
||||
|
||||
const ax = [(b[0] - a[0]) / axisLen, (b[1] - a[1]) / axisLen, (b[2] - a[2]) / axisLen];
|
||||
let maxPerp = 0;
|
||||
const perps = new Array(count);
|
||||
for (let i = 0; i < count; i++) {
|
||||
const p = at(i);
|
||||
const v = [p[0] - a[0], p[1] - a[1], p[2] - a[2]];
|
||||
const t = v[0] * ax[0] + v[1] * ax[1] + v[2] * ax[2];
|
||||
const perp2 =
|
||||
(v[0] - t * ax[0]) ** 2 + (v[1] - t * ax[1]) ** 2 + (v[2] - t * ax[2]) ** 2;
|
||||
if (perp2 > maxPerp) maxPerp = perp2;
|
||||
perps[i] = Math.sqrt(perp2);
|
||||
}
|
||||
// "Linha reta e fina": todos os pontos ficam muito perto do próprio eixo
|
||||
// mais longo (desvio perpendicular pequeno comparado ao comprimento).
|
||||
return Math.sqrt(maxPerp) < axisLen * 0.08;
|
||||
perps.sort((x, y) => x - y);
|
||||
const p90 = perps[Math.floor(0.9 * (count - 1))];
|
||||
// "Linha reta e fina": 90% dos pontos ficam muito perto do próprio eixo
|
||||
// mais longo (desvio perpendicular pequeno comparado ao comprimento) —
|
||||
// tolera até 10% de vértices "fora da linha" (gancho/marcador na ponta).
|
||||
return p90 < axisLen * 0.1;
|
||||
}
|
||||
|
||||
function classifySystem(key, rawName) {
|
||||
|
||||
Reference in new issue
Block a user