799 lines
30 KiB
C++
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();
|
|
|
|
}
|