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

799 lines
30 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 PDFWithBOMAndCarousel.cpp
***********************************************************************************************************************/
#define INITIALIZE_A3D_API
#define HOOPS_PRODUCT_PUBLISH_ADVANCED
#include <A3DSDKIncludes.h>
#include "../common.hpp"
#include "../CommonInit.h"
#include <vector>
#include <sstream>
// 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 SAMPLES_DATA_DIRECTORY"\\prc\\__drill.prc"
# define IN_PDF_TEMPLATE SAMPLES_DATA_DIRECTORY"\\pdf_templates\\PDFWithBOMAndCarouselTemplate.pdf"
# define IN_POSTERIMAGE SAMPLES_DATA_DIRECTORY"\\images\\empty.jpg"
# define OUT_FILE SAMPLES_PUBLISH_GALLERY_DIRECTORY"\\sample_PDFWithBOMAndCarousel.pdf"
#else
# define IN_3DFILE SAMPLES_DATA_DIRECTORY"/prc/__drill.prc"
# define IN_PDF_TEMPLATE SAMPLES_DATA_DIRECTORY"/pdf_templates/PDFWithBOMAndCarouselTemplate.pdf"
# define IN_POSTERIMAGE SAMPLES_DATA_DIRECTORY"/images/empty.jpg"
# define OUT_FILE SAMPLES_PUBLISH_GALLERY_DIRECTORY"/sample_PDFWithBOMAndCarousel.pdf"
#endif
const size_t MAXSZFILENAME = 4096;
// rgb colors
#define COL_RED 1.0, 0.0, 0.0
#if defined _MSC_VER
#define snprintf _snprintf
#endif
std::string intToString(int i)
{
std::ostringstream oss;
oss << i;
return oss.str();
}
//######################################################################################################################
// 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;
}
//######################################################################################################################
A3DVoid mallocAndSetString(const A3DUTF8Char* srcString, A3DUTF8Char*& destString)
{
// we return empty strings rather than NULL because some strings usages crash with NULL values
// (for example std::string xx = NULL crashes !)
unsigned int uiSize = (unsigned int)(srcString ? strlen(srcString) : 0);
destString = (A3DUTF8Char*)CheckMalloc((uiSize + 1) * sizeof(A3DUTF8Char));
if (uiSize > 0)
{
strcpy(destString, srcString);
}
destString[uiSize] = 0;
}
//######################################################################################################################
// cleaning functions
void stFreeTable(A3DPDFDataTableData &sTableData)
{
for (A3DUns32 ir = 0; ir < sTableData.m_iNbRows ; ir++)
{
for(A3DUns32 ic = 0; ic < sTableData.m_iNbCols ; ic++)
CheckFree(sTableData.m_ppcTexts[ir*sTableData.m_iNbCols+ic]);
}
CheckFree(sTableData.m_ppcTexts);
}
void stFreeTable3DViews(A3DPDFTable3DViewsData &sTable3DViewsData)
{
if (sTable3DViewsData.m_piViewIndexes)
CheckFree(sTable3DViewsData.m_piViewIndexes);
if (sTable3DViewsData.m_ppcViewLabels)
{
for(unsigned int ic = 0; ic < sTable3DViewsData.m_iNbViews ; ic++)
if (sTable3DViewsData.m_ppcViewLabels[ic])
CheckFree(sTable3DViewsData.m_ppcViewLabels[ic]);
CheckFree(sTable3DViewsData.m_ppcViewLabels);
}
if (sTable3DViewsData.m_ppImages)
CheckFree(sTable3DViewsData.m_ppImages);
if (sTable3DViewsData.m_pDataTableData)
{
for (A3DUns32 ir = 0; ir < sTable3DViewsData.m_pDataTableData->m_iNbRows ; ir++)
{
for(A3DUns32 ic = 0; ic < sTable3DViewsData.m_pDataTableData->m_iNbCols ; ic++)
CheckFree(sTable3DViewsData.m_pDataTableData->m_ppcTexts[ir*sTable3DViewsData.m_pDataTableData->m_iNbCols+ic]);
}
}
}
void stFreeRelationship(A3DPDFDataRelationshipData &sRelationshipData)
{
CheckFree(sRelationshipData.m_pMapIndexes);
}
//######################################################################################################################
A3DStatus stCreateTable(A3DPDFDocument* pDoc, const std::vector<std::vector<std::string> > &aRows, A3DPDFDataTable*& pDataTable)
{
A3DStatus iRet = A3D_SUCCESS;
A3DUns32 iNbRows = (A3DUns32)aRows.size();
A3DUns32 iNbCols = (A3DUns32)aRows[0].size();
A3DPDFDataTableData sTableData;
A3D_INITIALIZE_DATA(A3DPDFDataTableData, sTableData);
sTableData.m_iNbRows = iNbRows;
sTableData.m_iNbCols = iNbCols;
sTableData.m_ppcTexts = (A3DUTF8Char**)CheckMalloc(iNbRows * iNbCols * A3DUns32(sizeof(A3DUTF8Char*)));
for (A3DUns32 ir = 0; ir < iNbRows; ir++)
{
for (A3DUns32 ic = 0; ic < iNbCols; ic++)
mallocAndSetString(
aRows[ir][ic].c_str(), // src
sTableData.m_ppcTexts[ir*iNbCols + ic]); // dest
}
CHECK_RET(A3DPDFDataTableCreate(pDoc, &sTableData, &pDataTable));
stFreeTable(sTableData);
return iRet;
}
A3DStatus stCreateRelationship(A3DPDFDocument* pDoc, std::vector< std::pair <size_t, size_t> > &aMapIndexes,
A3DPDFDataTable* pDataTableSource, A3DPDFDataTable* pDataTableTarget)
{
A3DStatus iRet = A3D_SUCCESS;
A3DUns32 iNbRows = (A3DUns32)aMapIndexes.size();
A3DPDFDataRelationshipData sRelationshipData;
A3D_INITIALIZE_DATA(A3DPDFDataRelationshipData, sRelationshipData);
sRelationshipData.m_iSizeMap = iNbRows;
sRelationshipData.m_pDataTableSource = pDataTableSource;
sRelationshipData.m_pDataTableTarget = pDataTableTarget;
sRelationshipData.m_pMapIndexes = (A3DPDFMapIndexData *)CheckMalloc(iNbRows * sizeof(A3DPDFMapIndexData));
memset(sRelationshipData.m_pMapIndexes, 0, iNbRows * sizeof(A3DPDFMapIndexData));
for (A3DUns32 ir = 0; ir < iNbRows; ir++)
{
sRelationshipData.m_pMapIndexes[ir].m_aiIndexes[0] = (A3DInt32)(aMapIndexes[ir].first);
sRelationshipData.m_pMapIndexes[ir].m_aiIndexes[1] = (A3DInt32)(aMapIndexes[ir].second);
}
CHECK_RET(A3DPDFDataRelationshipCreate(pDoc, &sRelationshipData));
stFreeRelationship(sRelationshipData);
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**) CheckMalloc(aViewCarouselButtons.size() * A3DUns32(sizeof(A3DUTF8Char*)));
A3DPDFButton** ppButtonsViews = (A3DPDFButton**) CheckMalloc(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)
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)
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));
// cleanup
for (size_t i=0 ; i<aViewCarouselButtons.size() ; i++)
{
CheckFree(ppButtonsNames[i]);
}
CheckFree(ppButtonsNames);
CheckFree(ppButtonsViews);
CheckFree(ppButtonsNamesPrevNext[0]);
CheckFree(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,
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 *)CheckMalloc(sScrollTableData.m_iGridNbCols*sizeof(A3DInt32));
for (size_t ic=0; ic<aiWidthCols.size(); ic++)
sScrollTableData.m_piGridWidthCells[ic]=aiWidthCols[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));
}
CheckFree(pcSTName);
// clean
if (sScrollTableData.m_piGridWidthCells!=NULL)
CheckFree( sScrollTableData.m_piGridWidthCells);
return A3D_SUCCESS;
}
A3DStatus stCreateTable_3DViews_WithCarousel(A3DPDFDocument* pDoc, A3DPDF3DArtwork* p3DArtwork, A3DAsmModelFile* pModelFile,
A3DPDFDataTable3DViews*& pDataTable)
{
A3DStatus iRet = A3D_SUCCESS;
A3DUns32 uiNbViews = 0;
A3DPDFView** ppViews = NULL;
pDataTable = NULL;
// first get views from the 3D model: do we really need a carousel
iRet = A3DPDF3DArtworkGetViews(p3DArtwork, &uiNbViews, &ppViews);
// create icons and texts for all views
A3DUns32 ui, uiFirstIcon=0, uiLastIcon=uiNbViews-1;
uiNbViews = uiLastIcon - uiFirstIcon + 1;
A3DInt32 *piViewIndexes = (A3DInt32 *)CheckMalloc(uiNbViews*sizeof(A3DInt32));
A3DUTF8Char* *ppcViewLabels = (A3DUTF8Char* *)CheckMalloc(uiNbViews*sizeof(A3DUTF8Char*));
A3DPDFImage* *ppImages = (A3DPDFImage* *)CheckMalloc(uiNbViews*sizeof(A3DPDFImage*));
for(ui=uiFirstIcon; ui<=uiLastIcon; ++ui)
{
piViewIndexes[ui-uiFirstIcon] = ui;// index in list view, ordered as in A3DPDF3DArtworkGetViews
ppcViewLabels[ui-uiFirstIcon] = NULL;//optional: labels for carousel buttons. if null, view name are used.
ppImages[ui-uiFirstIcon] = NULL; // icon for view. if kA3DPDFTableFor3DViewsComputePosters, the image is automatically generated if needed for carousel.
}
A3DPDFTable3DViewsData sTable3DViewsData;
A3D_INITIALIZE_DATA(A3DPDFTable3DViewsData, sTable3DViewsData);
sTable3DViewsData.m_iNbViews = uiNbViews;
sTable3DViewsData.m_piViewIndexes = piViewIndexes;
sTable3DViewsData.m_ppcViewLabels = ppcViewLabels;
sTable3DViewsData.m_ppImages = ppImages; // not useful if kA3DPDFTableFor3DViewsComputePosters is specified
CHECK_RET(A3DPDFDataTable3DViewsCreate(pDoc, p3DArtwork,pModelFile,
kA3DPDFTableFor3DViewsCustom | kA3DPDFTableFor3DViewsComputePosters, // kA3DPDFTableFor3DViewsComputePosters to automatically compute posters for all views specified
&sTable3DViewsData,
&pDataTable));
// clean
stFreeTable3DViews(sTable3DViewsData);
iRet = A3DPDF3DArtworkGetViews(NULL, NULL, &ppViews);
return iRet;
}
A3DStatus stCreateTables_3D_Bom(A3DPDFDocument* pDoc,
A3DInt32 iNumberOfElements,
A3DPDFBomElementInfoData* &pBomElementInfos,
A3DPDF3DNodesReferencesData* &p3DNodesReferences,
int& iKeyNode3dUID,
A3DPDFDataTable*& pDataTable3D,
A3DPDFDataTable*& pDataTableBom)
{
A3DStatus iRet = A3D_SUCCESS;
// structure for Tables definitions
std::vector<std::vector<std::string> > aRows3d;
std::vector<std::vector<std::string> > aRowsBom;
// structure for Relationships definitions
std::vector< std::pair <size_t,size_t> > aMapIndexes_3dToBom;
std::vector< std::pair <size_t,size_t> > aMapIndexes_BomTo3D;
std::vector<std::string> aOneRowBom;
std::vector<std::string> aOneRow3d;
for (size_t idxinbom = 0; idxinbom < (size_t)iNumberOfElements; idxinbom++)
{
// table bom entry
aOneRowBom.clear();
aOneRowBom.push_back(intToString((int)idxinbom));
aOneRowBom.push_back(pBomElementInfos[idxinbom].m_pcName);
aOneRowBom.push_back(intToString((int)p3DNodesReferences[idxinbom].m_iNbNodes));
aRowsBom.push_back(aOneRowBom);
// table 3d nodes entries
for(A3DUns32 in = 0; in < p3DNodesReferences[idxinbom].m_iNbNodes ; in++)
{
aOneRow3d.clear();
aOneRow3d.push_back(p3DNodesReferences[idxinbom].m_ppUUIDsForNodes[in]);iKeyNode3dUID = (int)aOneRow3d.size()-1;
aRows3d.push_back(aOneRow3d);
// create relationship between 3d node and bom entry
size_t idxin3dnodes = aRows3d.size()-1;
aMapIndexes_3dToBom.push_back( std::make_pair (idxin3dnodes, idxinbom) );
aMapIndexes_BomTo3D.push_back( std::make_pair (idxinbom, idxin3dnodes) );
}
}
iRet = stCreateTable(pDoc, aRows3d, pDataTable3D);
iRet = stCreateTable(pDoc, aRowsBom, pDataTableBom);
iRet = stCreateRelationship(pDoc, aMapIndexes_3dToBom, pDataTable3D, pDataTableBom);
iRet = stCreateRelationship(pDoc, aMapIndexes_BomTo3D, pDataTableBom, pDataTable3D);
return iRet;
}
A3DStatus BuildPDFDocument()
{
A3DStatus iRet = A3D_SUCCESS;
// create empty document
A3DPDFDocument* pDoc = NULL;
CHECK_RET(A3DPDFDocumentCreateEmpty(&pDoc));
if(pDoc != NULL)
{
A3DPDFPage* pPage = NULL;
// the NULL suffix string keeps the same field names
CHECK_RET(A3DPDFDocumentAppendPageFromPDFFileAndSuffixFields(pDoc, IN_PDF_TEMPLATE, NULL, &pPage));
if(pPage != NULL)
{
// reading the input file; the file can be disposed of afterwards.
A3DPDF3DStream* pStream;
A3DAsmModelFile* pModelFile;
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 = true;
sReadParam.m_sPmi.m_pcSubstitutionFont = const_cast<A3DUTF8Char*>("Arial Black");
sReadParam.m_sTessellation.m_eTessellationLevelOfDetail = kA3DTessLODMedium;
sReadParam.m_sMultiEntries.m_bLoadDefault = true;
sReadParam.m_sAssembly.m_bUseRootDirectory = true;
CHECK_RET(A3DAsmModelFileLoadFromFile(IN_3DFILE, &sReadParam, &pModelFile));
if(pModelFile)
{
// 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);
sParamsExportData.m_bCompressBrep = true;
sParamsExportData.m_bCompressTessellation = true;
sParamsExportData.m_eCompressBrepType = kA3DCompressionHigh;
// To get unique IDs, we need a A3DRWParamsPrcWriteHelper.
// A3DPDF3DStreamCreateFromModelFileAsPRC builds this object.
A3DRWParamsPrcWriteHelper* pA3DRWParamsPrcWriteHelper = NULL;
CHECK_RET(A3DPDF3DStreamCreateFromModelFileAsPRC(pDoc, pModelFile, &sParamsExportData, &pStream, &pA3DRWParamsPrcWriteHelper));
// creating the poster image
A3DPDFImage* pImage;
CHECK_RET(A3DPDFImageCreateFromFile(pDoc, IN_POSTERIMAGE, kA3DPDFImageFormatUnknown, &pImage));
// creating the 3D artwork
A3DPDF3DArtwork* p3DArtwork;
A3DPDF3DArtworkData2 s3DArtworkData;
A3D_INITIALIZE_DATA(A3DPDF3DArtworkData2, s3DArtworkData);
s3DArtworkData.m_pStream = pStream;
//s3DArtworkData.m_pcJavaScriptFileName = IN_JSFILE;
s3DArtworkData.m_bActivatePMICrossHighlight=true;
//s3DArtworkData.m_bAddPMISemanticInformation=true;
s3DArtworkData.m_bKeepNativeDefaultView=true;
s3DArtworkData.m_sDisplaySectionData.m_bAddSectionCaps = true;
s3DArtworkData.m_sDisplaySectionData.m_bIsIntersectionVisible = true;
s3DArtworkData.m_sDisplaySectionData.m_sIntersectionColor.m_dRed = 0.;
s3DArtworkData.m_sDisplaySectionData.m_sIntersectionColor.m_dGreen = 1.;
s3DArtworkData.m_sDisplaySectionData.m_sIntersectionColor.m_dBlue = 0.;
CHECK_RET(A3DPDF3DArtworkCreate2(pDoc, &s3DArtworkData, &p3DArtwork));
A3DPDF3DAnnotData sAnnotData;
A3D_INITIALIZE_DATA(A3DPDF3DAnnotData, sAnnotData);
sAnnotData.m_bOpenModelTree = false;
sAnnotData.m_bShowToolbar = false;
sAnnotData.m_eLighting = kA3DPDFLightWhite;
sAnnotData.m_eRenderingStyle = kA3DPDFRenderingSolidOutline;
sAnnotData.m_sBackgroundColor.m_dRed = 206.0/255.0;
sAnnotData.m_sBackgroundColor.m_dGreen = 235.0/255.0;
sAnnotData.m_sBackgroundColor.m_dBlue = 251.0/255.0;
sAnnotData.m_bTransparentBackground = false;
sAnnotData.m_eActivateWhen = kA3DPDFActivPageOpened;
sAnnotData.m_eDesactivateWhen = kA3DPDFActivPageClosed;
sAnnotData.m_iAppearanceBorderWidth = 0;
sAnnotData.m_pPosterImage = pImage;
sAnnotData.m_p3DArtwork = p3DArtwork;
A3DPDF3DAnnot* p3DAnnot = NULL;
CHECK_RET(A3DPDF3DAnnotCreate(pDoc, &sAnnotData, &p3DAnnot));
// 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 = 10; // lower left x
sPos.m_iBottom = 161; // lower left y
sPos.m_iRight = 531; // upper right x
sPos.m_iTop = 552; // upper right y
iRet = A3DPDFPageInsert3DAnnot(pPage, p3DAnnot, &sPos);
// new fields with template 5:
CHECK_RET(A3DPDFPageFieldTextSetValue(pPage, "FileName", "Hammer Drill N327"));
CHECK_RET(A3DPDFPageFieldTextSetValue(pPage, "Date", "01/01/2016"));
// 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("ButScrollViewsPrev");
aViewCarouselButPrevNext.push_back("ButScrollViewsNext");
std::vector<std::string> aViewCarouselButtons;
for (int i=0 ; i<5 ; i++)
aViewCarouselButtons.push_back("ButViewCarousel"+intToString(i));
CHECK_RET(AddViewCarousel(pDoc, pPage,
2, // iLeftCarou
34, // iBottomCarou
113, // iHeigthCarousel
56, // iWidthCarouButtonPrevNext
129, // iWidthCarouButton
5, // iHorizMargin
aViewCarouselButPrevNext, aViewCarouselButtons,
&pViewCarousel));
// create Scroll table on the page
A3DPDFScrollTable* pScrollTableBom = NULL;
std::vector<int> aiWidthCols; // in points
aiWidthCols.push_back(22);
aiWidthCols.push_back(176);
aiWidthCols.push_back(25);
std::vector<std::string> aRowHeader;
aRowHeader.push_back("NB");
aRowHeader.push_back("PART NAME");
aRowHeader.push_back("QTY");
CHECK_RET(AddScrollTable(pDoc, pPage,
539, 578, // iPosLeft, iPosTop
15, //iSliderWidth
22, // iNbRowsInFrame
20, // iHeightRowHeader - in points
18, // iHeightRows - in points
aiWidthCols, // in points
aRowHeader,
&pScrollTableBom));
// BOM automatically built from API
A3DInt32 iNumberOfElements = 0;
A3DPDFBomElementInfoData *pBomElementInfos = NULL;
A3DPDF3DNodesReferencesData *p3DNodesReferences = NULL;
iRet = A3DPDFGetBOMInfo(pModelFile, pA3DRWParamsPrcWriteHelper,
false, // bHierarchical
&iNumberOfElements, &pBomElementInfos, &p3DNodesReferences);
// DATAMODEL
// --- creation Tables and relationships
// TABLE 3D VIEWS
A3DPDFDataTable3DViews* pDataTable_3DViews = NULL;
CHECK_RET(stCreateTable_3DViews_WithCarousel(pDoc, p3DArtwork, pModelFile, pDataTable_3DViews));
// TABLES 3D, BOM, + RELATIONSHIPs
A3DPDFDataTable* pDataTable_3D = NULL;
A3DPDFDataTable* pDataTable_Bom = NULL;
int iKeyNode3dUID;
CHECK_RET(stCreateTables_3D_Bom(pDoc, iNumberOfElements, pBomElementInfos, p3DNodesReferences,
iKeyNode3dUID, pDataTable_3D, pDataTable_Bom));
// --- binding to widgets
// --- widgets binding for Table 3D
CHECK_RET(A3DPDF3DNodeSceneBindToTable(p3DNodeScene, pDataTable_3D, iKeyNode3dUID));// 3DAnnotUIListNodes 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 for Table BOM
const A3DInt32 piMapColumns_Bom[] = { 0, 1, 2 };
CHECK_RET(A3DPDFScrollTableBindToTable(pScrollTableBom, pDataTable_Bom, sizeof(piMapColumns_Bom)/sizeof(A3DInt32), piMapColumns_Bom ));
// --- Define interactions between widgets
// 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 ));
// 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 ));
// cleanup data
iRet = A3DPDFFreeBOMInfo(iNumberOfElements, &pBomElementInfos, &p3DNodesReferences);
// cleaning up -- WARNING: DO NOT CALL THIS BEFORE A3DPDF3DArtworkCreate!
CHECK_RET(A3DAsmModelFileDelete(pModelFile));
// freeing the A3DRWParamsPrcWriteHelper object at the end
if (pA3DRWParamsPrcWriteHelper!=NULL)
A3DRWParamsPrcWriteHelperFree(pA3DRWParamsPrcWriteHelper);
/*
// adding the file attachment
sprintf_s(acFullFileName, MAXSZFILENAME, "%s%s", ASSETS_DIR, "Hammer_Drill_N327.jt");
CHECK_RET(A3DPDFDocumentAddFileAttachment(pDoc, acFullFileName, "JT version of the model"));
*/
// saving the 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);
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();
}