Skip to content

Commit ccf5ed0

Browse files
dakerfloryst
authored andcommitted
feat(TriangleStrip): add vtkTriangleStrip
1 parent e750b38 commit ccf5ed0

File tree

8 files changed

+1249
-20
lines changed

8 files changed

+1249
-20
lines changed

Sources/Common/Core/CellArray/index.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import macro from 'vtk.js/Sources/macros';
22
import vtkDataArray from 'vtk.js/Sources/Common/Core/DataArray';
33
import { VtkDataTypes } from 'vtk.js/Sources/Common/Core/DataArray/Constants';
44

5+
const { isVtkObject } = macro;
56
// ----------------------------------------------------------------------------
67
// Global methods
78
// ----------------------------------------------------------------------------
@@ -100,7 +101,13 @@ function vtkCellArray(publicAPI, model) {
100101
return model.values.subarray(cellLoc, cellLoc + numberOfPoints);
101102
};
102103

103-
publicAPI.insertNextCell = (cellPointIds) => {
104+
publicAPI.insertNextCell = (cell) => {
105+
let cellPointIds;
106+
if (isVtkObject(cell)) {
107+
cellPointIds = cell.getPointsIds();
108+
} else {
109+
cellPointIds = cell;
110+
}
104111
const cellId = publicAPI.getNumberOfCells();
105112
publicAPI.insertNextTuples([cellPointIds.length, ...cellPointIds]);
106113
// By computing the number of cells earlier, we made sure that numberOfCells is defined

Sources/Common/DataModel/Triangle/index.d.ts

Lines changed: 68 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Vector3 } from '../../../types';
1+
import { Vector2, Vector3 } from '../../../types';
22
import vtkCell, { ICellInitialValues } from '../Cell';
33

44
export interface ITriangleInitialValues extends ICellInitialValues {}
@@ -11,6 +11,14 @@ export interface IIntersectWithLine {
1111
betweenPoints?: boolean;
1212
}
1313

14+
export interface IIntersectWithTriangle {
15+
intersect: boolean;
16+
coplanar: boolean;
17+
pt1: Vector3;
18+
pt2: Vector3;
19+
surfaceId: number;
20+
}
21+
1422
export interface vtkTriangle extends vtkCell {
1523
/**
1624
* Get the topological dimensional of the cell (0, 1, 2 or 3).
@@ -48,23 +56,36 @@ export interface vtkTriangle extends vtkCell {
4856
): IIntersectWithLine;
4957

5058
/**
51-
* Evaluate the position of x in relation with triangle.
52-
*
53-
* Compute the closest point in the cell.
54-
* - pccords parametric coordinate (computed in function)
55-
* - weights Interpolation weights in cell.
56-
* - the number of weights is equal to the number of points defining the
57-
* cell (computed in function).
58-
*
59-
* A javascript object is returned :
60-
*
61-
* ```js
62-
* {
63-
* evaluation: 1 = inside 0 = outside -1 = problem during execution
64-
* subId: always set to 0
65-
* dist2: squared distance from x to cell
66-
* }
67-
* ```
59+
* Get the nearest cell boundary to the specified parametric
60+
* coordinates and whether the point is inside or outside the cell.
61+
* @param {Number} subId The sub-id of the cell.
62+
* @param {Vector3} pcoords The parametric coordinates.
63+
* @param {Vector2} pts The points of the cell.
64+
*/
65+
cellBoundary(subId: number, pcoords: Vector3, pts: Vector2): boolean;
66+
67+
/**
68+
* Get the derivatives of the triangle at the specified parametric
69+
* coordinates.
70+
* @param {Number} subId - The sub-id of the triangle.
71+
* @param {Vector3} pcoords - The parametric coordinates.
72+
* @param {Number[]} values - The values at the points.
73+
* @param {Number} dim - The dimension.
74+
* @param {Number[]} derivs - The derivatives.
75+
*/
76+
derivatives(
77+
subId: number,
78+
pcoords: Vector3,
79+
values: any,
80+
dim: number,
81+
derivs: number[]
82+
): void;
83+
84+
/**
85+
* Evaluates whether the specified point is inside (1), outside (0), or
86+
* indeterminate (-1) for the cell; computes parametric coordinates, sub-cell
87+
* ID (if applicable), squared distance to the cell (and closest point if
88+
* requested), and interpolation weights for the cell.
6889
*
6990
* @param {Vector3} x The x point coordinate.
7091
* @param {Vector3} closestPoint The closest point coordinate.
@@ -79,7 +100,8 @@ export interface vtkTriangle extends vtkCell {
79100
): IIntersectWithLine;
80101

81102
/**
82-
* Determine global coordinate (x]) from subId and parametric coordinates.
103+
* Determine global coordinates (x) from the given subId and parametric
104+
* coordinates.
83105
* @param {Vector3} pcoords The parametric coordinates.
84106
* @param {Vector3} x The x point coordinate.
85107
* @param {Number[]} weights The number of weights.
@@ -144,6 +166,31 @@ export function computeNormal(
144166
n: Vector3
145167
): void;
146168

169+
/**
170+
* Compute the interpolation functions/derivatives
171+
* @param {Number[]} derivs - The derivatives.
172+
*/
173+
export function interpolationDerivs(derivs: number[]): void;
174+
175+
/**
176+
* Compute the intersection between two triangles.
177+
* @param {Vector3} p1 The first point coordinate of the first triangle.
178+
* @param {Vector3} q1 The second point coordinate of the first triangle.
179+
* @param {Vector3} r1 The third point coordinate of the first triangle.
180+
* @param {Vector3} p2 The first point coordinate of the second triangle.
181+
* @param {Vector3} q2 The second point coordinate of the second triangle.
182+
* @param {Vector3} r2 The third point coordinate of the second triangle.
183+
*/
184+
export function intersectWithTriangle(
185+
p1: Vector3,
186+
q1: Vector3,
187+
r1: Vector3,
188+
p2: Vector3,
189+
q2: Vector3,
190+
r2: Vector3,
191+
tolerance?: number
192+
): IIntersectWithTriangle;
193+
147194
/**
148195
* vtkTriangle is a cell which representant a triangle. It contains static
149196
* method to make some computations directly link to triangle.
@@ -155,5 +202,7 @@ export declare const vtkTriangle: {
155202
extend: typeof extend;
156203
computeNormalDirection: typeof computeNormalDirection;
157204
computeNormal: typeof computeNormal;
205+
interpolationDerivs: typeof interpolationDerivs;
206+
intersectWithTriangle: typeof intersectWithTriangle;
158207
};
159208
export default vtkTriangle;

Sources/Common/DataModel/Triangle/index.js

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,19 @@ function computeNormal(v1, v2, v3, n) {
3232
}
3333
}
3434

35+
function interpolationDerivs(derivs) {
36+
// Order: [dN1/dr, dN2/dr, dN3/dr, dN1/ds, dN2/ds, dN3/ds]
37+
// r-derivatives
38+
derivs[0] = -1.0;
39+
derivs[1] = 1.0;
40+
derivs[2] = 0.0;
41+
42+
// s-derivatives
43+
derivs[3] = -1.0;
44+
derivs[4] = 0.0;
45+
derivs[5] = 1.0;
46+
}
47+
3548
function intersectWithTriangle(p1, q1, r1, p2, q2, r2, tolerance = 1e-6) {
3649
let coplanar = false;
3750
const pt1 = [];
@@ -228,6 +241,7 @@ function intersectWithTriangle(p1, q1, r1, p2, q2, r2, tolerance = 1e-6) {
228241
export const STATIC = {
229242
computeNormalDirection,
230243
computeNormal,
244+
interpolationDerivs,
231245
intersectWithTriangle,
232246
};
233247

@@ -240,6 +254,7 @@ function vtkTriangle(publicAPI, model) {
240254
model.classHierarchy.push('vtkTriangle');
241255

242256
publicAPI.getCellDimension = () => 2;
257+
243258
publicAPI.intersectWithLine = (p1, p2, tol, x, pcoords) => {
244259
const outObj = {
245260
subId: 0,
@@ -338,6 +353,17 @@ function vtkTriangle(publicAPI, model) {
338353
return outObj;
339354
};
340355

356+
/**
357+
* Evaluates whether the specified point is inside (1), outside (0), or
358+
* indeterminate (-1) for the cell; computes parametric coordinates, sub-cell
359+
* ID (if applicable), squared distance to the cell (and closest point if
360+
* requested), and interpolation weights for the cell.
361+
*
362+
* @param {Vector3} x The x point coordinate.
363+
* @param {Vector3} closestPoint The closest point coordinate.
364+
* @param {Vector3} pcoords The parametric coordinates.
365+
* @param {Number[]} weights The number of weights.
366+
*/
341367
publicAPI.evaluatePosition = (x, closestPoint, pcoords, weights) => {
342368
// will return obj
343369
const outObj = { subId: 0, dist2: 0, evaluation: -1 };
@@ -526,6 +552,13 @@ function vtkTriangle(publicAPI, model) {
526552
return outObj;
527553
};
528554

555+
/**
556+
* Determine global coordinates (x) from the given subId and parametric
557+
* coordinates.
558+
* @param {Vector3} pcoords The parametric coordinates.
559+
* @param {Vector3} x The x point coordinate.
560+
* @param {Number[]} weights The number of weights.
561+
*/
529562
publicAPI.evaluateLocation = (pcoords, x, weights) => {
530563
const p0 = [];
531564
const p1 = [];
@@ -544,6 +577,10 @@ function vtkTriangle(publicAPI, model) {
544577
weights[2] = pcoords[1];
545578
};
546579

580+
/**
581+
* Get the distance of the parametric coordinate provided to the cell.
582+
* @param {Vector3} pcoords The parametric coordinates.
583+
*/
547584
publicAPI.getParametricDistance = (pcoords) => {
548585
let pDist;
549586
let pDistMax = 0.0;
@@ -567,6 +604,119 @@ function vtkTriangle(publicAPI, model) {
567604
}
568605
return pDistMax;
569606
};
607+
608+
/**
609+
* Get the derivatives of the triangle strip.
610+
* @param {Number} subId - The sub-id of the triangle.
611+
* @param {Vector3} pcoords - The parametric coordinates.
612+
* @param {Number[]} values - The values at the points.
613+
* @param {Number} dim - The dimension.
614+
* @param {Number[]} derivs - The derivatives.
615+
*/
616+
publicAPI.derivatives = (subId, pcoords, values, dim, derivs) => {
617+
const x0 = [];
618+
const x1 = [];
619+
const x2 = [];
620+
model.points.getPoint(0, x0);
621+
model.points.getPoint(1, x1);
622+
model.points.getPoint(2, x2);
623+
624+
const n = [];
625+
const v10 = [];
626+
const v20 = [];
627+
const v = [];
628+
computeNormal(x0, x1, x2, n);
629+
630+
for (let i = 0; i < 3; i++) {
631+
v10[i] = x1[i] - x0[i];
632+
v[i] = x2[i] - x0[i];
633+
}
634+
635+
vtkMath.cross(n, v10, v20);
636+
637+
const lenX = vtkMath.normalize(v10); // check for degenerate triangle
638+
639+
if (lenX <= 0.0 || vtkMath.normalize(v20) <= 0.0) {
640+
// degenerate
641+
for (let j = 0; j < dim; j++) {
642+
for (let i = 0; i < 3; i++) {
643+
derivs[j * dim + i] = 0.0;
644+
}
645+
}
646+
return;
647+
}
648+
649+
// 2D coordinates
650+
const v0 = [0, 0];
651+
const v1 = [lenX, 0];
652+
const v2 = [vtkMath.dot(v, v10), vtkMath.dot(v, v20)];
653+
654+
const functionDerivs = new Array(6);
655+
interpolationDerivs(functionDerivs);
656+
657+
// Compute Jacobian: Jacobian is constant for a triangle.
658+
const J = [v1[0] - v0[0], v1[1] - v0[1], v2[0] - v0[0], v2[1] - v0[1]];
659+
660+
// Compute inverse Jacobian (expects flat array)
661+
const JI = new Array(4).fill(0.0);
662+
vtkMath.invertMatrix(J, JI, 2); // returns flat array [JI00, JI01, JI10, JI11]
663+
664+
// Compute derivatives
665+
for (let j = 0; j < dim; j++) {
666+
let sum0 = 0.0;
667+
let sum1 = 0.0;
668+
for (let i = 0; i < 3; i++) {
669+
sum0 += functionDerivs[i] * values[dim * i + j];
670+
sum1 += functionDerivs[3 + i] * values[dim * i + j];
671+
}
672+
const dBydx = sum0 * JI[0] + sum1 * JI[1];
673+
const dBydy = sum0 * JI[2] + sum1 * JI[3];
674+
675+
// Transform into global system (dot product with global axes)
676+
derivs[3 * j] = dBydx * v10[0] + dBydy * v20[0];
677+
derivs[3 * j + 1] = dBydx * v10[1] + dBydy * v20[1];
678+
derivs[3 * j + 2] = dBydx * v10[2] + dBydy * v20[2];
679+
}
680+
};
681+
682+
/**
683+
* Get the nearest cell boundary to the specified parametric
684+
* coordinates and whether the point is inside or outside the cell.
685+
* @param {Number} subId The sub-id of the cell.
686+
* @param {Vector3} pcoords The parametric coordinates.
687+
* @param {Vector2} pts The points of the cell.
688+
*/
689+
publicAPI.cellBoundary = (subId, pcoords, pts) => {
690+
const t1 = pcoords[0] - pcoords[1];
691+
const t2 = 0.5 * (1.0 - pcoords[0]) - pcoords[1];
692+
const t3 = 2.0 * pcoords[0] + pcoords[1] - 1.0;
693+
694+
// compare against three lines in parametric space that divide element
695+
// into three pieces
696+
if (t1 >= 0.0 && t2 >= 0.0) {
697+
pts[0] = model.pointsIds[0];
698+
pts[1] = model.pointsIds[1];
699+
} else if (t2 < 0.0 && t3 >= 0.0) {
700+
pts[0] = model.pointsIds[1];
701+
pts[1] = model.pointsIds[2];
702+
} // ( t1 < 0.0 && t3 < 0.0 )
703+
else {
704+
pts[0] = model.pointsIds[2];
705+
pts[1] = model.pointsIds[0];
706+
}
707+
708+
if (
709+
pcoords[0] < 0.0 ||
710+
pcoords[1] < 0.0 ||
711+
pcoords[0] > 1.0 ||
712+
pcoords[1] > 1.0 ||
713+
1.0 - pcoords[0] - pcoords[1] < 0.0
714+
) {
715+
return false; // outside of triangle
716+
}
717+
718+
return true; // inside triangle
719+
};
570720
}
571721

572722
// ----------------------------------------------------------------------------

0 commit comments

Comments
 (0)