Files
2025-12-15 22:10:55 +08:00

743 lines
27 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 DemoFunctionalities.cpp
This file demonstrates numerous functionalities of HOOPS Publish.
***********************************************************************************************************************/
#define INITIALIZE_A3D_API
#define HOOPS_PRODUCT_PUBLISH_STANDARD
#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 OUT_FILE SAMPLES_PUBLISH_GALLERY_DIRECTORY"\\sample_DemoFunctionalities.pdf"
# define POSTER_PATH SAMPLES_DATA_DIRECTORY"\\images\\pleaseactivate.bmp"
# define IN_BKIMAGE SAMPLES_PUBLISH_QUICKSTARTS_DIRECTORY"\\BackgroundImages\\Simple3_Letter_Blue_L.jpg"
# define IN_LOGOIMAGE SAMPLES_DATA_DIRECTORY"\\images\\logo_e.jpg"
# define IN_POSTER_IMAGE1 SAMPLES_DATA_DIRECTORY"\\images\\Carter_poster.jpg"
# define IN_3DFILE SAMPLES_DATA_DIRECTORY"\\prc\\Crank-Pulley.pdf"
# define IN_3DFILE2 SAMPLES_DATA_DIRECTORY"\\prc\\Crank-Valve.pdf"
# define IN_3DFILE3 SAMPLES_DATA_DIRECTORY"\\prc\\Crank-Instructions.prc"
# define IN_3DFILE4 SAMPLES_DATA_DIRECTORY"\\prc\\Carter.prc"
# define IN_MAPIMAGE SAMPLES_DATA_DIRECTORY"\\images\\colormap.jpg"
# define EXTRA_PAGE SAMPLES_DATA_DIRECTORY"\\pdf_templates\\DemoFuncTables.pdf"
# define ATTACHED_FILE SAMPLES_DATA_DIRECTORY"\\pdf_templates\\DemoFuncTables.xls"
#else
# define OUT_FILE SAMPLES_PUBLISH_GALLERY_DIRECTORY"/sample_DemoFunctionalities.pdf"
# define POSTER_PATH SAMPLES_DATA_DIRECTORY"/images/pleaseactivate.bmp"
# define IN_BKIMAGE SAMPLES_PUBLISH_QUICKSTARTS_DIRECTORY"/BackgroundImages/Simple3_Letter_Blue_L.jpg"
# define IN_LOGOIMAGE SAMPLES_DATA_DIRECTORY"/images/logo_e.jpg"
# define IN_POSTER_IMAGE1 SAMPLES_DATA_DIRECTORY"/images/Carter_poster.jpg"
# define IN_3DFILE SAMPLES_DATA_DIRECTORY"/prc/Crank-Pulley.pdf"
# define IN_3DFILE2 SAMPLES_DATA_DIRECTORY"/prc/Crank-Valve.pdf"
# define IN_3DFILE3 SAMPLES_DATA_DIRECTORY"/prc/Crank-Instructions.prc"
# define IN_3DFILE4 SAMPLES_DATA_DIRECTORY"/prc/Carter.prc"
# define IN_MAPIMAGE SAMPLES_DATA_DIRECTORY"/images/colormap.jpg"
# define EXTRA_PAGE SAMPLES_DATA_DIRECTORY"/pdf_templates/DemoFuncTables.pdf"
# define ATTACHED_FILE SAMPLES_DATA_DIRECTORY"/pdf_templates/DemoFuncTables.xls"
#endif
// rgb colors
#define COL_BLACK 0.0, 0.0, 0.0
#define COL_RED 1.0, 0.0, 0.0
#define COL_LIGHTGREY 0.4, 0.4, 0.4
#define COL_LIGHTBLUE 0.0, 0.5, 0.5
const size_t MAXSZFILENAME = 4096;
//######################################################################################################################
// 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 iPosLeft, A3DInt32 iPosBottom)
{
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, iPosLeft, iPosBottom)); // iPosLeft, iPosBottom from the bottom left
return iRet;
}
//######################################################################################################################
// displays an image on the page
A3DStatus WriteImage(A3DPDFDocument* pDoc, A3DPDFPage* pPage, const A3DUTF8Char* pcFileName,
int iLeft, int iBottom, int iRight, int iTop)
{
A3DStatus iRet = A3D_SUCCESS;
A3DPDFImage* pImage = NULL;
CHECK_RET(A3DPDFImageCreateFromFile(pDoc, pcFileName, kA3DPDFImageFormatUnknown, &pImage));
// positioning the object on the page
A3DPDFRectData sPos;
A3D_INITIALIZE_DATA(A3DPDFRectData, sPos);
// coordinates are from bottom left of the page
sPos.m_iLeft = iLeft; // lower left x
sPos.m_iBottom = iBottom; // lower left y
sPos.m_iRight = iRight; // upper right x
sPos.m_iTop = iTop; // upper right y
CHECK_RET(A3DPDFPageInsertImage2(pPage, pImage, &sPos));
return iRet;
}
//######################################################################################################################
// writes a link on the page
A3DStatus WriteLink(A3DPDFDocument* pDoc, A3DPDFPage* pPage, A3DPDFELinkHighlightMode eHighlightingMode, A3DInt32 iBorderWidth,
A3DDouble dR, A3DDouble dG, A3DDouble dB,
int iLeft, int iBottom, int iRight, int iTop,
A3DPDFLink** ppLink)
{
A3DStatus iRet = A3D_SUCCESS;
*ppLink = NULL;
A3DPDFLinkData sLinkData;
A3D_INITIALIZE_DATA(A3DPDFLinkData, sLinkData);
sLinkData.m_eHighlightingMode = eHighlightingMode;
sLinkData.m_iBorderWidth = iBorderWidth;
sLinkData.m_sColor.m_dRed = dR;
sLinkData.m_sColor.m_dGreen = dG;
sLinkData.m_sColor.m_dBlue = dB;
CHECK_RET(A3DPDFLinkCreate(pDoc, &sLinkData, ppLink));
// positioning the object on the page
A3DPDFRectData sPos;
A3D_INITIALIZE_DATA(A3DPDFRectData, sPos);
// coordinates are from bottom left of the page
sPos.m_iLeft = iLeft; // lower left x
sPos.m_iBottom = iBottom; // lower left y
sPos.m_iRight = iRight ; // upper right x
sPos.m_iTop = iTop ; // upper right y
CHECK_RET(A3DPDFPageInsertLink(pPage, *ppLink, &sPos));
return iRet;
}
//######################################################################################################################
A3DStatus Create3DAnnot(A3DPDFDocument* pDoc,
const A3DUTF8Char* pcFileName,
A3DPDFImage* pPoster,
const A3DUTF8Char* pcInjsfile,
A3DPDFELighting eLighting, A3DPDFERenderingStyle eRenderingStyle,
bool bExplicitActivDesactiv,
A3DPDF3DArtwork** pp3DArtwork,
A3DPDF3DAnnot** pp3DAnnot,
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, NULL));
}
if(pStream != NULL)
{
// creating the 3D artwork
*pp3DArtwork = NULL;
A3DPDF3DArtworkData2 s3DArtworkData;
A3D_INITIALIZE_DATA(A3DPDF3DArtworkData2, s3DArtworkData);
s3DArtworkData.m_pStream = pStream;
s3DArtworkData.m_sDisplaySectionData.m_bAddSectionCaps = true;
s3DArtworkData.m_pcJavaScriptFileName = const_cast<A3DUTF8Char*>(pcInjsfile);
CHECK_RET(A3DPDF3DArtworkCreate2(pDoc, &s3DArtworkData, pp3DArtwork));
A3DPDF3DAnnotData sAnnotData;
A3D_INITIALIZE_DATA(A3DPDF3DAnnotData, sAnnotData);
sAnnotData.m_bOpenModelTree = false;
sAnnotData.m_bShowToolbar = false;
sAnnotData.m_eLighting = eLighting;
sAnnotData.m_eRenderingStyle = eRenderingStyle;
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 = bExplicitActivDesactiv ? kA3DPDFActivExplicitActivation : kA3DPDFActivPageOpened;
sAnnotData.m_eDesactivateWhen = bExplicitActivDesactiv ? kA3DPDFActivExplicitDesactivation : kA3DPDFActivPageClosed;
sAnnotData.m_iAppearanceBorderWidth = 0;
sAnnotData.m_pPosterImage = pPoster; // default poster automatically generated
sAnnotData.m_p3DArtwork = *pp3DArtwork;
CHECK_RET(A3DPDF3DAnnotCreate(pDoc, &sAnnotData, pp3DAnnot));
// cleaning up -- WARNING: DO NOT CALL THIS BEFORE inserting the 3D annot
//CHECK_RET(A3DAsmModelFileDelete(pModelFile));
}
return iRet;
}
A3DUTF8Char pcHtmlTablePage1[] = "<table class=\"gridtable\"> \
<tr>\
<th>Deviation</th><th># of Points</th><th>% of Total</th>\
</tr>\
<tr>\
<td>0.109</td><td>16903</td><td>33.9</td>\
</tr>\
<tr>\
<td>0.218</td><td>5124</td><td>10.3</td>\
</tr>\
<tr>\
<td>0.327</td><td>7811</td><td>15.6</td>\
</tr>\
<tr>\
<td>0.436</td><td>7811</td><td>15.6</td>\
</tr>\
<tr>\
<td>0.545</td><td>6605</td><td>13.2</td>\
</tr>\
<tr>\
<td>0.654</td><td>1688</td><td>3.4</td>\
</tr>\
<tr>\
<td>0.763</td><td>1279</td><td>2.6</td>\
</tr>\
<tr>\
<td>0.872</td><td>1109</td><td>2.2</td>\
</tr>\
<tr>\
<td>0.981</td><td>1035</td><td>2.1</td>\
</tr>\
<tr>\
<td>1.09</td><td>565</td><td>1.1</td>\
</tr>\
</table>";
A3DUTF8Char pcHtmlStyle[] = "<style type=\"text/css\"> \
table.gridtable {\
font-family: helvetica;\
font-size:10pt;\
text-align: center;\
border-width: 0pt;\
border-collapse: collapse;\
}\
table.gridtable th {\
border-width: 0pt;\
border-style: solid;\
background-color: #dedede;\
padding: 0pt;\
width:100pt;\
height:12pt;\
max-width:100pt;\
min-width:100pt;\
}\
table.gridtable td {\
border-width: 0pt;\
border-style: solid;\
background-color: #ffffff;\
padding: 0pt;\
width:100pt;\
height:12pt;\
max-width:100pt;\
min-width:100pt;\
}\
table.gridtable td.link {\
text-decoration:underline;\
color:blue;\
}\
table.gridtable td.pass {\
background-color: rgb(0,255,0);\
}\
table.gridtable td.fail {\
background-color: rgb(255,0,0);\
}\
</style>;";
A3DStatus BuildPDFDocument()
{
A3DStatus iRet = A3D_SUCCESS;
A3DInt32 nbpages = -1;
int indexpage = 0;
// creating a document
A3DPDFDocument* pDoc = NULL;
CHECK_RET(A3DPDFDocumentCreateEmpty(&pDoc));
if (pDoc != NULL)
{
// 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 shows miscellaneous functionalities of HOOS Publish");
sInformationData.m_pcAuthor = const_cast<A3DUTF8Char*>("Tech Soft 3D");
CHECK_RET(A3DPDFDocumentSetInformation(pDoc, &sInformationData));
A3DPDFPage* pPage = NULL;
// creating a poster image to be used as a poster for 3D.
A3DPDFImage* pBlankImage = NULL;
A3DPDFImageCreateFromFile(pDoc, POSTER_PATH, kA3DPDFImageFormatUnknown, &pBlankImage);
// create page 1
A3DPDFPageData2 sPageData;
A3D_INITIALIZE_DATA(A3DPDFPageData2, sPageData);
sPageData.m_ePageOrientation = kA3DPDFPageLandscape;
sPageData.m_ePageSize = kA3DPDFPageLetter; // standard letter format: 612 x 792
int iPageWidth = 792, iPageHeight = 612;
CHECK_RET(A3DPDFDocumentAppendNewPage2(pDoc, &sPageData, &pPage));
if (pPage != NULL)
{
// all the posX and posY parameters for WriteImage are from the bottom left!
// background image
const int iBkImageRes = 150;
const int iBkImageW = 1648 * 72 / iBkImageRes;
const int iBkImageH = 1276 * 72 / iBkImageRes;
const int iBkLeft = 0; // lower left x
const int iBkBottom = 0; // lower left y
CHECK_RET(WriteImage(pDoc, pPage, IN_BKIMAGE, iBkLeft, iBkBottom, iBkLeft + iBkImageW, iBkBottom + iBkImageH));
// logo image
const int iLogoRes = 72;
// factor / 3 to reduce the size of the logo
const int iLogoW = (int)(195 * 72 / iLogoRes / 3);
const int iLogoH = (int)(219 * 72 / iLogoRes / 3);
const int iLogoLeft = 10; // lower left x
const int iLogoBottom = iPageHeight - 42 - iLogoH; // lower left y
CHECK_RET(WriteImage(pDoc, pPage, IN_LOGOIMAGE, iLogoLeft, iLogoBottom, iLogoLeft + iLogoW, iLogoBottom + iLogoH));
// title in black
CHECK_RET(WriteTextString(pDoc, pPage, kA3DPDFFontHelveticaBold, 50, COL_BLACK,
"Crank", 250, iPageHeight - 103));
// header right line1 in light grey
CHECK_RET(WriteTextString(pDoc, pPage, kA3DPDFFontHelveticaBold, 10, COL_LIGHTGREY,
"Emulate Manufacturing", iPageWidth - 150, iPageHeight - 60));
// header right line2 in light grey
CHECK_RET(WriteTextString(pDoc, pPage, kA3DPDFFontHelvetica, 10, COL_LIGHTGREY,
"Tel: +44 123 456 789", iPageWidth - 150, iPageHeight - 70));
// header right line3 in light grey
CHECK_RET(WriteTextString(pDoc, pPage, kA3DPDFFontHelvetica, 10, COL_LIGHTGREY,
"Fax: +44 123 467 890", iPageWidth - 150, iPageHeight - 80));
// header right line4 in light grey
CHECK_RET(WriteTextString(pDoc, pPage, kA3DPDFFontHelvetica, 10, COL_LIGHTGREY,
"Email: sales@emulate-man.com", iPageWidth - 150, iPageHeight - 90));
// header right line5 in light grey
CHECK_RET(WriteTextString(pDoc, pPage, kA3DPDFFontHelvetica, 10, COL_LIGHTGREY,
"www.emulate-man.com", iPageWidth - 150, iPageHeight - 100));
// bottom text in red
CHECK_RET(WriteTextString(pDoc, pPage, kA3DPDFFontHelvetica, 20, COL_RED,
"Company Confidential: Do Not Redistribute", 200, 30));
A3DPDF3DAnnot* p3DAnnot = NULL;
A3DPDF3DArtwork* p3DArtwork = NULL;
A3DAsmModelFile* pModelFile = NULL;
iRet = Create3DAnnot(pDoc, IN_3DFILE3, pBlankImage, NULL,
kA3DPDFLightHeadlamp, kA3DPDFRenderingSolid, false,
&p3DArtwork, &p3DAnnot, &pModelFile);
if (p3DAnnot != NULL)
{
// position the 3D annotation in the page
A3DPDFRectData sPos;
A3D_INITIALIZE_DATA(A3DPDFRectData, sPos);
// coordinates are from bottom left of the page
sPos.m_iLeft = 150; // lower left x
sPos.m_iBottom = 100; // lower left y
sPos.m_iRight = iPageWidth - 150; // upper right x
sPos.m_iTop = iPageHeight - 145; // upper right y
CHECK_RET(A3DPDFPageInsert3DAnnot(pPage, p3DAnnot, &sPos));
// cleanup 3D modelfile
CHECK_RET(A3DAsmModelFileDelete(pModelFile));
}
indexpage++;
}
// import pages from PDF file (not template)
CHECK_RET(A3DPDFDocumentAppendPageFromPDFFileEx(pDoc, EXTRA_PAGE, false, &pPage));
// browse new pages. in this example, we know we want to insert a 3D model in the 2 first pages
CHECK_RET(A3DPDFDocumentGetNumberPages(pDoc, &nbpages));
int indexpageprev = indexpage;
for (indexpage = indexpageprev; indexpage < nbpages; indexpage++)
{
CHECK_RET(A3DPDFDocumentGetPage(pDoc, indexpage, &pPage));
if (pPage != NULL)
{
// we have to know the size of the imported pages
// for any reason, these excel generated PDF are in a box [-12, 583 / 12, 853]
//const int iPageWidth = 595, iPageHeight = 841;
// in this example, we know where we want to insert the 3D
A3DPDFRectData sPos;
A3D_INITIALIZE_DATA(A3DPDFRectData, sPos);
// coordinates are from bottom left of the page
sPos.m_iLeft = 44 - 12; // lower left x
sPos.m_iBottom = 36 + 12; // lower left y
sPos.m_iRight = 595 - 44 - 12; // upper right x
sPos.m_iTop = 400 + 12; // upper right y
A3DPDF3DAnnot* p3DAnnot = NULL;
A3DPDF3DArtwork* p3DArtwork = NULL;
A3DAsmModelFile* pModelFile = NULL;
// 3D only in first 2 pages
if (indexpage - indexpageprev == 0)
iRet = Create3DAnnot(pDoc, IN_3DFILE, pBlankImage, NULL,
kA3DPDFLightCADOptimized, kA3DPDFRenderingSolid, false,
&p3DArtwork, &p3DAnnot, &pModelFile);
else if (indexpage - indexpageprev == 1)
iRet = Create3DAnnot(pDoc, IN_3DFILE2, pBlankImage, NULL,
kA3DPDFLightCADOptimized, kA3DPDFRenderingSolid, false,
&p3DArtwork, &p3DAnnot, &pModelFile);
// position the 3D annotation in the page
if (p3DAnnot != NULL)
{
CHECK_RET(A3DPDFPageInsert3DAnnot(pPage, p3DAnnot, &sPos));
// cleanup 3D modelfile
if (pModelFile != NULL)
CHECK_RET(A3DAsmModelFileDelete(pModelFile));
}
}
}
sPageData.m_ePageOrientation = kA3DPDFPagePortrait;
sPageData.m_ePageSize = kA3DPDFPageLetter; // standard letter format: 612 x 792
iPageWidth = 612;
iPageHeight = 792;
CHECK_RET(A3DPDFDocumentAppendNewPage2(pDoc, &sPageData, &pPage));
if (pPage != NULL)
{
// table creation
// Warning: table creation is only available using the free add-on TableToPDF.
// The usage of tables using HOOPS Publish add-on requires our customer's
// application to comply with LGPL requirements.
// TableToPDF can be downloaded at http://developer.techsoft3d.com/tabletopdf/.
// The deployment process is simple and just requires to copy the provided DLLs in
// the HOOPS Publish binaries folder.
A3DPDFTable* pTable;
A3DPDFTableData sTableData;
A3D_INITIALIZE_DATA(A3DPDFTableData, sTableData);
sTableData.m_pcHtmlTable = pcHtmlTablePage1;
sTableData.m_pcHtmlStyle = pcHtmlStyle;
// all the posX and posY parameters for WriteImage are from the bottom left!
// logo image
const int iLogoRes = 72;
// factor / 3 to reduce the size of the logo
const int iLogoW = (int)(195 * 72 / iLogoRes / 3);
const int iLogoH = (int)(219 * 72 / iLogoRes / 3);
const int iLogoLeft = 69; // lower left x
const int iLogoBottom = iPageHeight - 34 - iLogoH; // lower left y
CHECK_RET(WriteImage(pDoc, pPage, IN_LOGOIMAGE, iLogoLeft, iLogoBottom, iLogoLeft + iLogoW, iLogoBottom + iLogoH));
// link
A3DPDFLink* pLink = NULL;
CHECK_RET(WriteLink(pDoc, pPage, kA3DPDFLinkHighlightOutline, 0, COL_LIGHTBLUE,
iLogoLeft, iLogoBottom, iLogoLeft + iLogoW, iLogoBottom + iLogoH,
&pLink));
// set action on link
if (pLink != NULL)
{
A3DPDFAction* pAction = NULL;
A3DPDFActionLaunchURLData sActionData;
A3D_INITIALIZE_DATA(A3DPDFActionLaunchURLData, sActionData);
sActionData.m_pcURL = const_cast<A3DUTF8Char*>("http://www.techsoft3d.com/");
CHECK_RET(A3DPDFActionLaunchURLCreate(&sActionData, &pAction));
CHECK_RET(A3DPDFLinkAddAction(pLink, pAction));
}
// map image
const int iMapRes = 72;
// factor / 1.8 to reduce the size of the image
const int iMapH = (int)(309 * 72 / iMapRes / 1.8);
const int iMapW = (int)(204 * 72 / iMapRes / 1.8);
const int iMapLeft = 490; // lower left x
const int iMapBottom = iPageHeight - 195 - iMapH; // lower left y
CHECK_RET(WriteImage(pDoc, pPage, IN_MAPIMAGE, iMapLeft, iMapBottom, iMapLeft + iMapW, iMapBottom + iMapH));
// title in black
CHECK_RET(WriteTextString(pDoc, pPage, kA3DPDFFontHelveticaBold, 20, COL_BLACK,
"Model Validation Report", 213, iPageHeight - 70));
// table title line
CHECK_RET(WriteTextString(pDoc, pPage, kA3DPDFFontHelveticaBold, 12, COL_BLACK,
"Deviation Distribution", 230, iPageHeight - 520));
// Warning: the TableToPDF DLL must be in the HOOPS Publish binary directory.
iRet = A3DPDFTableCreate(pDoc, &sTableData, &pTable);
if (iRet == A3DPDF_CANNOT_LOAD_TABLETOPDF_DLL)
{
std::cout << "The TableToPDF add-on is required to run this sample. Please add the binaries from the Tabletopdf_redist archive to this installation then run this sample again.\n";
CHECK_RET(WriteTextString(pDoc, pPage, kA3DPDFFontHelveticaBold, 20, COL_RED,
"The TableToPDF add-on is required to add table on this page", 10, iPageHeight - 600));
}
else
{
// 3 columns size 100 makes table size 300
int iLeft = (iPageWidth - 300) / 2;
CHECK_RET(A3DPDFPageInsertTable(pPage, pTable, iLeft, iPageHeight - 540));
}
// bottom text line
CHECK_RET(WriteTextString(pDoc, pPage, kA3DPDFFontHelvetica, 10, COL_BLACK,
"Adden & Hart LLC., 123 ABC Way, Dublin, Ireland | +353.1.847.6324 | www.addenandhart.com", 93, iPageHeight - 780));
// creating a poster image to be used as a poster for 3D.
A3DPDFImage* pImage = NULL;
A3DPDFImageCreateFromFile(pDoc, IN_POSTER_IMAGE1, kA3DPDFImageFormatUnknown, &pImage);
// 3D model
A3DPDF3DAnnot* p3DAnnot = NULL;
A3DPDF3DArtwork* p3DArtwork = NULL;
A3DAsmModelFile* pModelFile = NULL;
iRet = Create3DAnnot(pDoc, IN_3DFILE4, pImage, NULL,
kA3DPDFLightCADOptimized, kA3DPDFRenderingSolidWireframe, true,
&p3DArtwork, &p3DAnnot, &pModelFile);
if (p3DAnnot != NULL)
{
// position the 3D annotation in the page
A3DPDFRectData sPos;
A3D_INITIALIZE_DATA(A3DPDFRectData, sPos);
// coordinates are from bottom left of the page
sPos.m_iLeft = 24; // lower left x
sPos.m_iBottom = iPageHeight - 455; // lower left y
sPos.m_iRight = 478; // upper right x
sPos.m_iTop = iPageHeight - 125; // upper right y
CHECK_RET(A3DPDFPageInsert3DAnnot(pPage, p3DAnnot, &sPos));
// cleanup 3D modelfile
CHECK_RET(A3DAsmModelFileDelete(pModelFile));
}
}
// add a page footer to each page except first one
// note that pages generated by external applications such as excel in this example
// might crop the page a little bit, hence difficulties in positioning the objects.
CHECK_RET(A3DPDFDocumentGetNumberPages(pDoc, &nbpages));
for (indexpage = 1; indexpage < nbpages; indexpage++)
{
CHECK_RET(A3DPDFDocumentGetPage(pDoc, indexpage, &pPage));
if (pPage != NULL)
{
A3DUTF8Char acPageTxt[2048];
sprintf(acPageTxt, "Page %i", indexpage);
CHECK_RET(WriteTextString(pDoc, pPage, kA3DPDFFontHelvetica, 8, COL_BLACK, acPageTxt, 10, 18));
}
}
// add properties to the document
/*
// setting passwords and permissions (please uncomment to try the feature)
CHECK_RET(A3DPDFDocumentSetPasswordSecurity(pDoc,
"myuserpassword", "myownerpassword",
kA3DPDFDocumentPermDocAssembly + kA3DPDFDocumentPermPrint,
kA3DPDFEncryptAll));
*/
// adding the file attachment
CHECK_RET(A3DPDFDocumentAddFileAttachment(pDoc, ATTACHED_FILE, "Excel file for measures"));
// end document
CHECK_RET(A3DPDFDocumentSaveEx(pDoc, kA3DPDFSaveFull|kA3DPDFSaveOptimized, OUT_FILE));
CHECK_RET(A3DPDFDocumentClose(pDoc));
}
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();
}