1149 lines
48 KiB
C++
1149 lines
48 KiB
C++
/***********************************************************************************************************************
|
|
*
|
|
* Copyright (c) 2010 - 2022 by Tech Soft 3D, Inc.
|
|
* The information contained herein is confidential and proprietary to Tech Soft 3D, Inc., and considered a trade secret
|
|
* as defined under civil and criminal statutes. Tech Soft 3D shall pursue its civil and criminal remedies in the event
|
|
* of unauthorized use or misappropriation of its trade secrets. Use of this information by anyone other than authorized
|
|
* employees of Tech Soft 3D, Inc. is granted only under a written non-disclosure agreement, expressly prescribing the
|
|
* scope and manner of such use.
|
|
*
|
|
***********************************************************************************************************************/
|
|
/**
|
|
\file DemoDataModel.cpp
|
|
|
|
Demonstrates how to create a table in which the table data is linked to the model data.
|
|
|
|
***********************************************************************************************************************/
|
|
|
|
#define INITIALIZE_A3D_API
|
|
#define HOOPS_PRODUCT_PUBLISH_ADVANCED
|
|
#include <A3DSDKIncludes.h>
|
|
#include "../common.hpp"
|
|
#include "../CommonInit.h"
|
|
|
|
#include <sstream>
|
|
#include <ostream>
|
|
#include <iostream>
|
|
#include <vector>
|
|
|
|
|
|
// default sample arguments:
|
|
// in visual c++: the current directory is set through properties to $OutDir, which is $(Platform)\$(Configuration)
|
|
// in linux: the current directory is supposed to be the same as this cpp file
|
|
#ifdef _MSC_VER
|
|
# define IN_3DFILE_1 SAMPLES_DATA_DIRECTORY"\\prc\\Crank-Instructions.prc"
|
|
# define IN_3DFILE_2 SAMPLES_DATA_DIRECTORY"\\prc\\pmi_Sample.prc"
|
|
# define IN_3DFILE_3 SAMPLES_DATA_DIRECTORY"\\prc\\_micro engine.prc"
|
|
# define PDF_TEMPLATE_1 SAMPLES_DATA_DIRECTORY"\\pdf_templates\\DemoDataModelTemplate.pdf"
|
|
# define PDF_TEMPLATE_2 SAMPLES_DATA_DIRECTORY"\\pdf_templates\\DemoDataModelTemplate-Views.pdf"
|
|
# define PDF_TEMPLATE_3 SAMPLES_DATA_DIRECTORY"\\pdf_templates\\DemoDataModelTemplate-BOM.pdf"
|
|
# define ICONS_PATH SAMPLES_DATA_DIRECTORY"\\images\\"
|
|
# define ICON_CAROUSEL_PREV SAMPLES_DATA_DIRECTORY"\\images\\carouselprevrot.bmp"
|
|
# define ICON_CAROUSEL_NEXT SAMPLES_DATA_DIRECTORY"\\images\\carouselnextrot.bmp"
|
|
# define POSTER_PATH SAMPLES_DATA_DIRECTORY"\\images\\pleaseactivate.bmp"
|
|
# define OUT_FILE SAMPLES_PUBLISH_GALLERY_DIRECTORY"\\sample_DemoDataModel.pdf"
|
|
#else
|
|
# define IN_3DFILE_1 SAMPLES_DATA_DIRECTORY"/prc/Crank-Instructions.prc"
|
|
# define IN_3DFILE_2 SAMPLES_DATA_DIRECTORY"/prc/pmi_Sample.prc"
|
|
# define IN_3DFILE_3 SAMPLES_DATA_DIRECTORY"/prc/_micro engine.prc"
|
|
# define PDF_TEMPLATE_1 SAMPLES_DATA_DIRECTORY"/pdf_templates/DemoDataModelTemplate.pdf"
|
|
# define PDF_TEMPLATE_2 SAMPLES_DATA_DIRECTORY"/pdf_templates/DemoDataModelTemplate-Views.pdf"
|
|
# define PDF_TEMPLATE_3 SAMPLES_DATA_DIRECTORY"/pdf_templates/DemoDataModelTemplate-BOM.pdf"
|
|
# define ICONS_PATH SAMPLES_DATA_DIRECTORY"/images/"
|
|
# define ICON_CAROUSEL_PREV SAMPLES_DATA_DIRECTORY"/images/carouselprevrot.bmp"
|
|
# define ICON_CAROUSEL_NEXT SAMPLES_DATA_DIRECTORY"/images/carouselnextrot.bmp"
|
|
# define POSTER_PATH SAMPLES_DATA_DIRECTORY"/images/pleaseactivate.bmp"
|
|
# define OUT_FILE SAMPLES_PUBLISH_GALLERY_DIRECTORY"/sample_DemoDataModel.pdf"
|
|
#endif
|
|
|
|
const size_t MAXSZFILENAME = 4096;
|
|
|
|
// rgb colors
|
|
#define COL_RED 1.0, 0.0, 0.0
|
|
|
|
A3DVoid mallocAndSetString(const A3DUTF8Char* srcString, A3DUTF8Char*& destString);
|
|
// tools functions
|
|
A3DStatus PageGetTextField(A3DPDFPage* pPage, const std::string& sFieldId, A3DPDFTextField** ppField);
|
|
A3DStatus PageGetButtonField(A3DPDFPage* pPage, const std::string& sFieldId, A3DPDFButton** ppField);
|
|
A3DStatus PageGetListBoxField(A3DPDFPage* pPage, const std::string& sFieldId, A3DPDFListBox** ppField);
|
|
|
|
// fill data functions sample 1
|
|
A3DStatus CreateTable_Sple1_Statics(A3DPDFDocument* pDoc, A3DPDFDataTable*& pDataTable_Statics);
|
|
A3DStatus CreateTable_Sple1_3DModel_Bom(A3DPDFDocument* pDoc, A3DAsmModelFile* pModelFile, A3DRWParamsPrcWriteHelper* pPRCWriteHelper,
|
|
const std::string& sPathIcons,
|
|
int& iKeyNode3dUID, int& iKeyNode3dName, int& iKeyNode3dInstance,
|
|
int& iKeyBomNumArt, int& iKeyBomNamePart, int& iKeyBomQty, int& iKeyBomMaterial, int& iKeyBomIcon,
|
|
A3DPDFDataTable*& pDataTable3D, A3DPDFDataTable*& pDataTableBom,
|
|
A3DPDFDataTable* pDataTableManufacturers);
|
|
A3DStatus CreateTable_Sple1_CBFILTER(A3DPDFDocument* pDoc, A3DPDFDataTable*& pDataTable);
|
|
A3DStatus CreateTable_Sple1_Manufacturers(A3DPDFDocument* pDoc, A3DPDFDataTable*& pDataTable);
|
|
A3DStatus CreateRelationship_Sple1_CBFILTER_To_Bom(A3DPDFDocument* pDoc, A3DPDFDataTable* pDataTable_Source, A3DPDFDataTable* pDataTable_Target);
|
|
// fill data functions sample 2
|
|
A3DStatus CreateTable_Sple2_Statics(A3DPDFDocument* pDoc, A3DPDFDataTable*& pDataTable_Statics);
|
|
A3DStatus CreateTable_Sple2_ViewNames(A3DPDFDocument* pDoc, A3DPDFDataTable*& pDataTable);
|
|
A3DStatus CreateTable_Sple2_3DModel(A3DPDFDocument* pDoc, A3DAsmModelFile* pModelFile, A3DRWParamsPrcWriteHelper* pPRCWriteHelper,
|
|
int& iKeyNode3dUID, int& iKeyPmiName, int& iKeyPmiType, int& iKeyPmiValue, int& iKeyPmiTol,
|
|
A3DPDFDataTable*& pDataTable3D, A3DPDFDataTable*& pDataTable_Pmis);
|
|
//A3DStatus createTable_Sple2_3DViews(A3DPDF3DArtwork* p3DArtwork, A3DPDFDocument* pDoc, A3DPDFDataTable3DViews*& pDataTable);
|
|
A3DStatus CreateTable_Sple2_3DViews_WithCarousel(A3DPDFDocument* pDoc, A3DPDF3DArtwork* p3DArtwork, A3DAsmModelFile* pModelFile,
|
|
A3DPDFDataTable3DViews*& pDataTable);
|
|
A3DStatus CreateRelationship_Sple2_ViewNames_To_Views(A3DPDFDocument* pDoc, A3DPDFDataTable* pDataTable_Source, A3DPDFDataTable* pDataTable_Target);
|
|
A3DStatus CreateRelationship_Sple2_View_To_Pmis(A3DPDFDocument* pDoc, A3DPDFDataTable* pDataTable_Source, A3DPDFDataTable* pDataTable_Target);
|
|
//A3DStatus createRelationship_Sple2_Pmis_To_3D(A3DPDFDocument* pDoc, A3DPDFDataTable* pDataTable_Source, A3DPDFDataTable* pDataTable_Target);
|
|
// fill data functions sample 3
|
|
A3DStatus CreateTable_Sple3_Statics(A3DPDFDocument* pDoc, A3DPDFDataTable*& pDataTable_Statics);
|
|
A3DStatus CreateTable_Sple3_3DModel_Bom(A3DPDFDocument* pDoc, A3DAsmModelFile* pModelFile, A3DRWParamsPrcWriteHelper* pPRCWriteHelper,
|
|
const std::string& sPathIcons,
|
|
int& iKeyNode3dUID, int& iKeyNode3dInstance,
|
|
int& iKeyBomNumArt, int& iKeyBomNamePart, int& iKeyBomQty, int& iKeyBomIcon,
|
|
A3DPDFDataTable*& pDataTable3D, A3DPDFDataTable*& pDataTableBom);
|
|
|
|
|
|
|
|
//######################################################################################################################
|
|
// writes a text line on the page
|
|
A3DStatus WriteTextString(A3DPDFDocument* pDoc, A3DPDFPage* pPage, A3DPDFEFontName eFontName, A3DInt32 iFontSize,
|
|
A3DDouble dR, A3DDouble dG, A3DDouble dB, const A3DUTF8Char* pcTextString,
|
|
A3DInt32 iPosX, A3DInt32 iPosY)
|
|
{
|
|
A3DStatus iRet = A3D_SUCCESS;
|
|
|
|
A3DPDFTextData sTextData;
|
|
A3D_INITIALIZE_DATA(A3DPDFTextData, sTextData);
|
|
|
|
sTextData.m_eFontName = eFontName;
|
|
sTextData.m_iFontSize = iFontSize;
|
|
sTextData.m_sColor.m_dRed = dR;
|
|
sTextData.m_sColor.m_dGreen = dG;
|
|
sTextData.m_sColor.m_dBlue = dB;
|
|
sTextData.m_pcTextString = const_cast<A3DUTF8Char*>(pcTextString);
|
|
A3DPDFText* pText = NULL;
|
|
CHECK_RET(A3DPDFTextCreate(pDoc, &sTextData, &pText));
|
|
|
|
CHECK_RET(A3DPDFPageInsertText(pPage, pText, iPosX, iPosY)); // posX, posY from the bottom left
|
|
|
|
return iRet;
|
|
}
|
|
|
|
//######################################################################################################################
|
|
A3DStatus Create3DAnnot(A3DPDFDocument* pDoc,
|
|
const A3DUTF8Char* pcFileName,
|
|
A3DPDFImage* pPoster,
|
|
const A3DUTF8Char* pcInjsfile,
|
|
A3DPDF3DArtwork** pp3DArtwork,
|
|
A3DPDF3DAnnot** pp3DAnnot,
|
|
A3DRWParamsPrcWriteHelper** ppA3DRWParamsPrcWriteHelper,
|
|
A3DAsmModelFile** ppModelFile)
|
|
{
|
|
A3DStatus iRet = A3D_SUCCESS;
|
|
*pp3DAnnot = NULL;
|
|
*ppModelFile = NULL;
|
|
A3DPDF3DStream* pStream = NULL;
|
|
char tempfilename[1024];
|
|
|
|
// Publish 6.0 - Particularity when the input 3D model is stored in a PDF file. The functions to read the 3D data from the PDF
|
|
// are not the same as for other formats.
|
|
if(strstr(pcFileName, ".pdf") != NULL)
|
|
{
|
|
A3DStream3DPDFData* pStream3DPDFData;
|
|
A3DInt32 iNumStreams;
|
|
iRet = A3DGet3DPDFStreams(pcFileName, &pStream3DPDFData, &iNumStreams);
|
|
if(iRet!=A3D_SUCCESS || iNumStreams == 0)
|
|
return A3D_ERROR;
|
|
|
|
// a real use case might parse every streams in the input file. Here we just take the first one (pStream3DPDFData[0]).
|
|
|
|
// even an input PRC file must be read in memory and mapped into modelfile data structures
|
|
if(pStream3DPDFData[0].m_bIsPrc)
|
|
{
|
|
iRet = A3DAsmModelFileLoadFromPrcStream(pStream3DPDFData[0].m_acStream, pStream3DPDFData[0].m_uiStreamSize, NULL, ppModelFile);
|
|
if(iRet!=A3D_SUCCESS)
|
|
{
|
|
A3DGet3DPDFStreams(NULL, &pStream3DPDFData, &iNumStreams); // to clean up the array of stream data
|
|
return iRet;
|
|
}
|
|
}
|
|
// a U3D stream must first be stored as a physical file ; then 2 situations occur:
|
|
// 1. read and LOAD the physical file into a modelfile using the common A3DAsmModelFileLoadFromFile function, then transform the modelfile into a stream
|
|
// OR
|
|
// 2. read the physical file into a binary stream (not loaded into a modelfile) using A3DPDF3DStreamCreateFromFile function
|
|
// In this sample we illustrate the workflow 2.
|
|
else
|
|
{
|
|
sprintf(tempfilename, "%s.u3d", OUT_FILE);
|
|
FILE * pFile=NULL;
|
|
#ifdef _MSC_VER
|
|
errno_t ret = fopen_s(&pFile, tempfilename , "wb");
|
|
if(ret == 0 && pFile)
|
|
#else
|
|
pFile = fopen(tempfilename , "wb");
|
|
if(pFile)
|
|
#endif
|
|
{
|
|
fwrite(pStream3DPDFData[0].m_acStream, 1, pStream3DPDFData[0].m_uiStreamSize, pFile);
|
|
fclose(pFile);
|
|
}
|
|
|
|
// physical file to stream
|
|
CHECK_RET(A3DPDF3DStreamCreateFromFile(pDoc, tempfilename, false, &pStream));
|
|
|
|
// !!! the file will have to be disposed of afterwards
|
|
remove(tempfilename);
|
|
}
|
|
|
|
A3DGet3DPDFStreams(NULL, &pStream3DPDFData, &iNumStreams); // to clean up the array of stream data
|
|
}
|
|
|
|
// Load the physical file in a ModelFile data structure if not already done
|
|
if(pStream == NULL && *ppModelFile == NULL)
|
|
{
|
|
// reading the input CAD file; the file can be disposed of afterwards.
|
|
A3DRWParamsLoadData sReadParam;
|
|
A3D_INITIALIZE_DATA(A3DRWParamsLoadData, sReadParam);
|
|
|
|
sReadParam.m_sGeneral.m_bReadSolids = true;
|
|
sReadParam.m_sGeneral.m_bReadSurfaces = true;
|
|
sReadParam.m_sGeneral.m_bReadWireframes = true;
|
|
sReadParam.m_sGeneral.m_bReadPmis = true;
|
|
sReadParam.m_sGeneral.m_bReadAttributes = true;
|
|
sReadParam.m_sGeneral.m_bReadHiddenObjects = false;
|
|
sReadParam.m_sGeneral.m_bReadConstructionAndReferences = false;
|
|
sReadParam.m_sGeneral.m_bReadActiveFilter = true;
|
|
sReadParam.m_sGeneral.m_eReadingMode2D3D = kA3DRead_3D;
|
|
sReadParam.m_sGeneral.m_eReadGeomTessMode = kA3DReadGeomAndTess;
|
|
sReadParam.m_sGeneral.m_eDefaultUnit = kA3DUnitUnknown;
|
|
sReadParam.m_sPmi.m_bAlwaysSubstituteFont = false;
|
|
sReadParam.m_sPmi.m_pcSubstitutionFont = const_cast<A3DUTF8Char*>("Myriad CAD");
|
|
sReadParam.m_sTessellation.m_eTessellationLevelOfDetail = kA3DTessLODMedium;
|
|
sReadParam.m_sMultiEntries.m_bLoadDefault = true;
|
|
sReadParam.m_sAssembly.m_bUseRootDirectory = true;
|
|
CHECK_RET(A3DAsmModelFileLoadFromFile(pcFileName, &sReadParam, ppModelFile));
|
|
}
|
|
|
|
if(*ppModelFile != NULL)
|
|
{
|
|
// whatever the input format, we store it as PRC in the output PDF
|
|
// creating the PRC stream from the model file that is going to be inserted into the PDF file
|
|
A3DRWParamsExportPrcData sParamsExportData;
|
|
A3D_INITIALIZE_DATA(A3DRWParamsExportPrcData, sParamsExportData);
|
|
|
|
CHECK_RET(A3DPDF3DStreamCreateFromModelFileAsPRC(pDoc, *ppModelFile, &sParamsExportData, &pStream, ppA3DRWParamsPrcWriteHelper));
|
|
}
|
|
|
|
if(pStream != NULL)
|
|
{
|
|
// creating the 3D artwork
|
|
*pp3DArtwork = NULL;
|
|
A3DPDF3DArtworkData2 s3DArtworkData;
|
|
A3D_INITIALIZE_DATA(A3DPDF3DArtworkData2, s3DArtworkData);
|
|
|
|
s3DArtworkData.m_pStream = pStream;
|
|
s3DArtworkData.m_pcJavaScriptFileName = const_cast<A3DUTF8Char*>(pcInjsfile);
|
|
s3DArtworkData.m_bActivatePMICrossHighlight = true;
|
|
s3DArtworkData.m_bAddPMISemanticInformation = true;
|
|
s3DArtworkData.m_sDisplaySectionData.m_bAddSectionCaps = true;
|
|
CHECK_RET(A3DPDF3DArtworkCreate2(pDoc, &s3DArtworkData, pp3DArtwork));
|
|
|
|
A3DPDF3DAnnotData sAnnotData;
|
|
A3D_INITIALIZE_DATA(A3DPDF3DAnnotData, sAnnotData);
|
|
|
|
sAnnotData.m_bOpenModelTree = false;
|
|
sAnnotData.m_bShowToolbar = false;
|
|
sAnnotData.m_eLighting = kA3DPDFLightCADOptimized;
|
|
sAnnotData.m_eRenderingStyle = kA3DPDFRenderingSolid;
|
|
sAnnotData.m_sBackgroundColor.m_dRed = 0.25;
|
|
sAnnotData.m_sBackgroundColor.m_dGreen = 0.25;
|
|
sAnnotData.m_sBackgroundColor.m_dBlue = 0.25;
|
|
sAnnotData.m_bTransparentBackground = false;
|
|
sAnnotData.m_eActivateWhen = kA3DPDFActivPageOpened;
|
|
sAnnotData.m_eDesactivateWhen = kA3DPDFActivPageClosed;
|
|
sAnnotData.m_iAppearanceBorderWidth = 0;
|
|
sAnnotData.m_pPosterImage = pPoster; // default poster automatically generated
|
|
sAnnotData.m_p3DArtwork = *pp3DArtwork;
|
|
|
|
CHECK_RET(A3DPDF3DAnnotCreate(pDoc, &sAnnotData, pp3DAnnot));
|
|
}
|
|
|
|
return iRet;
|
|
}
|
|
|
|
|
|
|
|
A3DStatus AddViewCarousel(A3DPDFDocument* pDoc, A3DPDFPage* pPage,
|
|
int iLeftCarou,
|
|
int iBottomCarou,
|
|
int iHeigthCarousel,
|
|
int iWidthCarouButtonPrevNext,
|
|
int iWidthCarouButton,
|
|
int iHorizMargin,
|
|
std::vector<std::string>& aViewCarouselButPrevNext,
|
|
std::vector<std::string>& aViewCarouselButtons,
|
|
A3DPDF3DViewCarousel** ppViewCarousel)
|
|
{
|
|
A3DStatus iRet = A3D_SUCCESS;
|
|
|
|
// --- buttons for carousel
|
|
A3DPDFRectData sPos;
|
|
A3D_INITIALIZE_DATA(A3DPDFRectData, sPos);
|
|
std::string sFieldId;
|
|
|
|
// buttons views all act the same and have same attributes
|
|
A3DUTF8Char* ppButtonsNamesPrevNext[2];
|
|
A3DPDFButton* ppButtonsPrevNext[2];
|
|
A3DUTF8Char** ppButtonsNames = (A3DUTF8Char**) malloc(aViewCarouselButtons.size() * A3DUns32(sizeof(A3DUTF8Char*)));
|
|
A3DPDFButton** ppButtonsViews = (A3DPDFButton**) malloc(aViewCarouselButtons.size() * A3DUns32(sizeof(A3DPDFButton*)));
|
|
|
|
A3DPDFButtonData sButtonViewsData;
|
|
A3D_INITIALIZE_DATA(A3DPDFButtonData, sButtonViewsData);
|
|
//sButtonViewsData.m_eFormField = kA3DPDFVisible;
|
|
sButtonViewsData.m_pcFontName = const_cast<A3DUTF8Char*>("Helv");
|
|
sButtonViewsData.m_iFontSize = 8;
|
|
sButtonViewsData.m_bHasFillColor = false;
|
|
sButtonViewsData.m_bHasBorder = false;
|
|
sButtonViewsData.m_eThicknessBorder = kA3DPDFThin;
|
|
sButtonViewsData.m_eLineStyleBorder = kA3DPDFSolid;
|
|
sButtonViewsData.m_eLayoutTextIcon = kA3DPDFIconTopLabelBottom;
|
|
sButtonViewsData.m_eHighlightingMode = kA3DPDFLinkHighlightOutline;
|
|
|
|
for (size_t i=0 ; i<aViewCarouselButtons.size() ; i++)
|
|
{
|
|
// button view i
|
|
mallocAndSetString(
|
|
aViewCarouselButtons[i].c_str(),// src
|
|
ppButtonsNames[i]); // dest
|
|
sButtonViewsData.m_pcName = ppButtonsNames[i];
|
|
CHECK_RET(A3DPDFButtonCreate(pDoc, &sButtonViewsData, &ppButtonsViews[i]));
|
|
}
|
|
|
|
// buttons scrolls both act the same and have same attributes
|
|
A3DPDFButtonData sButtonsScrollData;
|
|
A3D_INITIALIZE_DATA(A3DPDFButtonData, sButtonsScrollData);
|
|
sButtonsScrollData.m_bHasFillColor = false;
|
|
sButtonsScrollData.m_bHasBorder = false;
|
|
sButtonsScrollData.m_eThicknessBorder = kA3DPDFThin;
|
|
sButtonsScrollData.m_eLineStyleBorder = kA3DPDFSolid;
|
|
sButtonsScrollData.m_eLayoutTextIcon = kA3DPDFIconOnly;
|
|
sButtonsScrollData.m_eHighlightingMode = kA3DPDFLinkHighlightOutline;
|
|
|
|
// button scroll up (previous)
|
|
|
|
// create image object from file for button icon
|
|
A3DPDFImage* pImagePrev;
|
|
CHECK_RET(A3DPDFImageCreateFromFile(pDoc, ICON_CAROUSEL_PREV, kA3DPDFImageFormatUnknown, &pImagePrev));
|
|
sButtonsScrollData.m_pImage = pImagePrev;
|
|
// button name
|
|
mallocAndSetString(
|
|
aViewCarouselButPrevNext[0].c_str(),// src
|
|
ppButtonsNamesPrevNext[0]); // dest
|
|
sButtonsScrollData.m_pcName = ppButtonsNamesPrevNext[0];
|
|
CHECK_RET(A3DPDFButtonCreate(pDoc, &sButtonsScrollData, &ppButtonsPrevNext[0]));
|
|
|
|
// button scroll down (next)
|
|
|
|
// create image object from file for button icon
|
|
A3DPDFImage* pImageNext;
|
|
CHECK_RET(A3DPDFImageCreateFromFile(pDoc, ICON_CAROUSEL_NEXT, kA3DPDFImageFormatUnknown, &pImageNext));
|
|
sButtonsScrollData.m_pImage = pImageNext;
|
|
// button name
|
|
mallocAndSetString(
|
|
aViewCarouselButPrevNext[1].c_str(),// src
|
|
ppButtonsNamesPrevNext[1]); // dest
|
|
sButtonsScrollData.m_pcName = ppButtonsNamesPrevNext[1];
|
|
CHECK_RET(A3DPDFButtonCreate(pDoc, &sButtonsScrollData, &ppButtonsPrevNext[1]));
|
|
|
|
// buttons insertions
|
|
// coordinates are from bottom left of the page
|
|
|
|
int iTopCarou = iBottomCarou+iHeigthCarousel;
|
|
sPos.m_iLeft = iLeftCarou; // lower left x
|
|
sPos.m_iBottom = iBottomCarou; // lower left y
|
|
sPos.m_iRight = sPos.m_iLeft+iWidthCarouButtonPrevNext; // upper right x
|
|
sPos.m_iTop = iTopCarou; // upper right y
|
|
CHECK_RET(A3DPDFPageInsertButton(pPage, ppButtonsPrevNext[0], &sPos));
|
|
|
|
for (size_t i=0 ; i<aViewCarouselButtons.size() ; i++)
|
|
{
|
|
sPos.m_iLeft = sPos.m_iRight+iHorizMargin; // lower left x
|
|
sPos.m_iBottom = iBottomCarou; // lower left y
|
|
sPos.m_iRight = sPos.m_iLeft+iWidthCarouButton; // upper right x
|
|
sPos.m_iTop = iTopCarou; // upper right y
|
|
CHECK_RET(A3DPDFPageInsertButton(pPage, ppButtonsViews[i], &sPos));
|
|
}
|
|
|
|
sPos.m_iLeft = sPos.m_iRight+iHorizMargin; // lower left x
|
|
sPos.m_iBottom = iBottomCarou; // lower left y
|
|
sPos.m_iRight = sPos.m_iLeft+iWidthCarouButtonPrevNext; // upper right x
|
|
sPos.m_iTop = iTopCarou; // upper right y
|
|
CHECK_RET(A3DPDFPageInsertButton(pPage, ppButtonsPrevNext[1], &sPos));
|
|
|
|
|
|
// --- view carousel
|
|
|
|
A3DPDF3DViewCarouselData sViewCarouselData;
|
|
A3D_INITIALIZE_DATA(A3DPDF3DViewCarouselData, sViewCarouselData);
|
|
sViewCarouselData.m_iNbButtons = (int)aViewCarouselButtons.size();
|
|
sViewCarouselData.m_ppcButtonsNames = ppButtonsNames;
|
|
sViewCarouselData.m_pcPreviousButtonName = ppButtonsNamesPrevNext[0];
|
|
sViewCarouselData.m_pcNextButtonName = ppButtonsNamesPrevNext[1];
|
|
sViewCarouselData.m_eScrollDirection = kA3DPDFHorizontal;
|
|
sViewCarouselData.m_iScrollStep = 1;
|
|
|
|
CHECK_RET(A3DPDF3DViewCarouselCreate(pDoc, &sViewCarouselData, ppViewCarousel));
|
|
|
|
CHECK_RET(A3DPDFPageInsert3DViewCarousel(pPage, *ppViewCarousel));
|
|
|
|
|
|
// draw a border + background color, if required
|
|
if (*ppViewCarousel!=NULL)
|
|
{
|
|
A3DPDFGraphicRectangleData sGraphRectData;
|
|
A3D_INITIALIZE_DATA(A3DPDFGraphicRectangleData, sGraphRectData);
|
|
sGraphRectData.m_dWidth=1;
|
|
// border line color
|
|
sGraphRectData.m_sLineColor.m_dBlue=0.;
|
|
sGraphRectData.m_sLineColor.m_dGreen=0.;
|
|
sGraphRectData.m_sLineColor.m_dRed=0.;
|
|
/*
|
|
// background color
|
|
A3DPDFRgbColorData sFillColorData;
|
|
sGraphRectData.m_pFillColor = &sFillColorData;
|
|
sGraphRectData.m_pFillColor->m_dBlue=0.9;
|
|
sGraphRectData.m_pFillColor->m_dGreen=0.9;
|
|
sGraphRectData.m_pFillColor->m_dRed=0.9;
|
|
*/
|
|
CHECK_RET(A3DPDFWidgetGetPosition(*ppViewCarousel, &sGraphRectData.m_sRectangleData));
|
|
sGraphRectData.m_sRectangleData.m_dBottom --;
|
|
sGraphRectData.m_sRectangleData.m_dTop ++;
|
|
A3DPDFPageDrawRectangle(pPage, &sGraphRectData);
|
|
}
|
|
|
|
|
|
// cleanup
|
|
for (size_t i=0 ; i<aViewCarouselButtons.size() ; i++)
|
|
{
|
|
free(ppButtonsNames[i]);
|
|
}
|
|
free(ppButtonsNames);
|
|
free(ppButtonsViews);
|
|
free(ppButtonsNamesPrevNext[0]);
|
|
free(ppButtonsNamesPrevNext[1]);
|
|
|
|
return iRet;
|
|
}
|
|
|
|
|
|
//######################################################################################################################
|
|
// Define a slide table
|
|
A3DStatus AddScrollTable(A3DPDFDocument* pDoc, A3DPDFPage* pPage,
|
|
int iPosLeft, int iPosTop, int iSliderWidth,
|
|
int iNbRowsInFrame,
|
|
int iHeightRowHeader, // in points
|
|
int iHeightRows, // in points
|
|
std::vector<int>& aiWidthCols, // in points
|
|
std::vector<std::string>& aRowHeader,
|
|
std::vector<A3DPDFEColumnType>& aeColumnTypes,
|
|
A3DPDFScrollTable** ppScrollTable)
|
|
{
|
|
A3DStatus iRet = A3D_SUCCESS;
|
|
|
|
A3DPDFScrollTableData sScrollTableData;
|
|
A3D_INITIALIZE_DATA(A3DPDFScrollTableData, sScrollTableData);
|
|
sScrollTableData.m_iGridNbRows = iNbRowsInFrame;
|
|
sScrollTableData.m_iGridNbCols = (int)aiWidthCols.size();
|
|
sScrollTableData.m_iGridHeightCells = iHeightRows;
|
|
sScrollTableData.m_piGridWidthCells = (A3DInt32 *)malloc(sScrollTableData.m_iGridNbCols*sizeof(A3DInt32));
|
|
for (size_t ic=0; ic<aiWidthCols.size(); ic++)
|
|
sScrollTableData.m_piGridWidthCells[ic]=aiWidthCols[ic];
|
|
|
|
sScrollTableData.m_peColumnTypes = (A3DPDFEColumnType *)malloc(sScrollTableData.m_iGridNbCols * sizeof(A3DPDFEColumnType));
|
|
for (size_t ic = 0; ic<aeColumnTypes.size(); ic++)
|
|
sScrollTableData.m_peColumnTypes[ic] = aeColumnTypes[ic];
|
|
|
|
sScrollTableData.m_iSliderWidth = iSliderWidth;
|
|
|
|
// optional to define custom format
|
|
// comment these lines to get default format
|
|
A3DPDFTextFieldData sCellFormatData;
|
|
A3D_INITIALIZE_DATA(A3DPDFTextFieldData, sCellFormatData);
|
|
sCellFormatData.m_pcFontName = const_cast<A3DUTF8Char*>("Helv");
|
|
sCellFormatData.m_iFontSize = 10;
|
|
sCellFormatData.m_sTextColor.m_dRed = 0.0; // black
|
|
sCellFormatData.m_sTextColor.m_dGreen = 0.0;
|
|
sCellFormatData.m_sTextColor.m_dBlue = 0.0;
|
|
sCellFormatData.m_eTextAlignment = kA3DPDFLeft;
|
|
sScrollTableData.m_pCellFormat = &sCellFormatData;
|
|
|
|
/* optional to define custom row highlight color
|
|
// comment these lines to get default highlight color
|
|
A3DPDFRgbColorData sHighlightColorData;
|
|
A3D_INITIALIZE_DATA(A3DPDFRgbColorData, sHighlightColorData);
|
|
sHighlightColorData.m_dRed = 100./255.;
|
|
sHighlightColorData.m_dGreen = 200./255.;
|
|
sHighlightColorData.m_dBlue = 100./255.;
|
|
sScrollTableData.m_pHighlightColor = &sHighlightColorData;
|
|
*/
|
|
|
|
CHECK_RET(A3DPDFScrollTableCreate(pDoc, &sScrollTableData, ppScrollTable));
|
|
|
|
CHECK_RET(A3DPDFPageInsertScrollTable(pPage, *ppScrollTable, iPosLeft, iPosTop-iHeightRowHeader));
|
|
|
|
// --- create header as text fields: create it after table to use the ST name created
|
|
|
|
A3DUTF8Char* pcSTName = NULL;
|
|
CHECK_RET(A3DPDFWidgetGetName(*ppScrollTable, &pcSTName));
|
|
|
|
A3DPDFTextFieldData sTextFieldData;
|
|
A3D_INITIALIZE_DATA(A3DPDFTextFieldData, sTextFieldData);
|
|
sTextFieldData.m_pcFontName = const_cast<A3DUTF8Char*>("HeBo");
|
|
sTextFieldData.m_iFontSize = 10;
|
|
sTextFieldData.m_sTextColor.m_dRed = 0; // black
|
|
sTextFieldData.m_sTextColor.m_dGreen = 0;
|
|
sTextFieldData.m_sTextColor.m_dBlue = 0;
|
|
sTextFieldData.m_eTextAlignment = kA3DPDFLeft;
|
|
A3DPDFRectData sPos;
|
|
A3D_INITIALIZE_DATA(A3DPDFRectData, sPos);
|
|
sPos.m_iLeft = iPosLeft; // lower left x
|
|
sPos.m_iBottom = iPosTop-iHeightRowHeader; // lower left y
|
|
sPos.m_iRight = iPosLeft; // upper right x
|
|
sPos.m_iTop = iPosTop; // upper right y
|
|
for(size_t ic = 0; ic < aRowHeader.size() ; ic++)
|
|
{
|
|
A3DPDFTextField* pText = NULL;
|
|
A3DUTF8Char tmpname[1024];
|
|
sprintf(tmpname, "%s_Header%d", pcSTName, (int)ic);
|
|
sTextFieldData.m_pcName = tmpname;
|
|
sTextFieldData.m_pcDefaultValue = const_cast<A3DUTF8Char*>(aRowHeader[ic].c_str());
|
|
iRet = A3DPDFTextFieldCreate(pDoc, &sTextFieldData, &pText);
|
|
|
|
// coordinates are from bottom left of the page
|
|
sPos.m_iLeft = sPos.m_iRight; // lower left x
|
|
sPos.m_iRight = sPos.m_iLeft + aiWidthCols[ic]; // upper right x
|
|
if ((A3DInt32)ic==sScrollTableData.m_iGridNbCols-1) // last column goes above the slider
|
|
sPos.m_iRight += iSliderWidth;
|
|
CHECK_RET(A3DPDFPageInsertTextField(pPage, pText, &sPos));
|
|
}
|
|
|
|
A3DPDFWidgetGetName(nullptr, &pcSTName);
|
|
|
|
|
|
// clean
|
|
if (sScrollTableData.m_piGridWidthCells!=NULL)
|
|
free( sScrollTableData.m_piGridWidthCells);
|
|
if (sScrollTableData.m_peColumnTypes != NULL)
|
|
free(sScrollTableData.m_peColumnTypes);
|
|
|
|
return A3D_SUCCESS;
|
|
}
|
|
|
|
|
|
|
|
A3DStatus stBuildDocument(A3DPDFDocument* pDoc)
|
|
{
|
|
A3DStatus iRet = A3D_SUCCESS;
|
|
|
|
A3DPDFPage* pPage = NULL;
|
|
int indexpage = 0;
|
|
std::string sSuffixFields;
|
|
|
|
// populating the document metadata
|
|
A3DPDFDocumentInformationData sInformationData;
|
|
A3D_INITIALIZE_DATA(A3DPDFDocumentInformationData, sInformationData);
|
|
|
|
sInformationData.m_pcTitle = const_cast<A3DUTF8Char*>("HOOPS Publish Functionalities");
|
|
sInformationData.m_pcCreator = const_cast<A3DUTF8Char*>("HOOPS Publish Sample Application");
|
|
sInformationData.m_pcSubject = const_cast<A3DUTF8Char*>("This sample demoes the data model functionality of HOOPS Publish");
|
|
sInformationData.m_pcAuthor = const_cast<A3DUTF8Char*>("Tech Soft 3D");
|
|
CHECK_RET(A3DPDFDocumentSetInformation(pDoc, &sInformationData));
|
|
|
|
// creating a poster image to be used as a poster for 3D.
|
|
A3DPDFImage* pBlankImage = NULL;
|
|
A3DPDFImageCreateFromFile(pDoc, POSTER_PATH, kA3DPDFImageFormatUnknown, &pBlankImage);
|
|
|
|
// create page idx+1 from template file. we force the fields renaming to avoid duplicated names.
|
|
sSuffixFields = "uuid0";
|
|
CHECK_RET(A3DPDFDocumentAppendPageFromPDFFileAndSuffixFields(pDoc, PDF_TEMPLATE_1, sSuffixFields.c_str(), &pPage));
|
|
if(pPage != NULL)
|
|
{
|
|
// --- create and fill Fields to map to DataModel
|
|
|
|
A3DPDF3DAnnot* p3DAnnot = NULL;
|
|
A3DPDF3DArtwork* p3DArtwork = NULL;
|
|
A3DAsmModelFile* pModelFile = NULL;
|
|
// To get unique IDs, we need a A3DRWParamsPrcWriteHelper.
|
|
// A3DPDF3DStreamCreateFromModelFileAsPRC builds this object.
|
|
A3DRWParamsPrcWriteHelper* pPRCWriteHelper = NULL;
|
|
iRet = Create3DAnnot(pDoc, IN_3DFILE_1, pBlankImage, NULL, &p3DArtwork, &p3DAnnot, &pPRCWriteHelper, &pModelFile);
|
|
|
|
if(p3DAnnot != NULL && p3DArtwork != NULL && pModelFile != NULL)
|
|
{
|
|
// populating the field with the 3D annotation
|
|
CHECK_RET(A3DPDFPageFieldSet3DAnnot(pPage, std::string("DF_3DWindow_" + sSuffixFields).c_str(), p3DAnnot));
|
|
|
|
// get widget for list nodes
|
|
A3DPDF3DNodeScene* p3DNodeScene = NULL;
|
|
CHECK_RET(A3DPDF3DAnnotGet3DNodeScene( p3DAnnot, &p3DNodeScene));
|
|
|
|
|
|
// create Scroll table on the page
|
|
A3DPDFScrollTable* pScrollTableBom = NULL;
|
|
|
|
std::vector<int> aiWidthCols; // in points
|
|
aiWidthCols.push_back(30);
|
|
aiWidthCols.push_back(170);
|
|
aiWidthCols.push_back(30);
|
|
aiWidthCols.push_back(60);
|
|
aiWidthCols.push_back(50);
|
|
std::vector<std::string> aRowHeader;
|
|
aRowHeader.push_back("No");
|
|
aRowHeader.push_back("NAME PART");
|
|
aRowHeader.push_back("QTY");
|
|
aRowHeader.push_back("MATERIAL");
|
|
aRowHeader.push_back("SNAPSHOT");
|
|
std::vector<A3DPDFEColumnType> aeTypes;
|
|
aeTypes.push_back(kA3DPDFTextContent);
|
|
aeTypes.push_back(kA3DPDFTextContent);
|
|
aeTypes.push_back(kA3DPDFTextContent);
|
|
aeTypes.push_back(kA3DPDFTextContent);
|
|
aeTypes.push_back(kA3DPDFImageContent);
|
|
|
|
CHECK_RET(AddScrollTable(pDoc, pPage,
|
|
20, 632, // iPosLeft, iPosTop
|
|
15, //iSliderWidth
|
|
4, // iNbRowsInFrame
|
|
20, // iHeightRowHeader - in points
|
|
40, // iHeightRows - in points
|
|
aiWidthCols, // in points
|
|
aRowHeader,
|
|
aeTypes,
|
|
&pScrollTableBom));
|
|
|
|
// get existing widgets on template page
|
|
|
|
A3DPDFTextField* pTextTitle = NULL;
|
|
CHECK_RET(PageGetTextField(pPage, std::string("DF_Title_" + sSuffixFields).c_str(), &pTextTitle));
|
|
|
|
A3DPDFTextField* pTextDate = NULL;
|
|
CHECK_RET(PageGetTextField(pPage, std::string("DF_Date_" + sSuffixFields).c_str(), &pTextDate));
|
|
|
|
A3DPDFTextField* pTextCreatedBy = NULL;
|
|
CHECK_RET(PageGetTextField(pPage, std::string("DF_CreatedBy_" + sSuffixFields).c_str(), &pTextCreatedBy));
|
|
|
|
A3DPDFTextField* pTextInstance = NULL;
|
|
CHECK_RET(PageGetTextField(pPage, std::string("DF_InstanceNode_" + sSuffixFields).c_str(), &pTextInstance));
|
|
|
|
A3DPDFTextField* pTextColNumArt = NULL;
|
|
CHECK_RET(PageGetTextField(pPage, std::string("DF_Col0_" + sSuffixFields).c_str(), &pTextColNumArt));
|
|
|
|
A3DPDFTextField* pTextColNamePart = NULL;
|
|
CHECK_RET(PageGetTextField(pPage, std::string("DF_Col1_" + sSuffixFields).c_str(), &pTextColNamePart));
|
|
|
|
A3DPDFListBox* pListManufacturers = NULL;
|
|
CHECK_RET(PageGetListBoxField(pPage, std::string("DF_ManufacturersList_" + sSuffixFields).c_str(), &pListManufacturers));
|
|
|
|
A3DPDFTextField* pTextManufDetails = NULL;
|
|
CHECK_RET(PageGetTextField(pPage, std::string("DF_ManufacturerDetails_" + sSuffixFields).c_str(), &pTextManufDetails));
|
|
|
|
A3DPDFDataFilter* pDropDownListFilter = NULL;
|
|
CHECK_RET(A3DPDFPageGetDataFilterFromDropDownListField(pPage, std::string("DF_FilterList_" + sSuffixFields).c_str(), &pDropDownListFilter));
|
|
|
|
|
|
// DATAMODEL
|
|
|
|
// --- creation Tables and relationships
|
|
|
|
// TABLE Statics
|
|
A3DPDFDataTable* pDataTable_Statics = NULL;
|
|
CHECK_RET(CreateTable_Sple1_Statics(pDoc, pDataTable_Statics));
|
|
|
|
// TABLE CBFILTER
|
|
A3DPDFDataTable* pDataTable_CBFILTER = NULL;
|
|
CHECK_RET(CreateTable_Sple1_CBFILTER(pDoc, pDataTable_CBFILTER));
|
|
|
|
// TABLE Manufacturers
|
|
A3DPDFDataTable* pDataTable_Manufacturers = NULL;
|
|
CHECK_RET(CreateTable_Sple1_Manufacturers(pDoc, pDataTable_Manufacturers));
|
|
|
|
// TABLE 3D MODEL + TABLE BOM + RELATIONSHIPs
|
|
A3DPDFDataTable* pDataTable_3D = NULL;
|
|
A3DPDFDataTable* pDataTable_Bom = NULL;
|
|
int iKeyNode3dUID, iKeyNode3dName, iKeyNode3dInstance;
|
|
int iKeyBomNumArt, iKeyBomNamePart, iKeyBomQty, iKeyBomMaterial, iKeyBomIcon;
|
|
CHECK_RET(CreateTable_Sple1_3DModel_Bom(pDoc, pModelFile, pPRCWriteHelper,
|
|
ICONS_PATH,
|
|
iKeyNode3dUID, iKeyNode3dName, iKeyNode3dInstance,
|
|
iKeyBomNumArt, iKeyBomNamePart, iKeyBomQty, iKeyBomMaterial, iKeyBomIcon,
|
|
pDataTable_3D, pDataTable_Bom, pDataTable_Manufacturers));
|
|
|
|
// RELATIONSHIP CBCBFILTER_To_Bom
|
|
CHECK_RET(CreateRelationship_Sple1_CBFILTER_To_Bom(pDoc, pDataTable_CBFILTER, pDataTable_Bom));
|
|
|
|
|
|
// --- binding to widgets
|
|
|
|
// --- Widgets binding for Table Static
|
|
CHECK_RET(A3DPDFTextFieldBindToTable(pTextTitle, pDataTable_Statics, 0));
|
|
CHECK_RET(A3DPDFTextFieldBindToTable(pTextDate, pDataTable_Statics, 1));
|
|
CHECK_RET(A3DPDFTextFieldBindToTable(pTextCreatedBy, pDataTable_Statics, 2));
|
|
|
|
// --- Widgets binding for init Filter
|
|
const A3DInt32 piMapColumns_CBFILTER[] = { 0 } ; const int iSzColCBFILTER = 1;
|
|
CHECK_RET(A3DPDFDataFilterWidgetBindToTable(pDropDownListFilter, pDataTable_CBFILTER, iSzColCBFILTER, piMapColumns_CBFILTER,
|
|
"Filter All" ));
|
|
// pcValueNoFilterApplied: if defined, a first specific row is added in the widget: select this row -> unapply all filters
|
|
// if pcValueNoFilterApplied is NULL: a filter is always applied (there is no 'nofilter' state ; default is row0)
|
|
|
|
// --- Widgets binding for Table 3D
|
|
CHECK_RET(A3DPDF3DNodeSceneBindToTable(p3DNodeScene, pDataTable_3D, iKeyNode3dUID));// A3DPDF3DNodeScene maps only 1 col : the one with uuid node names
|
|
CHECK_RET(A3DPDFTextFieldBindToTable(pTextInstance, pDataTable_3D, iKeyNode3dInstance));
|
|
|
|
// --- Widgets binding for Table BOM
|
|
const A3DInt32 piMapColumns_Bom[] = { iKeyBomNumArt, iKeyBomNamePart, iKeyBomQty, iKeyBomMaterial, iKeyBomIcon };
|
|
CHECK_RET(A3DPDFScrollTableBindToTable(pScrollTableBom, pDataTable_Bom, sizeof(piMapColumns_Bom)/sizeof(A3DInt32), piMapColumns_Bom ));
|
|
CHECK_RET(A3DPDFTextFieldBindToTable(pTextColNumArt, pDataTable_Bom, iKeyBomNumArt));
|
|
CHECK_RET(A3DPDFTextFieldBindToTable(pTextColNamePart, pDataTable_Bom, iKeyBomNamePart));
|
|
|
|
// --- Widgets binding for Table Manufacturers
|
|
CHECK_RET(A3DPDFListBoxBindToTable(pListManufacturers, pDataTable_Manufacturers, 0));
|
|
CHECK_RET(A3DPDFTextFieldBindToTable(pTextManufDetails, pDataTable_Manufacturers, 3));
|
|
|
|
|
|
// --- Define interactions between widgets
|
|
|
|
// if Bom is populated coming from a selection in filter dropdown list, only resulting elements of the filter are displayed in Bom
|
|
CHECK_RET(A3DPDFWidgetSetTargetBehaviour( pDropDownListFilter, pScrollTableBom, kA3DPDFDataIsolate ));
|
|
|
|
// Select a BOM item -> only associated Manufacturers are displayed in Manufacturers list
|
|
CHECK_RET(A3DPDFWidgetSetTargetBehaviour( pScrollTableBom, pListManufacturers, kA3DPDFDataIsolate ));
|
|
|
|
// selection of a row in Bom -> 2 column values are displayed in 2 text field
|
|
CHECK_RET(A3DPDFWidgetSetTargetBehaviour(pScrollTableBom, pTextColNumArt, kA3DPDFDataIsolate));
|
|
CHECK_RET(A3DPDFWidgetSetTargetBehaviour(pScrollTableBom, pTextColNamePart, kA3DPDFDataIsolate));
|
|
|
|
// selection of a row in Bom -> the associated elements of widget (=3d nodes) are highlighted
|
|
CHECK_RET(A3DPDFWidgetSetTargetBehaviour( pScrollTableBom, p3DNodeScene, kA3DPDFDataHighlight ));
|
|
|
|
// select a node in 3D annot -> the elements of BOM (=scroll table rows) are selected (i.e. acts as if the user clicked on the BOM row)
|
|
CHECK_RET(A3DPDFWidgetSetTargetBehaviour( p3DNodeScene, pScrollTableBom, kA3DPDFDataSelect ));
|
|
|
|
// TextInstance is populated coming from a selection in 3D
|
|
CHECK_RET(A3DPDFWidgetSetTargetBehaviour( p3DNodeScene, pTextInstance, kA3DPDFDataIsolate ));
|
|
|
|
// selection of a row in Manufacturers list box -> 1 column value is displayed in text field
|
|
CHECK_RET(A3DPDFWidgetSetTargetBehaviour( pListManufacturers, pTextManufDetails, kA3DPDFDataIsolate ));
|
|
|
|
|
|
// cleanup 3D modelfile
|
|
CHECK_RET(A3DAsmModelFileDelete(pModelFile));
|
|
// Free the A3DRWParamsPrcWriteHelper object at the end
|
|
if (pPRCWriteHelper != NULL)
|
|
A3DRWParamsPrcWriteHelperFree(pPRCWriteHelper);
|
|
}
|
|
|
|
indexpage++;
|
|
}
|
|
|
|
// create page idx+1 from template file. we force the fields renaming to avoid duplicated names.
|
|
sSuffixFields = "uuid1";
|
|
CHECK_RET(A3DPDFDocumentAppendPageFromPDFFileAndSuffixFields(pDoc, PDF_TEMPLATE_2, sSuffixFields.c_str(), &pPage));
|
|
if(pPage != NULL)
|
|
{
|
|
// --- create and fill Fields to map to DataModel
|
|
|
|
A3DPDF3DAnnot* p3DAnnot = NULL;
|
|
A3DPDF3DArtwork* p3DArtwork = NULL;
|
|
A3DAsmModelFile* pModelFile = NULL;
|
|
// To get unique IDs, we need a A3DRWParamsPrcWriteHelper.
|
|
// A3DPDF3DStreamCreateFromModelFileAsPRC builds this object.
|
|
A3DRWParamsPrcWriteHelper* pPRCWriteHelper = NULL;
|
|
iRet = Create3DAnnot(pDoc, IN_3DFILE_2, pBlankImage, NULL, &p3DArtwork, &p3DAnnot, &pPRCWriteHelper, &pModelFile);
|
|
|
|
if(p3DAnnot != NULL && p3DArtwork != NULL && pModelFile != NULL)
|
|
{
|
|
// populating the field with the 3D annotation
|
|
CHECK_RET(A3DPDFPageFieldSet3DAnnot(pPage, std::string("DF_3DWindow_" + sSuffixFields).c_str(), p3DAnnot));
|
|
|
|
// get widget for list nodes
|
|
A3DPDF3DNodeScene* p3DNodeScene = NULL;
|
|
CHECK_RET(A3DPDF3DAnnotGet3DNodeScene( p3DAnnot, &p3DNodeScene));
|
|
// get widget for list views
|
|
A3DPDF3DViewList* p3DViewList = NULL;
|
|
CHECK_RET(A3DPDF3DAnnotGet3DViewList( p3DAnnot, &p3DViewList));
|
|
|
|
// create view carousel on the page
|
|
A3DPDF3DViewCarousel* pViewCarousel = NULL;
|
|
std::vector<std::string> aViewCarouselButPrevNext;
|
|
aViewCarouselButPrevNext.push_back(std::string("ButScrollViewsPrev_" + sSuffixFields));
|
|
aViewCarouselButPrevNext.push_back(std::string("ButScrollViewsNext_" + sSuffixFields));
|
|
std::vector<std::string> aViewCarouselButtons;
|
|
for (int i=0 ; i<3 ; i++)
|
|
{
|
|
char acButName[256];
|
|
sprintf ( acButName, "ButViewCarousel%d_", i );
|
|
aViewCarouselButtons.push_back(std::string(acButName + sSuffixFields));
|
|
}
|
|
CHECK_RET(AddViewCarousel(pDoc, pPage,
|
|
30, // iLeftCarou
|
|
340, // iBottomCarou
|
|
108, // iHeigthCarousel
|
|
22, // iWidthCarouButtonPrevNext
|
|
145, // iWidthCarouButton
|
|
2, // iHorizMargin
|
|
aViewCarouselButPrevNext, aViewCarouselButtons,
|
|
&pViewCarousel));
|
|
|
|
// create Scroll table on the page
|
|
A3DPDFScrollTable* pScrollTablePmis = NULL;
|
|
std::vector<int> aiWidthCols; // in points
|
|
aiWidthCols.push_back(100);
|
|
aiWidthCols.push_back(100);
|
|
aiWidthCols.push_back(100);
|
|
aiWidthCols.push_back(100);
|
|
std::vector<std::string> aRowHeader;
|
|
aRowHeader.push_back("PMI Name");
|
|
aRowHeader.push_back("Type");
|
|
aRowHeader.push_back("Value");
|
|
aRowHeader.push_back("Tolerance");
|
|
std::vector<A3DPDFEColumnType> aeTypes;
|
|
aeTypes.push_back(kA3DPDFTextContent);
|
|
aeTypes.push_back(kA3DPDFTextContent);
|
|
aeTypes.push_back(kA3DPDFTextContent);
|
|
aeTypes.push_back(kA3DPDFTextContent);
|
|
CHECK_RET(AddScrollTable(pDoc, pPage,
|
|
20, 270, // iPosLeft, iPosTop
|
|
15, //iSliderWidth
|
|
8, // iNbRowsInFrame
|
|
20, // iHeightRowHeader - in points
|
|
20, // iHeightRows - in points
|
|
aiWidthCols, // in points
|
|
aRowHeader,
|
|
aeTypes,
|
|
&pScrollTablePmis));
|
|
|
|
// get existing widgets on template page
|
|
|
|
A3DPDFListBox* pListViewNames = NULL;
|
|
CHECK_RET(PageGetListBoxField(pPage, std::string("DF_Steps_" + sSuffixFields).c_str(), &pListViewNames));
|
|
|
|
A3DPDFTextField* pTextTitle = NULL;
|
|
CHECK_RET(PageGetTextField(pPage, std::string("DF_Title_" + sSuffixFields).c_str(), &pTextTitle));
|
|
|
|
A3DPDFTextField* pTextDate = NULL;
|
|
CHECK_RET(PageGetTextField(pPage, std::string("DF_Date_" + sSuffixFields).c_str(), &pTextDate));
|
|
|
|
A3DPDFTextField* pTextCreatedBy = NULL;
|
|
CHECK_RET(PageGetTextField(pPage, std::string("DF_CreatedBy_" + sSuffixFields).c_str(), &pTextCreatedBy));
|
|
|
|
A3DPDFTextField* pTextCol0 = NULL;
|
|
CHECK_RET(PageGetTextField(pPage, std::string("DF_Col0_" + sSuffixFields).c_str(), &pTextCol0));
|
|
|
|
A3DPDFTextField* pTextCol1 = NULL;
|
|
CHECK_RET(PageGetTextField(pPage, std::string("DF_Col1_" + sSuffixFields).c_str(), &pTextCol1));
|
|
|
|
|
|
// DATAMODEL
|
|
|
|
// --- creation Tables and relationships
|
|
|
|
// TABLE Statics
|
|
A3DPDFDataTable* pDataTable_Statics = NULL;
|
|
CHECK_RET(CreateTable_Sple2_Statics(pDoc, pDataTable_Statics));
|
|
|
|
// TABLE ViewNames
|
|
A3DPDFDataTable* pDataTable_ViewNames = NULL;
|
|
CHECK_RET(CreateTable_Sple2_ViewNames(pDoc, pDataTable_ViewNames));
|
|
|
|
// TABLE 3D MODEL
|
|
A3DPDFDataTable* pDataTable_3D = NULL;
|
|
A3DPDFDataTable* pDataTable_Pmis = NULL;
|
|
int iKeyNode3dUID, iKeyPmiName, iKeyPmiType, iKeyPmiValue, iKeyPmiTol;
|
|
CHECK_RET(CreateTable_Sple2_3DModel(pDoc, pModelFile, pPRCWriteHelper,
|
|
iKeyNode3dUID, iKeyPmiName, iKeyPmiType, iKeyPmiValue, iKeyPmiTol,
|
|
pDataTable_3D, pDataTable_Pmis));
|
|
|
|
// TABLE 3D VIEWS
|
|
A3DPDFDataTable3DViews* pDataTable_3DViews = NULL;
|
|
CHECK_RET(CreateTable_Sple2_3DViews_WithCarousel(pDoc, p3DArtwork, pModelFile, pDataTable_3DViews));
|
|
|
|
// RELATIONSHIP ViewNames_To_Views
|
|
CHECK_RET(CreateRelationship_Sple2_ViewNames_To_Views(pDoc, pDataTable_ViewNames, pDataTable_3DViews));
|
|
|
|
// RELATIONSHIP Views_To_Pmis
|
|
CHECK_RET(CreateRelationship_Sple2_View_To_Pmis(pDoc, pDataTable_3DViews, pDataTable_Pmis));
|
|
|
|
// RELATIONSHIP Pmis_To_3D
|
|
//CHECK_RET(createRelationship_Sple2_Pmis_To_3D(pDoc, pDataTable_Pmis, pDataTable_3D));
|
|
|
|
|
|
// --- binding to widgets
|
|
|
|
// --- Widgets binding for Table ViewNames
|
|
CHECK_RET(A3DPDFListBoxBindToTable(pListViewNames, pDataTable_ViewNames, 0));
|
|
|
|
// --- Widgets binding for Table Static
|
|
CHECK_RET(A3DPDFTextFieldBindToTable(pTextTitle, pDataTable_Statics, 0));
|
|
CHECK_RET(A3DPDFTextFieldBindToTable(pTextDate, pDataTable_Statics, 1));
|
|
CHECK_RET(A3DPDFTextFieldBindToTable(pTextCreatedBy, pDataTable_Statics, 2));
|
|
|
|
// --- Widgets binding for Table 3D
|
|
CHECK_RET(A3DPDF3DNodeSceneBindToTable(p3DNodeScene, pDataTable_3D, iKeyNode3dUID));// A3DPDF3DNodeScene maps only 1 col : the one with uuid node names
|
|
|
|
// --- Widgets binding for Table 3D Views
|
|
// UI of 3D annot list views
|
|
CHECK_RET(A3DPDF3DViewListBindToTable(p3DViewList, pDataTable_3DViews));
|
|
// Carousel widget binding
|
|
CHECK_RET(A3DPDF3DViewCarouselBindToTable(pViewCarousel, pDataTable_3DViews));
|
|
// widgets binding to map columns
|
|
CHECK_RET(A3DPDFTextFieldBindToTable(pTextCol0, pDataTable_3DViews, 1));// col 1 is for view name
|
|
CHECK_RET(A3DPDFTextFieldBindToTable(pTextCol1, pDataTable_3DViews, 4));// col 4 is first additional column
|
|
|
|
// --- Widgets binding for Table PMIs
|
|
const A3DInt32 piMapColumnsPmis[] = { iKeyPmiName, iKeyPmiType, iKeyPmiValue, iKeyPmiTol };
|
|
CHECK_RET(A3DPDFScrollTableBindToTable(pScrollTablePmis, pDataTable_Pmis, sizeof(piMapColumnsPmis)/sizeof(A3DInt32), piMapColumnsPmis ));
|
|
|
|
|
|
// --- Define interactions between widgets
|
|
|
|
// selection of a row in list ViewNames -> the associated elements of widget (=3d view) is selected
|
|
CHECK_RET(A3DPDFWidgetSetTargetBehaviour(pListViewNames, p3DViewList, kA3DPDFDataSelect));
|
|
// and conversely so that we can see the item selected in the listbox if the selction is done by view list or caroussel
|
|
CHECK_RET(A3DPDFWidgetSetTargetBehaviour(p3DViewList, pListViewNames, kA3DPDFDataSelect));
|
|
|
|
// selection of a row in Pmis -> the associated elements of widget (=3d nodes) are selected
|
|
CHECK_RET(A3DPDFWidgetSetTargetBehaviour( pScrollTablePmis, p3DNodeScene, kA3DPDFDataSelect ));
|
|
//... and conversely, select a node in 3d -> associated element in scroll table is highlighted
|
|
CHECK_RET(A3DPDFWidgetSetTargetBehaviour(p3DNodeScene, pScrollTablePmis, kA3DPDFDataHighlight));
|
|
|
|
// select a view in 3D annot view list -> the elements of PMIs are filtered
|
|
CHECK_RET(A3DPDFWidgetSetTargetBehaviour( p3DViewList, pScrollTablePmis, kA3DPDFDataIsolate ));
|
|
// select a view in 3D annot view list -> the elements of texts for columns are filtered
|
|
CHECK_RET(A3DPDFWidgetSetTargetBehaviour( p3DViewList, pTextCol0, kA3DPDFDataIsolate ));
|
|
CHECK_RET(A3DPDFWidgetSetTargetBehaviour( p3DViewList, pTextCol1, kA3DPDFDataIsolate ));
|
|
// select a view in 3D annot view list -> the carousel is selected
|
|
CHECK_RET(A3DPDFWidgetSetTargetBehaviour( p3DViewList, pViewCarousel, kA3DPDFDataSelect ));
|
|
|
|
// select a view in carousel -> the 3D annot view list is selected
|
|
CHECK_RET(A3DPDFWidgetSetTargetBehaviour( pViewCarousel, p3DViewList, kA3DPDFDataSelect ));
|
|
|
|
|
|
// activate a specific view when the file is opened + all actions on cascading widgets
|
|
// NULL should be specified on the widget source to select a row at init time
|
|
CHECK_RET(A3DPDFWidgetSetTargetBehaviour(NULL, p3DViewList, kA3DPDFDataSelect));
|
|
// This forces the selection on table at init time
|
|
CHECK_RET(A3DPDFDataTableSetInitIndex(pDataTable_3DViews, 1));
|
|
|
|
|
|
// cleanup 3D modelfile
|
|
CHECK_RET(A3DAsmModelFileDelete(pModelFile));
|
|
// Free the A3DRWParamsPrcWriteHelper object at the end
|
|
if (pPRCWriteHelper != NULL)
|
|
A3DRWParamsPrcWriteHelperFree(pPRCWriteHelper);
|
|
}
|
|
|
|
indexpage++;
|
|
}
|
|
|
|
// create page idx+1 from template file. we force the fields renaming to avoid duplicated names.
|
|
sSuffixFields = "uuid2";
|
|
CHECK_RET(A3DPDFDocumentAppendPageFromPDFFileAndSuffixFields(pDoc, PDF_TEMPLATE_3, sSuffixFields.c_str(), &pPage));
|
|
if(pPage != NULL)
|
|
{
|
|
// --- create and fill Fields to map to DataModel
|
|
|
|
A3DPDF3DAnnot* p3DAnnot = NULL;
|
|
A3DPDF3DArtwork* p3DArtwork = NULL;
|
|
A3DAsmModelFile* pModelFile = NULL;
|
|
// To get unique IDs, we need a A3DRWParamsPrcWriteHelper.
|
|
// A3DPDF3DStreamCreateFromModelFileAsPRC builds this object.
|
|
A3DRWParamsPrcWriteHelper* pPRCWriteHelper = NULL;
|
|
iRet = Create3DAnnot(pDoc, IN_3DFILE_3, pBlankImage, NULL, &p3DArtwork, &p3DAnnot, &pPRCWriteHelper, &pModelFile);
|
|
|
|
if(p3DAnnot != NULL && p3DArtwork != NULL && pModelFile != NULL)
|
|
{
|
|
// populating the field with the 3D annotation
|
|
CHECK_RET(A3DPDFPageFieldSet3DAnnot(pPage, std::string("DF_3DWindow_" + sSuffixFields).c_str(), p3DAnnot));
|
|
|
|
// get widget for list nodes
|
|
A3DPDF3DNodeScene* p3DNodeScene = NULL;
|
|
CHECK_RET(A3DPDF3DAnnotGet3DNodeScene( p3DAnnot, &p3DNodeScene));
|
|
|
|
|
|
// create Scroll table on the page
|
|
A3DPDFScrollTable* pScrollTableBom = NULL;
|
|
|
|
std::vector<int> aiWidthCols; // in points
|
|
aiWidthCols.push_back(130);
|
|
aiWidthCols.push_back(160);
|
|
aiWidthCols.push_back(30);
|
|
std::vector<std::string> aRowHeader;
|
|
aRowHeader.push_back("No. ARTICLE");
|
|
aRowHeader.push_back("NAME PART");
|
|
aRowHeader.push_back("QTY");
|
|
std::vector<A3DPDFEColumnType> aeTypes;
|
|
aeTypes.push_back(kA3DPDFTextContent);
|
|
aeTypes.push_back(kA3DPDFTextContent);
|
|
aeTypes.push_back(kA3DPDFTextContent);
|
|
|
|
|
|
CHECK_RET(AddScrollTable(pDoc, pPage,
|
|
20, 632, // iPosLeft, iPosTop
|
|
15, //iSliderWidth
|
|
4, // iNbRowsInFrame
|
|
20, // iHeightRowHeader - in points
|
|
20, // iHeightRows - in points
|
|
aiWidthCols, // in points
|
|
aRowHeader,
|
|
aeTypes,
|
|
&pScrollTableBom));
|
|
|
|
// get existing widgets on template page
|
|
|
|
A3DPDFTextField* pTextTitle = NULL;
|
|
CHECK_RET(PageGetTextField(pPage, std::string("DF_Title_" + sSuffixFields).c_str(), &pTextTitle));
|
|
|
|
A3DPDFTextField* pTextDate = NULL;
|
|
CHECK_RET(PageGetTextField(pPage, std::string("DF_Date_" + sSuffixFields).c_str(), &pTextDate));
|
|
|
|
A3DPDFTextField* pTextCreatedBy = NULL;
|
|
CHECK_RET(PageGetTextField(pPage, std::string("DF_CreatedBy_" + sSuffixFields).c_str(), &pTextCreatedBy));
|
|
|
|
A3DPDFTextField* pTextInstance = NULL;
|
|
CHECK_RET(PageGetTextField(pPage, std::string("DF_InstanceNode_" + sSuffixFields).c_str(), &pTextInstance));
|
|
|
|
A3DPDFTextField* pTextCol0 = NULL;
|
|
CHECK_RET(PageGetTextField(pPage, std::string("DF_Col0_" + sSuffixFields).c_str(), &pTextCol0));
|
|
|
|
A3DPDFTextField* pTextCol1 = NULL;
|
|
CHECK_RET(PageGetTextField(pPage, std::string("DF_Col1_" + sSuffixFields).c_str(), &pTextCol1));
|
|
|
|
A3DPDFButton* pButIcon = NULL;
|
|
CHECK_RET(PageGetButtonField(pPage, std::string("DF_Image_" + sSuffixFields).c_str(), &pButIcon));
|
|
|
|
// DATAMODEL
|
|
|
|
// --- creation Tables and relationships
|
|
|
|
// TABLE Statics
|
|
A3DPDFDataTable* pDataTable_Statics = NULL;
|
|
CHECK_RET(CreateTable_Sple3_Statics(pDoc, pDataTable_Statics));
|
|
|
|
// TABLE 3D MODEL + TABLE BOM + RELATIONSHIPs
|
|
A3DPDFDataTable* pDataTable_3D = NULL;
|
|
A3DPDFDataTable* pDataTable_Bom = NULL;
|
|
int iKeyNode3dUID, iKeyNode3dInstance;
|
|
int iKeyBomNumArt, iKeyBomNamePart, iKeyBomQty, iKeyBomIcon;
|
|
CHECK_RET(CreateTable_Sple3_3DModel_Bom(pDoc, pModelFile, pPRCWriteHelper,
|
|
ICONS_PATH,
|
|
iKeyNode3dUID, iKeyNode3dInstance, iKeyBomNumArt, iKeyBomNamePart, iKeyBomQty, iKeyBomIcon,
|
|
pDataTable_3D, pDataTable_Bom));
|
|
|
|
// --- binding to widgets
|
|
|
|
// --- Widgets binding for Table Static
|
|
CHECK_RET(A3DPDFTextFieldBindToTable(pTextTitle, pDataTable_Statics, 0));
|
|
CHECK_RET(A3DPDFTextFieldBindToTable(pTextDate, pDataTable_Statics, 1));
|
|
CHECK_RET(A3DPDFTextFieldBindToTable(pTextCreatedBy, pDataTable_Statics, 2));
|
|
|
|
// --- Widgets binding for Table 3D
|
|
CHECK_RET(A3DPDF3DNodeSceneBindToTable(p3DNodeScene, pDataTable_3D, iKeyNode3dUID));// A3DPDF3DNodeScene maps only 1 col : the one with uuid node names
|
|
CHECK_RET(A3DPDFTextFieldBindToTable(pTextInstance, pDataTable_3D, iKeyNode3dInstance));
|
|
|
|
// --- Widgets binding for Table BOM
|
|
const A3DInt32 piMapColumns_Bom[] = { iKeyBomNumArt, iKeyBomNamePart, iKeyBomQty };
|
|
CHECK_RET(A3DPDFScrollTableBindToTable(pScrollTableBom, pDataTable_Bom, sizeof(piMapColumns_Bom)/sizeof(A3DInt32), piMapColumns_Bom ));
|
|
CHECK_RET(A3DPDFTextFieldBindToTable(pTextCol0, pDataTable_Bom, iKeyBomNumArt));
|
|
CHECK_RET(A3DPDFTextFieldBindToTable(pTextCol1, pDataTable_Bom, iKeyBomNamePart));
|
|
const A3DInt32 piMapColumns_But[] = { iKeyBomIcon };
|
|
CHECK_RET(A3DPDFButtonBindToTable(pButIcon, pDataTable_Bom, sizeof(piMapColumns_But) / sizeof(A3DInt32), piMapColumns_But));
|
|
|
|
// --- Define interactions between widgets
|
|
|
|
// selection of a row in Bom -> 2 column values are displayed in 2 text field
|
|
CHECK_RET(A3DPDFWidgetSetTargetBehaviour( pScrollTableBom, pTextCol0, kA3DPDFDataIsolate ));
|
|
CHECK_RET(A3DPDFWidgetSetTargetBehaviour(pScrollTableBom, pTextCol1, kA3DPDFDataIsolate));
|
|
CHECK_RET(A3DPDFWidgetSetTargetBehaviour(pScrollTableBom, pButIcon, kA3DPDFDataIsolate));
|
|
|
|
// selection of a row in Bom -> the associated elements of widget (=3d nodes) are highlighted
|
|
CHECK_RET(A3DPDFWidgetSetTargetBehaviour( pScrollTableBom, p3DNodeScene, kA3DPDFDataHighlight ));
|
|
|
|
// select a node in 3D annot -> the elements of BOM (=scroll table rows) are selected (i.e. acts as if the user clicked on the BOM row)
|
|
CHECK_RET(A3DPDFWidgetSetTargetBehaviour( p3DNodeScene, pScrollTableBom, kA3DPDFDataSelect ));
|
|
|
|
// TextInstance is populated coming from a selection in 3D
|
|
CHECK_RET(A3DPDFWidgetSetTargetBehaviour( p3DNodeScene, pTextInstance, kA3DPDFDataIsolate ));
|
|
|
|
|
|
// cleanup 3D modelfile
|
|
CHECK_RET(A3DAsmModelFileDelete(pModelFile));
|
|
// Free the A3DRWParamsPrcWriteHelper object at the end
|
|
if (pPRCWriteHelper != NULL)
|
|
A3DRWParamsPrcWriteHelperFree(pPRCWriteHelper);
|
|
}
|
|
|
|
indexpage++;
|
|
}
|
|
|
|
// end document
|
|
|
|
CHECK_RET(A3DPDFDocumentSaveEx(pDoc, kA3DPDFSaveFull|kA3DPDFSaveOptimized, OUT_FILE));
|
|
|
|
|
|
return iRet;
|
|
}
|
|
|
|
|
|
A3DStatus BuildPDFDocument()
|
|
{
|
|
A3DStatus iRet = A3D_SUCCESS;
|
|
|
|
// creating a document
|
|
A3DPDFDocument* pDoc = NULL;
|
|
|
|
iRet = A3DPDFDocumentCreateEmpty(&pDoc);
|
|
if(pDoc != NULL)
|
|
{
|
|
iRet = stBuildDocument(pDoc);
|
|
if (iRet!= A3D_SUCCESS)
|
|
std::cout << "Error building document ; Error number=" << iRet << std::endl;
|
|
|
|
// need to always close the doc to clean data
|
|
int iRetClose = A3DPDFDocumentClose(pDoc);
|
|
if (iRetClose!= A3D_SUCCESS)
|
|
std::cout << "Cannot close document ; Error number=" << iRetClose << std::endl;
|
|
}
|
|
else
|
|
std::cout << "Cannot build document ; Error number=" << iRet << std::endl;
|
|
|
|
return iRet;
|
|
}
|
|
|
|
|
|
//######################################################################################################################
|
|
// Main function
|
|
#ifdef _MSC_VER
|
|
int wmain(A3DInt32, A3DUniChar**)
|
|
#else
|
|
int main(int, A3DUTF8Char**)
|
|
#endif
|
|
{
|
|
#ifndef _MSC_VER
|
|
setenv("LC_NUMERIC", "en_US.UTF-8", 1); // Locally force locale
|
|
#endif
|
|
|
|
// init A3DLIB library - automatically handled init/terminate
|
|
A3DSDKHOOPSPublishLoader sHoopsPublishLoader(_T(HOOPS_BINARY_DIRECTORY));
|
|
CHECK_RET(sHoopsPublishLoader.m_eSDKStatus);
|
|
CHECK_RET(A3DDllSetCallbacksMemory(CheckMalloc, CheckFree));
|
|
|
|
// init HOOPS Publish related PDF library - automatically handled init/terminate
|
|
// do it only only once during the life of the application
|
|
CHECK_RET(sHoopsPublishLoader.InitPDFLib());
|
|
|
|
// launch PDF treatment
|
|
A3DStatus iRet = BuildPDFDocument();
|
|
if (iRet != A3D_SUCCESS)
|
|
return iRet;
|
|
|
|
// Check memory allocations
|
|
return (int)ListLeaks();
|
|
}
|