Files
2025-12-15 22:10:55 +08:00

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();
}