/*********************************************************************************************************************** * * 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 U3DWithAnimation.cpp This file demonstrates how to programmatically create a PDF 3D file with a poster, a U3D file and a javascript animation. ***********************************************************************************************************************/ #define INITIALIZE_A3D_API #define HOOPS_PRODUCT_PUBLISH_STANDARD #include #include "../common.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"\\u3d\\car.u3d" # define IN_POSTERIMAGE SAMPLES_DATA_DIRECTORY"\\images\\pleaseactivate.bmp" # define IN_JSFILE SAMPLES_DATA_DIRECTORY"\\javascript\\timer.js" # define IN_PDFFILE SAMPLES_DATA_DIRECTORY"\\pdf_templates\\AnimationTemplate.pdf" # define OUT_FILE SAMPLES_PUBLISH_GALLERY_DIRECTORY"\\sample_U3DWithAnimation.pdf" #else # define IN_3DFILE SAMPLES_DATA_DIRECTORY"/u3d/car.u3d" # define IN_POSTERIMAGE SAMPLES_DATA_DIRECTORY"/images/pleaseactivate.bmp" # define IN_JSFILE SAMPLES_DATA_DIRECTORY"/javascript/timer.js" # define IN_PDFFILE SAMPLES_DATA_DIRECTORY"/pdf_templates/AnimationTemplate.pdf" # define OUT_FILE SAMPLES_PUBLISH_GALLERY_DIRECTORY"/sample_U3DWithAnimation.pdf" #endif //###################################################################################################################### // creates a view A3DStatus CreateView(A3DPDFDocument* pDoc, A3DPDF3DArtwork* p3DArtwork, A3DDouble dPosX, A3DDouble dPosY, A3DDouble dPosZ, A3DDouble dTargetX, A3DDouble dTargetY, A3DDouble dTargetZ, A3DDouble dUpX, A3DDouble dUpY, A3DDouble dUpZ, A3DPDFEProjectionMode eProjectionMode, A3DDouble dZoomFactor, A3DDouble dFieldOfView, A3DBool bIsDefault, const A3DUTF8Char* pcViewName, A3DPDFView** ppView) { A3DStatus iRet = A3D_SUCCESS; A3DPDFViewData sViewData; A3D_INITIALIZE_DATA(A3DPDFViewData, sViewData); sViewData.m_sViewBackgroundColor.m_dBlue = 0.25; sViewData.m_sViewBackgroundColor.m_dGreen = 0.25; sViewData.m_sViewBackgroundColor.m_dRed = 0.25; sViewData.m_eViewLighting = kA3DPDFLightCADOptimized; sViewData.m_eViewRenderingStyle = kA3DPDFRenderingSolid; sViewData.m_sPosition.m_dX = dPosX; sViewData.m_sPosition.m_dY = dPosY; sViewData.m_sPosition.m_dZ = dPosZ; sViewData.m_sTarget.m_dX = dTargetX; sViewData.m_sTarget.m_dY = dTargetY; sViewData.m_sTarget.m_dZ = dTargetZ; sViewData.m_sUpVector.m_dX = dUpX; sViewData.m_sUpVector.m_dY = dUpY; sViewData.m_sUpVector.m_dZ = dUpZ; sViewData.m_eProjectionMode = eProjectionMode; sViewData.m_dZoomFactor = dZoomFactor; // only valid for orthographic projection sViewData.m_dFieldOfView = dFieldOfView; // only valid for perspective projection sViewData.m_bIsDefault = bIsDefault; // note: the m_bTransparentBackground 3DAnnot parameter needs to be false to take the background color into account. sViewData.m_sViewBackgroundColor.m_dBlue = 1.; sViewData.m_sViewBackgroundColor.m_dGreen = 1.; sViewData.m_sViewBackgroundColor.m_dRed = 1.; sViewData.m_eViewLighting = kA3DPDFLightArtworkCurrent; sViewData.m_eViewRenderingStyle = kA3DPDFRenderingSolid; size_t iLen = strlen(pcViewName); sViewData.m_pcExternalName = new A3DUTF8Char[iLen+1]; strcpy(sViewData.m_pcExternalName, pcViewName); CHECK_RET(A3DPDFViewCreate(pDoc, &sViewData, ppView)); delete []sViewData.m_pcExternalName; CHECK_RET(A3DPDF3DArtworkAddView(p3DArtwork, *ppView)); return iRet; } A3DStatus BuildPDFDocument() { A3DStatus iRet = A3D_SUCCESS; // creating empty document A3DPDFDocument* pDoc = NULL; CHECK_RET(A3DPDFDocumentCreateEmpty(&pDoc)); if (pDoc != NULL) { // inserting page from a template file A3DPDFPage* pPage = NULL; // the false boolean keeps the same field names CHECK_RET(A3DPDFDocumentAppendPageFromPDFFileEx(pDoc, IN_PDFFILE, false, &pPage)); if (pPage != NULL) { // reading the U3D file; the file can be disposed of afterwards. A3DPDF3DStream* pStream; CHECK_RET(A3DPDF3DStreamCreateFromFile(pDoc, IN_3DFILE, false, &pStream)); // 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_pcJavaScriptFileName = const_cast(IN_JSFILE); // The animation style has to be set to kA3DPDFAnimStyleNoAnimation. // If not, the script won't be able to play the animation. s3DArtworkData.m_eAnimationStyle = kA3DPDFAnimStyleNoAnimation; CHECK_RET(A3DPDF3DArtworkCreate2(pDoc, &s3DArtworkData, &p3DArtwork)); // creating the view // Note: in this workflow where a 3D file is stored as a stream in the PDF, // Publish will simply insert the U3D stream inside the PDF without parsing and converting it, // in order to retain the animation inside it. Consequently, a view needs to be created // to exert control over several parameters, like background color, lighting or rendering style. A3DPDFView* pView; CHECK_RET(CreateView(pDoc, p3DArtwork, 95.0965, 98.2332, 62.2425, 2.84981, 1.67981, 9.58986, -0.242386, -0.275673, 0.930187, kA3DPDFOrthographicMode, 1.0 / (2 * 38.46153766798552), 30, true, "Default", &pView)); A3DPDF3DAnnotData sAnnotData; A3D_INITIALIZE_DATA(A3DPDF3DAnnotData, sAnnotData); // Note: default view parameters (background color, lighting, rendering style) are not used // in this workflow. sAnnotData.m_bOpenModelTree = false; sAnnotData.m_bShowToolbar = false; sAnnotData.m_bTransparentBackground = false; sAnnotData.m_eActivateWhen = kA3DPDFActivPageOpened; sAnnotData.m_eDesactivateWhen = kA3DPDFActivPageClosed; sAnnotData.m_iAppearanceBorderWidth = 1; sAnnotData.m_pPosterImage = pImage; sAnnotData.m_p3DArtwork = p3DArtwork; A3DPDF3DAnnot* p3DAnnot = NULL; CHECK_RET(A3DPDF3DAnnotCreate(pDoc, &sAnnotData, &p3DAnnot)); if (p3DAnnot != NULL) { // populating the field with the 3D annotation CHECK_RET(A3DPDFPageFieldSet3DAnnot(pPage, "My3DWindow", p3DAnnot)); // populating a text field A3DPDFTextField* pTextTitle = NULL; A3DPDFPageGetField(pPage, "MyTitle", &pTextTitle); if (pTextTitle) A3DPDFTextFieldSetValue(pTextTitle, "U3D model with animation"); // set actions on buttons // button Start A3DPDFButton* pButStart = NULL; A3DPDFPageGetField(pPage, "Button1", &pButStart); if (pButStart) { CHECK_RET(A3DPDFButtonSetLabel(pButStart, "Start")); A3DPDFAction* pAction = NULL; A3DPDFActionStartAnimationData sActionData; A3D_INITIALIZE_DATA(A3DPDFActionStartAnimationData, sActionData); sActionData.m_p3DAnnot = p3DAnnot; sActionData.m_bIsNativeAnimation = TRUE; // Note: with the car.u3d sample, the animation really starts at 8 secs. sActionData.m_dStartTime = 8; sActionData.m_dEndTime = -1; CHECK_RET(A3DPDFActionStartAnimationCreate(&sActionData, &pAction)); CHECK_RET(A3DPDFButtonAddAction(pButStart, pAction)); } // button Pause A3DPDFButton* pButPause = NULL; A3DPDFPageGetField(pPage, "Button2", &pButPause); if (pButPause) { CHECK_RET(A3DPDFButtonSetLabel(pButPause, "Pause")); A3DPDFAction* pAction = NULL; A3DPDFActionPauseAnimationData sActionData; A3D_INITIALIZE_DATA(A3DPDFActionPauseAnimationData, sActionData); sActionData.m_p3DAnnot = p3DAnnot; CHECK_RET(A3DPDFActionPauseAnimationCreate(&sActionData, &pAction)); CHECK_RET(A3DPDFButtonAddAction(pButPause, pAction)); } // button Resume A3DPDFButton* pButResume = NULL; A3DPDFPageGetField(pPage, "Button3", &pButResume); if (pButResume) { CHECK_RET(A3DPDFButtonSetLabel(pButResume, "Resume")); A3DPDFAction* pAction = NULL; A3DPDFActionResumeAnimationData sActionData; A3D_INITIALIZE_DATA(A3DPDFActionResumeAnimationData, sActionData); sActionData.m_p3DAnnot = p3DAnnot; CHECK_RET(A3DPDFActionResumeAnimationCreate(&sActionData, &pAction)); CHECK_RET(A3DPDFButtonAddAction(pButResume, pAction)); } } // 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(); }