274 lines
10 KiB
C++
274 lines
10 KiB
C++
/***********************************************************************************************************************
|
|
*
|
|
* Copyright (c) 2010 - 2025 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 Shattered.cpp
|
|
|
|
PRC Can be used as a multi-file format using our shattered mode.
|
|
This sample demonstrates how to load a CAD file independently from each other.
|
|
Then it creates one PRC per file. Finally the full model is reloaded in memory from these multiple files.
|
|
|
|
***********************************************************************************************************************/
|
|
|
|
#ifndef _MSC_VER
|
|
# include <libgen.h> // for dirname
|
|
# define MAX_PATH 512
|
|
#endif
|
|
|
|
#define INITIALIZE_A3D_API
|
|
#include <A3DSDKIncludes.h>
|
|
#include <hoops_license.h>
|
|
|
|
#include "../common.hpp"
|
|
|
|
//######################################################################################################################
|
|
#ifndef _MSC_VER
|
|
|
|
void SplitPathLinux(
|
|
const char *pcPath, /* I: Path to split */
|
|
char pcDir[MAX_PATH], /* O: Extracted dir */
|
|
char pcFile[MAX_PATH], /* O: Extracted file name */
|
|
char pcExt[8]) /* O: Extracted file extension */
|
|
{
|
|
char acBuf[MAX_PATH*3];
|
|
char *pcDirName, *pcFileName, *pcCur;
|
|
int iLen, iLenExt;
|
|
|
|
strcpy(acBuf, pcPath);
|
|
pcDirName = dirname(acBuf );
|
|
strcpy(pcDir, pcDirName);
|
|
|
|
strcpy(acBuf, pcPath);
|
|
pcFileName = basename(acBuf);
|
|
if(*pcFileName == '/')
|
|
pcFileName++;
|
|
|
|
iLen = strlen(pcFileName);
|
|
pcCur = pcFileName+iLen-1;
|
|
iLenExt = 0;
|
|
while(pcCur >= pcFileName)
|
|
{
|
|
if(*pcCur == '.')
|
|
break;
|
|
pcCur--;
|
|
iLenExt++;
|
|
}
|
|
if(iLenExt == iLen)
|
|
{
|
|
strcpy(pcFile, pcFileName);
|
|
*pcExt = '\0';
|
|
}
|
|
else if(iLenExt)
|
|
{
|
|
strncpy(pcFile, pcFileName, pcCur-pcFileName);
|
|
pcFile[pcCur-pcFileName] = '\0';
|
|
strncpy(pcExt, pcCur+1, iLenExt);
|
|
pcExt[iLenExt] = '\0';
|
|
}
|
|
else
|
|
{
|
|
strncpy(pcFile, pcFileName, iLen-1);
|
|
pcFile[iLen] = '\0';
|
|
*pcExt = '\0';
|
|
}
|
|
}
|
|
#endif
|
|
|
|
static MY_CHAR acSrcFileName[_MAX_PATH * 2];
|
|
static MY_CHAR acDstPathName[_MAX_PATH * 2];
|
|
static MY_CHAR acLogFileName[_MAX_PATH * 2];
|
|
|
|
//######################################################################################################################
|
|
// Main function
|
|
#ifdef _MSC_VER
|
|
int wmain(A3DInt32 iArgc, A3DUniChar** ppcArgv)
|
|
#else
|
|
int main(A3DInt32 iArgc, A3DUTF8Char** ppcArgv)
|
|
#endif
|
|
{
|
|
//
|
|
// ### COMMAND LINE ARGUMENTS
|
|
//
|
|
|
|
if (iArgc > 4)
|
|
{
|
|
MY_PRINTF2("Usage:\n %s [input CAD file] [output PRC directory] [output LOG file]\n", ppcArgv[0]);
|
|
MY_PRINTF(" Default output PRC directory is 'CURRENT_DIR'\n");
|
|
MY_PRINTF(" Default output LOG file is [input CAD file]_Log.txt\n\n");
|
|
return A3D_ERROR;
|
|
}
|
|
|
|
if (iArgc > 1) MY_STRCPY(acSrcFileName, ppcArgv[1]);
|
|
else MY_STRCPY(acSrcFileName, DEFAULT_INPUT_CAD);
|
|
if (iArgc > 2) MY_STRCPY(acDstPathName, ppcArgv[2]);
|
|
else MY_STRCPY(acDstPathName, _T(SAMPLES_DEFAULT_OUTPUT_PATH));
|
|
if (iArgc > 3) MY_STRCPY(acLogFileName, ppcArgv[3]);
|
|
else MY_SPRINTF(acLogFileName, "%s_Log.txt", acSrcFileName);
|
|
GetLogFile(acLogFileName); // Initialize log file
|
|
|
|
//
|
|
// ### INITIALIZE HOOPS EXCHANGE
|
|
//
|
|
|
|
A3DSDKHOOPSExchangeLoader sHoopsExchangeLoader(_T(HOOPS_BINARY_DIRECTORY), HOOPS_LICENSE);
|
|
CHECK_RET(sHoopsExchangeLoader.m_eSDKStatus);
|
|
|
|
// Initialize callbacks
|
|
CHECK_RET(A3DDllSetCallbacksMemory(CheckMalloc, CheckFree));
|
|
CHECK_RET(A3DDllSetCallbacksReport(PrintLogMessage, PrintLogWarning, PrintLogError));
|
|
|
|
//
|
|
// ### PROCESS SAMPLE CODE
|
|
//
|
|
|
|
A3DImport sImport(acSrcFileName); // see A3DSDKInternalConvert.hxx for import and export detailed parameters
|
|
A3DStatus iRet = sHoopsExchangeLoader.Import(sImport);
|
|
if (iRet != A3D_SUCCESS && iRet != A3D_LOAD_MISSING_COMPONENTS)
|
|
CHECK_RET(iRet);
|
|
|
|
//Extract all dependencies from a CAD file - This step is not necessary when the assemblies dependencies are known
|
|
A3DUTF8Char** ppPart, ** ppAssembly, ** ppMissing;
|
|
A3DUns32 uNbPart, uNbAssembly, uNbMissing;
|
|
A3DAsmGetFilesPathFromModelFile(sHoopsExchangeLoader.m_psModelFile, &uNbPart, &ppPart, &uNbAssembly, &ppAssembly, &uNbMissing, &ppMissing);
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Load and convert Each CAD to a PRC.
|
|
// Each part is managed independently because sImport.m_sLoadData.m_sIncremental.m_bLoadNoDependencies is set to true
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
A3DUniChar acDrive[8];
|
|
A3DUniChar acDir[_MAX_PATH];
|
|
A3DUniChar acName[_MAX_PATH];
|
|
A3DUniChar acExt[_MAX_PATH];
|
|
A3DUniChar acPrcFileName[_MAX_PATH * 3];
|
|
|
|
A3DUTF8Char** acPrcFilePath = (A3DUTF8Char**)malloc(sizeof(A3DUTF8Char*) * (uNbPart + uNbAssembly + 1));
|
|
memset(acPrcFilePath, 0, sizeof(A3DUTF8Char*) * (uNbPart + uNbAssembly + 1));
|
|
const MemoryGuard sGuardPrcFilePath(acPrcFilePath);
|
|
A3DUTF8Char** acCADFilePath = (A3DUTF8Char**)malloc(sizeof(A3DUTF8Char*) * (uNbPart + uNbAssembly + 1));
|
|
memset(acCADFilePath, 0, sizeof(A3DUTF8Char*) * (uNbPart + uNbAssembly + 1));
|
|
const MemoryGuard sGuardCADFilePath(acCADFilePath);
|
|
|
|
for (unsigned int uI = 0; uI < uNbAssembly; ++uI)
|
|
{
|
|
if (sHoopsExchangeLoader.m_psModelFile)
|
|
{
|
|
A3DAsmModelFileDelete(sHoopsExchangeLoader.m_psModelFile);
|
|
sHoopsExchangeLoader.m_psModelFile = NULL;
|
|
}
|
|
|
|
// Determine PRc File Name + Unicode to UT8 conversions
|
|
#ifdef _MSC_VER
|
|
wchar_t* pucString = (wchar_t*)malloc(_MAX_PATH * 3 * sizeof(wchar_t));
|
|
A3DMiscUTF8ToUnicode(ppAssembly[uI], (A3DUTF8Char*)pucString);
|
|
_wsplitpath(pucString, acDrive, acDir, acName, acExt);
|
|
free(pucString);
|
|
pucString = NULL;
|
|
swprintf(&acPrcFileName[0], _MAX_PATH * 3, L"%s\\%s.prc", &acDstPathName[0], acName);
|
|
|
|
acPrcFilePath[uI] = (A3DUTF8Char*)malloc(_MAX_PATH * 3 * sizeof(A3DUTF8Char));
|
|
A3DMiscUnicodeToUTF8((A3DUTF8Char*)&acPrcFileName[0], acPrcFilePath[uI]);
|
|
#else
|
|
SplitPathLinux(ppAssembly[uI], acDir, acName, acExt);
|
|
acPrcFilePath[uI] = (A3DUTF8Char*)malloc(_MAX_PATH * 3 * sizeof(A3DUTF8Char));
|
|
sprintf(acPrcFilePath[uI], "%s/%s.prc", &acDstPathName[0], acName);
|
|
#endif
|
|
acCADFilePath[uI] = ppAssembly[uI];
|
|
|
|
//Convert assembly files to PRC
|
|
A3DImport sSubImport(ppAssembly[uI]); // see A3DSDKInternalConvert.hxx for import and export detailed parameters
|
|
sSubImport.m_sLoadData.m_sIncremental.m_bLoadNoDependencies = true;
|
|
|
|
A3DExport sExport(acPrcFilePath[uI]); // see A3DSDKInternalConvert.hxx for import and export detailed parameters
|
|
TEST_RET(sHoopsExchangeLoader.Convert(sSubImport, sExport));
|
|
}
|
|
|
|
//Convert CAD part files to PRC
|
|
for (unsigned int uI = 0; uI < uNbPart; ++uI)
|
|
{
|
|
if (sHoopsExchangeLoader.m_psModelFile)
|
|
{
|
|
A3DAsmModelFileDelete(sHoopsExchangeLoader.m_psModelFile);
|
|
sHoopsExchangeLoader.m_psModelFile = NULL;
|
|
}
|
|
|
|
#ifdef _MSC_VER
|
|
//Generate PRC filename; convert wchar_t path to UTF-8
|
|
wchar_t* pucString = (wchar_t*)malloc(_MAX_PATH * 3 * sizeof(wchar_t));
|
|
A3DMiscUTF8ToUnicode(ppPart[uI], (A3DUTF8Char*)pucString);
|
|
_wsplitpath(pucString, acDrive, acDir, acName, acExt);
|
|
free(pucString);
|
|
pucString = NULL;
|
|
swprintf(&acPrcFileName[0], _MAX_PATH * 3, L"%s\\%s.prc", &acDstPathName[0], acName);
|
|
|
|
acPrcFilePath[uI + uNbAssembly] = (A3DUTF8Char*)malloc(_MAX_PATH * 3 * sizeof(A3DUTF8Char));
|
|
A3DMiscUnicodeToUTF8((A3DUTF8Char*)&acPrcFileName[0], acPrcFilePath[uI + uNbAssembly]);
|
|
#else
|
|
SplitPathLinux(ppPart[uI], acDir, acName, acExt);
|
|
acPrcFilePath[uI + uNbAssembly] = (A3DUTF8Char*)malloc(_MAX_PATH * 3 * sizeof(A3DUTF8Char));
|
|
sprintf(acPrcFilePath[uI + uNbAssembly], "%s/%s.prc", &acDstPathName[0], acName);
|
|
#endif
|
|
acCADFilePath[uI + uNbAssembly] = ppPart[uI];
|
|
|
|
//Convert assembly files to PRC
|
|
A3DImport sSubImport(ppPart[uI]); // see A3DSDKInternalConvert.hxx for import and export detailed parameters
|
|
sSubImport.m_sLoadData.m_sIncremental.m_bLoadNoDependencies = true;
|
|
|
|
A3DExport sExport(acPrcFilePath[uI + uNbAssembly]); // see A3DSDKInternalConvert.hxx for import and export detailed parameters
|
|
TEST_RET(sHoopsExchangeLoader.Convert(sSubImport, sExport));
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Load the full Model from PRC.
|
|
// A mapping between CAD filepath and PRC filepath needs to be maintained by customers to use this fuction.
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
if (sHoopsExchangeLoader.m_psModelFile)
|
|
{
|
|
A3DAsmModelFileDelete(sHoopsExchangeLoader.m_psModelFile);
|
|
sHoopsExchangeLoader.m_psModelFile = NULL;
|
|
}
|
|
|
|
A3DRWParamsLoadData sParamsLoadData;
|
|
A3D_INITIALIZE_DATA(A3DRWParamsLoadData, sParamsLoadData);
|
|
A3DUTF8Char acRootPrcFilePath[_MAX_PATH * 3];
|
|
|
|
#ifdef _MSC_VER
|
|
_wsplitpath(iArgc > 1 ? ppcArgv[1] : DEFAULT_INPUT_CAD, acDrive, acDir, acName, acExt);
|
|
swprintf(acPrcFileName, _MAX_PATH * 3, L"%s\\%s.prc", &acDstPathName[0], acName);
|
|
A3DMiscUnicodeToUTF8((A3DUTF8Char*)&acPrcFileName[0], &acRootPrcFilePath[0]);
|
|
#else
|
|
SplitPathLinux(iArgc > 1 ? ppcArgv[1] : DEFAULT_INPUT_CAD, acDir, acName, acExt);
|
|
sprintf(acRootPrcFilePath, "%s/%s.prc", &acDstPathName[0], acName);
|
|
#endif
|
|
|
|
CHECK_RET(A3DAsmModelFileLoadFromPRCFiles(&acRootPrcFilePath[0], uNbPart + uNbAssembly,
|
|
(const A3DUTF8Char**)acPrcFilePath, (const A3DUTF8Char**)acCADFilePath, &sParamsLoadData,
|
|
&(sHoopsExchangeLoader.m_psModelFile)));
|
|
|
|
A3DAsmGetFilesPathFromModelFile(NULL, &uNbPart, &ppPart, &uNbAssembly, &ppAssembly, &uNbMissing, &ppMissing);
|
|
|
|
for (unsigned int uI = 0; uI < uNbAssembly + uNbPart; ++uI)
|
|
{
|
|
free(acPrcFilePath[uI]);
|
|
}
|
|
|
|
//
|
|
// ### TERMINATE HOOPS EXCHANGE
|
|
//
|
|
|
|
// Check memory allocations
|
|
return (int)ListLeaks();
|
|
}
|