/*********************************************************************************************************************** * * 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 #include "../common.hpp" #include "../CommonInit.h" #include #include // 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(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 > &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 > &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& aViewCarouselButPrevNext, std::vector& 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("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& aiWidthCols, // in points std::vector& 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("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("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(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 > aRows3d; std::vector > aRowsBom; // structure for Relationships definitions std::vector< std::pair > aMapIndexes_3dToBom; std::vector< std::pair > aMapIndexes_BomTo3D; std::vector aOneRowBom; std::vector 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("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 aViewCarouselButPrevNext; aViewCarouselButPrevNext.push_back("ButScrollViewsPrev"); aViewCarouselButPrevNext.push_back("ButScrollViewsNext"); std::vector 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 aiWidthCols; // in points aiWidthCols.push_back(22); aiWidthCols.push_back(176); aiWidthCols.push_back(25); std::vector 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(); }