-
-
Notifications
You must be signed in to change notification settings - Fork 18
Attempt manifold 3D text mesh creation with verbose logging and fallback #524
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 7 commits
e94aa6e
70c0434
364ce0b
c503569
5fd2ff4
105da91
46a4f81
5b0d1a6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -708,6 +708,9 @@ | |||||
| const { modelId: resolvedModelId, blockKey } = | ||||||
| resolveCsgModelIdentity(modelId); | ||||||
| modelId = resolvedModelId; | ||||||
| const traceId = options.traceId || "no-trace-id"; | ||||||
| const traceStep = Number.isFinite(options.traceStep) ? options.traceStep : 1; | ||||||
| const initialTrace = traceStep === 1; | ||||||
|
|
||||||
| const collectMaterialMeshesDeep = (root) => { | ||||||
| const out = []; | ||||||
|
|
@@ -751,6 +754,11 @@ | |||||
| }; | ||||||
|
|
||||||
| return new Promise((resolve) => { | ||||||
| if (initialTrace) { | ||||||
| console.info( | ||||||
| `[subtractMeshes][path] trace=${traceId} step=${traceStep} approach=merge modelId=${modelId} base=${baseMeshName} tools=${meshNames.length}`, | ||||||
| ); | ||||||
| } | ||||||
| flock.whenModelReady(baseMeshName, (baseMesh) => { | ||||||
| if (!baseMesh) return resolve(null); | ||||||
| let actualBase = baseMesh.metadata?.modelName | ||||||
|
|
@@ -783,7 +791,6 @@ | |||||
| // Check if mesh itself has valid geometry (e.g., manifold text meshes) | ||||||
| const meshHasGeometry = | ||||||
| mesh.getTotalVertices && mesh.getTotalVertices() > 0; | ||||||
|
|
||||||
| if (parts.length > 0) { | ||||||
| const partClones = parts.map((p, i) => | ||||||
| cloneForCSG(p, `temp_${meshIndex}_${i}`), | ||||||
|
|
@@ -822,7 +829,6 @@ | |||||
| subtractDuplicates.push(clone); | ||||||
| } | ||||||
| }); | ||||||
|
|
||||||
| subtractDuplicates.forEach((m, idx) => { | ||||||
| try { | ||||||
| const meshCSG = flock.BABYLON.CSG2.FromMesh(m, false); | ||||||
|
|
@@ -832,6 +838,9 @@ | |||||
| `[subtractMeshesMerge] Subtraction ${idx} failed:`, | ||||||
| e.message, | ||||||
| ); | ||||||
| console.info( | ||||||
| `[subtractMeshes][merge] trace=${traceId} subtractionIndex=${idx} status=failed tool=${m.name}`, | ||||||
| ); | ||||||
| } | ||||||
| }); | ||||||
|
|
||||||
|
|
@@ -902,6 +911,9 @@ | |||||
| const { modelId: resolvedModelId, blockKey } = | ||||||
| resolveCsgModelIdentity(modelId); | ||||||
| modelId = resolvedModelId; | ||||||
| const traceId = options.traceId || "no-trace-id"; | ||||||
| const traceStep = Number.isFinite(options.traceStep) ? options.traceStep : 1; | ||||||
| const initialTrace = traceStep === 1; | ||||||
|
|
||||||
| const collectMaterialMeshesDeep = (root) => { | ||||||
| const out = []; | ||||||
|
|
@@ -922,6 +934,11 @@ | |||||
| }; | ||||||
|
|
||||||
| return new Promise((resolve) => { | ||||||
| if (initialTrace) { | ||||||
| console.info( | ||||||
| `[subtractMeshes][path] trace=${traceId} step=${traceStep} approach=individual modelId=${modelId} base=${baseMeshName} tools=${meshNames.length}`, | ||||||
| ); | ||||||
| } | ||||||
| flock.whenModelReady(baseMeshName, (baseMesh) => { | ||||||
| if (!baseMesh) return resolve(null); | ||||||
| let actualBase = baseMesh; | ||||||
|
|
@@ -958,7 +975,7 @@ | |||||
|
|
||||||
| let outerCSG = flock.BABYLON.CSG2.FromMesh(baseDuplicate, false); | ||||||
| const allToolParts = []; | ||||||
| validMeshes.forEach((mesh) => { | ||||||
| validMeshes.forEach((mesh, meshIndex) => { | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix ESLint violation: unused The pipeline is failing because 🔧 Proposed fix- validMeshes.forEach((mesh, meshIndex) => {
+ validMeshes.forEach((mesh, _meshIndex) => {Alternatively, if the index is not needed at all: - validMeshes.forEach((mesh, meshIndex) => {
+ validMeshes.forEach((mesh) => {📝 Committable suggestion
Suggested change
🧰 Tools🪛 GitHub Actions: ESLint[error] 978-978: ESLint (no-unused-vars): 'meshIndex' is defined but never used. Allowed unused args must match /^_/u 🪛 GitHub Check: eslint[failure] 978-978: 🤖 Prompt for AI Agents |
||||||
| const parts = collectMaterialMeshesDeep(mesh); | ||||||
| parts.forEach((p) => { | ||||||
| const dup = p.clone("partDup", null, true); | ||||||
|
|
@@ -968,12 +985,15 @@ | |||||
| }); | ||||||
| }); | ||||||
|
|
||||||
| allToolParts.forEach((part) => { | ||||||
| allToolParts.forEach((part, index) => { | ||||||
| try { | ||||||
| const partCSG = flock.BABYLON.CSG2.FromMesh(part, false); | ||||||
| outerCSG = outerCSG.subtract(partCSG); | ||||||
| } catch (e) { | ||||||
| console.warn(e); | ||||||
| console.info( | ||||||
| `[subtractMeshes][individual] trace=${traceId} subtractionIndex=${index} status=failed tool=${part.name}`, | ||||||
| ); | ||||||
| } | ||||||
| }); | ||||||
|
|
||||||
|
|
@@ -1058,16 +1078,42 @@ | |||||
| typeof optionsOrApproach === "string" | ||||||
| ? optionsOrApproach | ||||||
| : options.approach || "merge"; | ||||||
| if (!flock._subtractTraceSteps) flock._subtractTraceSteps = new Map(); | ||||||
| const traceKey = typeof modelId === "string" ? modelId : String(modelId); | ||||||
| const nextStep = (flock._subtractTraceSteps.get(traceKey) || 0) + 1; | ||||||
| flock._subtractTraceSteps.set(traceKey, nextStep); | ||||||
|
Comment on lines
+1081
to
+1084
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Bound trace-state map to prevent unbounded memory growth.
♻️ Suggested bounded-cache fix if (!flock._subtractTraceSteps) flock._subtractTraceSteps = new Map();
const traceKey = typeof modelId === "string" ? modelId : String(modelId);
+const TRACE_STEP_CACHE_LIMIT = 1000;
+const isNewTraceKey = !flock._subtractTraceSteps.has(traceKey);
+if (isNewTraceKey && flock._subtractTraceSteps.size >= TRACE_STEP_CACHE_LIMIT) {
+ const oldestKey = flock._subtractTraceSteps.keys().next().value;
+ flock._subtractTraceSteps.delete(oldestKey);
+}
const nextStep = (flock._subtractTraceSteps.get(traceKey) || 0) + 1;
flock._subtractTraceSteps.set(traceKey, nextStep);🤖 Prompt for AI Agents |
||||||
| const traceId = | ||||||
| (options && options.traceId) || | ||||||
| `${traceKey.split("__")[0]}:${traceKey.slice(-6)}`; | ||||||
| const tracedOptions = { | ||||||
| ...options, | ||||||
| traceId, | ||||||
| traceStep: nextStep, | ||||||
| }; | ||||||
| if (nextStep === 1) { | ||||||
| console.info( | ||||||
| `[subtractMeshes][entry] trace=${traceId} step=${nextStep} requestedApproach=${approach} modelId=${modelId} base=${baseMeshName} tools=${meshNames.length}`, | ||||||
| ); | ||||||
| } else if (nextStep === 2) { | ||||||
| console.info( | ||||||
| `[subtractMeshes][entry] trace=${traceId} repeated_steps_detected=true suppressing_repetitive_logs=true`, | ||||||
| ); | ||||||
| } | ||||||
|
|
||||||
| if (approach === "individual") { | ||||||
| return this.subtractMeshesIndividual( | ||||||
| modelId, | ||||||
| baseMeshName, | ||||||
| meshNames, | ||||||
| options, | ||||||
| tracedOptions, | ||||||
| ); | ||||||
| } else { | ||||||
| return this.subtractMeshesMerge(modelId, baseMeshName, meshNames, options); | ||||||
| return this.subtractMeshesMerge( | ||||||
| modelId, | ||||||
| baseMeshName, | ||||||
| meshNames, | ||||||
| tracedOptions, | ||||||
| ); | ||||||
| } | ||||||
| }, | ||||||
| intersectMeshes(modelId, meshList) { | ||||||
|
|
||||||
Uh oh!
There was an error while loading. Please reload this page.