Close

Relief for ODA Team in Ukraine

Learn more
ODA PRC SDK
Extract 3D Data from PDF

To extract PRC and U3D streams from a PDF document, use the OdPdf3DStreamExtractor class from the OdPdf3DStreamExtractor.tx module.

The general routine of extraction is represented below.

  1. Load the module that contains the extraction functionality:
              
    OdPdf3DStreamExtractorModulePtr pModule = ::odrxDynamicLinker()->loadModule(OdPdf3DStreamExtractorModuleName, false);
              
            
  2. Create an extractor object (an instance of the OdPdf3DStreamExtractor class):
              
    OdPdf3DStreamExtractorPtr OdPdf3DStreamExtractor = pModule->create();
              
            
  3. Open a PDF document to extract the 3D stream data from:
              
    OdString pdfFile("document.pdf"), pdfPassword("");
    OdPdf3DStreamExtractor::ExtractResult result = OdPdf3DStreamExtractor->openPdfDocument(pdfFile, pdfPassword);
              
            
  4. Check the result of opening the document:
              
    if (OdPdf3DStreamExtractor::success == result)
    {
      // add needed actions in this block
    }
              
            
  5. Add the needed actions in the if block from the previous step. You can:
    • Request the number of pages.
    • Request the number of 3D streams within a page.
    • Request the types of streams (PRC or 3D).
    • Request the stream names.
    • Extract 3D data from the streams.

    The code fragment below shows how to iterate through pages of an opened document, find the first PRC 3D stream data, and extract it into the OdStreamBuf object:

              
    if (OdPdf3DStreamExtractor::success == result)
    {
      OdString prcOutputFile;
      OdUInt32 pageCount = OdPdf3DStreamExtractor->getPageCount(result);
      OdUInt32 streamCount = 0;
      OdString streamName;
      OdStreamBufPtr ptrStreamPrc;
      bool isStreamFound = false;
      
      //iterate through the PDF document pages
      for (OdUInt32 pageIdx = 0; pageIdx < pageCount; ++pageIdx)
      {
        streamCount = OdPdf3DStreamExtractor->getCount3DStreamForPage(pageIdx, result);
        
        //iterate through the 3D streams within the page
        for (OdUInt32 streamIdx = 0; streamIdx < streamCount; ++streamIdx)
        {
          //check the stream type
          if (OdPdf3DStreamExtractor->Get3DStreamType(pageIdx, streamIdx, result) == OdPdf3DStreamExtractor::StreamType::ePRC)
          {
            streamName = OdPdf3DStreamExtractor->Get3DStreamName(pageIdx, streamIdx, result);
            odPrintConsoleString(L"\nPRC stream found! page number: %d stream number: %d stream name: %ls", pageIdx, streamIdx, streamName);
            
            prcOutputFile = OdString("stream_") + streamName + OdString(".prc");
            
            //create a stream buffer object associated with the output .prc file.
            ptrStreamPrc = odSystemServices()->createFile(prcOutputFileFile, Oda::kFileWrite, Oda::kShareDenyNo, Oda::kCreateAlways);
                                 
            //extraction of the stream data into a PRC file
            result = OdPdf3DStreamExtractor->fill3DStream(pageIdx, streamIdx, ptrStreamPrc);
            
            if (OdPdf3DStreamExtractor::ExtractResult::success == result)
            {
              isStreamFound = true;
              break;
            }
          }
        }
        
        if (isStreamFound)
          break;
      }
    }
              
            

You can also use the functionality of the OdPdf3DStreamExtractor class to convert U3D data to the PRC format:


OdStreamBufPtr stream = OdMemoryStream::createNew();
OdPdf3DStreamExtractor->fill3DStream(pageIdx, streamIdx, stream);
stream->rewind();

OdPrcFilePtr pDb = pHostApp->createDatabase();
pDb->setVersions(8137, 8137);
pDb->fileStructureId() = OdPrcUniqueId::generateUID();

OdPdf3DStreamExtractor::StreamType stream_type = OdPdf3DStreamExtractor->Get3DStreamType(pageIdx, streamIdx, result);
if (OdPdf3DStreamExtractor::eU3D == stream_type)
{
  //U3D stream
  OdU3D2PrcImportModulePtr pModule = ::odrxDynamicLinker()->loadModule(OdU3D2PrcImportModuleName, false);

  OdU3D2PrcImportPtr importer = pModule->create();
  if(!importer.isNull());
  {
    importer->properties()->putAt(L"Database", pDb);
    importer->properties()->putAt(L"SourceType", OdRxVariantValue((OdUInt8)1));
    importer->properties()->putAt(L"InputStream", stream);

    importer->import();
  }
}
else
{
  // PRC stream
  pDb->readFile(stream);
}
    

The OdaPrcApp example application also contains a feature for 3D data stream extraction; to use it, choose File > Extract 3D stream.