Autodesk Forge is now Autodesk Platform Services

25 Apr 2022

Parsing Line Points in Viewer

Line Points in DWG

 

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);

 

Related Article