/*********************************************************************************************************************** * * 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 AnimWorkinstruction.cpp This file demonstrates how to programmatically create an animation. ***********************************************************************************************************************/ #define INITIALIZE_A3D_API #include "AnimDef.hpp" #include "../CommonInit.h" #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\\_micro engine.prc" # define IN_PDFFILE SAMPLES_DATA_DIRECTORY"\\pdf_templates\\AnimWorkinstructionTemplate.pdf" # define IN_POSTERIMAGE SAMPLES_DATA_DIRECTORY"\\images\\empty.jpg" # define OUT_FILE SAMPLES_PUBLISH_GALLERY_DIRECTORY"\\sample_AnimWorkinstruction.pdf" #else # define IN_3DFILE SAMPLES_DATA_DIRECTORY"/prc/_micro engine.prc" # define IN_PDFFILE SAMPLES_DATA_DIRECTORY"/pdf_templates/AnimWorkinstructionTemplate.pdf" # define IN_POSTERIMAGE SAMPLES_DATA_DIRECTORY"/images/empty.jpg" # define OUT_FILE SAMPLES_PUBLISH_GALLERY_DIRECTORY"/sample_AnimWorkinstruction.pdf" #endif 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_PDFFILE, 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 = false; sReadParam.m_sPmi.m_pcSubstitutionFont = const_cast("Myriad CAD"); 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); CHECK_RET(A3DPDF3DStreamCreateFromModelFileAsPRC(pDoc, pModelFile, &sParamsExportData, &pStream, NULL)); // create all targets sets CreateAllTargetsSet(pModelFile); // create each steps as a different animation const int INBANIMS = 10; A3DPDFAnimation **ppAnims = (A3DPDFAnimation**)malloc(INBANIMS * A3DUns32(sizeof(A3DPDFAnimation*))); int idxAnim = 0; double dStepInitTimeOffset = 0.0; double dStepTimeDuration; double dStartStep1, dStartStep2, dStartStep3, dStartStep4, dStartStep5, dStartStep6, dStartStep7, dStartStep8; dStartStep1 = 0.0; CHECK_RET(BuildAnimationStep1(&ppAnims[idxAnim++], dStepInitTimeOffset, dStepTimeDuration)); dStepInitTimeOffset += dStepTimeDuration; dStartStep2 = dStepInitTimeOffset; CHECK_RET(BuildAnimationStep2(&ppAnims[idxAnim++], dStepInitTimeOffset, dStepTimeDuration)); dStepInitTimeOffset += dStepTimeDuration; dStartStep3 = dStepInitTimeOffset; CHECK_RET(BuildAnimationStep3(&ppAnims[idxAnim++], dStepInitTimeOffset, dStepTimeDuration)); dStepInitTimeOffset += dStepTimeDuration; dStartStep4 = dStepInitTimeOffset; CHECK_RET(BuildAnimationStep4(&ppAnims[idxAnim++], dStepInitTimeOffset, dStepTimeDuration)); dStepInitTimeOffset += dStepTimeDuration; dStartStep5 = dStepInitTimeOffset; CHECK_RET(BuildAnimationStep5(&ppAnims[idxAnim++], dStepInitTimeOffset, dStepTimeDuration)); dStepInitTimeOffset += dStepTimeDuration; dStartStep6 = dStepInitTimeOffset; CHECK_RET(BuildAnimationStep6(&ppAnims[idxAnim++], dStepInitTimeOffset, dStepTimeDuration)); dStepInitTimeOffset += dStepTimeDuration; dStartStep7 = dStepInitTimeOffset; CHECK_RET(BuildAnimationStep7(&ppAnims[idxAnim++], dStepInitTimeOffset, dStepTimeDuration)); dStepInitTimeOffset += dStepTimeDuration; dStartStep8 = dStepInitTimeOffset; // creating a poster image to be used as a poster for 3D. A3DPDFImage* pImage = NULL; 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_sDisplaySectionData.m_bAddSectionCaps = true; s3DArtworkData.m_eAnimationStyle = kA3DPDFAnimStyleBounce; s3DArtworkData.m_iNumberOfAnimations = idxAnim; s3DArtworkData.m_ppAnimations = ppAnims; CHECK_RET(A3DPDF3DArtworkCreate2(pDoc, &s3DArtworkData, &p3DArtwork)); // Default view activated at PDF opening A3DPDFView* pView; CHECK_RET(CreateView(pDoc, p3DArtwork, 334.117035, 243.555069, 101.844193, 45.135365, 43.723457, -33.948994, -0.311321, -0.183419, 0.932440, kA3DPDFOrthographicMode, 1.0 / (2 * 106), 30, true, "Default", &pView)); A3DPDF3DAnnotData sAnnotData; A3D_INITIALIZE_DATA(A3DPDF3DAnnotData, sAnnotData); sAnnotData.m_bOpenModelTree = false; sAnnotData.m_bShowToolbar = true; sAnnotData.m_eLighting = kA3DPDFLightCADOptimized; sAnnotData.m_eRenderingStyle = kA3DPDFRenderingSolid; sAnnotData.m_sBackgroundColor.m_dRed = 0.25; sAnnotData.m_sBackgroundColor.m_dGreen = 0.25; sAnnotData.m_sBackgroundColor.m_dBlue = 0.25; sAnnotData.m_bTransparentBackground = false; sAnnotData.m_eActivateWhen = kA3DPDFActivPageOpened; sAnnotData.m_eDesactivateWhen = kA3DPDFActivPageClosed; sAnnotData.m_iAppearanceBorderWidth = 0; sAnnotData.m_pPosterImage = pImage; sAnnotData.m_p3DArtwork = p3DArtwork; A3DPDF3DAnnot* p3DAnnot = NULL; CHECK_RET(A3DPDF3DAnnotCreate(pDoc, &sAnnotData, &p3DAnnot)); // populating the field with the 3D annotation CHECK_RET(A3DPDFPageFieldSet3DAnnot(pPage, "But3D", p3DAnnot)); CHECK_RET(A3DPDFPageFieldListAddItem(pPage, "ListInstructions", "Start", "Step1")); CHECK_RET(A3DPDFPageFieldListAddItem(pPage, "ListInstructions", "Remove holding screws", "Step2")); CHECK_RET(A3DPDFPageFieldListAddItem(pPage, "ListInstructions", "Remove pump mini-housing", "Step3")); CHECK_RET(A3DPDFPageFieldListAddItem(pPage, "ListInstructions", "Remove front casing", "Step4")); CHECK_RET(A3DPDFPageFieldListAddItem(pPage, "ListInstructions", "Remove pump jet", "Step5")); CHECK_RET(A3DPDFPageFieldListAddItem(pPage, "ListInstructions", "Replace washer", "Step6")); CHECK_RET(A3DPDFPageFieldListAddItem(pPage, "ListInstructions", "Re-assemble engine", "Step7")); // set an action to populate a text field with the selected item in the list A3DUTF8Char myjslist[2048]; sprintf(myjslist, "thisfield = this.getField(\"ListInstructions\");\n" "if(thisfield)\n" "{\n" " idx = thisfield.currentValueIndices;\n" " //f=this.getField(\"Details\");\n" " //f.value=thisfield.getItemAt(idx, false);\n" " selectstep(idx+1);\n" "}"); CHECK_RET(A3DPDFPageFieldSetActionJavascriptFromString(pPage, "ListInstructions", myjslist)); sprintf(myjslist, "var list = this.getField(\"ListInstructions\");\n" "if (stiSelectedStep>1)\n" "{\n" " list.currentValueIndices = (stiSelectedStep-1)-1;\n" " decselectedstep();\n" "}"); CHECK_RET(A3DPDFPageFieldSetActionJavascriptFromString(pPage, "PlayPrevious", myjslist)); sprintf(myjslist, "var list = this.getField(\"ListInstructions\");\n" "if (stiSelectedStep<7)\n" "{\n" " list.currentValueIndices = (stiSelectedStep+1)-1;\n" " incselectedstep();\n" "}"); CHECK_RET(A3DPDFPageFieldSetActionJavascriptFromString(pPage, "PlayNext", myjslist)); CHECK_RET(A3DPDFPageFieldSetActionJavascriptFromString(pPage, "PlayStep", "runanimcurrentstep();")); CHECK_RET(A3DPDFPageFieldSetActionJavascriptFromString(pPage, "PlayAll", "runanimallsteps();")); CHECK_RET(A3DPDFPageFieldSetActionJavascriptFromString(pPage, "Restart", "restartanim();")); // store javascript functions on the document. these functions can be used by javascript stored on the fields. A3DUTF8Char myjsondoc[5 * 1024]; sprintf(myjsondoc, "var stbuttonPlayer = 0;\n" "var stbuttonPlayerValInit = \"\";\n" "var stiSelectedStep = 0;\n" "var stdSelectedStepStart = 0;\n" "var stdSelectedStepEnd = 0;\n" "\n" "function incselectedstep()\n" "{\n" " if (stiSelectedStep<7)\n" " selectstep(stiSelectedStep+1);\n" "}\n" "function decselectedstep()\n" "{\n" " if (stiSelectedStep>1)\n" " selectstep(stiSelectedStep-1);\n" "}\n" "\n" "function selectstep(istep)\n" "{\n" " // activate the 3D annotation\n" " // in getAnnots3D, page index starts from 0\n" " var a3d = this.getAnnots3D(0)[0];\n" " a3d.activated=true;\n" " c3d = a3d.context3D;\n" " detailsfield = this.getField(\"Details\");\n" " dStartStep1=%lf;\n" " dStartStep2=%lf;\n" " dStartStep3=%lf;\n" " dStartStep4=%lf;\n" " dStartStep5=%lf;\n" " dStartStep6=%lf;\n" " dStartStep7=%lf;\n" " dStartStep8=%lf;\n" " \n" " stiSelectedStep = istep;\n" " \n" " if (istep==1)\n" " {\n" " detailsfield.value=\"Follow these simple steps to replace the rubber washer on the micro engine 2*2001.\";\n" " stdSelectedStepStart = dStartStep1;\n" " stdSelectedStepEnd = dStartStep2;\n" " }\n" " else if (istep==2)\n" " {\n" " detailsfield.value=\"To get access to the washer we must first remove the locking screws on the back of the engine.\";\n" " stdSelectedStepStart = dStartStep2;\n" " stdSelectedStepEnd = dStartStep3;\n" " }\n" " else if (istep==3)\n" " {\n" " detailsfield.value=\"We need to remove the mini-housing before we can remove the font facing.\";\n" " stdSelectedStepStart = dStartStep3;\n" " stdSelectedStepEnd = dStartStep4;\n" " }\n" " else if (istep==4)\n" " {\n" " detailsfield.value=\"Removing the front casing will give us access to the washer.\";\n" " stdSelectedStepStart = dStartStep4;\n" " stdSelectedStepEnd = dStartStep5;\n" " }\n" " else if (istep==5)\n" " {\n" " detailsfield.value=\"To get access to the washer we also need to remove the pump jet.\";\n" " stdSelectedStepStart = dStartStep5;\n" " stdSelectedStepEnd = dStartStep6;\n" " }\n" " else if (istep==6)\n" " {\n" " detailsfield.value=\"We can now replace the washer. You may need to first add lubricant in case the washer is impacted.\";\n" " stdSelectedStepStart = dStartStep6;\n" " stdSelectedStepEnd = dStartStep7;\n" " }\n" " else if (istep==7)\n" " {\n" " detailsfield.value=\"Now re-assemble everything in the reverse order to which you took them off.\";\n" " stdSelectedStepStart = dStartStep7;\n" " stdSelectedStepEnd = dStartStep8;\n" " }\n" " butStep = this.getField(\"PlayStep\");\n" " butStep.buttonSetCaption(\"Play Step\");\n" " butStep.fillColor = color.white;\n" " runanim(\"PlayStep\", \"Play Step\", stdSelectedStepStart, stdSelectedStepEnd);\n" "}" "\n" "function funcCallbackStart()\n" "{\n" " if (stbuttonPlayer)\n" " {\n" " stbuttonPlayer.buttonSetCaption(\"Pause\");\n" " stbuttonPlayer.fillColor = color.gray;\n" " }\n" "}\n" "function funcCallbackStop()\n" "{\n" " if (stbuttonPlayer)\n" " {\n" " stbuttonPlayer.buttonSetCaption(stbuttonPlayerValInit);\n" " stbuttonPlayer.fillColor = color.white;\n" " }\n" "}\n" "\n" "//sButPlayerValInit= \"Play Step\" or \"Play All\"\n" "function runanim(sButPlayerName, sButPlayerValInit, dSelectedStepStart, dSelectedStepEnd)\n" "{\n" " pageIndex = this.pageNum;\n" " annotIndex = 0;\n" " annot = getAnnots3D(pageIndex)[annotIndex];\n" " if (annot != undefined) \n" " {\n" " context = annot.context3D;\n" " butStep = this.getField(\"PlayStep\");\n" " butAll = this.getField(\"PlayAll\");\n" " butCurrent = this.getField(sButPlayerName);\n" "\n" " if ( butCurrent.buttonGetCaption() == sButPlayerValInit ) \n" " {\n" " butStep.buttonSetCaption(\"Play Step\");\n" " butStep.fillColor = color.white;\n" " butAll.buttonSetCaption(\"Play All\");\n" " butAll.fillColor = color.white;\n" " butCurrent.buttonSetCaption(\"Pause\");\n" " butCurrent.fillColor = color.gray;\n" " stbuttonPlayer = butCurrent;\n" " stbuttonPlayerValInit = sButPlayerValInit;\n" " context.playSequence(dSelectedStepStart, dSelectedStepEnd, funcCallbackStart,funcCallbackStop);\n" " //context.playAnims(dSelectedStepStart, dSelectedStepStart, funcCallbackStart,funcCallbackStop);\n" " }\n" " else if ( butCurrent.buttonGetCaption() == \"Pause\" ) \n" " {\n" " butCurrent.buttonSetCaption(\"Continue\");\n" " context.runtime.pause();\n" " }\n" " else if ( butCurrent.buttonGetCaption() == \"Continue\" ) \n" " {\n" " butCurrent.buttonSetCaption(\"Pause\");\n" " context.runtime.play();\n" " }\n" " }\n" "}\n" "\n" "function runanimallsteps()\n" "{\n" " runanim(\"PlayAll\", \"Play All\", 0.0, -1);\n" "}\n" "\n" "function runanimcurrentstep()\n" "{\n" " runanim(\"PlayStep\", \"Play Step\", stdSelectedStepStart, stdSelectedStepEnd);\n" "}\n" "\n" "function restartanim()\n" "{\n" " pageIndex = this.pageNum;\n" " annotIndex = 0;\n" " annot = getAnnots3D(pageIndex)[annotIndex];\n" " if (annot != undefined) \n" " {\n" " context = annot.context3D;\n" " butStep = this.getField(\"PlayStep\");\n" " butAll = this.getField(\"PlayAll\");\n" " butStep.buttonSetCaption(\"Play Step\");\n" " butStep.fillColor = color.white;\n" " butAll.buttonSetCaption(\"Play All\");\n" " butAll.fillColor = color.white;\n" " context.restartSequence();\n" " //context.restartAnims();\n" " }\n" "}", dStartStep1, dStartStep2, dStartStep3, dStartStep4, dStartStep5, dStartStep6, dStartStep7, dStartStep8); CHECK_RET(A3DPDFDocumentAddJavascriptFromString(pDoc, "MyFns", myjsondoc)); // cleaning up -- WARNING: DO NOT CALL THIS BEFORE A3DPDF3DArtworkCreate! CHECK_RET(A3DAsmModelFileDelete(pModelFile)); // 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); 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(); }