Skip to content

Commit 074248e

Browse files
committed
Fix text extrusion with proper vertex deduplication, edge detection, and normal calculation with recomended chnages
1 parent 38fef3a commit 074248e

File tree

1 file changed

+20
-15
lines changed

1 file changed

+20
-15
lines changed

src/type/p5.Font.js

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -549,29 +549,36 @@ export class Font {
549549
contours = [contours];
550550
}
551551

552+
// Step 2: build base flat geometry - single shape
552553
const geom = this._pInst.buildGeometry(() => {
553554
const prevValidateFaces = this._pInst._renderer._validateFaces;
554555
this._pInst._renderer._validateFaces = true;
555-
this._pInst.push();
556-
this._pInst.stroke(0);
557556

558-
contours.forEach(glyphContours => {
559-
this._pInst.beginShape();
557+
this._pInst.beginShape();
558+
for (const glyphContours of contours) {
560559
for (const contour of glyphContours) {
561560
this._pInst.beginContour();
562-
contour.forEach(({ x, y }) => this._pInst.vertex(x, y, 0));
561+
for (const pt of contour) {
562+
this._pInst.vertex(pt.x, pt.y, 0);
563+
}
563564
this._pInst.endContour(this._pInst.CLOSE);
564565
}
565-
this._pInst.endShape(this._pInst.CLOSE);
566-
});
567-
this._pInst.pop();
566+
}
567+
568+
this._pInst.endShape(this._pInst.CLOSE);
569+
568570
this._pInst._renderer._validateFaces = prevValidateFaces;
569571
});
570572

571573
if (extrude === 0) {
572574
return geom;
573575
}
574576

577+
// The tessellation process creates separate vertices for each triangle,
578+
// even when they share the same position. We need to deduplicate them
579+
// to find which faces are actually connected, so we can identify the
580+
// outer edges for extrusion.
581+
575582
const vertexIndices = {};
576583
const vertexId = v => `${v.x.toFixed(6)}-${v.y.toFixed(6)}-${v.z.toFixed(6)}`;
577584
const newVertices = [];
@@ -608,8 +615,6 @@ export class Font {
608615
}
609616
}
610617

611-
console.log(`Found ${validEdges.length} outer edges from ${Object.keys(seen).length} total edges`);
612-
613618
// Step 5: Create extruded geometry
614619
const extruded = this._pInst.buildGeometry(() => {});
615620
const half = extrude * 0.5;
@@ -622,11 +627,11 @@ export class Font {
622627
const vA = newVertices[a];
623628
const vB = newVertices[b];
624629
// Skip if vertices are too close (degenerate edge)
625-
const dist = Math.sqrt(
626-
Math.pow(vB.x - vA.x, 2) +
627-
Math.pow(vB.y - vA.y, 2) +
628-
Math.pow(vB.z - vA.z, 2)
629-
);
630+
// Check if the cross product of edge vectors has sufficient magnitude
631+
const edgeVector = new Vector(vB.x - vA.x, vB.y - vA.y, vB.z - vA.z);
632+
const extrudeVector = new Vector(0, 0, extrude);
633+
const crossProduct = p5.Vector.cross(edgeVector, extrudeVector);
634+
if (crossProduct.mag() < 0.0001) continue;
630635
if (dist < 0.0001) continue;
631636
// Front face vertices
632637
const frontA = extruded.vertices.length;

0 commit comments

Comments
 (0)