477 lines
17 KiB
C++
477 lines
17 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.
|
|
*
|
|
***********************************************************************************************************************/
|
|
|
|
#include <A3DSDKIncludes.h>
|
|
#include "PRC2XML.h"
|
|
|
|
#include <string>
|
|
#include <codecvt>
|
|
#include <string>
|
|
|
|
#ifdef WIN32
|
|
#include <direct.h>
|
|
#else
|
|
#include <sys/stat.h>
|
|
#endif
|
|
|
|
//######################################################################################################################
|
|
int _MakeFolder(const std::string& folderPath)
|
|
{
|
|
#ifdef WIN32
|
|
return _mkdir(folderPath.c_str());
|
|
#else
|
|
return mkdir(folderPath.c_str(), 0777);
|
|
#endif
|
|
}
|
|
|
|
|
|
//######################################################################################################################
|
|
A3DStatus traverseUnit(A3DMiscAttributeUnit* const pUnit, _TiXmlElement* setting)
|
|
{
|
|
A3DStatus iRet = A3D_SUCCESS;
|
|
A3DMiscAttributeUnitData sDataUnit;
|
|
A3D_INITIALIZE_DATA(A3DMiscAttributeUnitData, sDataUnit);
|
|
|
|
_TiXmlElement* unit = new _TiXmlElement("A3DMiscAttributeUnit");
|
|
|
|
CHECK_RET(A3DGlobalGetUnitData(pUnit, &sDataUnit));
|
|
|
|
if (sDataUnit.m_pcName && sDataUnit.m_pcName[0] != '\0')
|
|
unit->SetAttribute("m_pcName", sDataUnit.m_pcName);
|
|
|
|
for (auto uj = 0u; uj < sDataUnit.m_uiBasicUnitSize; uj++)
|
|
{
|
|
_TiXmlElement* basicunit = new _TiXmlElement("A3DMiscAttributeBasicUnit");
|
|
basicunit->SetAttribute("m_eUnit", (int)sDataUnit.m_ppBasicUnits[uj]->m_eUnit);
|
|
basicunit->SetAttribute("m_iExponent", (int)sDataUnit.m_ppBasicUnits[uj]->m_iExponent);
|
|
basicunit->SetDoubleAttribute("m_dFactor", (double)sDataUnit.m_ppBasicUnits[uj]->m_dFactor);
|
|
unit->LinkEndChild(basicunit);
|
|
}
|
|
A3DGlobalGetUnitData(NULL, &sDataUnit);
|
|
|
|
setting->LinkEndChild(unit);
|
|
|
|
return iRet;
|
|
}
|
|
|
|
//######################################################################################################################
|
|
A3DStatus traverseDottingPattern(const A3DGraphDottingPatternData& sData, _TiXmlElement* setting)
|
|
{
|
|
A3DStatus iRet = A3D_SUCCESS;
|
|
|
|
_TiXmlElement* pattern = new _TiXmlElement("A3DGraphDottingPatternData");
|
|
|
|
setDoubleAttribute(pattern, "m_dPitch", (double) sData.m_dPitch);
|
|
pattern->SetAttribute("m_bZigZag", (int) sData.m_bZigZag);
|
|
pattern->SetAttribute("m_uiColorIndex", (int) sData.m_uiColorIndex);
|
|
pattern->SetAttribute("m_uiNextPatternIndex", (int) sData.m_uiNextPatternIndex);
|
|
|
|
setting->LinkEndChild(pattern);
|
|
return iRet;
|
|
}
|
|
|
|
//######################################################################################################################
|
|
A3DStatus traverseHatchingPattern(const A3DGraphHatchingPatternData& sData, _TiXmlElement* setting)
|
|
{
|
|
A3DStatus iRet = A3D_SUCCESS;
|
|
|
|
_TiXmlElement *pattern= new _TiXmlElement("A3DGraphHatchingPatternData");
|
|
|
|
A3DUns32 ui, uiSize = sData.m_uiSize;
|
|
for(ui = 0; ui < uiSize; ++ui)
|
|
{
|
|
_TiXmlElement* hatchline = new _TiXmlElement("A3DGraphHatchingPatternLineData");
|
|
setDoubleAttribute(hatchline, "m_dAngle", (double) sData.m_psHatchLines[ui].m_dAngle);
|
|
hatchline->SetAttribute("m_uiStyleIndex", (int) sData.m_psHatchLines[ui].m_uiStyleIndex);
|
|
traversePoint2d("m_sStart" , sData.m_psHatchLines[ui].m_sStart, hatchline);
|
|
traversePoint2d("m_sOffset", sData.m_psHatchLines[ui].m_sOffset, hatchline);
|
|
pattern->LinkEndChild(hatchline);
|
|
}
|
|
pattern->SetAttribute("m_uiNextPatternIndex", (int) sData.m_uiNextPatternIndex);
|
|
|
|
setting->LinkEndChild(pattern);
|
|
return iRet;
|
|
}
|
|
|
|
//######################################################################################################################
|
|
A3DStatus traverseSolidPattern(const A3DGraphSolidPatternData& sData, _TiXmlElement* setting)
|
|
{
|
|
A3DStatus iRet = A3D_SUCCESS;
|
|
|
|
_TiXmlElement* pattern = new _TiXmlElement("A3DGraphSolidPatternData");
|
|
|
|
pattern->SetAttribute("m_bMaterial", (int) sData.m_bMaterial);
|
|
pattern->SetAttribute("m_uiRgbColorIndex", (int) sData.m_uiRgbColorIndex);
|
|
pattern->SetAttribute("m_uiNextPatternIndex", (int) sData.m_uiNextPatternIndex);
|
|
|
|
setting->LinkEndChild(pattern);
|
|
return iRet;
|
|
}
|
|
|
|
//######################################################################################################################
|
|
A3DStatus traverseVPicturePattern(const A3DGraphVPicturePatternData& sData, _TiXmlElement* setting)
|
|
{
|
|
A3DStatus iRet = A3D_SUCCESS;
|
|
|
|
_TiXmlElement* pattern = new _TiXmlElement("A3DGraphVPicturePatternData");
|
|
pattern->SetAttribute("m_uiNextPatternIndex", (int) sData.m_uiNextPatternIndex);
|
|
|
|
traverseMarkupTess(sData.m_pMarkupTess, pattern);
|
|
|
|
setting->LinkEndChild(pattern);
|
|
return iRet;
|
|
}
|
|
|
|
//######################################################################################################################
|
|
std::string st_texturePath;
|
|
void setTextureDirectory(const MY_CHAR* texturePath)
|
|
{
|
|
// string conversion
|
|
std::string utf8Path;
|
|
#if defined _UNICODE || defined UNICODE
|
|
std::wstring_convert<std::codecvt_utf8<wchar_t>> convert;
|
|
utf8Path = convert.to_bytes(std::wstring(texturePath));
|
|
#else
|
|
utf8Path = texturePath;
|
|
#endif
|
|
|
|
// extract output dir, and create /img/ dir
|
|
std::string path(utf8Path);
|
|
size_t found = path.find_last_of("/\\");
|
|
st_texturePath = path.substr(0, found) + "/img/";
|
|
_MakeFolder(st_texturePath);
|
|
|
|
// add current XML filename for all associated texture files
|
|
st_texturePath += path.substr(found + 1);
|
|
}
|
|
|
|
//######################################################################################################################
|
|
static bool stMakeFileWithBinarydata(A3DUns32 uiSize, A3DUns8* const pucBinaryData, const std::string &psFileName)
|
|
{
|
|
FILE* psFile = fopen(psFileName.c_str(), "wb");
|
|
|
|
if(psFile != NULL)
|
|
{
|
|
int iFileSize = uiSize;
|
|
fwrite(pucBinaryData, sizeof(char), size_t(iFileSize), psFile);
|
|
fclose(psFile);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
//######################################################################################################################
|
|
A3DStatus traversePicture(const A3DGraphPictureData& sData, _TiXmlElement* setting)
|
|
{
|
|
A3DStatus iRet = A3D_SUCCESS;
|
|
|
|
_TiXmlElement* picture = new _TiXmlElement("A3DGraphPictureData");
|
|
|
|
std::string ext;
|
|
switch(sData.m_eFormat)
|
|
{
|
|
case kA3DPicturePng: ext = "png"; break;
|
|
case kA3DPictureJpg: ext = "jpg"; break;
|
|
|
|
case kA3DPictureBmp:
|
|
case kA3DPictureBitmapRgbByte:
|
|
case kA3DPictureBitmapRgbaByte:
|
|
case kA3DPictureBitmapGreyByte:
|
|
case kA3DPictureBitmapGreyaByte:
|
|
default:
|
|
ext = "bmp";
|
|
break;
|
|
}
|
|
picture->SetAttribute("m_eFormat", (int)sData.m_eFormat);
|
|
picture->SetAttribute("m_uiPixelWidth", (int) sData.m_uiPixelWidth);
|
|
picture->SetAttribute("m_uiPixelHeight", (int) sData.m_uiPixelHeight);
|
|
|
|
const char* cIndex = setting->Attribute("index");
|
|
if (cIndex && !st_texturePath.empty())
|
|
{
|
|
std::string picturePath = st_texturePath + "_" + cIndex + "." + ext;
|
|
stMakeFileWithBinarydata(sData.m_uiSize, sData.m_pucBinaryData, picturePath);
|
|
size_t found = picturePath.find_last_of("/\\");
|
|
picture->SetAttribute("m_sTextureFile", picturePath.substr(found+1).c_str());
|
|
}
|
|
|
|
setting->LinkEndChild(picture);
|
|
return iRet;
|
|
}
|
|
|
|
//######################################################################################################################
|
|
A3DStatus traverseMaterial(const A3DGraphMaterialData& sData, _TiXmlElement* setting)
|
|
{
|
|
A3DStatus iRet = A3D_SUCCESS;
|
|
|
|
_TiXmlElement* material = new _TiXmlElement("A3DGraphMaterialData");
|
|
|
|
setDoubleAttribute(material, "m_dAmbientAlpha", sData.m_dAmbientAlpha);
|
|
setDoubleAttribute(material, "m_dDiffuseAlpha", sData.m_dDiffuseAlpha);
|
|
setDoubleAttribute(material, "m_dEmissiveAlpha", sData.m_dEmissiveAlpha);
|
|
setDoubleAttribute(material, "m_dSpecularAlpha", sData.m_dSpecularAlpha);
|
|
setDoubleAttribute(material, "m_dShininess", sData.m_dShininess);
|
|
|
|
material->SetAttribute("m_uiAmbient", (int) sData.m_uiAmbient);
|
|
material->SetAttribute("m_uiDiffuse", (int) sData.m_uiDiffuse);
|
|
material->SetAttribute("m_uiEmissive", (int) sData.m_uiEmissive);
|
|
material->SetAttribute("m_uiSpecular", (int) sData.m_uiSpecular);
|
|
|
|
setting->LinkEndChild(material);
|
|
return iRet;
|
|
}
|
|
|
|
//######################################################################################################################
|
|
A3DStatus traverseLinePattern(const A3DGraphLinePatternData& sData, _TiXmlElement* setting)
|
|
{
|
|
A3DStatus iRet = A3D_SUCCESS;
|
|
|
|
_TiXmlElement* linepattern = new _TiXmlElement("A3DGraphLinePatternData");
|
|
traverseDoubles("m_pdLengths", sData.m_uiNumberOfLengths, sData.m_pdLengths, linepattern);
|
|
setDoubleAttribute(linepattern, "m_dPhase", sData.m_dPhase);
|
|
linepattern->SetAttribute("m_bRealLength", (int) sData.m_bRealLength);
|
|
|
|
setting->LinkEndChild(linepattern);
|
|
return iRet;
|
|
}
|
|
|
|
//######################################################################################################################
|
|
A3DStatus traverseStyle(const A3DGraphStyleData& sStyleData, _TiXmlElement* setting)
|
|
{
|
|
A3DStatus iRet = A3D_SUCCESS;
|
|
|
|
_TiXmlElement* style = new _TiXmlElement("A3DGraphStyleData");
|
|
|
|
style->SetAttribute("m_bMaterial", (int) sStyleData.m_bMaterial);
|
|
style->SetAttribute("m_uiRgbColorIndex", (int) sStyleData.m_uiRgbColorIndex);
|
|
style->SetAttribute("m_bVPicture", (int) sStyleData.m_bVPicture);
|
|
style->SetAttribute("m_uiLinePatternIndex", (int) sStyleData.m_uiLinePatternIndex);
|
|
|
|
if(sStyleData.m_bIsTransparencyDefined)
|
|
style->SetAttribute("m_ucTransparency", (int) sStyleData.m_ucTransparency);
|
|
|
|
setDoubleAttribute(style, "m_dWidth", sStyleData.m_dWidth);
|
|
|
|
style->SetAttribute("m_bSpecialCulling", (int)sStyleData.m_bSpecialCulling);
|
|
style->SetAttribute("m_bFrontCulling", (int)sStyleData.m_bFrontCulling);
|
|
style->SetAttribute("m_bBackCulling", (int)sStyleData.m_bBackCulling);
|
|
style->SetAttribute("m_bNoLight", (int)sStyleData.m_bNoLight);
|
|
style->SetAttribute("m_eRenderingMode", (int)sStyleData.m_eRenderingMode);
|
|
|
|
setting->LinkEndChild(style);
|
|
return iRet;
|
|
}
|
|
|
|
//######################################################################################################################
|
|
A3DStatus traverseGlobal(const A3DGlobal* pGlobal, _TiXmlElement* setting)
|
|
{
|
|
A3DStatus iRet = A3D_SUCCESS;
|
|
A3DGlobalData sData;
|
|
A3D_INITIALIZE_DATA(A3DGlobalData, sData);
|
|
|
|
_TiXmlElement* global = new _TiXmlElement("A3DGlobalData");
|
|
|
|
iRet = A3DGlobalGet(pGlobal, &sData);
|
|
if(iRet == A3D_SUCCESS)
|
|
{
|
|
A3DStatus traverseBase(const A3DEntity* pEntity, _TiXmlElement* setting);
|
|
A3DUns32 ui, uiSize = sData.m_uiColorsSize;
|
|
if(uiSize)
|
|
{
|
|
A3DGraphRgbColorData sColorData;
|
|
A3D_INITIALIZE_DATA(A3DGraphRgbColorData, sColorData);
|
|
A3DDouble* pdAllColors = (A3DDouble*) malloc(size_t(uiSize) * 3 * sizeof(A3DDouble));
|
|
if (pdAllColors)
|
|
{
|
|
for(ui = 0; ui < uiSize; ++ui)
|
|
{
|
|
CHECK_RET(A3DGlobalGetGraphRgbColorData(ui*3, &sColorData));
|
|
pdAllColors[3*ui] = sColorData.m_dRed;
|
|
pdAllColors[3*ui+1] = sColorData.m_dGreen;
|
|
pdAllColors[3*ui+2] = sColorData.m_dBlue;
|
|
}
|
|
traverseDoubles("Colors", uiSize*3, pdAllColors, global);
|
|
free(pdAllColors);
|
|
}
|
|
}
|
|
|
|
if(sData.m_uiStylesSize)
|
|
{
|
|
uiSize = sData.m_uiStylesSize;
|
|
A3DGraphStyleData sStyleData;
|
|
A3D_INITIALIZE_DATA(A3DGraphStyleData, sStyleData);
|
|
for(ui = 0; ui < uiSize; ++ui)
|
|
{
|
|
CHECK_RET(A3DGlobalGetGraphStyleData(ui, &sStyleData));
|
|
traverseStyle(sStyleData, global);
|
|
A3DGlobalGetGraphStyleData(A3D_DEFAULT_STYLE_INDEX, &sStyleData);
|
|
}
|
|
}
|
|
|
|
if(sData.m_uiLinePatternsSize)
|
|
{
|
|
uiSize = sData.m_uiLinePatternsSize;
|
|
A3DGraphLinePatternData sLinePatternData;
|
|
A3D_INITIALIZE_DATA(A3DGraphLinePatternData, sLinePatternData);
|
|
|
|
for(ui = 0; ui < uiSize; ++ui)
|
|
{
|
|
CHECK_RET(A3DGlobalGetGraphLinePatternData(ui, &sLinePatternData));
|
|
traverseLinePattern(sLinePatternData, global);
|
|
A3DGlobalGetGraphLinePatternData(A3D_DEFAULT_LINEPATTERN_INDEX, &sLinePatternData);
|
|
}
|
|
}
|
|
|
|
if(sData.m_uiMaterialsSize)
|
|
{
|
|
uiSize= sData.m_uiMaterialsSize;
|
|
|
|
A3DBool bIsTexture;
|
|
for(ui = 0; ui < uiSize; ++ui)
|
|
{
|
|
CHECK_RET(A3DGlobalIsMaterialTexture(ui, &bIsTexture));
|
|
|
|
if(bIsTexture)
|
|
{
|
|
A3DGraphTextureApplicationData sTextureApplicationData;
|
|
A3D_INITIALIZE_DATA(A3DGraphTextureApplicationData, sTextureApplicationData);
|
|
CHECK_RET(A3DGlobalGetGraphTextureApplicationData(ui, &sTextureApplicationData));
|
|
traverseTextureApplication(sTextureApplicationData, global);
|
|
A3DGlobalGetGraphTextureApplicationData(A3D_DEFAULT_MATERIAL_INDEX, &sTextureApplicationData);
|
|
}
|
|
else
|
|
{
|
|
_TiXmlElement* material = new _TiXmlElement("A3DGraphMaterial");
|
|
material->SetAttribute("index", ui);
|
|
|
|
A3DEntity* pMaterial = NULL;
|
|
CHECK_RET(A3DMiscPointerFromIndexGet(ui, kA3DTypeGraphMaterial, &pMaterial))
|
|
if (pMaterial)
|
|
traverseBase(pMaterial, material);
|
|
|
|
A3DGraphMaterialData sMaterialData;
|
|
A3D_INITIALIZE_DATA(A3DGraphMaterialData, sMaterialData);
|
|
CHECK_RET(A3DGlobalGetGraphMaterialData(ui, &sMaterialData));
|
|
traverseMaterial(sMaterialData, material);
|
|
A3DGlobalGetGraphMaterialData(A3D_DEFAULT_MATERIAL_INDEX, &sMaterialData);
|
|
|
|
global->LinkEndChild(material);
|
|
}
|
|
}
|
|
}
|
|
|
|
if(sData.m_uiTextureDefinitionsSize)
|
|
{
|
|
uiSize = sData.m_uiTextureDefinitionsSize;
|
|
A3DGraphTextureDefinitionData sTextureDefinitionData;
|
|
A3D_INITIALIZE_DATA(A3DGraphTextureDefinitionData, sTextureDefinitionData);
|
|
for(ui = 0; ui < uiSize; ++ui)
|
|
{
|
|
CHECK_RET(A3DGlobalGetGraphTextureDefinitionData(ui, &sTextureDefinitionData));
|
|
traverseTextureDefinition(sTextureDefinitionData, global);
|
|
A3DGlobalGetGraphTextureDefinitionData(A3D_DEFAULT_TEXTURE_DEFINITION_INDEX, &sTextureDefinitionData);
|
|
}
|
|
}
|
|
|
|
if(sData.m_uiPicturesSize)
|
|
{
|
|
uiSize = sData.m_uiPicturesSize;
|
|
A3DGraphPictureData sPictureData;
|
|
A3D_INITIALIZE_DATA(A3DGraphPictureData, sPictureData);
|
|
|
|
for(ui = 0; ui < uiSize; ++ui)
|
|
{
|
|
_TiXmlElement* picture = new _TiXmlElement("A3DGraphPicture");
|
|
picture->SetAttribute("index", ui);
|
|
|
|
A3DEntity* pPicture = NULL;
|
|
CHECK_RET(A3DMiscPointerFromIndexGet(ui, kA3DTypeGraphPicture, &pPicture))
|
|
if (pPicture)
|
|
traverseBase(pPicture, picture);
|
|
|
|
CHECK_RET(A3DGlobalGetGraphPictureData(ui, &sPictureData));
|
|
traversePicture(sPictureData, picture);
|
|
A3DGlobalGetGraphPictureData(A3D_DEFAULT_MATERIAL_INDEX, &sPictureData);
|
|
|
|
global->LinkEndChild(picture);
|
|
}
|
|
}
|
|
|
|
if(sData.m_uiFillPatternsSize)
|
|
{
|
|
uiSize = sData.m_uiFillPatternsSize;
|
|
A3DEEntityType ePatternType;
|
|
for(ui = 0; ui < uiSize; ++ui)
|
|
{
|
|
CHECK_RET(A3DGlobalGetFillPatternType(ui, &ePatternType));
|
|
|
|
switch(ePatternType)
|
|
{
|
|
case kA3DTypeGraphHatchingPattern:
|
|
A3DGraphHatchingPatternData sHatchingPatternData;
|
|
A3D_INITIALIZE_DATA(A3DGraphHatchingPatternData, sHatchingPatternData);
|
|
CHECK_RET(A3DGlobalGetGraphHatchingPatternData(ui, &sHatchingPatternData));
|
|
iRet = traverseHatchingPattern(sHatchingPatternData, global);
|
|
A3DGlobalGetGraphHatchingPatternData(A3D_DEFAULT_PATTERN_INDEX, &sHatchingPatternData);
|
|
break;
|
|
|
|
case kA3DTypeGraphSolidPattern:
|
|
A3DGraphSolidPatternData sSolidPatternData;
|
|
A3D_INITIALIZE_DATA(A3DGraphSolidPatternData, sSolidPatternData);
|
|
CHECK_RET(A3DGlobalGetGraphSolidPatternData(ui, &sSolidPatternData));
|
|
iRet = traverseSolidPattern(sSolidPatternData, global);
|
|
A3DGlobalGetGraphSolidPatternData(A3D_DEFAULT_PATTERN_INDEX, &sSolidPatternData);
|
|
break;
|
|
|
|
case kA3DTypeGraphDottingPattern:
|
|
A3DGraphDottingPatternData sDottingPatternData;
|
|
A3D_INITIALIZE_DATA(A3DGraphDottingPatternData, sDottingPatternData);
|
|
CHECK_RET(A3DGlobalGetGraphDottingPatternData(ui, &sDottingPatternData));
|
|
iRet = traverseDottingPattern(sDottingPatternData, global);
|
|
A3DGlobalGetGraphDottingPatternData(A3D_DEFAULT_PATTERN_INDEX, &sDottingPatternData);
|
|
break;
|
|
|
|
case kA3DTypeGraphVPicturePattern:
|
|
A3DGraphVPicturePatternData sVPicturePatternData;
|
|
A3D_INITIALIZE_DATA(A3DGraphVPicturePatternData, sVPicturePatternData);
|
|
CHECK_RET(A3DGlobalGetGraphVPicturePatternData(ui, &sVPicturePatternData));
|
|
iRet = traverseVPicturePattern(sVPicturePatternData, global);
|
|
A3DGlobalGetGraphVPicturePatternData(A3D_DEFAULT_PATTERN_INDEX, &sVPicturePatternData);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (sData.m_uiUnitsSize)
|
|
{
|
|
uiSize = sData.m_uiUnitsSize;
|
|
|
|
for (ui = 0; ui < uiSize; ++ui)
|
|
{
|
|
A3DMiscAttributeUnit *pUnit = nullptr;
|
|
CHECK_RET(A3DGlobalGetUnit(ui, &pUnit));
|
|
|
|
traverseUnit(pUnit, global);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
global->SetAttribute("error", A3DMiscGetErrorMsg(iRet));
|
|
}
|
|
|
|
setting->LinkEndChild(global);
|
|
return iRet;
|
|
}
|