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