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

757 lines
30 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 "HXmlElement.h"
#include "HXFeatureTreeReport.h"
#include <algorithm>
#include <cmath>
#include <sstream>
#include <stdlib.h>
#include <vector>
//######################################################################################################################
void HXFeatureTreeReport::traverseIndexes(const A3DUns32 uiSize, const A3DUns32* puiIndexes)
{
if (uiSize == 0)
return;
// max size of one uint: "%u " 14 + 1 = 15
const A3DUns32 uiFormat = 15;
const size_t uiMaxSize = static_cast<size_t>(uiSize) * static_cast<size_t>(uiFormat);
std::vector<A3DUTF8Char> pc(uiMaxSize + 1, '\0');
// store indexes in ascending order: useful for non regression tests
std::vector<A3DUns32> indexes(puiIndexes, puiIndexes + uiSize);
std::sort(indexes.begin(), indexes.end());
size_t uiNext = 0;
for (const auto& index: indexes)
{
const size_t uiwritten = sprintf_s(pc.data() + uiNext, uiMaxSize - uiNext, "%u ", index);
uiNext += uiwritten;
}
if (uiNext != 0)
{
// To remove the end whitespace.
pc[uiNext - 1] = '\0';
}
m_sReport.setAttribute("size" , (int)uiSize);
m_sReport.setAttribute("indexes", pc.data());
}
//######################################################################################################################
A3DStatus HXFeatureTreeReport::visitEnter(const A3DFRMTreeConnector& /*sConnector*/)
{
m_failed_count = 0;
m_not_implemented_node_count = 0;
m_not_implemented_subnode_count = 0;
m_mandatory_missing_count = 0;
m_hole_mandatory_missing_count = 0;
m_pattern_mandatory_missing_count = 0;
return A3D_SUCCESS;
}
A3DStatus HXFeatureTreeReport::visitLeave(const A3DFRMTreeConnector& /*sConnector*/)
{
return A3D_SUCCESS;
}
void HXFeatureTreeReport::traverseFeatureStatus(const A3DFRMFeatureConnector& sConnector)
{
switch (sConnector.m_sData.m_sType.m_eStatus)
{
case kA3DFRMStatus_Failed: m_sReport.setAttribute("status", "Failed"); break;
case kA3DFRMStatus_NotYetImplemented: m_sReport.setAttribute("status", "NotYetImplemented"); break;
case kA3DFRMStatus_Success: // ignored, otherwise the XML file is too verbose
default: break;
}
}
template<typename T>
void DumpFRMFeatureData(HXmlReport& report, const A3DUns32 size, const T* values)
{
if (size == 0)
{
report.setAttribute("data", "empty");
}
else
{
std::ostringstream os;
os << values[0];
for (A3DUns32 i = 1; i < size; ++i)
os << " " << values[i];
report.setAttribute("data", os.str().c_str());
}
}
void HXFeatureTreeReport::traverseFeatureData(const A3DFRMFeatureConnector& sConnector)
{
switch (sConnector.m_sData.m_eDataType)
{
case kA3DFRMDataInteger:
{
A3DFRMIntegerData sIntegerData;
A3D_INITIALIZE_DATA(A3DFRMIntegerData, sIntegerData);
A3DFRMIntegerDataGet(sConnector.GetA3DEntity(), &sIntegerData);
DumpFRMFeatureData(m_sReport, sIntegerData.m_uiValuesSize, sIntegerData.m_piValues);
A3DFRMIntegerDataGet(NULL, &sIntegerData);
break;
}
case kA3DFRMDataDouble:
{
A3DFRMDoubleData sDoubleData;
A3D_INITIALIZE_DATA(A3DFRMDoubleData, sDoubleData);
A3DFRMDoubleDataGet(sConnector.GetA3DEntity(), &sDoubleData);
// We keep three digits after the decimal point without rounding for the output.
std::transform(sDoubleData.m_pdValues, sDoubleData.m_pdValues + sDoubleData.m_uiValuesSize,
sDoubleData.m_pdValues, [](double value)
{
return std::trunc(value * 1000.0) / 1000.0;
});
DumpFRMFeatureData(m_sReport, sDoubleData.m_uiValuesSize, sDoubleData.m_pdValues);
A3DFRMDoubleDataGet(NULL, &sDoubleData);
break;
}
case kA3DFRMDataString:
{
A3DFRMStringData sStringData;
A3D_INITIALIZE_DATA(A3DFRMStringData, sStringData);
A3DFRMStringDataGet(sConnector.GetA3DEntity(), &sStringData);
if (sStringData.m_uiValuesSize == 0)
{
m_sReport.setAttribute("data", "empty");
}
else
{
std::ostringstream os;
os << sStringData.m_ppcValues[0];
for (A3DUns32 i = 1; i < sStringData.m_uiValuesSize; ++i)
if (sStringData.m_ppcValues[i] != nullptr)
// we use a separator between the values for the .xsl file, in case the values contain spaces
os << " xts3dx " << sStringData.m_ppcValues[i];
m_sReport.setAttribute("data", os.str().c_str());
}
A3DFRMStringDataGet(NULL, &sStringData);
break;
}
case kA3DFRMDataEnum:
{
A3DInt32 iEnumValue = 0;
A3DUTF8Char* pcStringValue = NULL;
A3DFRMEnumDataGet(sConnector.GetA3DEntity(), &iEnumValue, &pcStringValue);
if (pcStringValue)
m_sReport.setAttribute("Value", pcStringValue);
else
m_sReport.setAttribute("Value", static_cast<int>(iEnumValue));
A3DFRMEnumDataGet(NULL, &iEnumValue, &pcStringValue);
break;
}
default:
break;
}
}
A3DStatus HXFeatureTreeReport::visitEnter(const A3DFRMFeatureConnector& sConnector)
{
switch (sConnector.m_sData.m_sType.m_eFamily)
{
case kA3DFamily_Root:
m_sReport.createSubNode("Node");
traverseRootBaseData(sConnector.GetA3DEntity());
m_sReport.setAttribute("data_type", "root");
switch (sConnector.m_sData.m_sType.m_uiType)
{
case kA3DFRMRoot_Node: m_sReport.setAttribute("root_type", "Node"); break;
case kA3DFRMRoot_Container: m_sReport.setAttribute("root_type", "Container"); break;
case kA3DFRMRoot_Package: m_sReport.setAttribute("root_type", "Package"); break;
case kA3DFRMRoot_None:
default: m_sReport.setAttribute("root_type", "None"); break;
}
break;
case kA3DFamily_Information:
m_sReport.createSubNode("Feature");
break;
case kA3DFamily_Type:
m_sReport.createSubNode("Feature");
m_sReport.setAttribute("data_type", "type");
switch (sConnector.m_sData.m_sType.m_uiType)
{
case kA3DFRMEnumDataType_CAD: m_sReport.setAttribute("type_type", "CAD"); break;
case kA3DFRMEnumDataType_Mode: m_sReport.setAttribute("type_type", "Mode"); break;
case kA3DFRMEnumDataType_Depth: m_sReport.setAttribute("type_type", "Depth"); break;
case kA3DFRMEnumDataType_Pattern: m_sReport.setAttribute("type_type", "Pattern"); break;
case kA3DFRMEnumDataType_HoleShape: m_sReport.setAttribute("type_type", "HoleShape"); break;
case kA3DFRMEnumDataType_DepthLevel: m_sReport.setAttribute("type_type", "DepthLevel"); break;
case kA3DFRMEnumDataType_RevolveAngle: m_sReport.setAttribute("type_type", "RevolveAngle"); break;
case kA3DFRMEnumDataType_Chamfer: m_sReport.setAttribute("type_type", "Chamfer"); break;
case kA3DFRMEnumDataType_Fillet: m_sReport.setAttribute("type_type", "Fillet"); break;
case kA3DFRMEnumDataType_FilletLength: m_sReport.setAttribute("type_type", "FilletLength"); break;
case kA3DFRMEnumDataType_FilletConic: m_sReport.setAttribute("type_type", "FilletConic"); break;
case kA3DFRMEnumDataType_LengthMode: m_sReport.setAttribute("type_type", "LengthMode"); break;
case kA3DFRMEnumDataType_PatternMaster: m_sReport.setAttribute("type_type", "PatternMaster"); break;
case kA3DFRMEnumDataType_ReferenceMaster: m_sReport.setAttribute("type_type", "ReferenceMaster"); break;
case kA3DFRMDoubleNone:
default: m_sReport.setAttribute("type_type", "None"); break;
}
break;
case kA3DFamily_FeatureDefinition:
m_sReport.createSubNode("Feature");
m_sReport.setAttribute("data_type", "feature_definition");
switch (sConnector.m_sData.m_sType.m_uiType)
{
case kA3DFRMFeatureDefinitionType_Hole: m_sReport.setAttribute("feature_definition_type", "Hole"); break;
case kA3DFRMFeatureDefinitionType_Pattern: m_sReport.setAttribute("feature_definition_type", "Pattern"); break;
case kA3DFRMFeatureDefinitionType_Sketch: m_sReport.setAttribute("feature_definition_type", "Sketch"); break;
case kA3DFRMFeatureDefinitionType_Thread: m_sReport.setAttribute("feature_definition_type", "Thread"); break;
case kA3DFRMFeatureDefinitionType_Extrude: m_sReport.setAttribute("feature_definition_type", "Extrude"); break;
case kA3DFRMFeatureDefinitionType_Revolve: m_sReport.setAttribute("feature_definition_type", "Revolve"); break;
case kA3DFRMFeatureDefinitionType_Cosmetic: m_sReport.setAttribute("feature_definition_type", "Cosmetic"); break;
case kA3DFRMFeatureDefinitionType_Chamfer: m_sReport.setAttribute("feature_definition_type", "Chamfer"); break;
case kA3DFRMFeatureDefinitionType_Fillet: m_sReport.setAttribute("feature_definition_type", "Fillet"); break;
case kA3DFRMFeatureDefinitionType_Mirror: m_sReport.setAttribute("feature_definition_type", "Mirror"); break;
case kA3DFRMFeatureDefinitionType_Symmetry: m_sReport.setAttribute("feature_definition_type", "Symmetry"); break;
case kA3DFRMFeatureDefinitionType_Translate: m_sReport.setAttribute("feature_definition_type", "Translate"); break;
case kA3DFRMFeatureDefinitionType_Rotate: m_sReport.setAttribute("feature_definition_type", "Rotate"); break;
case kA3DFRMFeatureDefinitionType_None:
default: m_sReport.setAttribute("definition_type", "None"); break;
}
break;
case kA3DFamily_DoubleData:
m_sReport.createSubNode("Feature");
m_sReport.setAttribute("data_type", "double");
switch (sConnector.m_sData.m_sType.m_uiType)
{
case kA3DFRMDoubleValue: m_sReport.setAttribute("double_type", "Value"); break;
case kA3DFRMDoubleUnit: m_sReport.setAttribute("double_type", "Unit"); break;
case kA3DFRMDoubleOffset: m_sReport.setAttribute("double_type", "Offset"); break;
case kA3DFRMDoubleDepth: m_sReport.setAttribute("double_type", "Depth"); break;
case kA3DFRMDoubleDiameter: m_sReport.setAttribute("double_type", "Diameter"); break;
case kA3DFRMDoubleAngle: m_sReport.setAttribute("double_type", "Angle"); break;
case kA3DFRMDoublePitch: m_sReport.setAttribute("double_type", "Pitch"); break;
case kA3DFRMDoubleDistance: m_sReport.setAttribute("double_type", "Distance"); break;
case kA3DFRMDoubleExtensionAndStep: m_sReport.setAttribute("double_type", "ExtensionAndStep"); break;
case kA3DFRMDoubleLinearParameter: m_sReport.setAttribute("double_type", "LinearParameter"); break;
case kA3DFRMDoubleUVParameter: m_sReport.setAttribute("double_type", "UVParameter"); break;
case kA3DFRMDoubleRadius: m_sReport.setAttribute("double_type", "Radius"); break;
case kA3DFRMDoubleNone:
default: m_sReport.setAttribute("double_type", "None"); break;
}
break;
case kA3DFamily_IntegerData:
m_sReport.createSubNode("Feature");
m_sReport.setAttribute("data_type", "integer");
switch (sConnector.m_sData.m_sType.m_uiType)
{
case kA3DFRMIntegerDataValue: m_sReport.setAttribute("integer_type", "Value"); break;
case kA3DFRMIntegerDataBoolean: m_sReport.setAttribute("integer_type", "Boolean"); break;
case kA3DFRMIntegerDataIndex: m_sReport.setAttribute("integer_type", "Index"); break;
case kA3DFRMIntegerDataKeepSpecification: m_sReport.setAttribute("integer_type", "KeepSpecification"); break;
case kA3DFRMIntegerDataRadialAlignment: m_sReport.setAttribute("integer_type", "RadialAlignment"); break;
case kA3DFRMIntegerDataClockwise: m_sReport.setAttribute("integer_type", "Clockwise"); break;
case kA3DFRMIntegerDataId: m_sReport.setAttribute("integer_type", "Id"); break;
case kA3DFRMIntegerDataFlip: m_sReport.setAttribute("integer_type", "Flip"); break;
case kA3DFRMIntegerDataType: m_sReport.setAttribute("integer_type", "Type"); break;
case kA3DFRMIntegerDataCount: m_sReport.setAttribute("integer_type", "Count"); break;
case kA3DFRMIntegerDataSize: m_sReport.setAttribute("integer_type", "Size"); break;
case kA3DFRMIntegerDataNbStart: m_sReport.setAttribute("integer_type", "NbStart"); break;
case kA3DFRMIntegerDataNone:
default: m_sReport.setAttribute("integer_type", "None"); break;
}
break;
case kA3DFamily_StringData:
m_sReport.createSubNode("Feature");
m_sReport.setAttribute("data_type", "string");
switch (sConnector.m_sData.m_sType.m_uiType)
{
case kA3DFRMStringDataName: m_sReport.setAttribute("string_type", "Name"); break;
case kA3DFRMStringDataAttribute: m_sReport.setAttribute("string_type", "Attribute"); break;
case kA3DFRMStringDataType: m_sReport.setAttribute("string_type", "Type"); break;
case kA3DFRMStringDataValue: m_sReport.setAttribute("string_type", "Value"); break;
case kA3DFRMStringDataOption: m_sReport.setAttribute("string_type", "Option"); break;
case kA3DFRMStringDataNone:
default: m_sReport.setAttribute("string_type", "None"); break;
}
break;
case kA3DFamily_Value:
m_sReport.createSubNode("Feature");
m_sReport.setAttribute("data_type", "value");
switch (sConnector.m_sData.m_sType.m_uiType)
{
case kA3DFRMValueType_Length: m_sReport.setAttribute("value_type", "Length"); break;
case kA3DFRMValueType_Angle: m_sReport.setAttribute("value_type", "Angle"); break;
case kA3DFRMValueType_Diameter: m_sReport.setAttribute("value_type", "Diameter"); break;
case kA3DFRMValueType_Radius: m_sReport.setAttribute("value_type", "Radius"); break;
case kA3DFRMValueType_Depth: m_sReport.setAttribute("value_type", "Depth"); break;
case kA3DFRMValueType_Thickness: m_sReport.setAttribute("value_type", "Thickness"); break;
case kA3DFRMValueType_Offset: m_sReport.setAttribute("value_type", "Offset"); break;
case kA3DFRMValueType_Distance: m_sReport.setAttribute("value_type", "Distance"); break;
case kA3DFRMValueType_Coords: m_sReport.setAttribute("value_type", "Coords"); break;
case kA3DFRMValueType_Vector: m_sReport.setAttribute("value_type", "Vector"); break;
case kA3DFRMValueType_Matrix: m_sReport.setAttribute("value_type", "Matrix"); break;
case kA3DFRMValueType_Area: m_sReport.setAttribute("value_type", "Area"); break;
case kA3DFRMValueType_Volume: m_sReport.setAttribute("value_type", "Volume"); break;
case kA3DFRMValueType_Mass: m_sReport.setAttribute("value_type", "Mass"); break;
case kA3DFRMValueType_Time: m_sReport.setAttribute("value_type", "Time"); break;
case kA3DFRMValueType_None:
default: m_sReport.setAttribute("value_type", "None"); break;
}
break;
case kA3DFamily_Definition:
m_sReport.createSubNode("Feature");
m_sReport.setAttribute("data_type", "definition");
switch (sConnector.m_sData.m_sType.m_uiType)
{
case kA3DFRMDefinitionType_Depth: m_sReport.setAttribute("definition_type", "Depth"); break;
case kA3DFRMDefinitionType_DepthFrom: m_sReport.setAttribute("definition_type", "DepthFrom"); break;
case kA3DFRMDefinitionType_Position: m_sReport.setAttribute("definition_type", "Position"); break;
case kA3DFRMDefinitionType_Direction: m_sReport.setAttribute("definition_type", "Direction"); break;
case kA3DFRMDefinitionType_Thread: m_sReport.setAttribute("definition_type", "Thread"); break;
case kA3DFRMDefinitionType_Shape: m_sReport.setAttribute("definition_type", "Shape"); break;
case kA3DFRMDefinitionType_Reference: m_sReport.setAttribute("definition_type", "Reference"); break;
case kA3DFRMDefinitionType_Sketch: m_sReport.setAttribute("definition_type", "Sketch"); break;
case kA3DFRMDefinitionType_RevolveAngle: m_sReport.setAttribute("definition_type", "RevolveAngle"); break;
case kA3DFRMDefinitionType_RevolveAngleFrom: m_sReport.setAttribute("definition_type", "RevolveAngleFrom"); break;
case kA3DFRMDefinitionType_Axis: m_sReport.setAttribute("definition_type", "Axis"); break;
case kA3DFRMDefinitionType_Chamfer: m_sReport.setAttribute("definition_type", "Chamfer"); break;
case kA3DFRMDefinitionType_FilletLength: m_sReport.setAttribute("definition_type", "FilletLength"); break;
case kA3DFRMDefinitionType_ReferenceMaster: m_sReport.setAttribute("definition_type", "ReferenceMaster"); break;
case kA3DFRMDefinitionType_Tolerance: m_sReport.setAttribute("definition_type", "Tolerance"); break;
case kA3DFRMDefinitionType_None:
default: m_sReport.setAttribute("definition_type", "None"); break;
}
break;
case kA3DFamily_Definition_Hole:
m_sReport.createSubNode("Feature");
m_sReport.setAttribute("data_type", "definition_hole");
switch (sConnector.m_sData.m_sType.m_uiType)
{
case kA3DFRMDefinitionHoleType_RectangularDefinition: m_sReport.setAttribute("definition_hole_type", "RectangularDefinition"); break;
case kA3DFRMDefinitionHoleType_ChamferDefinition: m_sReport.setAttribute("definition_hole_type", "ChamferDefinition"); break;
case kA3DFRMDefinitionHoleType_CboreDefinition: m_sReport.setAttribute("definition_hole_type", "CboreDefinition"); break;
case kA3DFRMDefinitionHoleType_SunkDefinition: m_sReport.setAttribute("definition_hole_type", "SunkDefinition"); break;
case kA3DFRMDefinitionHoleType_TaperedDefinition: m_sReport.setAttribute("definition_hole_type", "TaperedDefinition"); break;
case kA3DFRMDefinitionHoleType_StandardDefinition: m_sReport.setAttribute("definition_hole_type", "StandardDefinition"); break;
case kA3DFRMDefinitionHoleType_ElementDefinition: m_sReport.setAttribute("definition_hole_type", "ElementDefinition"); break;
case kA3DFRMDefinitionHoleType_None:
default: m_sReport.setAttribute("definition_hole_type", "None"); break;
}
break;
case kA3DFamily_Definition_Pattern:
m_sReport.createSubNode("Feature");
m_sReport.setAttribute("data_type", "definition_pattern");
switch (sConnector.m_sData.m_sType.m_uiType)
{
case kA3DFRMDefinitionPatternType_PatternMaster: m_sReport.setAttribute("definition_pattern_type", "PatternMaster"); break;
case kA3DFRMDefinitionPatternType_PolygonalShape: m_sReport.setAttribute("definition_pattern_type", "PolygonalShape"); break;
case kA3DFRMDefinitionPatternType_SpiralShape: m_sReport.setAttribute("definition_pattern_type", "SpiralShape"); break;
case kA3DFRMDefinitionPatternType_DirectionSpacing: m_sReport.setAttribute("definition_pattern_type", "DirectionSpacing"); break;
case kA3DFRMDefinitionPatternType_AxialSpacing: m_sReport.setAttribute("definition_pattern_type", "AxialSpacing"); break;
case kA3DFRMDefinitionPatternType_RadialSpacing: m_sReport.setAttribute("definition_pattern_type", "RadialSpacing"); break;
case kA3DFRMDefinitionPatternType_PolygonalSpacing: m_sReport.setAttribute("definition_pattern_type", "PolygonalSpacing"); break;
case kA3DFRMDefinitionPatternType_SpiralSpacing: m_sReport.setAttribute("definition_pattern_type", "SpiralSpacing"); break;
case kA3DFRMDefinitionPatternType_InstanceStatus: m_sReport.setAttribute("definition_pattern_type", "InstanceStatus"); break;
case kA3DFRMDefinitionPatternType_InstanceInformation:m_sReport.setAttribute("definition_pattern_type", "InstanceInformation"); break;
case kA3DFRMDefinitionPatternType_None:
default: m_sReport.setAttribute("definition_pattern_type", "None"); break;
}
break;
case kA3DFamily_Definition_Thread:
m_sReport.createSubNode("Feature");
m_sReport.setAttribute("data_type", "definition_thread");
switch (sConnector.m_sData.m_sType.m_uiType)
{
case kA3DFRMDefinitionThreadType_Undercut: m_sReport.setAttribute("definition_thread_type", "Undercut"); break;
case kA3DFRMDefinitionThreadType_Shaft: m_sReport.setAttribute("definition_thread_type", "Shaft"); break;
case kA3DFRMDefinitionThreadType_None:
default: m_sReport.setAttribute("definition_thread_type", "None"); break;
}
break;
default:
m_sReport.createSubNode("Feature");
m_sReport.setAttribute("data_type", "None");
}
traverseFeatureStatus(sConnector);
traverseFeatureData(sConnector);
return A3D_SUCCESS;
}
A3DStatus HXFeatureTreeReport::visitLeave(const A3DFRMFeatureConnector& /*sConnector*/)
{
m_sReport.closeSubNode();
return A3D_SUCCESS;
}
void HXFeatureTreeReport::DumpIndexesBy3(
const char* name,
const A3DUns32 uiAdditionalIndexesSize,
const A3DUns32* puiAdditionalIndexes)
{
if (uiAdditionalIndexesSize % 3)
return;
for (A3DUns32 i = 0; i + 2 < uiAdditionalIndexesSize; i += 3)
{
char acName[255];
sprintf_s(acName, sizeof(acName) - 1, "%d %d %d",
puiAdditionalIndexes[i],
puiAdditionalIndexes[i + 1],
puiAdditionalIndexes[i + 2]);
HXmlElement* pXmlElement= new HXmlElement(name);
pXmlElement->SetAttribute("indexes", acName);
m_sReport.addNode(pXmlElement);
}
}
void HXFeatureTreeReport::DumpIndexesBy4(
const char* name,
const A3DUns32 uiAdditionalIndexesSize,
const A3DUns32* puiAdditionalIndexes)
{
if (uiAdditionalIndexesSize % 4)
return;
for (A3DUns32 i = 0; i + 3 < uiAdditionalIndexesSize; i += 4)
{
char acName[255];
sprintf_s(acName, sizeof(acName) - 1, "%d %d %d %d",
puiAdditionalIndexes[i],
puiAdditionalIndexes[i + 1],
puiAdditionalIndexes[i + 2],
puiAdditionalIndexes[i + 3]);
HXmlElement* pXmlElement = new HXmlElement(name);
pXmlElement->SetAttribute("indexes", acName);
m_sReport.addNode(pXmlElement);
}
}
void HXFeatureTreeReport::traverseMiscReferenceOnTessData(const A3DMiscEntityReference* pEntityReference)
{
m_sReport.createSubNode("ReferenceOnTessellation");
A3DMiscReferenceOnTessData sReferenceOnTessData;
A3D_INITIALIZE_DATA(A3DMiscReferenceOnTessData, sReferenceOnTessData);
A3DStatus iRet = A3DMiscReferenceOnTessGet(pEntityReference, &sReferenceOnTessData);
if (iRet != A3D_SUCCESS)
return;
traverseMiscReferenceOnBRep(
sReferenceOnTessData.m_pPolyBrepModel,
sReferenceOnTessData.m_eTopoItemType,
sReferenceOnTessData.m_puiAdditionalIndexes,
sReferenceOnTessData.m_uiSize);
A3DMiscReferenceOnTessGet(NULL, &sReferenceOnTessData);
m_sReport.closeSubNode();
}
void HXFeatureTreeReport::traverseMiscReferenceOnCsysItem(const A3DMiscReferenceOnCsysItem* pEntityReference)
{
m_sReport.createSubNode("ReferenceOnCSYSItem");
A3DMiscReferenceOnCsysItemData sA3DMiscReferenceOnCSYSITemData;
A3D_INITIALIZE_DATA(A3DMiscReferenceOnCsysItemData, sA3DMiscReferenceOnCSYSITemData);
A3DStatus iRet = A3DMiscReferenceOnCsysItemGet(pEntityReference, &sA3DMiscReferenceOnCSYSITemData);
if (iRet != A3D_SUCCESS || !sA3DMiscReferenceOnCSYSITemData.m_pCoordinateSystem)
return;
A3DRootBaseData sCSYSRootData;
A3D_INITIALIZE_DATA(A3DRootBaseData, sCSYSRootData);
if (A3DRootBaseGet(sA3DMiscReferenceOnCSYSITemData.m_pCoordinateSystem, &sCSYSRootData) == A3D_SUCCESS)
{
m_sReport.setAttribute("index", sA3DMiscReferenceOnCSYSITemData.m_uiIndex);
A3DRootBaseGet(NULL, &sCSYSRootData);
}
traverseRootBaseData(sA3DMiscReferenceOnCSYSITemData.m_pCoordinateSystem);
m_sReport.closeSubNode();
}
void HXFeatureTreeReport::traverseMiscReferenceOnTopology(const A3DMiscReferenceOnTopology* pEntityReference)
{
m_sReport.createSubNode("ReferenceOnTopology");
A3DMiscReferenceOnTopologyData sReferenceOnTopologyData;
A3D_INITIALIZE_DATA(A3DMiscReferenceOnTopologyData, sReferenceOnTopologyData);
A3DStatus iRet = A3DMiscReferenceOnTopologyGet((A3DMiscReferenceOnTopology*)pEntityReference, &sReferenceOnTopologyData);
if (iRet != A3D_SUCCESS)
return;
traverseMiscReferenceOnBRep(
sReferenceOnTopologyData.m_pBrepData,
sReferenceOnTopologyData.m_eTopoItemType,
sReferenceOnTopologyData.m_puiAdditionalIndexes,
sReferenceOnTopologyData.m_uiSize);
A3DMiscReferenceOnTopologyGet(NULL, &sReferenceOnTopologyData);
m_sReport.closeSubNode();
}
void HXFeatureTreeReport::traverseMiscReferenceOnBRep(
const A3DEntity* pEntity,
const A3DEEntityType eType,
const A3DUns32* puiAdditionalIndexes,
const A3DUns32 uiAdditionalIndexesSize)
{
switch (eType)
{
case kA3DTypeTopoEdge:
m_sReport.setAttribute("topo_type", "Edge");
DumpIndexesBy3("Edge", uiAdditionalIndexesSize, puiAdditionalIndexes);
break;
case kA3DTypeTopoCoEdge:
m_sReport.setAttribute("topo_type", "CoEdge");
DumpIndexesBy3("Edge", uiAdditionalIndexesSize, puiAdditionalIndexes);
break;
case kA3DTypeTopoFace:
m_sReport.setAttribute("topo_type", "Face");
traverseIndexes(uiAdditionalIndexesSize, puiAdditionalIndexes);
break;
case kA3DTypeTopoUniqueVertex:
m_sReport.setAttribute("topo_type", "UniqueVertex");
DumpIndexesBy4("Vertex", uiAdditionalIndexesSize, puiAdditionalIndexes);
break;
case kA3DTypeTopoMultipleVertex:
m_sReport.setAttribute("topo_type", "MultipleVertex");
DumpIndexesBy4("Vertex", uiAdditionalIndexesSize, puiAdditionalIndexes);
break;
case kA3DTypeUnknown:
default:
break;
}
traverseRootBaseData(pEntity);
}
void HXFeatureTreeReport::traverseDrawingBlock(const A3DDrawingBlockBasic *pDrwBlock)
{
A3DInt32 iRet = A3D_SUCCESS;
A3DDrawingBlockBasicData sDrwBlockData;
A3D_INITIALIZE_DATA(A3DDrawingBlockBasicData, sDrwBlockData);
m_sReport.createSubNode("DrawingBlock");
if ((iRet = A3DDrawingBlockBasicGet((A3DDrawingBlockBasic const*)pDrwBlock, &sDrwBlockData)) == A3D_SUCCESS)
{
m_sReport.setAttribute("nb_entities", (int)sDrwBlockData.m_uiDrwEntitiesSize);
m_sReport.setAttribute("nb_markups", (int)sDrwBlockData.m_uiMarkupsSize);
m_sReport.setAttribute("nb_drawing_blocks", (int)sDrwBlockData.m_uiDrwBlocksSize);
traverseRootBaseData(pDrwBlock);
for (A3DUns32 ui = 0; ui < sDrwBlockData.m_uiDrwBlocksSize; ++ui)
traverseDrawingBlock(sDrwBlockData.m_ppDrwBlocks[ui]);
A3DDrawingBlockBasicGet(NULL, &sDrwBlockData);
}
m_sReport.closeSubNode();
}
void HXFeatureTreeReport::traverseEntityReference(const A3DEntity* pEntityReference)
{
A3DMiscEntityReferenceData sData;
A3D_INITIALIZE_DATA(A3DMiscEntityReferenceData, sData);
A3DEEntityType eType = kA3DTypeUnknown;
A3DEntityGetType(pEntityReference, &eType);
if (eType == kA3DTypeMiscReferenceOnTopology)
{
traverseMiscReferenceOnTopology(pEntityReference);
}
else if (eType == kA3DTypeMiscReferenceOnCsysItem)
{
traverseMiscReferenceOnCsysItem(pEntityReference);
}
else if (eType == kA3DTypeFRMFeature)
{
traverseRootBaseData(pEntityReference);
}
else if (eType == kA3DTypeDrawingBlockBasic)
{
traverseDrawingBlock((const A3DDrawingBlockBasic *)pEntityReference);
}
else
{
if (eType == kA3DTypeRiPolyBrepModel)
{
traverseMiscReferenceOnTessData(pEntityReference);
}
else if (eType == kA3DTypeRiPlane)
{
A3DMiscMarkupLinkedItem* pLinkedItem = NULL;
A3DRiPlaneSupportGet((const A3DRiPlane*)pEntityReference, &pLinkedItem);
if (pLinkedItem)
{
m_sReport.createSubNode("Support");
A3DMiscEntityReferenceGet(pLinkedItem, &sData);
traverseEntityReference(sData.m_pEntity);
m_sReport.closeSubNode();
}
}
else if (eType == kA3DTypeRiCurve)
{
A3DMiscMarkupLinkedItem* pLinkedItem = NULL;
A3DRiCurveSupportGet((const A3DRiCurve*)pEntityReference, &pLinkedItem);
if (pLinkedItem)
{
m_sReport.createSubNode("Support");
A3DMiscEntityReferenceGet(pLinkedItem, &sData);
traverseEntityReference(sData.m_pEntity);
m_sReport.closeSubNode();
}
}
traverseRootBaseData(pEntityReference);
}
A3DMiscEntityReferenceGet(NULL, &sData);
}
A3DStatus HXFeatureTreeReport::visitEnter(const A3DFRMLinkedItemConnector& sConnector)
{
m_sReport.createSubNode("Connection");
switch (sConnector.m_sData.m_eType)
{
case kA3DFRMLink_Outcome:
m_sReport.setAttribute("Type", "Outcome");
break;
case kA3DFRMLink_Construction:
m_sReport.setAttribute("Type", "Construction");
break;
case kA3DFRMLink_Position:
m_sReport.setAttribute("Type", "Position");
break;
case kA3DFRMLink_Support:
m_sReport.setAttribute("Type", "Support");
break;
case kA3DFRMLink_None:
default:
m_sReport.setAttribute("Type", "None");
break;
}
if (sConnector.m_sData.m_pReference)
traverseEntityReference(sConnector.m_sData.m_pReference);
return A3D_SUCCESS;
}
A3DStatus HXFeatureTreeReport::visitLeave(const A3DFRMLinkedItemConnector& /*sConnector*/)
{
m_sReport.closeSubNode();
return A3D_SUCCESS;
}
A3DStatus HXFeatureTreeReport::visitEnter(const A3DFRMParameterConnector& sConnector)
{
switch (sConnector.m_sData.m_eType)
{
case kA3DParameterType_Information:
{
m_sReport.createSubNode("Information");
break;
}
case kA3DParameterType_Type:
{
m_sReport.createSubNode("Type");
break;
}
case kA3DParameterType_Specification:
{
m_sReport.createSubNode("Specification");
break;
}
case kA3DParameterType_FeatureDefinition:
{
m_sReport.createSubNode("FeatureDefinition");
break;
}
case kA3DParameterType_Definition:
{
m_sReport.createSubNode("Definition");
break;
}
case kA3DParameterType_Container:
{
m_sReport.createSubNode("Container");
break;
}
case kA3DParameterType_ContainerInternal:
{
m_sReport.createSubNode("ContainerInternal");
break;
}
case kA3DParameterType_Data:
{
m_sReport.createSubNode("Data");
break;
}
case kA3DParameterType_None:
default:
m_sReport.createSubNode("None");
break;
}
return A3D_SUCCESS;
}
A3DStatus HXFeatureTreeReport::visitLeave(const A3DFRMParameterConnector& /*sConnector*/)
{
m_sReport.closeSubNode();
return A3D_SUCCESS;
}
void HXFeatureTreeReport::traverseRootBaseData(const A3DEntity* pEntity)
{
A3DRootBaseData sRBData;
A3D_INITIALIZE_DATA(A3DRootBaseData, sRBData);
A3DStatus iRet = A3DRootBaseGet(pEntity, &sRBData);
if (iRet != A3D_SUCCESS)
return;
HXmlElement* pXmlRootBaseData = new HXmlElement("RootBase");
m_sReport.addNode(pXmlRootBaseData);
if (sRBData.m_pcName && sRBData.m_pcName[0] != '\0')
pXmlRootBaseData->SetAttribute("name", sRBData.m_pcName);
pXmlRootBaseData->SetAttribute("persistent_id", sRBData.m_uiPersistentId);
pXmlRootBaseData->SetAttribute("non_persistent_id", sRBData.m_uiNonPersistentId);
A3DRootBaseGet(NULL, &sRBData);
}
bool HXFeatureTreeReport::isAlreadyTreadted(const A3DFRMFeatureConnector& sFeature)
{
std::vector<const A3DEntity*>::iterator feature = m_apAlreadyparsedFeatures.begin();
for (; feature != m_apAlreadyparsedFeatures.end(); ++feature)
if (*feature == sFeature.GetA3DEntity())
return FALSE;
m_apAlreadyparsedFeatures.push_back(sFeature.GetA3DEntity());
return TRUE;
}