Posted By

Varun Patil
I'm a full-stack developer, working on Autodesk Platform Services and Autodesk Developer Network.
25 Apr 2022
In Forge Viewer, sometimes we want the information about lines like polyline in AutoCAD in both 2D and a 3D polyline to apply the PageToModelTransform
to transform them back to CAD or use it to recreate duplicate lines etc.. same with a model line from Revit file, etc... parsing those lines is possible, and it's bit different in 2D and 3D, in 2D it's relatively easy as with the following code:
2D:
Its key concept is using the VertexBufferReader
to read vertices of a Forge Viewer 2D model, and get the corresponding transformation matrix to project points of the Viewer back to DWG coordinate system.
function GeometryCallback(viewer) {
this.viewer = viewer;
}
GeometryCallback.prototype.onLineSegment = function(x1, y1, x2, y2, vpId) {
var vpXform = this.viewer.model.getPageToModelTransform(vpId);
var pt1 = new THREE.Vector3().set(x1, y1, 0).applyMatrix4(vpXform);
var pt2 = new THREE.Vector3().set(x2, y2, 0).applyMatrix4(vpXform);
console.log('Line segment vertices in CAD coordinate system', {
pointX1: pt1.x,
pointY1: pt1.y,
pointX2: pt2.x,
pointY2: pt2.y
});
}
GeometryCallback.prototype.onCircularArc = function(cx, cy, start, end, radius, vpId) {
};
GeometryCallback.prototype.onEllipticalArc = function(cx, cy, start, end, major, minor, tilt, vpId) {
};
let it = viewer.model.getData().instanceTree;
it.enumNodeFragments( dbId, function( fragId ) {
let m = viewer.impl.getRenderProxy(viewer.model, fragId);
let vbr = new Autodesk.Viewing.Private.VertexBufferReader(m.geometry, viewer.impl.use2dInstancing);
vbr.enumGeomsForObject(dbId, new GeometryCallback());
});
3D:
In 3D we make use of vertex buffer array and get the points using stride and offset:
const it = viewer.model.getInstanceTree();
it.enumNodeFragments(dbid, function (fragId) {
const geometry = viewer.impl.model.getFragmentList().getGeometry(fragId)
const isLine = geometry.isLines; // verify that this is line geometry
if(!isLine) return;
const vb = geometry.vb; // The vertex buffer
const positions = geometry.attributes.position; // The position attribute
const offset = positions.itemOffset; // The offset of positions in the buffer
const stride = geometry.vbstride; // The stride of elements in the buffer
let LinePoints = {'start':{},'end':{}}
for (let i = 0; i < vb.length/ stride; i += 2) {
LinePoints.start.x = vb[i * stride + offset];
LinePoints.start.y = vb[i * stride + offset + 1];
LinePoints.start.z = vb[i * stride + offset + 2];
LinePoints.end.x = vb[(i + 1) * stride + offset];
LinePoints.end.y = vb[(i + 1) * stride + offset + 1];
LinePoints.end.z = vb[(i + 1) * stride + offset + 2];
}
console.log('LinePoints',LinePoints)
}, true);