Files
Hoops_Exchange/exchange/exchangesource/PRC2XML/PRC2XMLTessellation.cpp
2025-12-15 23:22:33 +08:00

320 lines
11 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"
//######################################################################################################################
static _TiXmlElement* stfonts = NULL;
//######################################################################################################################
A3DVoid _InitializeFontsArray()
{
if(stfonts == NULL)
stfonts = new _TiXmlElement("Fonts");
}
//######################################################################################################################
A3DVoid _TerminateFontsArray()
{
delete stfonts;
stfonts = NULL;
}
//######################################################################################################################
static A3DBool stCompareFontData(const _TiXmlElement* node, const A3DFontData* psFontData)
{
if(node->Attribute("m_pcFamilyName") && strcmp(node->Attribute("m_pcFamilyName"), psFontData->m_pcFamilyName) != 0)
return false;
int iSize;
if(node->Attribute("m_uiSize", &iSize) && iSize != (int) psFontData->m_uiSize)
return false;
if(node->Attribute("m_eCharset", &iSize) && iSize != psFontData->m_eCharset)
return false;
if(node->Attribute("m_cAttributes", &iSize) && iSize != psFontData->m_cAttributes)
return false;
return true;
}
//######################################################################################################################
static A3DVoid stAddFont(const A3DFontData* psFontData)
{
if(stfonts == NULL || psFontData == NULL)
return;
_TiXmlElement* node = stfonts->FirstChildElement();
while(node)
{
if(stCompareFontData(node, psFontData))
return;
node = node->NextSiblingElement();
}
_TiXmlElement* font = new _TiXmlElement("A3DFontData");
font->SetAttribute("m_pcFamilyName", psFontData->m_pcFamilyName);
font->SetAttribute("m_eCharset", psFontData->m_eCharset);
font->SetAttribute("m_uiSize", (int)psFontData->m_uiSize);
font->SetAttribute("m_cAttributes", psFontData->m_cAttributes);
stfonts->LinkEndChild(font);
}
//######################################################################################################################
static A3DInt32 stExportFontsFromMarkupTessellation(const A3DTessMarkupData* psTess)
{
if(psTess->m_uiCodesSize == 0)
return A3D_SUCCESS;
A3DFontKeyData sFontKeyData;
A3DFontData sFontData;
unsigned int uiCount, uiExtraDataType;
const A3DUns32* puiStart = &psTess->m_puiCodes[0];
const A3DUns32* puiEnd = &psTess->m_puiCodes[psTess->m_uiCodesSize-1];
for(; puiStart < puiEnd; puiStart++)
{
uiCount = *puiStart & kA3DMarkupIntegerMask;
if((*puiStart & kA3DMarkupIsExtraData) != 0)
{
uiExtraDataType = (*puiStart & kA3DMarkupExtraDataType);
switch(uiExtraDataType) // forced to decode these modes to traverse the inside
{
case kA3DMarkupFaceViewMask:
case kA3DMarkupFrameDrawMask:
case kA3DMarkupFixedSizeMask:
puiStart += 1;
break;
case kA3DMarkupFontMask:
A3D_INITIALIZE_DATA(A3DFontKeyData, sFontKeyData);
sFontKeyData.m_iFontFamilyIndex = *(puiStart+2);
sFontKeyData.m_iFontStyleIndex = (*(puiStart+3) & kA3DFontKeyStyle) >> 24;
sFontKeyData.m_iFontSizeIndex = (*(puiStart+3) & kA3DFontKeySize) >> 12;
sFontKeyData.m_cAttributes = (A3DInt8) (*(puiStart+3) & kA3DFontKeyAttrib);
A3D_INITIALIZE_DATA(A3DFontData, sFontData);
CHECK_RET(A3DGlobalFontKeyGet(&sFontKeyData, &sFontData));
stAddFont(&sFontData);
puiStart += size_t(uiCount + 1);
CHECK_RET(A3DGlobalFontKeyGet(nullptr, &sFontData));
break;
default:
puiStart += size_t(uiCount + 1);
break;
}
}
// forced to decode that mode to traverse the inside
else if((*puiStart & kA3DMarkupIsMatrix) != 0)
puiStart += 1;
else
puiStart += size_t(uiCount + 1);
}
return A3D_SUCCESS;
}
//######################################################################################################################
A3DStatus traverseFonts(_TiXmlElement* setting)
{
if(stfonts == NULL)
return A3D_ERROR;
_TiXmlElement* node = setting->FirstChildElement("A3DGlobalData");
if(node == NULL)
return A3D_ERROR;
_TiXmlElement* font = stfonts->FirstChildElement();
while(font)
{
_TiXmlElement* newfont = new _TiXmlElement(*font);
node->LinkEndChild(newfont);
font = font->NextSiblingElement();
}
return A3D_SUCCESS;
}
//######################################################################################################################
static A3DInt32 stTraverseTessBase(const A3DTessBase* pTess, _TiXmlElement* setting)
{
A3DTessBaseData sData;
A3D_INITIALIZE_DATA(A3DTessBaseData, sData);
_TiXmlElement* tessbase = new _TiXmlElement("A3DTessBaseData");
A3DStatus iRet = A3DTessBaseGet(pTess, &sData);
if(iRet == A3D_SUCCESS)
{
tessbase->SetAttribute("m_bIsCalculated", sData.m_bIsCalculated ? 1 : 0);
traverseDoubles("m_pdCoords", sData.m_uiCoordSize, sData.m_pdCoords, tessbase);
A3DTessBaseGet(NULL, &sData);
}
setting->LinkEndChild(tessbase);
return iRet;
}
//######################################################################################################################
A3DStatus traverseMarkupTess(const A3DTessMarkup* pMarkupTess, _TiXmlElement* setting)
{
A3DStatus iRet = A3D_SUCCESS;
A3DTessMarkupData sData;
A3D_INITIALIZE_DATA(A3DTessMarkupData, sData);
_TiXmlElement* markuptess = new _TiXmlElement("A3DTessMarkupData");
stTraverseTessBase(pMarkupTess, markuptess);
iRet = A3DTessMarkupGet(pMarkupTess, &sData);
if(iRet == A3D_SUCCESS)
{
traverseUInts("m_puiCodes",sData.m_uiCodesSize, sData.m_puiCodes, markuptess);
for(A3DUns32 i = 0; i < sData.m_uiTextsSize; ++i)
{
if (sData.m_ppcTexts[i] != nullptr)
{
_TiXmlElement* text = new _TiXmlElement("pcText");
text->SetAttribute("data", sData.m_ppcTexts[i]);
markuptess->LinkEndChild(text);
}
}
if(sData.m_pcLabel)
markuptess->SetAttribute("m_pcLabel", sData.m_pcLabel);
markuptess->SetAttribute("m_cBehaviour", (int) sData.m_cBehaviour);
stExportFontsFromMarkupTessellation(&sData);
A3DTessMarkupGet(NULL, &sData);
}
else
{
markuptess->SetAttribute("error", A3DMiscGetErrorMsg(iRet));
}
setting->LinkEndChild(markuptess);
return iRet;
}
//######################################################################################################################
static A3DStatus stTraverse3DWireTess(const A3DTess3DWire* pWireTess, _TiXmlElement* setting)
{
A3DStatus iRet = A3D_SUCCESS;
A3DTess3DWireData sData;
A3D_INITIALIZE_DATA(A3DTess3DWireData, sData);
_TiXmlElement* wiretess = new _TiXmlElement("A3DTess3DWireData");
stTraverseTessBase(pWireTess, wiretess);
iRet = A3DTess3DWireGet(pWireTess, &sData);
if(iRet == A3D_SUCCESS)
{
traverseUInts("m_puiSizesWires", sData.m_uiSizesWiresSize, sData.m_puiSizesWires, wiretess);
traverseUChars("m_pucRGBAVertices", sData.m_uiRGBAVerticesSize, sData.m_pucRGBAVertices, wiretess);
A3DTess3DWireGet(NULL, &sData);
}
else
{
wiretess->SetAttribute("error", A3DMiscGetErrorMsg(iRet));
}
setting->LinkEndChild(wiretess);
return iRet;
}
//######################################################################################################################
static A3DStatus stTraverseFaceTessData(const A3DTessFaceData& sFaceTessData, _TiXmlElement* setting)
{
A3DStatus iRet = A3D_SUCCESS;
_TiXmlElement* facetess = new _TiXmlElement("A3DTessFaceData");
facetess->SetAttribute("m_usUsedEntitiesFlags", (int) sFaceTessData.m_usUsedEntitiesFlags);
facetess->SetAttribute("m_uiStartTriangulated", (int) sFaceTessData.m_uiStartTriangulated);
facetess->SetAttribute("m_uiStartWire", (int) sFaceTessData.m_uiStartWire);
facetess->SetAttribute("m_uiTextureCoordIndexesSize", (int) sFaceTessData.m_uiTextureCoordIndexesSize);
traverseUInts("m_puiStyleIndexes", sFaceTessData.m_uiStyleIndexesSize, sFaceTessData.m_puiStyleIndexes, facetess);
traverseUInts("m_puiSizesTriangulated", sFaceTessData.m_uiSizesTriangulatedSize,
sFaceTessData.m_puiSizesTriangulated, facetess);
traverseUInts("m_puiSizesWires", sFaceTessData.m_uiSizesWiresSize, sFaceTessData.m_puiSizesWires, facetess);
traverseUChars("m_pucRGBAVertices", sFaceTessData.m_uiRGBAVerticesSize, sFaceTessData.m_pucRGBAVertices, facetess);
setting->LinkEndChild(facetess);
return iRet;
}
//######################################################################################################################
static A3DStatus stTraverse3DTess(const A3DTess3D* pTess, _TiXmlElement* setting)
{
A3DStatus iRet = A3D_SUCCESS;
A3DTess3DData sData;
A3D_INITIALIZE_DATA(A3DTess3DData, sData);
_TiXmlElement* tess = new _TiXmlElement("A3DTess3DData");
stTraverseTessBase(pTess, tess);
iRet = A3DTess3DGet(pTess, &sData);
if(iRet == A3D_SUCCESS)
{
tess->SetAttribute("m_bHasFaces", (int)(sData.m_bHasFaces));
traverseDoubles("m_pdNormals", sData.m_uiNormalSize, sData.m_pdNormals, tess);
traverseUInts("m_puiWireIndexes", sData.m_uiWireIndexSize, sData.m_puiWireIndexes, tess);
traverseUInts("m_puiTriangulatedIndexes", sData.m_uiTriangulatedIndexSize, sData.m_puiTriangulatedIndexes,
tess);
traverseDoubles("m_pdTextureCoords", sData.m_uiTextureCoordSize, sData.m_pdTextureCoords, tess);
tess->SetDoubleAttribute("m_dCreaseAngle", sData.m_dCreaseAngle);
for(A3DUns32 ui = 0; ui < sData.m_uiFaceTessSize; ++ui)
stTraverseFaceTessData(sData.m_psFaceTessData[ui], tess);
A3DTess3DGet(NULL, &sData);
}
else
{
tess->SetAttribute("error", A3DMiscGetErrorMsg(iRet));
}
setting->LinkEndChild(tess);
return iRet;
}
//######################################################################################################################
A3DStatus traverseTessBase(const A3DTessBase* pTess, _TiXmlElement* setting)
{
A3DEEntityType eType;
A3DStatus iRet = A3DEntityGetType(pTess, &eType);
if(iRet == A3D_SUCCESS)
{
switch(eType)
{
case kA3DTypeTess3D:
stTraverse3DTess(pTess,setting);
break;
case kA3DTypeTess3DWire:
stTraverse3DWireTess(pTess,setting);
break;
case kA3DTypeTessMarkup:
traverseMarkupTess(pTess,setting);
break;
default:
break;
}
}
return iRet;
}