Skip to content
This repository has been archived by the owner on Mar 20, 2023. It is now read-only.

Commit

Permalink
Fix caps on closed cylinders
Browse files Browse the repository at this point in the history
The caps were missing because the files do not provide thickness for
closed general cylinders. The thickness is the same as the radius in
this case. In addition, there is only one radius provided, but we
expected two.
  • Loading branch information
dragly committed Sep 24, 2019
1 parent c76eea7 commit 865ebc0
Showing 1 changed file with 70 additions and 55 deletions.
125 changes: 70 additions & 55 deletions src/parsers/i3d/unpackGeometry/Cylinder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,71 +162,83 @@ export function addOpenGeneralCylinder(
);
}

export function addClosedGeneralCylinder(
function addCap(
groups: { [name: string]: PrimitiveGroup },
data: PropertyLoader,
isA: boolean,
thickness: number,
filterOptions?: FilterOptions
) {
addOpenGeneralCylinder(groups, data, filterOptions);

[true, false].forEach(isA => {
const center = isA ? globalCenterA : globalCenterB;
const slope = isA ? data.slopeA : data.slopeB;
const zAngle = isA ? data.zAngleA : data.zAngleB;
const radius = isA ? data.radiusA : data.radiusB;
const center = isA ? globalCenterA : globalCenterB;
const slope = isA ? data.slopeA : data.slopeB;
const zAngle = isA ? data.zAngleA : data.zAngleB;

globalRotation.setFromUnitVectors(zAxis, data.normal);
globalSlicingPlaneNormal
.copy(zAxis)
.applyAxisAngle(yAxis, slope)
.applyAxisAngle(zAxis, zAngle)
.applyQuaternion(globalRotation);
globalRotation.setFromUnitVectors(zAxis, data.normal);
globalSlicingPlaneNormal
.copy(zAxis)
.applyAxisAngle(yAxis, slope)
.applyAxisAngle(zAxis, zAngle)
.applyQuaternion(globalRotation);

const plane = globalPlanes[Number(Boolean(isA))];
plane.setFromNormalAndCoplanarPoint(globalSlicingPlaneNormal, center);
const plane = globalPlanes[Number(Boolean(isA))];
plane.setFromNormalAndCoplanarPoint(globalSlicingPlaneNormal, center);

const capXAxis = xAxis
.clone()
.applyAxisAngle(yAxis, slope)
.applyAxisAngle(zAxis, zAngle)
.applyQuaternion(globalRotation)
.normalize();
const capXAxis = xAxis
.clone()
.applyAxisAngle(yAxis, slope)
.applyAxisAngle(zAxis, zAngle)
.applyQuaternion(globalRotation)
.normalize();

globalVertex
.set(Math.cos(data.rotationAngle), Math.sin(data.rotationAngle), 0)
.applyQuaternion(globalRotation)
.normalize();
globalVertex
.set(Math.cos(data.rotationAngle), Math.sin(data.rotationAngle), 0)
.applyQuaternion(globalRotation)
.normalize();

globalLineStart
.copy(globalVertex)
.multiplyScalar(data.radiusA)
.add(globalExtB)
.sub(data.normal);
globalLineEnd
.copy(globalVertex)
.multiplyScalar(data.radiusA)
.add(globalExtA)
.add(data.normal);
globalLine.set(globalLineStart, globalLineEnd);
plane.intersectLine(globalLine, globalVertex);
globalLineStart
.copy(globalVertex)
.multiplyScalar(data.radiusA)
.add(globalExtB)
.sub(data.normal);
globalLineEnd
.copy(globalVertex)
.multiplyScalar(data.radiusA)
.add(globalExtA)
.add(data.normal);
globalLine.set(globalLineStart, globalLineEnd);
plane.intersectLine(globalLine, globalVertex);

const capAngleAxis = globalVertex.sub(center).normalize();
const capAngle = angleBetweenVector3s(capAngleAxis, capXAxis, globalSlicingPlaneNormal);
const capAngleAxis = globalVertex.sub(center).normalize();
const capAngle = angleBetweenVector3s(capAngleAxis, capXAxis, globalSlicingPlaneNormal);

(groups.GeneralRing as GeneralRingGroup).add(
data.nodeId,
data.treeIndex,
data.size,
center,
globalSlicingPlaneNormal,
capXAxis,
radius / Math.abs(Math.cos(slope)),
radius,
data.thickness,
capAngle,
data.arcAngle,
filterOptions
);
(groups.GeneralRing as GeneralRingGroup).add(
data.nodeId,
data.treeIndex,
data.size,
center,
globalSlicingPlaneNormal,
capXAxis,
data.radiusA / Math.abs(Math.cos(slope)),
data.radiusA,
thickness,
capAngle,
data.arcAngle,
filterOptions
);
}
export function addClosedGeneralCylinder(
groups: { [name: string]: PrimitiveGroup },
data: PropertyLoader,
filterOptions?: FilterOptions
) {
// TODO do not assume that the global objects are set by calling the function for open general
// cylinder - instead, everything should be set in here
addOpenGeneralCylinder(groups, data, filterOptions);
// NOTE: the thickness of the closed general cylinder is not given from the file since it is
// always the radius of the cylinder
const thickness = data.radiusA;
[true, false].forEach(isA => {
addCap(groups, data, isA, thickness, filterOptions);
});
}

Expand All @@ -235,7 +247,10 @@ export function addSolidOpenGeneralCylinder(
data: PropertyLoader,
filterOptions?: FilterOptions
) {
addClosedGeneralCylinder(groups, data, filterOptions);
addOpenGeneralCylinder(groups, data, filterOptions);
[true, false].forEach(isA => {
addCap(groups, data, isA, data.thickness, filterOptions);
});
const distFromBToExtB = data.radiusA * Math.tan(data.slopeB);
const heightA = distFromBToExtB + data.height;
const heightB = distFromBToExtB;
Expand Down

0 comments on commit 865ebc0

Please sign in to comment.