• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Extracting data from 3D annotation

Community Beginner ,
May 11, 2019 May 11, 2019

Copy link to clipboard

Copied

Hello , Im using c++ sdk , I've created function to create the 3d annotation with embedded data ( my embedded data is GLTF file 😞

ASBool EmbedDataTo3dAnnot(PDPage pdPage,

  PDAnnot theAnnot, // 3D annot

  ASPathName GLTFPathName, // ASPathName to the U3D file

  ASPathName* asPosterPathName, // ASPathName to the poster file

  const char* strJsFileName) // Path to the JavaScript file

{

    CosObj cosAnnot = PDAnnotGetCosObj(theAnnot);

    CosDoc cosDoc = CosObjGetDoc(cosAnnot);

  ASPathName jsPathName = NULL;

  ASBool bRet = true;

DURING

    // *** Create the required 3D stream dictionary     

  // Open data file

  ASFile asGLTFFile = NULL;

  ASInt32 iRet = ASFileSysOpenFile(ASGetDefaultUnicodeFileSys(), GLTFPathName, ASFILE_READ, &asGLTFFile);

  if ((iRet != 0) || (asGLTFFile == NULL)) {

  AVAlertNote("error opening 3D data file.");

  E_RETURN (false);

  }

  // Read data stream from the file

  ASStm fileStm = ASFileStmRdOpen(asGLTFFile, 0);

  if(fileStm == NULL){

  AVAlertNote("empty 3D data stream.");

  E_RETURN (false);

  }

  // Set the stream's entries

  CosObj attrObj = CosNewDict(cosDoc, false, 1);

    CosDictPutKeyString(attrObj, "Subtype", CosNewName(cosDoc, false, ASAtomFromString("GLTF")));

    CosDictPutKeyString(attrObj, "Type", CosNewNameFromString(cosDoc, false, "3D"));

  CosDictPutKeyString(attrObj, "Filter", CosNewNameFromString(cosDoc, false, "FlateDecode"));

  PDDoc pdDoc = PDPageGetDoc(pdPage);

  // Create the optional "VA" entry

  CosObj cosArray = CosNewArray(cosDoc, true, 0);

  if(CosObjGetType(cosArray) == CosArray) {

  CosDictPutKeyString(attrObj, "VA", cosArray);

  ASUns32 i = 0;

  for(ASUns32 iCounter = 0; iCounter < NUM_VIEWS; iCounter++) {

  CosObj cosOneView = BuildOneView(pdDoc, cosAnnot, VIEW_NAMES[iCounter]);

  if(CosObjGetType(cosOneView) == CosDict) {

  CosArrayPut(cosArray, i, cosOneView);

  i++;

  }

  }

  }

  // Create a new 3D stream and set it under 3DD key in the annot dictionary

    CosObj stm3D = CosNewStream(cosDoc, true, fileStm, 0, true, attrObj, CosNewNull(), -1);

   CosDictPutKeyString(cosAnnot, "3DD", stm3D);

    ASStmClose(fileStm);

  ASFileClose(asGLTFFile);

  // Embed optional JavaScript code in the 3D stream

  // Open JavaScript file

#ifdef WIN_PLATFORM

  const char* strPathFlag = "Cstring";

#else

  const char* strPathFlag = "POSIXPath";

#endif

  jsPathName = ASFileSysCreatePathName (ASGetDefaultFileSys(),

  ASAtomFromString(strPathFlag), strJsFileName, 0);

  ASFile asJsFile = NULL;

  iRet = ASFileSysOpenFile(ASGetDefaultFileSys(), jsPathName, ASFILE_READ, &asJsFile);

  ASFileSysReleasePath (ASGetDefaultFileSys(), jsPathName);

  if ((iRet == 0) && (asJsFile != NULL)) {

  // Read js code  from the js file and set it in the 3D stream 

  ASStm jsFileStm = ASFileStmRdOpen(asJsFile, 0);

  if (jsFileStm != NULL) {

  CosObj cosJs = CosNewDict(cosDoc, false, 1);

  CosDictPutKeyString(cosJs, "Filter", CosNewNameFromString(cosDoc, false, "FlateDecode"));

  CosObj stm3dJsCode = CosNewStream(cosDoc, true, jsFileStm, 0, true, cosJs, CosNewNull(), -1);

  CosDictPutKeyString(attrObj, "OnInstantiate", stm3dJsCode);

  }

      ASStmClose(jsFileStm);

  ASFileClose(asJsFile);

  }

  // Set the optional animation style dictionary in the 3D stream

  CosObj animationDict = CosNewDict(cosDoc, false, 1);

  if(CosObjGetType(animationDict) == CosDict) {

  CosDictPutKeyString(attrObj, "AN", animationDict);

  CosDictPutKeyString(animationDict, "Type",

  CosNewName(cosDoc, false, ASAtomFromString("3DAnimationStyle")));

  CosDictPutKeyString(animationDict, "Subtype",

  CosNewName(cosDoc, false, ASAtomFromString("Linear")));

  CosDictPutKeyString(animationDict, "PC", CosNewInteger(cosDoc, false, -1));

  CosDictPutKeyString(animationDict, "TM", CosNewInteger(cosDoc, false, 1));

  }

  // Set the optional indirect reference to the page object in the annot dictionary

    CosDictPutKeyString(cosAnnot, "P", PDPageGetCosObj(pdPage));

  // Set the optional "Contents" entry in the annot dictionary

  CosDictPutKeyString(cosAnnot, "Contents", CosNewString(cosDoc, false, "3D Model", strlen("3D Model")));

  // Create a poster for the 3D annotation

  CosObj formXObj = BuildFormXObj(asPosterPathName, pdDoc);

  if (!CosObjEqual(formXObj, CosNewNull())){

  // Build the required "AP" entry for the 3D annotation

  CosObj apprDict = CosNewDict(cosDoc, false, 1);

  CosDictPutKeyString(apprDict, "N", formXObj);

  CosDictPutKeyString(cosAnnot, "AP", apprDict);

  }

  // *** Set the optional default initial view of the 3D artwork

  // You are supposed to parse the U3D model file and retrieve the format spec

  // such as transformation matrix for the view. Then construct the "MS", "CO", "C2W"

  // (if value for "MS" is "M"), etc. entries.

    // *** Set the optional activation dictionary

  CosObj activationDict = CosNewDict(cosDoc, false, 1);

    if(CosObjGetType(activationDict) == CosDict) {

  CosDictPutKeyString(cosAnnot, "3DA", activationDict);

        CosDictPutKeyString(activationDict, "DIS", CosNewName(cosDoc, false, ASAtomFromString("I")));

  // Set the optional activation choice

  CosDictPutKeyString(activationDict, "A", CosNewName(cosDoc, false, ASAtomFromString("PO")));

   }

HANDLER

  DisplayExceptionMsg();

  bRet = false;

END_HANDLER

  return bRet;

}

And also I have a function to create pdf with 3d annotation

How can i extract the GlTF file from my annotation and save it as a temp file ?

TOPICS
Acrobat SDK and JavaScript

Views

1.6K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
May 11, 2019 May 11, 2019

Copy link to clipboard

Copied

Since you have a detailed knowledge of the PDF structures, I'm not sure what advice to give. You find the annotation, fetch the relevant Cos object, and write the file. What obstacle do you face?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
May 11, 2019 May 11, 2019

Copy link to clipboard

Copied

I'm new to sdk,im only learning, sorry for the poorly posed question , but can you explain more deeply please ? This fucnction is from acrobat samples ( embbeded u3d) , i know how to get annotation from the page, but how i can get relevat cos obj ( is it dictionary or strem ? ) an how to write file from the given  cosobject

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
May 11, 2019 May 11, 2019

Copy link to clipboard

Copied

You said you that you have a function to make a 3d Annot with your embedded data. Since you already have this code, it is a simple matter to look through the code for the bit where the data is embedded. This will tell you all you need to know about extracting the data.

If you are going to be mucking about with the PDF COS structure, you'll need this tool, which manipulates COS structure, so you can see what's going on and prototype the structures you'll be working with.

Windjack Solutions, Inc. - PDf CanOpener

Thom Parker - Software Developer at PDFScripting
Use the Acrobat JavaScript Reference early and often

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
May 11, 2019 May 11, 2019

Copy link to clipboard

Copied

I think, that we embedded data here

  // Create a new 3D stream and set it under 3DD key in the annot dictionary

    CosObj stm3D = CosNewStream(cosDoc, true, fileStm, 0, true, attrObj, CosNewNull(), -1);

   CosDictPutKeyString(cosAnnot, "3DD", stm3D);

    ASStmClose(fileStm);

  ASFileClose(asGLTFFile);

As i think at first we can get PDAnnot from the current page with the help of  PDPageGetannotation, and the we can get Cos object ( PDAnnotGetCosObj) , but after this i still have no idea how to write new temp file from cos object , can you write corresponding methods to get my aim done , please ?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
May 14, 2019 May 14, 2019

Copy link to clipboard

Copied

Should i find 3dd cos object ?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
May 11, 2019 May 11, 2019

Copy link to clipboard

Copied

Have you studied the PDF specification in detail? You cannot proceed without detailed knowledge of the structure of your objects. You can enumerate PDAnnots to find it, and write using ASStm methods or platform file writing.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
May 11, 2019 May 11, 2019

Copy link to clipboard

Copied

Im new to pdf techs, im trying as hard as i can , but i need to complete my work as fast as i can , and only the thing left is this part wit hthe new file , can you write corresponding methods if its possible , please ?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
May 11, 2019 May 11, 2019

Copy link to clipboard

Copied

To read the data in a stream the key method is CosStreamGetStm.

You can write the data to a file with any method for writing files, or using the ASFile API. You already have the code for reading files. Have you read the detailed description of every method used in your sample code you are working with? (If it was up to me, I would ban sample code).

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
May 12, 2019 May 12, 2019

Copy link to clipboard

Copied

I've read the methods in sample , I came to this , thanks to your help. And now as I think , I need to youse ASStmRead method , but how I can get ASTArraySize and ASTCount , if I really need to use ASStmRead method

for (i2 = 0; i2 < PDPageGetNumAnnots(page); i2++)

                {

                    //Get a specific annotation

                    annot = PDPageGetAnnot(page,i2);

                //Checking annotation

                    if(!PDAnnotIsValid(annot))

                     {

                         sprintf(buf2, "No valid annotations");

                        AVAlertNote(buf1);

                     }

                    //open annotation

                    else

                    {

                        ASFile asGLTFFile = NULL;

                        CosObj stm = PDAnnotGetCosObj(annot);

                        ASStm a = CosStreamOpenStm(stm,0);

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
May 12, 2019 May 12, 2019

Copy link to clipboard

Copied

ASStmRead is very like the C "read" method. The two sizes are multiplied together to give a number of bytes. I always set itemSize to 1, so that the nItems value is the number of bytes in your buffer. Usefully, in this case, the return value is the number of bytes actually read.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
May 12, 2019 May 12, 2019

Copy link to clipboard

Copied

Okay , Now I get number of items read from stm into memory , but how I need to write this into file ?

char* ptr1 = NULL;

                        ASFile asGLTFFile = NULL;

                        CosObj stm = PDAnnotGetCosObj(annot);

                        ASStm streamopen = CosStreamOpenStm(stm,0);

                        ASTCount streamlength = CosStreamPos(stm);

                        ASTCount a = ASStmRead(ptr1,1,streamlength,streamopen);

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
May 12, 2019 May 12, 2019

Copy link to clipboard

Copied

How can I get the number of bytes to write the file ?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Employee ,
May 12, 2019 May 12, 2019

Copy link to clipboard

Copied

Return value from Read is number of bytes read. This is well described in the documentation.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
May 15, 2019 May 15, 2019

Copy link to clipboard

Copied

Maybe you should. What specific problem do you face? Please be detailed so we can help you find the information you need in the documentation.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
May 27, 2019 May 27, 2019

Copy link to clipboard

Copied

Hello , again , I have the problem with opening the file , Now I have the code , that's  searching the annotation on the current page , and writing  data from it to the memory , and then to the temp file , but i have the problem with this file : adobe write files to the annotation dict in compressed format , and after extracting the file from annotation , I also have compressed file , that I can't open.

char* ptr1 = new char[1900000];

                        ASFile asGLTFFile = NULL;

                        CosObj stm = PDAnnotGetCosObj(annot);

                        if(CosObjGetType(stm) != 6)

                        {

                            AVAlertNote("Error in getting Cos from annotation");

                        }

                        CosObj stm3d = CosDictGetKeyString(stm,"3DD");

                        if((CosObjGetType(stm3d)!= 8))

                        {

                            AVAlertNote("Error in getting 3DD Key");

                        }

                        ASStm streamopen = CosStreamOpenStm(stm3d,cosOpenRaw);

                        //ASTCount streamlength = CosStreamPos(stm3d);

                        ASTArraySize lenghth = CosStreamLength(stm3d);

                        ASTCount a = ASStmRead(ptr1,1,lenghth,streamopen);

                       

#if WIN_PLATFORM

                        const char* GLTFStringName = "C:\\setDefaultCamera.gltf";

#else

                        const char* GLTFStringName = "/Users/Shared/file1.gltf";

#endif

                        BuildFile(GLTFStringName);

                   

#ifdef    WIN_PLATFORM

                        const char* strPathFlag = "Cstring";

#else

                        const char* strPathFlag = "POSIXPath";

#endif

                       

                        ASPathName GLTFPathName = ASFileSysCreatePathName (ASGetDefaultFileSys(),

                                                              ASAtomFromString(strPathFlag), GLTFStringName, 0);

                        ASInt32 BRet = ASFileSysOpenFile(ASGetDefaultFileSys(), GLTFPathName, ASFILE_WRITE, &asGLTFFile);

                        if ((BRet != 0) || (asGLTFFile == NULL)) {

                            AVAlertNote("error opening 3D data file.");

                        }

                       

                        ASFileSysReleasePath (ASGetDefaultFileSys(), GLTFPathName);

                       

                        if ((BRet == 0) && (asGLTFFile != NULL))

                        {

                           

                            //Cast the ASAtom object to a character pointer

                           

                            ASTArraySize Bret = ASFileWrite(asGLTFFile,ptr1,lenghth);

                           

                            if(Bret!=0)

                            {

                                ASStmClose(streamopen);

                                ASFileClose(asGLTFFile);

                               

                            }

                            else

                            {

                                AVAlertNote("Error in writting");

                            }

                           

                        }

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
May 27, 2019 May 27, 2019

Copy link to clipboard

Copied

Look at the options for CosStreamOpenStm.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
May 27, 2019 May 27, 2019

Copy link to clipboard

Copied

I actually did , i've tried cosOpenUnfiltered, cosOpenRaw, cosOpenUnfiltered, and it didnt help

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
May 27, 2019 May 27, 2019

Copy link to clipboard

Copied

Unfiltered (from memory) is what you need. That is what is actually in the PDF in terms of the data. How are you testing the U3D data?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
May 27, 2019 May 27, 2019

Copy link to clipboard

Copied

Actually it helped , but now I can extract all my file in temp file ( not in compressed format ) only immediately after creating this file , I can't do this after I already saved my file with annotation as pdf , it extracts file from pdf with my annotation which already exists in compressed format.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
May 27, 2019 May 27, 2019

Copy link to clipboard

Copied

LATEST

And it helped (Now i  can open file  exactly before saving pdf file with annotation ) after I removed this from stream entries in my annotation

  CosDictPutKeyString(attrObj, "Filter", CosNewNameFromString(cosDoc, false, "FlateDecode"));

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines