Close

Relief for ODA Team in Ukraine

Learn more
ODA Drawings SDK
Reading Point Cloud Data from .rcs Files

The RCS format (Reality Capture Scan), one of the most popular formats for point cloud processing, is the basic format for point cloud attachments in .dwg files. Drawings SDK provides access to the RCS format using a special service. This topic describes how you can use the ODA service to load data from the RCS format.

Reading the .rsc file header

For reading point cloud data from .rcs files, the Kernel SDK provides the RcsFileServices.tx extension module. As any ODA module, RcsFileServices can be loaded using the loadApp() method:

pRcsFileServices = odrxDynamicLinker()->loadApp(RX_RCS_FILE_SERVICES);

The module contains the getRcsFileReader() method that performs reading point cloud data from an .rcs file:

OdRcsFileReaderPtr getRcsFileReader(const OdString& filePath) const = 0;

The method takes as an argument a name of the .rcs file to read and returns a smart pointer to an object of the OdRcsFileReader class, which contains the data read from the header of the .rcs file.

Once the data is read to an OdRcsFileReader object, you get access to the information contained in the source file using the following OdRcsFileReader class methods:

  • virtual OdRcsVoxelDataIteratorPtr newVoxelDataIterator() const = 0; - Returns the pointer to the voxel data iterator.
  • virtual OdGeVector3d getTranslation() const = 0; - Returns the translation vector.
  • virtual OdGeVector3d getRotation() const = 0; - Returns the rotation vector. Vector coordinates are rotation angles around a corresponding axis.
  • virtual OdGeVector3d getScale() const = 0; - Returns the scale vector.
  • virtual OdGeMatrix3d getTransformMatrix() const = 0; - Returns the complete transformation matrix.
  • virtual bool hasRGB() const = 0; - Returns the hasRGB flag.
  • virtual bool hasNormals() const = 0; - Returns the hasNormals flag.
  • virtual bool hasIntensity() const = 0; - Returns the hasIntensity flag.
  • virtual OdString getScanIdString() const = 0; - Returns the scan ID string.

Reading Points from Voxels

Once the header of the .rcs file is read, you get the array of voxels: volume elements, each of which contains one or more points of the cloud.

Voxels are represented by the OdRcsVoxel class.

You can iterate through all voxels from the voxels array using an OdRcsVoxelDataIterator object, which can be created using the OdRcsFileReader::newVoxelDataIterator() method:

virtual OdRcsVoxelDataIteratorPtr newVoxelDataIterator() const = 0;

For example, to go through all voxel objects from the point cloud:

OdRcsVoxelDataIteratorPtr pVoxelDataIterator = pRcsFileReader->newVoxelDataIterator();
while (!pVoxelDataIterator->done())
{    
  OdRcsVoxelPtr pRcsVoxelCurrent = pVoxelDataIterator->getVoxel();
  ...
}

The OdRcsVoxel class provides the following methods:

  • virtual OdRcsPointDataIteratorPtr newPointDataIterator() const = 0; - Creates an OdRcsPointDataIterator object to iterate through the points contained in this voxel.
  • virtual OdGeExtents3d getBox1() const = 0; - Gets the extents of the voxel.

Point data is represented by their 3D-coordinates and RGB color values and can be read from a voxel object using the OdRcsPointDataIterator::getPoints() method:

virtual OdUInt64 getPoints(OdGePoint3dArray& points, OdCmEntityColorArray& colorArray, OdUInt64 requiredQty) = 0;

The method takes the number of points to obtain and fills the specified arrays with point coordinates and colors. Specifying the requiredQty parameter allows you to save memory when processing a large point cloud, for example, when converting to another format. The returned value is an actual number of obtained points.

Note that the getPoints() method returns point coordinates relative to the minimum point (the lower left front point) of the voxel cell.

To get the global coordinates for a point within a cloud, add the coordinates of the minimum point to the point coordinates obtained by the getPoints() method.

The following routine reads point cloud data from an .rcs file and gets points from every voxel (by 2000 points per iteration):

OdRxRcsFileServicesPtr pRcsFileServices;
pRcsFileServices = odrxDynamicLinker()->loadApp(RX_RCS_FILE_SERVICES);

OdRcsFileReaderPtr pRcsFileReader;
try
{
  pRcsFileReader = pRcsFileServices->getRcsFileReader(filename);
}
catch (OdError_CantOpenFile& e)
{
  return eCantOpenFile;
}

OdRcsVoxelDataIteratorPtr pVoxelDataIterator = pRcsFileReader->newVoxelDataIterator();
while (!pVoxelDataIterator->done())
{    
  OdRcsVoxelPtr pRcsVoxelCurrent = pVoxelDataIterator->getVoxel();
  OdGeExtents3d voxelExtents = pRcsVoxelCurrent->getBox1();
  OdGePoint3d voxelExtentsMinPoint = voxelExtents.minPoint();
  OdRcsPointDataIteratorPtr pPointDataIterator = pRcsVoxelCurrent->newPointDataIterator();
  while (!pPointDataIterator->done())
  {
    OdGePoint3dArray pointArray;
    OdCmEntityColorArray colorArray;
    OdUInt64 pointQty = pPointDataIterator->getPoints(pointArray, colorArray, 2000);
    for (OdUInt64 j = 0; j < pointQty; j++)
    {
      const_cast<OdGeVector3d&>(pointArray[j].asVector()) += voxelExtentsMinPoint.asVector();
    }
  }
}

For more information, see also the ExPointCloudHost sample application.

 

Copyright © 2002 – 2022. Open Design Alliance. All rights reserved.