Hello,
This might be a newbie question as I’m only getting started. Please excuse me.
My goal is to create a “dimension” line that is made of a line and two cones, one at each end of the line that point at two given points (point A, point B).
I thought of creating the line by using a TubeFilter that takes in a polydata holding the two points, then two vtkConeSource
referring to the arrows.
I’m struggling to orient the cones with the TubeFilter. Here is my progress:
function initializePolyData(pointA, pointB) {
const numSegments = 1;
let pointType = VtkDataTypes.FLOAT;
const polyData = vtkPolyData.newInstance();
const points = vtkPoints.newInstance({ dataType: pointType });
points.setNumberOfPoints(numSegments + 1);
const pointData = new Float32Array([...model.pointA, ...model.pointB]);
const verts = new Uint32Array(2 * (numSegments + 1));
const lines = new Uint32Array(numSegments + 2);
lines[0] = numSegments + 1;
const scalarsData = new Float32Array(numSegments + 1);
const scalars = vtkDataArray.newInstance({
name: "Scalars",
values: scalarsData,
});
for (let i = 0; i < numSegments + 1; ++i) {
scalarsData[i] = i;
verts[i] = 1;
verts[i + 1] = i;
lines[i + 1] = i;
}
points.setData(pointData);
polyData.setPoints(points);
polyData.getVerts().setData(verts);
polyData.getLines().setData(lines);
polyData.getPointData().setScalars(scalars);
return polyData;
}
const polyData = initializePolyData(model.pointA, model.pointB);
// Create line tube
const tube = vtkTubeFilter.newInstance({
capping: false,
numberOfSides: 1,
radius: model.shaftRadius,
});
tube.setInputData(polyData);
// Create cones that will be used as "arrows"
const lowerCone = vtkConeSource.newInstance({
resolution: model.tipResolution,
height: model.tipLength,
radius: model.tipRadius,
});
const upperCone = vtkConeSource.newInstance({
resolution: model.tipResolution,
height: model.tipLength,
radius: model.tipRadius,
});
const tubeDirection = [tubeNormals[0], tubeNormals[1], tubeNormals[2]];
let rotationAxisY = [null, null, null];
vtkMath.cross([0, 1, 0], tubeDirection, rotationAxisY);
const rotationAngle = vtkMath.angleBetweenVectors([0, 1, 0], tubeDirection);
// Extract data to operate on
const tubePD = tube.getOutputData();
const tubePts = tubePD.getPoints();
const tubeNormals = tubePD.getPointData().getNormals().getData();
const upperConePD = upperCone.getOutputData();
const upperConePts = upperConePD.getPoints().getData();
const lowerConePD = lowerCone.getOutputData();
const lowerConePts = lowerConePD.getPoints().getData();
// Apply transformation to the upper cone
vtkMatrixBuilder
.buildFromRadian()
.translate(...model.pointA)
.rotateFromDirections([0, 1, 0], rotationAxisY)
.scale(1, 1, 1)
.apply(upperConePts);
const append = vtkAppendPolyData.newInstance();
append.setInputData(tubePD);
// Upper cone
append.addInputData(upperConePD);
// Lower cone
// append.addInputData(lowerConePD);
Cones are not oriented towards the point