Skip to content

Commit 02a911a

Browse files
dakersankhesh
authored andcommitted
feat(VectorText): add support for perLetterFaceColors
1 parent e832746 commit 02a911a

File tree

4 files changed

+128
-28
lines changed

4 files changed

+128
-28
lines changed

Sources/Rendering/Core/VectorText/Utils.js

Lines changed: 60 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -426,8 +426,21 @@ function scalePoint(pt, vec, size) {
426426
* @param {Number} c - Third index
427427
* @param {Array} verticesArray - The output vertices array
428428
* @param {Array} uvArray - The output UV array
429+
* @param {Array} colorArray - The output color array
430+
* @param {Array} color - The color [r, g, b]
431+
* @param {Boolean} perFaceUV - Flag for per-face UV mapping
432+
* @param {Number} faceIndex - Index of the face for UV mapping
429433
*/
430-
function addTriangle(layers, a, b, c, verticesArray, uvArray) {
434+
function addTriangle(
435+
layers,
436+
a,
437+
b,
438+
c,
439+
verticesArray,
440+
uvArray,
441+
colorArray,
442+
color
443+
) {
431444
const tri = [a, c, b];
432445
tri.forEach((i) => {
433446
verticesArray.push(layers[i * 3], layers[i * 3 + 1], layers[i * 3 + 2]);
@@ -445,6 +458,9 @@ function addTriangle(layers, a, b, c, verticesArray, uvArray) {
445458
uvs.forEach((uv) => {
446459
uvArray.push(uv[0], uv[1]);
447460
});
461+
if (colorArray && color) {
462+
for (let i = 0; i < 3; ++i) colorArray.push(color[0], color[1], color[2]);
463+
}
448464
}
449465

450466
/**
@@ -456,8 +472,20 @@ function addTriangle(layers, a, b, c, verticesArray, uvArray) {
456472
* @param {Number} d - Fourth index
457473
* @param {Array} verticesArray - The output vertices array
458474
* @param {Array} uvArray - The output UV array
475+
* @param {Array} colorArray - The output color array
476+
* @param {Array} color - The color [r, g, b]
459477
*/
460-
function addQuad(layers, a, b, c, d, verticesArray, uvArray) {
478+
function addQuad(
479+
layers,
480+
a,
481+
b,
482+
c,
483+
d,
484+
verticesArray,
485+
uvArray,
486+
colorArray,
487+
color
488+
) {
461489
const quad = [a, d, b, b, d, c];
462490
quad.forEach((i) =>
463491
verticesArray.push(layers[i * 3], layers[i * 3 + 1], layers[i * 3 + 2])
@@ -482,6 +510,10 @@ function addQuad(layers, a, b, c, d, verticesArray, uvArray) {
482510
uvArray.push(uvs[1][0], uvs[1][1]);
483511
uvArray.push(uvs[2][0], uvs[2][1]);
484512
uvArray.push(uvs[3][0], uvs[3][1]);
513+
514+
if (colorArray && color) {
515+
for (let i = 0; i < 6; ++i) colorArray.push(color[0], color[1], color[2]);
516+
}
485517
}
486518

487519
/**
@@ -503,7 +535,9 @@ function buildLidFaces(
503535
bevelEnabled,
504536
bevelSegments,
505537
verticesArray,
506-
uvArray
538+
uvArray,
539+
colorArray,
540+
color
507541
) {
508542
if (bevelEnabled) {
509543
let layer = 0;
@@ -515,7 +549,9 @@ function buildLidFaces(
515549
b + offset,
516550
a + offset,
517551
verticesArray,
518-
uvArray
552+
uvArray,
553+
colorArray,
554+
color
519555
);
520556
});
521557

@@ -530,13 +566,15 @@ function buildLidFaces(
530566
b + offset,
531567
c + offset,
532568
verticesArray,
533-
uvArray
569+
uvArray,
570+
colorArray,
571+
color
534572
);
535573
});
536574
} else {
537575
// Bottom faces
538576
faces.forEach(([a, b, c]) => {
539-
addTriangle(layers, c, b, a, verticesArray, uvArray);
577+
addTriangle(layers, c, b, a, verticesArray, uvArray, colorArray, color);
540578
});
541579

542580
// Top faces
@@ -548,7 +586,9 @@ function buildLidFaces(
548586
b + offset,
549587
c + offset,
550588
verticesArray,
551-
uvArray
589+
uvArray,
590+
colorArray,
591+
color
552592
);
553593
});
554594
}
@@ -573,7 +613,9 @@ function buildWalls(
573613
steps,
574614
bevelSegments,
575615
verticesArray,
576-
uvArray
616+
uvArray,
617+
colorArray,
618+
color
577619
) {
578620
const totalLayers = steps + bevelSegments * 2;
579621
for (let i = 0; i < contour.length; i++) {
@@ -589,7 +631,7 @@ function buildWalls(
589631
const c = layerOffset + k + slen2;
590632
const d = layerOffset + j + slen2;
591633

592-
addQuad(layers, a, b, c, d, verticesArray, uvArray);
634+
addQuad(layers, a, b, c, d, verticesArray, uvArray, colorArray, color);
593635
}
594636
}
595637
}
@@ -613,7 +655,9 @@ function buildSideFaces(
613655
steps,
614656
bevelSegments,
615657
verticesArray,
616-
uvArray
658+
uvArray,
659+
colorArray,
660+
color
617661
) {
618662
let layerOffset = 0;
619663
// Create contour walls
@@ -625,7 +669,9 @@ function buildSideFaces(
625669
steps,
626670
bevelSegments,
627671
verticesArray,
628-
uvArray
672+
uvArray,
673+
colorArray,
674+
color
629675
);
630676
layerOffset += contour.length;
631677

@@ -640,7 +686,9 @@ function buildSideFaces(
640686
steps,
641687
bevelSegments,
642688
verticesArray,
643-
uvArray
689+
uvArray,
690+
colorArray,
691+
color
644692
);
645693
layerOffset += ahole.length;
646694
}

Sources/Rendering/Core/VectorText/example/index.js

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ fontKeys.forEach((key) => {
4747
});
4848
fontSelect.value = selectedFont;
4949

50+
let text = 'I love VTK.js!';
51+
let size = 16;
52+
5053
// ----------------------------------------------------------------------------
5154
// Add a cone source
5255
// ----------------------------------------------------------------------------
@@ -61,11 +64,20 @@ async function load() {
6164
.then((response) => response.arrayBuffer())
6265
.then((buffer) => {
6366
const font = fontModule.parse(buffer);
67+
// Generate a random color based on the letter index
68+
function perLetterFaceColors(letterIndex) {
69+
const seed = letterIndex * 9301 + 49297;
70+
const r = (Math.sin(seed) + 1) / 2;
71+
const g = (Math.sin(seed + 1) + 1) / 2;
72+
const b = (Math.sin(seed + 2) + 1) / 2;
73+
return [r, g, b];
74+
}
6475
pd = vtkVectorText.newInstance({
6576
font,
6677
bevelEnabled: bevelInput.checked,
67-
text: 'I love VTK.js!',
68-
size: 16,
78+
text,
79+
size,
80+
perLetterFaceColors,
6981
earcut: earcutModule.default,
7082
});
7183
mapper.setInputConnection(pd.getOutputPort());
@@ -76,14 +88,14 @@ async function load() {
7688
});
7789

7890
textInput.addEventListener('input', (event) => {
79-
const text = event.target.value;
91+
text = event.target.value;
8092
pd.setText(text);
8193
renderer.resetCamera();
8294
renderWindow.render();
8395
});
8496

8597
fontSize.addEventListener('input', (event) => {
86-
const size = event.target.value;
98+
size = event.target.value;
8799
pd.setFontSize(size);
88100
renderer.resetCamera();
89101
renderWindow.render();

Sources/Rendering/Core/VectorText/index.d.ts

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { vtkAlgorithm, vtkObject } from '../../../interfaces';
2+
import { Nullable, RGBColor } from '../../../types';
23

34
export interface IVectorTextInitialValues {
45
fontSize?: number;
@@ -12,6 +13,8 @@ export interface IVectorTextInitialValues {
1213
bevelOffset?: number;
1314
bevelSegments?: number;
1415
font?: any;
16+
earcut?: any; // Earcut module for triangulation
17+
perLetterFaceColors?: (letterIndex: number) => [number, number, number];
1518
}
1619

1720
type vtkVectorTextBase = vtkObject & vtkAlgorithm;
@@ -52,11 +55,6 @@ export interface vtkVectorText extends vtkVectorTextBase {
5255
*/
5356
getDepth(): number;
5457

55-
/**
56-
* Returns the font object used for rendering the text.
57-
*/
58-
getFont(): any;
59-
6058
/**
6159
* Returns the current font size.
6260
*/
@@ -72,6 +70,12 @@ export interface vtkVectorText extends vtkVectorTextBase {
7270
*/
7371
getText(): string;
7472

73+
/**
74+
* Gets or sets the per-letter face color function.
75+
* @param fn - Function mapping letter index to [r,g,b] color.
76+
*/
77+
getPerLetterFaceColors(): Nullable<(letterIndex: number) => RGBColor>;
78+
7579
/**
7680
* Enables or disables beveling.
7781
* @param bevelEnabled - True to enable beveling, false to disable.
@@ -138,6 +142,12 @@ export interface vtkVectorText extends vtkVectorTextBase {
138142
* @param text - The new text to display.
139143
*/
140144
setText(text: string): boolean;
145+
146+
/**
147+
* Sets the per-letter face color function.
148+
* @param fn - Function mapping letter index to [r,g,b] color.
149+
*/
150+
setPerLetterFaceColors(fn: (letterIndex: number) => RGBColor): boolean;
141151
}
142152

143153
/**

0 commit comments

Comments
 (0)