/*********************************************************************************************************************** * * 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 #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; }