281 lines
10 KiB
C++
281 lines
10 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 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 <A3DSDKIncludes.h>
|
|
#include "../common.hpp"
|
|
#include "../CommonInit.h"
|
|
|
|
#include <iostream>
|
|
|
|
|
|
// 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<A3DUTF8Char*>(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();
|
|
|
|
}
|