1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-01 17:36:21 +03:00

GLTF Import - Metadata support #184

Limited support of metadata import is added to RWGltf_GltfJsonParser.
Following Json data types are currently supported: int32, double, string,
array of int32, array of double, array of strings, Json object.
Notable unsupported types are: binary data, array of Json objects.
Metadata is processed for nodes and meshes.
Tests "gltf_export" are updated with import testing and renamed to "gltf".

Method RWGltf_GltfJsonParser::gltfParseSceneNode() is slightly
refactored: parsing of transformations and transformation matrices is
moved into separate functions.
This commit is contained in:
dkulikov 2024-12-09 17:06:33 +00:00
parent d5afabec90
commit bbbb8ea79d
23 changed files with 1032 additions and 243 deletions

View File

@ -25,6 +25,7 @@
#include <OSD_ThreadPool.hxx>
#include <Precision.hxx>
#include <FSD_Base64.hxx>
#include <TDataStd_NamedData.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Iterator.hxx>
@ -52,6 +53,265 @@ namespace
private:
Handle(NCollection_Buffer) myBaseBuffer;
};
//! Helper class to parse "extras" section of glTF node.
//! In order to use, provide the ID and the "extras" value of the node
//! in the constructor, and then call Parse().
//! Alternatively, just call ParseExtras() static function.
class RWGltf_ExtrasParser
{
public:
//! Constructor. Initializes parser.
//! @param theParentID ID of the Json object that contains this "extras" value. Used only for printing messages.
//! @param theExtrasValue "extras" value to parse.
RWGltf_ExtrasParser(const TCollection_AsciiString& theParentID,
const RWGltf_JsonValue& theExtrasValue);
//! Parses the "extras" value provided in the constructor.
//! @return Container with parsed data. May be nullptr if failed to parse.
Handle(TDataStd_NamedData) Parse();
//! Parses provided "extras" value.
//! @param theParentID ID of the Json object that contains this "extras" value. Used only for printing messages.
//! @param theExtrasValue "extras" value to parse. May be nullptr, in which case function will return nullptr.
//! @return Container with parsed data. May be nullptr if failed to parse.
static Handle(TDataStd_NamedData) ParseExtras(const TCollection_AsciiString& theParentID,
const RWGltf_JsonValue* theExtrasValue);
private:
//! Parse value as the Json object. Serves as the entry point to parse "extras".
//! Can also parse any object inside it.
//! @param theValue Value to parse.
//! @param theValueName Name of the value. For "extras" object should be empty.
//! @return true if object was processed, false otherwise. Note that true doesn't mean that
//! object was successfully parsed and stored, it could be if unsupported type in
//! which case warning is issued. true only indicates that no further processing required.
bool parseObject(const RWGltf_JsonValue& theValue, const std::string& theValueName = {});
//! Parse value as the integer.
//! @param theValue Value to parse.
//! @param theValueName Name of the value.
//! @return true if object was processed, false otherwise. Note that true doesn't mean that
//! object was successfully parsed and stored, it could be if unsupported type in
//! which case warning is issued. true only indicates that no further processing required.
bool parseNumber(const RWGltf_JsonValue& theValue, const std::string& theValueName);
//! Parse value as the string.
//! @param theValue Value to parse.
//! @param theValueName Name of the value.
//! @return true if object was processed, false otherwise. Note that true doesn't mean that
//! object was successfully parsed and stored, it could be if unsupported type in
//! which case warning is issued. true only indicates that no further processing required.
bool parseString(const RWGltf_JsonValue& theValue, const std::string& theValueName);
//! Parse value as the array.
//! Currently only arrays of following types are supported: int, double, string.
//! IMPORTANT: Array of Json objects is NOT supported.
//! @param theValue Value to parse.
//! @param theValueName Name of the value.
//! @return true if object was processed, false otherwise. Note that true doesn't mean that
//! object was successfully parsed and stored, it could be if unsupported type in
//! which case warning is issued. true only indicates that no further processing required.
bool parseArray(const RWGltf_JsonValue& theValue, const std::string& theValueName);
//! Returns result container for internal usage. Is container in not initialized yet,
//! this function will initialize it, so it is guaranteed to be valid.
Handle(TDataStd_NamedData)& getResult();
private:
const TCollection_AsciiString& myParentID; //!< ID of the Json object that contains "extras" value. For printing messages.
const RWGltf_JsonValue& myExtrasValue; //!< "extras" value to parse.
Handle(TDataStd_NamedData) myResult; //!< Result of parsing.
};
// =======================================================================
// function : RWGltf_ExtrasParser
// purpose :
// =======================================================================
RWGltf_ExtrasParser::RWGltf_ExtrasParser(const TCollection_AsciiString& theParentID,
const RWGltf_JsonValue& theExtrasValue)
: myParentID(theParentID),
myExtrasValue(theExtrasValue),
myResult(nullptr)
{}
// =======================================================================
// function : parseValue
// purpose :
// =======================================================================
Handle(TDataStd_NamedData) RWGltf_ExtrasParser::Parse()
{
parseObject(myExtrasValue);
// Intentionally returning myResult instead of getResult(). If parseObject() parsed data
// successfully, it will be initialized already. Otherwise, we should return nullptr.
return myResult;
}
// =======================================================================
// function : parseValue
// purpose :
// =======================================================================
Handle(TDataStd_NamedData) RWGltf_ExtrasParser::ParseExtras(const TCollection_AsciiString& theParentID,
const RWGltf_JsonValue* theExtrasValue)
{
if (!theExtrasValue)
{
return nullptr;
}
RWGltf_ExtrasParser anExtrasParser(theParentID, *theExtrasValue);
return anExtrasParser.Parse();
}
// =======================================================================
// function : parseValue
// purpose :
// =======================================================================
bool RWGltf_ExtrasParser::parseObject(const RWGltf_JsonValue& theValue, const std::string& theValueName)
{
if (!theValue.IsObject())
{
return false;
}
bool anIsAnyValProcessed = false;
for (auto& anItem : theValue.GetObject())
{
std::string aCurrentValName = theValueName.empty() ? std::string(anItem.name.GetString())
: theValueName + "." + anItem.name.GetString();
const RWGltf_JsonValue& aCurrentValue = anItem.value;
const bool anIsCurrentValProcessed = parseNumber(aCurrentValue, aCurrentValName)
|| parseString(aCurrentValue, aCurrentValName)
|| parseArray(aCurrentValue, aCurrentValName)
|| parseObject(aCurrentValue, aCurrentValName);
anIsAnyValProcessed |= anIsCurrentValProcessed;
}
return anIsAnyValProcessed;
}
// =======================================================================
// function : parseNumber
// purpose :
// =======================================================================
bool RWGltf_ExtrasParser::parseNumber(const RWGltf_JsonValue& theValue, const std::string& theValueName)
{
if (theValue.IsNumber() && !theValue.IsInt() && !theValue.IsDouble())
{
Message::SendWarning() << "Warning: Extras owner \"" << myParentID << "\", Value \"" << theValueName << "\" - "
<< "Unsupported integer type. It will be skipped.";
return true;
}
if (theValue.IsInt())
{
getResult()->SetInteger(theValueName.c_str(), theValue.GetInt());
return true;
}
if (theValue.IsDouble())
{
getResult()->SetReal(theValueName.c_str(), theValue.GetDouble());
return true;
}
return false;
}
// =======================================================================
// function : parseString
// purpose :
// =======================================================================
bool RWGltf_ExtrasParser::parseString(const RWGltf_JsonValue& theValue, const std::string& theValueName)
{
if (theValue.IsString())
{
getResult()->SetString(theValueName.c_str(), theValue.GetString());
return true;
// Note: maybe in a future we should detect and parse binary data?
// Currently TDataStd_NamedData doesn't support array of bytes, so we can
// only try to process it as a string.
}
return false;
}
// =======================================================================
// function : parseArray
// purpose :
// =======================================================================
bool RWGltf_ExtrasParser::parseArray(const RWGltf_JsonValue& theValue, const std::string& theValueName)
{
if (!theValue.IsArray())
{
return false;
}
if (theValue.Size() == 0)
{
// Processing empty array first.
Message::SendInfo() << "Extras owner \"" << myParentID << "\", Value \"" << theValueName << "\" - "
<< "Empty array is detected. Storing as empty string.";
getResult()->SetString(theValueName.c_str(), "");
return true;
}
if (theValue[0].IsInt())
{
// Array of integers is supported, storing as normal.
Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(0, theValue.Size());
for (size_t anIndex = 0; anIndex < theValue.Size(); ++anIndex)
{
anArray->SetValue(static_cast<Standard_Integer>(anIndex), theValue[0].GetInt());
}
getResult()->SetArrayOfIntegers(theValueName.c_str(), anArray);
return true;
}
else if (theValue[0].IsDouble())
{
// Array of double is supported, storing as normal.
Handle(TColStd_HArray1OfReal) anArray = new TColStd_HArray1OfReal(0, theValue.Size());
for (size_t anIndex = 0; anIndex < theValue.Size(); ++anIndex)
{
anArray->SetValue(static_cast<Standard_Integer>(anIndex), theValue[0].GetDouble());
}
getResult()->SetArrayOfReals(theValueName.c_str(), anArray);
return true;
}
else if (theValue[0].IsString())
{
// Storing array of strings as string with separator.
Message::SendInfo() << "Extras owner \"" << myParentID << "\", Value \"" << theValueName << "\" - "
<< "Array of strings is detected. Storing as string with separators.";
std::string anArrayString;
const std::string aSeparator = ";";
for (size_t i = 0; i < theValue.Size(); ++i)
{
anArrayString = anArrayString + aSeparator + theValue[0].GetString();
}
getResult()->SetString(theValueName.c_str(), anArrayString.c_str());
return true;
}
// Unsupported type of array. Print waring and return.
Message::SendWarning() << "Warning: Extras owner \"" << myParentID << "\", Value \"" << theValueName << "\" - "
<< "Array of unsupported type is detected. It will be skipped.";
return true;
}
// =======================================================================
// function : parseArray
// purpose :
// =======================================================================
Handle(TDataStd_NamedData)& RWGltf_ExtrasParser::getResult()
{
if (myResult.IsNull())
{
myResult = new TDataStd_NamedData;
}
return myResult;
}
}
//! Find member of the object in a safe way.
@ -167,11 +427,175 @@ void RWGltf_GltfJsonParser::GltfElementMap::Init (const TCollection_AsciiString&
// purpose :
// =======================================================================
void RWGltf_GltfJsonParser::reportGltfSyntaxProblem (const TCollection_AsciiString& theMsg,
Message_Gravity theGravity)
Message_Gravity theGravity) const
{
Message::Send (myErrorPrefix + theMsg, theGravity);
}
// =======================================================================
// function : parseTransformationMatrix
// purpose :
// =======================================================================
bool RWGltf_GltfJsonParser::parseTransformationMatrix(const TCollection_AsciiString& theSceneNodeId,
const RWGltf_JsonValue& theMatrixVal,
TopLoc_Location& theResult) const
{
if (!theMatrixVal.IsArray() || theMatrixVal.Size() != 16)
{
reportGltfError("Scene node '" + theSceneNodeId + "' defines invalid transformation matrix array.");
return false;
}
Graphic3d_Mat4d aMat4;
for (int aColIter = 0; aColIter < 4; ++aColIter)
{
for (int aRowIter = 0; aRowIter < 4; ++aRowIter)
{
const RWGltf_JsonValue& aGenVal = theMatrixVal[aColIter * 4 + aRowIter];
if (!aGenVal.IsNumber())
{
reportGltfError("Scene node '" + theSceneNodeId + "' defines invalid transformation matrix.");
return false;
}
aMat4.SetValue(aRowIter, aColIter, aGenVal.GetDouble());
}
}
if (!aMat4.IsIdentity())
{
gp_Trsf aTrsf;
aTrsf.SetValues(aMat4.GetValue(0, 0), aMat4.GetValue(0, 1), aMat4.GetValue(0, 2), aMat4.GetValue(0, 3),
aMat4.GetValue(1, 0), aMat4.GetValue(1, 1), aMat4.GetValue(1, 2), aMat4.GetValue(1, 3),
aMat4.GetValue(2, 0), aMat4.GetValue(2, 1), aMat4.GetValue(2, 2), aMat4.GetValue(2, 3));
myCSTrsf.TransformTransformation(aTrsf);
if (aTrsf.Form() != gp_Identity)
{
theResult = TopLoc_Location(aTrsf);
}
}
return true;
}
// =======================================================================
// function : RWGltf_GltfJsonParser
// purpose :
// =======================================================================
bool RWGltf_GltfJsonParser::parseTransformationComponents(const TCollection_AsciiString& theSceneNodeId,
const RWGltf_JsonValue* theRotationVal,
const RWGltf_JsonValue* theScaleVal,
const RWGltf_JsonValue* theTranslationVal,
TopLoc_Location& theResult) const
{
gp_Trsf aTrsf;
if (theRotationVal != NULL)
{
if (!theRotationVal->IsArray() || theRotationVal->Size() != 4)
{
reportGltfError("Scene node '" + theSceneNodeId + "' defines invalid rotation quaternion.");
return false;
}
Graphic3d_Vec4d aRotVec4;
for (int aCompIter = 0; aCompIter < 4; ++aCompIter)
{
const RWGltf_JsonValue& aGenVal = (*theRotationVal)[aCompIter];
if (!aGenVal.IsNumber())
{
reportGltfError("Scene node '" + theSceneNodeId + "' defines invalid rotation.");
return false;
}
aRotVec4[aCompIter] = aGenVal.GetDouble();
}
const gp_Quaternion aQuaternion(aRotVec4.x(), aRotVec4.y(), aRotVec4.z(), aRotVec4.w());
if (Abs(aQuaternion.X()) > gp::Resolution()
|| Abs(aQuaternion.Y()) > gp::Resolution()
|| Abs(aQuaternion.Z()) > gp::Resolution()
|| Abs(aQuaternion.W() - 1.0) > gp::Resolution())
{
aTrsf.SetRotation(aQuaternion);
}
}
if (theTranslationVal != NULL)
{
if (!theTranslationVal->IsArray() || theTranslationVal->Size() != 3)
{
reportGltfError("Scene node '" + theSceneNodeId + "' defines invalid translation vector.");
return false;
}
gp_XYZ aTransVec;
for (int aCompIter = 0; aCompIter < 3; ++aCompIter)
{
const RWGltf_JsonValue& aGenVal = (*theTranslationVal)[aCompIter];
if (!aGenVal.IsNumber())
{
reportGltfError("Scene node '" + theSceneNodeId + "' defines invalid translation.");
return false;
}
aTransVec.SetCoord(aCompIter + 1, aGenVal.GetDouble());
}
aTrsf.SetTranslationPart(aTransVec);
}
if (theScaleVal != NULL)
{
Graphic3d_Vec3d aScaleVec;
if (!theScaleVal->IsArray() || theScaleVal->Size() != 3)
{
reportGltfError("Scene node '" + theSceneNodeId + "' defines invalid scale vector.");
return false;
}
for (int aCompIter = 0; aCompIter < 3; ++aCompIter)
{
const RWGltf_JsonValue& aGenVal = (*theScaleVal)[aCompIter];
if (!aGenVal.IsNumber())
{
reportGltfError("Scene node '" + theSceneNodeId + "' defines invalid scale.");
return false;
}
aScaleVec[aCompIter] = aGenVal.GetDouble();
if (Abs(aScaleVec[aCompIter]) <= gp::Resolution())
{
reportGltfError("Scene node '" + theSceneNodeId + "' defines invalid scale.");
return false;
}
}
if (Abs(aScaleVec.x() - aScaleVec.y()) > Precision::Confusion()
|| Abs(aScaleVec.y() - aScaleVec.z()) > Precision::Confusion()
|| Abs(aScaleVec.x() - aScaleVec.z()) > Precision::Confusion())
{
Graphic3d_Mat4d aScaleMat;
aScaleMat.SetDiagonal(aScaleVec);
Graphic3d_Mat4d aMat4;
aTrsf.GetMat4(aMat4);
aMat4 = aMat4 * aScaleMat;
aTrsf = gp_Trsf();
aTrsf.SetValues(aMat4.GetValue(0, 0), aMat4.GetValue(0, 1), aMat4.GetValue(0, 2), aMat4.GetValue(0, 3),
aMat4.GetValue(1, 0), aMat4.GetValue(1, 1), aMat4.GetValue(1, 2), aMat4.GetValue(1, 3),
aMat4.GetValue(2, 0), aMat4.GetValue(2, 1), aMat4.GetValue(2, 2), aMat4.GetValue(2, 3));
Message::SendWarning(TCollection_AsciiString("glTF reader, scene node '")
+ theSceneNodeId + "' defines unsupported scaling " + aScaleVec.x() + " " + aScaleVec.y() + " " + aScaleVec.z());
}
else if (Abs(aScaleVec.x() - 1.0) > Precision::Confusion())
{
aTrsf.SetScaleFactor(aScaleVec.x());
}
}
myCSTrsf.TransformTransformation(aTrsf);
if (aTrsf.Form() != gp_Identity)
{
theResult = TopLoc_Location(aTrsf);
}
return true;
}
// =======================================================================
// function : RWGltf_GltfJsonParser
// purpose :
@ -1123,6 +1547,11 @@ bool RWGltf_GltfJsonParser::gltfParseSceneNode (TopoDS_Shape& theNodeShape,
const RWGltf_JsonValue& theSceneNode,
const Message_ProgressRange& theProgress)
{
if (findNodeShape(theNodeShape, theSceneNodeId))
{
return true;
}
const RWGltf_JsonValue* aName = findObjectMember (theSceneNode, "name");
//const RWGltf_JsonValue* aJointName = findObjectMember (theSceneNode, "jointName");
const RWGltf_JsonValue* aChildren = findObjectMember (theSceneNode, "children");
@ -1133,180 +1562,44 @@ bool RWGltf_GltfJsonParser::gltfParseSceneNode (TopoDS_Shape& theNodeShape,
const RWGltf_JsonValue* aTrsfRotVal = findObjectMember (theSceneNode, "rotation");
const RWGltf_JsonValue* aTrsfScaleVal = findObjectMember (theSceneNode, "scale");
const RWGltf_JsonValue* aTrsfTransVal = findObjectMember (theSceneNode, "translation");
if (findNodeShape (theNodeShape, theSceneNodeId))
{
return true;
}
const RWGltf_JsonValue* anExtrasVal = findObjectMember (theSceneNode, "extras");
TopLoc_Location aNodeLoc;
const bool hasTrs = aTrsfRotVal != NULL
|| aTrsfScaleVal != NULL
|| aTrsfTransVal != NULL;
if (aTrsfMatVal != NULL)
const bool aHasTransformComponents = aTrsfRotVal != NULL
|| aTrsfScaleVal != NULL
|| aTrsfTransVal != NULL;
const bool aHasTransformMatrix = aTrsfMatVal != NULL;
if (aHasTransformComponents && aHasTransformMatrix)
{
if (hasTrs)
reportGltfError("Scene node '" + theSceneNodeId + "' defines ambiguous transformation.");
return false;
}
else if (aHasTransformMatrix)
{
if (!parseTransformationMatrix(theSceneNodeId, *aTrsfMatVal, aNodeLoc))
{
reportGltfError ("Scene node '" + theSceneNodeId + "' defines ambiguous transformation.");
return false;
}
else if (!aTrsfMatVal->IsArray()
|| aTrsfMatVal->Size() != 16)
}
else if (aHasTransformComponents)
{
if (!parseTransformationComponents(theSceneNodeId, aTrsfRotVal, aTrsfScaleVal, aTrsfTransVal, aNodeLoc))
{
reportGltfError ("Scene node '" + theSceneNodeId + "' defines invalid transformation matrix array.");
return false;
}
Graphic3d_Mat4d aMat4;
for (int aColIter = 0; aColIter < 4; ++aColIter)
{
for (int aRowIter = 0; aRowIter < 4; ++aRowIter)
{
const RWGltf_JsonValue& aGenVal = (*aTrsfMatVal)[aColIter * 4 + aRowIter];
if (!aGenVal.IsNumber())
{
reportGltfError ("Scene node '" + theSceneNodeId + "' defines invalid transformation matrix.");
return false;
}
aMat4.SetValue (aRowIter, aColIter, aGenVal.GetDouble());
}
}
if (!aMat4.IsIdentity())
{
gp_Trsf aTrsf;
aTrsf.SetValues (aMat4.GetValue (0, 0), aMat4.GetValue (0, 1), aMat4.GetValue (0, 2), aMat4.GetValue (0, 3),
aMat4.GetValue (1, 0), aMat4.GetValue (1, 1), aMat4.GetValue (1, 2), aMat4.GetValue (1, 3),
aMat4.GetValue (2, 0), aMat4.GetValue (2, 1), aMat4.GetValue (2, 2), aMat4.GetValue (2, 3));
myCSTrsf.TransformTransformation (aTrsf);
if (aTrsf.Form() != gp_Identity)
{
aNodeLoc = TopLoc_Location (aTrsf);
}
}
}
else if (hasTrs)
{
gp_Trsf aTrsf;
if (aTrsfRotVal != NULL)
{
if (!aTrsfRotVal->IsArray()
|| aTrsfRotVal->Size() != 4)
{
reportGltfError ("Scene node '" + theSceneNodeId + "' defines invalid rotation quaternion.");
return false;
}
Graphic3d_Vec4d aRotVec4;
for (int aCompIter = 0; aCompIter < 4; ++aCompIter)
{
const RWGltf_JsonValue& aGenVal = (*aTrsfRotVal)[aCompIter];
if (!aGenVal.IsNumber())
{
reportGltfError ("Scene node '" + theSceneNodeId + "' defines invalid rotation.");
return false;
}
aRotVec4[aCompIter] = aGenVal.GetDouble();
}
const gp_Quaternion aQuaternion (aRotVec4.x(), aRotVec4.y(), aRotVec4.z(), aRotVec4.w());
if (Abs (aQuaternion.X()) > gp::Resolution()
|| Abs (aQuaternion.Y()) > gp::Resolution()
|| Abs (aQuaternion.Z()) > gp::Resolution()
|| Abs (aQuaternion.W() - 1.0) > gp::Resolution())
{
aTrsf.SetRotation (aQuaternion);
}
}
if (aTrsfTransVal != NULL)
{
if (!aTrsfTransVal->IsArray()
|| aTrsfTransVal->Size() != 3)
{
reportGltfError ("Scene node '" + theSceneNodeId + "' defines invalid translation vector.");
return false;
}
gp_XYZ aTransVec;
for (int aCompIter = 0; aCompIter < 3; ++aCompIter)
{
const RWGltf_JsonValue& aGenVal = (*aTrsfTransVal)[aCompIter];
if (!aGenVal.IsNumber())
{
reportGltfError ("Scene node '" + theSceneNodeId + "' defines invalid translation.");
return false;
}
aTransVec.SetCoord (aCompIter + 1, aGenVal.GetDouble());
}
aTrsf.SetTranslationPart (aTransVec);
}
if (aTrsfScaleVal != NULL)
{
Graphic3d_Vec3d aScaleVec;
if (!aTrsfScaleVal->IsArray()
|| aTrsfScaleVal->Size() != 3)
{
reportGltfError ("Scene node '" + theSceneNodeId + "' defines invalid scale vector.");
return false;
}
for (int aCompIter = 0; aCompIter < 3; ++aCompIter)
{
const RWGltf_JsonValue& aGenVal = (*aTrsfScaleVal)[aCompIter];
if (!aGenVal.IsNumber())
{
reportGltfError ("Scene node '" + theSceneNodeId + "' defines invalid scale.");
return false;
}
aScaleVec[aCompIter] = aGenVal.GetDouble();
if (Abs (aScaleVec[aCompIter]) <= gp::Resolution())
{
reportGltfError ("Scene node '" + theSceneNodeId + "' defines invalid scale.");
return false;
}
}
if (Abs (aScaleVec.x() - aScaleVec.y()) > Precision::Confusion()
|| Abs (aScaleVec.y() - aScaleVec.z()) > Precision::Confusion()
|| Abs (aScaleVec.x() - aScaleVec.z()) > Precision::Confusion())
{
Graphic3d_Mat4d aScaleMat;
aScaleMat.SetDiagonal (aScaleVec);
Graphic3d_Mat4d aMat4;
aTrsf.GetMat4 (aMat4);
aMat4 = aMat4 * aScaleMat;
aTrsf = gp_Trsf();
aTrsf.SetValues (aMat4.GetValue (0, 0), aMat4.GetValue (0, 1), aMat4.GetValue (0, 2), aMat4.GetValue (0, 3),
aMat4.GetValue (1, 0), aMat4.GetValue (1, 1), aMat4.GetValue (1, 2), aMat4.GetValue (1, 3),
aMat4.GetValue (2, 0), aMat4.GetValue (2, 1), aMat4.GetValue (2, 2), aMat4.GetValue (2, 3));
Message::SendWarning (TCollection_AsciiString ("glTF reader, scene node '")
+ theSceneNodeId + "' defines unsupported scaling " + aScaleVec.x() + " " + aScaleVec.y() + " " + aScaleVec.z());
}
else if (Abs (aScaleVec.x() - 1.0) > Precision::Confusion())
{
aTrsf.SetScaleFactor (aScaleVec.x());
}
}
myCSTrsf.TransformTransformation (aTrsf);
if (aTrsf.Form() != gp_Identity)
{
aNodeLoc = TopLoc_Location (aTrsf);
}
}
const Handle(TDataStd_NamedData) anExtras = RWGltf_ExtrasParser::ParseExtras(theSceneNodeId, anExtrasVal);
BRep_Builder aBuilder;
TopoDS_Compound aNodeShape;
aBuilder.MakeCompound (aNodeShape);
TopTools_SequenceOfShape aChildShapes;
int aNbSubShapes = 0;
if (aChildren != NULL
&& !gltfParseSceneNodes (aChildShapes, *aChildren, theProgress))
if (aChildren != NULL && !gltfParseSceneNodes (aChildShapes, *aChildren, theProgress))
{
theNodeShape = aNodeShape;
bindNodeShape (theNodeShape, aNodeLoc, theSceneNodeId, aName);
bindNodeShape (theNodeShape, aNodeLoc, theSceneNodeId, aName, anExtras);
return false;
}
for (TopTools_SequenceOfShape::Iterator aChildShapeIter (aChildShapes); aChildShapeIter.More(); aChildShapeIter.Next())
@ -1315,8 +1608,7 @@ bool RWGltf_GltfJsonParser::gltfParseSceneNode (TopoDS_Shape& theNodeShape,
++aNbSubShapes;
}
if (aMeshes_1 != NULL
&& aMeshes_1->IsArray())
if (aMeshes_1 != NULL && aMeshes_1->IsArray())
{
// glTF 1.0
for (rapidjson::Value::ConstValueIterator aMeshIter = aMeshes_1->Begin();
@ -1326,7 +1618,7 @@ bool RWGltf_GltfJsonParser::gltfParseSceneNode (TopoDS_Shape& theNodeShape,
if (aMesh == NULL)
{
theNodeShape = aNodeShape;
bindNodeShape (theNodeShape, aNodeLoc, theSceneNodeId, aName);
bindNodeShape (theNodeShape, aNodeLoc, theSceneNodeId, aName, anExtras);
reportGltfError ("Scene node '" + theSceneNodeId + "' refers to non-existing mesh.");
return false;
}
@ -1335,7 +1627,7 @@ bool RWGltf_GltfJsonParser::gltfParseSceneNode (TopoDS_Shape& theNodeShape,
if (!gltfParseMesh (aMeshShape, getKeyString (*aMeshIter), *aMesh))
{
theNodeShape = aNodeShape;
bindNodeShape (theNodeShape, aNodeLoc, theSceneNodeId, aName);
bindNodeShape (theNodeShape, aNodeLoc, theSceneNodeId, aName, anExtras);
return false;
}
if (!aMeshShape.IsNull())
@ -1345,6 +1637,7 @@ bool RWGltf_GltfJsonParser::gltfParseSceneNode (TopoDS_Shape& theNodeShape,
}
}
}
if (aMesh_2 != NULL)
{
// glTF 2.0
@ -1352,7 +1645,7 @@ bool RWGltf_GltfJsonParser::gltfParseSceneNode (TopoDS_Shape& theNodeShape,
if (aMesh == NULL)
{
theNodeShape = aNodeShape;
bindNodeShape (theNodeShape, aNodeLoc, theSceneNodeId, aName);
bindNodeShape (theNodeShape, aNodeLoc, theSceneNodeId, aName, anExtras);
reportGltfError ("Scene node '" + theSceneNodeId + "' refers to non-existing mesh.");
return false;
}
@ -1361,7 +1654,7 @@ bool RWGltf_GltfJsonParser::gltfParseSceneNode (TopoDS_Shape& theNodeShape,
if (!gltfParseMesh (aMeshShape, getKeyString (*aMesh_2), *aMesh))
{
theNodeShape = aNodeShape;
bindNodeShape (theNodeShape, aNodeLoc, theSceneNodeId, aName);
bindNodeShape (theNodeShape, aNodeLoc, theSceneNodeId, aName, anExtras);
return false;
}
if (!aMeshShape.IsNull())
@ -1371,8 +1664,7 @@ bool RWGltf_GltfJsonParser::gltfParseSceneNode (TopoDS_Shape& theNodeShape,
}
}
if (aChildShapes.IsEmpty()
&& aNbSubShapes == 1)
if (aChildShapes.IsEmpty() && aNbSubShapes == 1)
{
theNodeShape = TopoDS_Iterator (aNodeShape).Value();
}
@ -1380,7 +1672,7 @@ bool RWGltf_GltfJsonParser::gltfParseSceneNode (TopoDS_Shape& theNodeShape,
{
theNodeShape = aNodeShape;
}
bindNodeShape (theNodeShape, aNodeLoc, theSceneNodeId, aName);
bindNodeShape (theNodeShape, aNodeLoc, theSceneNodeId, aName, anExtras);
return true;
}
@ -1392,8 +1684,9 @@ bool RWGltf_GltfJsonParser::gltfParseMesh (TopoDS_Shape& theMeshShape,
const TCollection_AsciiString& theMeshId,
const RWGltf_JsonValue& theMesh)
{
const RWGltf_JsonValue* aName = findObjectMember (theMesh, "name");
const RWGltf_JsonValue* aPrims = findObjectMember (theMesh, "primitives");
const RWGltf_JsonValue* aName = findObjectMember (theMesh, "name");
const RWGltf_JsonValue* aPrims = findObjectMember (theMesh, "primitives");
const RWGltf_JsonValue* anExtrasVal = findObjectMember(theMesh, "extras");
if (aPrims == NULL
|| !aPrims->IsArray())
{
@ -1439,7 +1732,9 @@ bool RWGltf_GltfJsonParser::gltfParseMesh (TopoDS_Shape& theMeshShape,
{
theMeshShape = aMeshShape;
}
bindMeshShape (theMeshShape, theMeshId, aName);
const Handle(TDataStd_NamedData) anExtras = RWGltf_ExtrasParser::ParseExtras(theMeshId, anExtrasVal);
bindMeshShape (theMeshShape, theMeshId, aName, anExtras);
return true;
}
@ -1977,7 +2272,8 @@ void RWGltf_GltfJsonParser::bindNamedShape (TopoDS_Shape& theShape,
ShapeMapGroup theGroup,
const TopLoc_Location& theLoc,
const TCollection_AsciiString& theId,
const RWGltf_JsonValue* theUserName)
const RWGltf_JsonValue* theUserName,
const Handle(TDataStd_NamedData)& theExtras)
{
if (theShape.IsNull())
{
@ -1998,8 +2294,7 @@ void RWGltf_GltfJsonParser::bindNamedShape (TopoDS_Shape& theShape,
}
TCollection_AsciiString aUserName;
if (theUserName != NULL
&& theUserName->IsString())
if (theUserName != NULL && theUserName->IsString())
{
aUserName = theUserName->GetString();
}
@ -2012,6 +2307,7 @@ void RWGltf_GltfJsonParser::bindNamedShape (TopoDS_Shape& theShape,
{
RWMesh_NodeAttributes aShapeAttribs;
aShapeAttribs.Name = aUserName;
aShapeAttribs.NamedData = theExtras;
if (myIsGltf1)
{
aShapeAttribs.RawName = theId;

View File

@ -297,17 +297,19 @@ protected:
void bindNodeShape (TopoDS_Shape& theShape,
const TopLoc_Location& theLoc,
const TCollection_AsciiString& theNodeId,
const RWGltf_JsonValue* theUserName)
const RWGltf_JsonValue* theUserName,
const Handle(TDataStd_NamedData)& theExtras)
{
bindNamedShape (theShape, ShapeMapGroup_Nodes, theLoc, theNodeId, theUserName);
bindNamedShape (theShape, ShapeMapGroup_Nodes, theLoc, theNodeId, theUserName, theExtras);
}
//! Bind name attribute.
void bindMeshShape (TopoDS_Shape& theShape,
const TCollection_AsciiString& theMeshId,
const RWGltf_JsonValue* theUserName)
const RWGltf_JsonValue* theUserName,
const Handle(TDataStd_NamedData)& theExtras)
{
bindNamedShape (theShape, ShapeMapGroup_Meshes, TopLoc_Location(), theMeshId, theUserName);
bindNamedShape (theShape, ShapeMapGroup_Meshes, TopLoc_Location(), theMeshId, theUserName, theExtras);
}
//! Find named shape.
@ -329,7 +331,8 @@ protected:
ShapeMapGroup theGroup,
const TopLoc_Location& theLoc,
const TCollection_AsciiString& theId,
const RWGltf_JsonValue* theUserName);
const RWGltf_JsonValue* theUserName,
const Handle(TDataStd_NamedData)& theExtras);
//! Find named shape.
bool findNamedShape (TopoDS_Shape& theShape,
@ -405,12 +408,38 @@ protected:
};
#endif
protected:
//! Print message about invalid glTF syntax.
void reportGltfSyntaxProblem (const TCollection_AsciiString& theMsg, Message_Gravity theGravity);
void reportGltfSyntaxProblem (const TCollection_AsciiString& theMsg, Message_Gravity theGravity) const;
private:
//! Parse transformation matrix of the node.
//! @param theSceneNodeId Name of the node. Used only for printing messages.
//! @param theMatrixVal Json value containing transformation matrix.
//! @param theResult TopLoc_Location object where result of parsing will be written.
//! @param If true - parsing was successful, transformation is written into @p theResult.
//! If true - failed to parse, @p theResult is unchanged.
bool parseTransformationMatrix(const TCollection_AsciiString& theSceneNodeId,
const RWGltf_JsonValue& theMatrixVal,
TopLoc_Location& theResult) const;
//! Parse transformation components of the node.
//! @param theSceneNodeId Name of the node. Used only for printing messages.
//! @param theRotationVal Json value containing rotation component of transformation.
//! May be null in which case it is ignored.
//! @param theScaleVal Json value containing scale component of transformation.
//! May be null in which case it is ignored.
//! @param theTranslationVal Json value containing translation component of transformation.
//! May be null in which case it is ignored.
//! @param theResult TopLoc_Location object where result of parsing will be written.
//! @param If true - parsing was successful, transformation is written into @p theResult.
//! If true - failed to parse, @p theResult is unchanged.
bool parseTransformationComponents(const TCollection_AsciiString& theSceneNodeId,
const RWGltf_JsonValue* theRotationVal,
const RWGltf_JsonValue* theScaleVal,
const RWGltf_JsonValue* theTranslationVal,
TopLoc_Location& theResult) const;
protected:
TopTools_SequenceOfShape* myRootShapes; //!< sequence of result root shapes
RWMesh_NodeAttributeMap* myAttribMap; //!< shape attributes
NCollection_IndexedMap<TCollection_AsciiString>*

29
tests/metadata/gltf/A1 Normal file
View File

@ -0,0 +1,29 @@
# !!!! This file is generated automatically, do not edit manually! See end script
set filename bug28345_30338.stp
set ref_size 5896
set check_metadata 1
set ref_metadata {Property for [0:1:1:1]:
H_CIP : 55.545955351400004
Property for [0:1:1:1:1]:
H : 45
E : 55
B : 16
I : 15
A : 3
D : 3
C : 140
F : 0.29999999999999999
DESCRIPTION :
MODELED_BY :
Property for [0:1:1:1:2]:
H : 45
E : 55
B : 16
I : 15
A : 3
D : 3
C : 140
F : 0.29999999999999999
DESCRIPTION :
MODELED_BY :
}

26
tests/metadata/gltf/A2 Normal file
View File

@ -0,0 +1,26 @@
# !!!! This file is generated automatically, do not edit manually! See end script
set filename bug28389_CONFIDENTIAL_SHEET_METAL_F3D.stp
set ref_size 86278
set check_metadata 1
set ref_metadata {Property for [0:1:1:1]:
yCenterOfGravity : 0.1148447698
Ixz : 9.3210000000000004e-07
Izx : 9.3210000000000004e-07
OriginY : 0
Surface : 0.34595390710000001
Volume : 0.0001375456
Iyz : -1.2030000000000001e-07
zCenterOfGravity : -0.056064514900000001
Ixy : 2.044e-07
Iyy : 3.6385e-06
xCenterOfGravity : -0.12673526900000001
Density : 1000
Izz : 3.3558999999999999e-06
Ixx : 1.7740000000000001e-06
Izy : -1.2030000000000001e-07
Mass : 0.13754561600000001
Iyx : 2.044e-07
OriginX : 0
OriginZ : 0
JoggleFormula :
}

23
tests/metadata/gltf/A3 Normal file
View File

@ -0,0 +1,23 @@
# !!!! This file is generated automatically, do not edit manually! See end script
set filename bug28444_nist_ftc_06_asme1_ct5240_rd.stp
set ref_size 85383
set check_metadata 1
set ref_metadata {Property for [0:1:1:1]:
yCenterOfGravity : 0.0289950044
Ixz : 0
Izx : 0
Surface : 0.28317040780000002
Volume : 0.0033238733999999999
Iyz : -1.3068999999999999e-06
zCenterOfGravity : -0.10963042420000001
Ixy : 0
Iyy : 4.46342e-05
xCenterOfGravity : -0
Density : 1000
Izz : 2.63853e-05
Length : 0
Ixx : 2.16819e-05
Izy : -1.3068999999999999e-06
Mass : 3.3238733752999998
Iyx : 0
}

View File

@ -1,3 +1,4 @@
# !!!! This file is generated automatically, do not edit manually! See end script
set filename bug29525_rev_part_neu_01.prt_converted_from_datakit.stp
set ref_size 80996
set check_metadata 0

18
tests/metadata/gltf/A5 Normal file
View File

@ -0,0 +1,18 @@
# !!!! This file is generated automatically, do not edit manually! See end script
set filename bug29633_nist_ctc_05_asme1_ap242-1.stp
set ref_size 69902
set check_metadata 1
set ref_metadata {Property for [0:1:1:1]:
FILESIZE : 1495040
GDT_STANDARD : 5302
MaterialMultipleAssigned : FALSE
ATTR_VERSION : 18.3.001
FILESAVETIME : Tue Dec 09 03:47:24 2014
Part Number : NIST PMI CTC 05 ASME1
Revision : D
CAD_SOURCE : ug
MTIME : 1418096844
MaterialMissingAssignments : TRUE
FILENAME : nist_ctc_05_asme1.prt
Description : NIST PMI test model downloaded from http://go.usa.gov/mGVm
}

41
tests/metadata/gltf/A6 Normal file
View File

@ -0,0 +1,41 @@
# !!!! This file is generated automatically, do not edit manually! See end script
set filename bug29803.stp
set ref_size 17032
set check_metadata 1
set ref_metadata {Property for [0:1:1:1]:
OUT_MASS : 50.813477444850157
RELIEF_DIA : 21.005800000000001
HELIX_LENGTH : 0
OUT_OAL : 78.049999999992593
HELIX_START : 0
OUT_SHANK_LEN : 27.2499999999926
RCA_SIZE : 0
SHANK_UNDER : 0
OUT_REF_LEN : 50.799999999999997
BODY_LENGTH : 48.514000000000003
THEO_BLADE_DIA : 11.074400000000001
BODY_DIA : 0
DRILL_DEPTH : 47.625
SHANK_SIZE : 16
FLUTE_LENGTH : 42.468800000000002
OUT_SHANK_DIA : 15.999999999999501
PRIORITY : 0
OUT_DRILL_DEPTH : 44.754800000000003
SCREW_HOLE_SKEW : 1.1000000000000001
SHANK_DIAMETER : 15.999999999999501
DESCRIPTION : T-A HOLDER
SS_FLANGE : NO
MODELED_BY : LSD
STANDARD_BODY_DIA : Y
DEEP_HOLE_WEBSITE :
ITEM_NUM : HOLDER
LENGTH : STUB
FINISH : BLACK OXIDE
NOTES :
SHANK_IM : M
FLUTE : STRAIGHT
SHANK : ER
MATERIAL : STEEL
SERIES : Y
DEEP_HOLE_NOTES :
}

236
tests/metadata/gltf/A7 Normal file
View File

@ -0,0 +1,236 @@
# !!!! This file is generated automatically, do not edit manually! See end script
set filename sp7_04-do-242.stp
set ref_size 224779
set check_metadata 1
set ref_metadata {Property for [0:1:1:1]:
PRO_MP_ALT_COGX : - >
DESCRIPTION ACCESS : Full
PRO_MP_TRF_21 DESCRIPTION : NULL
PRO_MP_IXY DESCRIPTION : NULL
PRO_MP_VOLUME ACCESS : Locked
PRO_MP_TRF_23 DESIGNATED : NO
PRO_MP_COGY DESIGNATED : NO
PRO_MP_COGY ACCESS : Locked
PRO_MP_ALT_IYY ACCESS : Full
PRO_MP_ALT_MASS SOURCE : Alternate Mass Prop
PRO_MP_ALT_COGY DESCRIPTION : NULL
PRO_MP_ALT_INERTIA_ORIGIN DESIGNATED : NO
PRO_MP_ALT_INERTIA_ORIGIN : PRO_MP_ALT_CSYS
PRO_MP_TRF_31 DESCRIPTION : NULL
PRO_MP_AREA SOURCE : Mass Properties
DESCRIPTION DESCRIPTION : NULL
PRO_MP_ALT_IXY DESIGNATED : NO
PRO_MP_ALT_VOLUME DESCRIPTION : NULL
PRO_MP_TRF_13 DESCRIPTION : NULL
PRO_MP_MASS DESIGNATED : NO
PRO_MP_COGY : - >
PRO_MP_AREA DESCRIPTION : NULL
PRO_MP_DENSITY DESIGNATED : NO
PRO_MP_ALT_IZZ ACCESS : Full
PRO_MP_IXX DESCRIPTION : NULL
PRO_MP_TRF_32 DESIGNATED : NO
PRO_MP_IYZ DESIGNATED : NO
PRO_MP_COGY SOURCE : Mass Properties
PRO_MP_IZZ DESIGNATED : NO
PRO_MP_TRF_42 SOURCE : Mass Properties
PRO_MP_ALT_AREA DESIGNATED : NO
PRO_MP_TRF_12 DESIGNATED : NO
PRO_MP_ALT_AREA SOURCE : Alternate Mass Prop
PRO_MP_ALT_INERTIA_ORIGIN DESCRIPTION : NULL
PRO_MP_CSYS DESCRIPTION : NULL
PRO_MP_TRF_12 SOURCE : Mass Properties
PRO_MP_TRF_31 DESIGNATED : NO
PRO_MP_IYZ : - >
PRO_MP_TRF_33 : - >
PRO_MP_ALT_COGY ACCESS : Full
REVISION SOURCE : User-Defined
PRO_MP_ALT_COGZ : - >
PRO_MP_TRF_41 ACCESS : Locked
PRO_MP_TRF_23 DESCRIPTION : NULL
PRO_MP_ALT_COGZ DESIGNATED : NO
PRO_MP_TRF_33 ACCESS : Locked
PRO_MP_MASS DESCRIPTION : NULL
PRO_MP_ALT_IZZ : - >
PRO_MP_TRF_32 : - >
DESCRIPTION : NIST PMI test model downloaded from http://go.usa.gov/mGVm
PRO_MP_TRF_22 SOURCE : Mass Properties
PRO_MP_ALT_INERTIA_ORIGIN ACCESS : Full
PRO_MP_ALT_VOLUME : - >
PRO_MP_TRF_41 SOURCE : Mass Properties
PRO_MP_ALT_CSYS : DEFAULT
MP_DENSITY : - >
PRO_MP_IZZ SOURCE : Mass Properties
PRO_MP_IYY DESCRIPTION : NULL
PRO_MP_MASS SOURCE : Mass Properties
PRO_MP_ALT_MASS : - >
PRO_MP_ALT_VOLUME SOURCE : Alternate Mass Prop
PRO_MP_ALT_IYY DESCRIPTION : NULL
DESCRIPTION SOURCE : User-Defined
PRO_MP_TRF_23 SOURCE : Mass Properties
PRO_MP_ALT_IYZ : - >
PRO_MP_MASS : - >
PRO_MP_DENSITY ACCESS : Locked
PRO_MP_DENSITY SOURCE : Mass Properties
PRO_MP_ALT_COGZ DESCRIPTION : NULL
PRO_MP_ALT_IXZ : - >
PRO_MP_ALT_IZZ DESCRIPTION : NULL
PRO_MP_ALT_IYY SOURCE : Alternate Mass Prop
PRO_MP_IYZ ACCESS : Locked
PRO_MP_ALT_IXZ DESIGNATED : NO
PRO_MP_IXY ACCESS : Locked
PRO_MP_TRF_13 ACCESS : Locked
PRO_MP_DENSITY DESCRIPTION : NULL
PRO_MP_AREA ACCESS : Locked
PRO_MP_TRF_31 : - >
PRO_MP_IYZ DESCRIPTION : NULL
PRO_MP_IYY SOURCE : Mass Properties
PRO_MP_COGX ACCESS : Locked
PRO_MP_COGZ : - >
PRO_MP_IYY DESIGNATED : NO
PRO_MP_TRF_33 DESCRIPTION : NULL
PRO_MP_ALT_IZZ SOURCE : Alternate Mass Prop
PRO_MP_IXX : - >
PRO_MP_TRF_11 ACCESS : Locked
PRO_MP_TRF_11 DESIGNATED : NO
PRO_MP_CSYS SOURCE : Mass Properties
PRO_MP_ALT_COGY SOURCE : Alternate Mass Prop
PRO_MP_INERTIA_ORIGIN ACCESS : Locked
PRO_MP_TRF_21 : - >
PART_NUMBER DESCRIPTION : NULL
MP_DENSITY SOURCE : Alternate Mass Prop
PRO_MP_ALT_IYZ ACCESS : Full
PRO_MP_COGX DESIGNATED : NO
PRO_MP_TRF_41 : - >
PRO_MP_TRF_11 SOURCE : Mass Properties
PRO_MP_TRF_32 DESCRIPTION : NULL
PRO_MP_ALT_IXX DESCRIPTION : NULL
PRO_MP_IXX SOURCE : Mass Properties
PRO_MP_ALT_CSYS DESCRIPTION : NULL
PRO_MP_TRF_13 : - >
PRO_MP_IYY : - >
PRO_MP_TRF_21 SOURCE : Mass Properties
PRO_MP_SOURCE DESCRIPTION : NULL
PRO_MP_TRF_32 SOURCE : Mass Properties
PRO_MP_IZZ ACCESS : Locked
PRO_MP_TRF_42 DESCRIPTION : NULL
PRO_MP_ALT_COGX DESIGNATED : NO
PRO_MP_TRF_13 SOURCE : Mass Properties
PRO_MP_ALT_IXX ACCESS : Full
PRO_MP_ALT_AREA : - >
PRO_MP_ALT_COGX SOURCE : Alternate Mass Prop
PRO_MP_AREA DESIGNATED : NO
PRO_MP_IXY SOURCE : Mass Properties
PRO_MP_SOURCE DESIGNATED : NO
PRO_MP_TRF_22 ACCESS : Locked
PRO_MP_VOLUME SOURCE : Mass Properties
MP_DENSITY DESIGNATED : NO
PRO_MP_IZZ DESCRIPTION : NULL
PRO_MP_IXX ACCESS : Locked
PRO_MP_TRF_31 ACCESS : Locked
PRO_MP_AREA : - >
PRO_MP_CSYS : - >
PRO_MP_ALT_COGX ACCESS : Full
PRO_MP_ALT_IYZ DESIGNATED : NO
PRO_MP_TRF_42 DESIGNATED : NO
PRO_MP_ALT_COGY : - >
PRO_MP_IXZ DESIGNATED : NO
PRO_MP_CSYS DESIGNATED : NO
PRO_MP_IZZ : - >
PRO_MP_TRF_12 DESCRIPTION : NULL
PRO_MP_ALT_IXZ ACCESS : Full
PRO_MP_INERTIA_ORIGIN : - >
PRO_MP_IXY DESIGNATED : NO
PRO_MP_TRF_33 DESIGNATED : NO
PRO_MP_ALT_COGY DESIGNATED : NO
PRO_MP_ALT_AREA DESCRIPTION : NULL
PRO_MP_IXZ DESCRIPTION : NULL
PRO_MP_INERTIA_ORIGIN DESCRIPTION : NULL
PRO_MP_ALT_IYY DESIGNATED : NO
PRO_MP_IYY ACCESS : Locked
PRO_MP_COGZ ACCESS : Locked
PRO_MP_SOURCE : GEOMETRY
PRO_MP_COGX DESCRIPTION : NULL
PRO_MP_ALT_IYZ DESCRIPTION : NULL
PRO_MP_IXZ SOURCE : Mass Properties
PRO_MP_TRF_23 ACCESS : Locked
PRO_MP_ALT_IXY : - >
PRO_MP_ALT_IYZ SOURCE : Alternate Mass Prop
PRO_MP_TRF_42 ACCESS : Locked
PRO_MP_ALT_INERTIA_ORIGIN SOURCE : Alternate Mass Prop
REVISION : D
PRO_MP_ALT_IXY ACCESS : Full
DESCRIPTION DESIGNATED : YES
PRO_MP_TRF_22 DESCRIPTION : NULL
PRO_MP_TRF_12 ACCESS : Locked
PRO_MP_SOURCE ACCESS : Full
REVISION DESIGNATED : YES
PRO_MP_IXZ ACCESS : Locked
PRO_MP_TRF_43 DESCRIPTION : NULL
PRO_MP_COGY DESCRIPTION : NULL
PRO_MP_INERTIA_ORIGIN DESIGNATED : NO
PRO_MP_TRF_12 : - >
REVISION DESCRIPTION : NULL
PRO_MP_ALT_IXY SOURCE : Alternate Mass Prop
PRO_MP_TRF_11 DESCRIPTION : NULL
PRO_MP_ALT_MASS DESIGNATED : NO
PRO_MP_TRF_11 : - >
PRO_MP_TRF_43 SOURCE : Mass Properties
PART_NUMBER ACCESS : Full
PRO_MP_VOLUME DESCRIPTION : NULL
PRO_MP_ALT_IXY DESCRIPTION : NULL
PRO_MP_COGZ DESCRIPTION : NULL
PRO_MP_COGX : - >
PRO_MP_SOURCE SOURCE : Alternate Mass Prop
PRO_MP_ALT_IXX : - >
PRO_MP_TRF_22 DESIGNATED : NO
PRO_MP_TRF_42 : - >
PRO_MP_INERTIA_ORIGIN SOURCE : Mass Properties
PRO_MP_COGZ DESIGNATED : NO
PRO_MP_TRF_31 SOURCE : Mass Properties
PART_NUMBER DESIGNATED : YES
PRO_MP_COGX SOURCE : Mass Properties
PRO_MP_TRF_23 : - >
PRO_MP_IXX DESIGNATED : NO
PRO_MP_ALT_CSYS ACCESS : Full
PRO_MP_CSYS ACCESS : Locked
PRO_MP_TRF_22 : - >
PRO_MP_TRF_33 SOURCE : Mass Properties
PRO_MP_COGZ SOURCE : Mass Properties
PRO_MP_VOLUME DESIGNATED : NO
PRO_MP_ALT_IXZ DESCRIPTION : NULL
PART_NUMBER SOURCE : User-Defined
PRO_MP_TRF_32 ACCESS : Locked
PRO_MP_IYZ SOURCE : Mass Properties
PRO_MP_TRF_43 DESIGNATED : NO
PRO_MP_ALT_VOLUME ACCESS : Full
PRO_MP_ALT_COGZ SOURCE : Alternate Mass Prop
PRO_MP_TRF_21 DESIGNATED : NO
MP_DENSITY DESCRIPTION : NULL
PRO_MP_TRF_41 DESIGNATED : NO
REVISION ACCESS : Full
PRO_MP_ALT_COGX DESCRIPTION : NULL
PRO_MP_ALT_IZZ DESIGNATED : NO
PRO_MP_DENSITY : 0.000000
PRO_MP_IXY : - >
PRO_MP_ALT_MASS ACCESS : Full
PRO_MP_ALT_CSYS DESIGNATED : NO
PRO_MP_TRF_43 : - >
PRO_MP_ALT_IXZ SOURCE : Alternate Mass Prop
PRO_MP_IXZ : - >
PRO_MP_MASS ACCESS : Locked
PRO_MP_ALT_IXX SOURCE : Alternate Mass Prop
PRO_MP_ALT_COGZ ACCESS : Full
PRO_MP_VOLUME : - >
PRO_MP_ALT_IXX DESIGNATED : NO
MP_DENSITY ACCESS : Full
PRO_MP_TRF_21 ACCESS : Locked
PRO_MP_ALT_IYY : - >
PRO_MP_TRF_41 DESCRIPTION : NULL
PRO_MP_ALT_MASS DESCRIPTION : NULL
PRO_MP_TRF_13 DESIGNATED : NO
PRO_MP_ALT_CSYS SOURCE : Alternate Mass Prop
PRO_MP_ALT_VOLUME DESIGNATED : NO
PART_NUMBER : NIST PMI CTC 04 ASME1
PRO_MP_TRF_43 ACCESS : Locked
PRO_MP_ALT_AREA ACCESS : Full
}

68
tests/metadata/gltf/A8 Normal file
View File

@ -0,0 +1,68 @@
# !!!! This file is generated automatically, do not edit manually! See end script
set filename bug32087_part.stp
set ref_size 15789
set check_metadata 1
set ref_metadata {Property for [0:1:1:1]:
SETUP_PART : 0
MODEL_3D_REVISION : 1
MATERIAL_DENSITY : 7850
WEIGHT_PROTOTYPE : 0
WEIGHT_FINAL : 0
WEIGHT_CALCULATED : 0.0070751592515700002
SUPPLIER_NAME :
SEMI_FINISHED_PRODUCT :
REFERENCE :
REFERENCE_DESIGNATION++ :
MODEL_3D_APPROVED_BY :
MODEL_3D_CAD_SYSTEM :
PART_NAME :
MODEL_3D_CHECKED_BY :
OWNER :
COPYRIGHT :
WORK_ORDER_NUMBER :
PART_NUMBER :
ID_NUMBER_MATERIAL :
SPARE_WEARING_PART :
GENERAL_TOLERANCES_DRILL_HOLE :
TREATMENT :
MODEL_3D_CREATED_BY :
UNIT_SYSTEM :
MODEL_3D_DATE_OF_ISSUE :
WELD_TOLERANCES :
PROJECT :
LANGUAGE :
MODEL_3D_CREATED_BY_DEPARTMENT :
MODEL_3D_RELEASED_STATUS :
TECHNICAL_SPECIFICATION :
SUPPLIER_NUMBER :
SURFACE_PROTECTION :
EDGE_CONDITION :
GENERAL_TOLERANCES :
EDGE_CONDITION_INNER_EDGE :
ORDER_NUMBER :
GENERAL_TOLERANCES_FIT_DRILL_HOLE :
REFERENCE_DESIGNATION= :
SURFACE_ROUGHNESS :
REFERENCE_DESIGNATION- :
TOLERANCING_PRINCIPLE :
TECHNICAL_DIRECTIVE :
STOCK_NUMBER :
MODEL_3D_APPROVED_BY_DEPARTMENT :
PART_REVISION_LEVEL :
EDGE_CONDITION_OUTER_EDGE :
ARTICLE_NUMBER :
MATERIAL :
REFERENCE_DESIGNATION== :
SIMPLIFIED_DRAWING_REVISION :
MODEL_3D_REVISION_LEVEL :
MODEL_3D_RELEASED_BY :
MODEL_3D_REPLACED_BY :
REFERENCE_DESIGNATION+ :
MODEL_3D_ID_NUMBER :
PART_NOTE :
WELD_PREPARATION :
MODEL_3D_RELEASED_DATE :
MODEL_3D_REPLACES :
PAINT_SURFACE :
PART_SOURCE :
}

9
tests/metadata/gltf/A9 Normal file
View File

@ -0,0 +1,9 @@
# !!!! This file is generated automatically, do not edit manually! See end script
set filename nist_ftc_08_asme1_ap242-2.stp
set ref_size 118200
set check_metadata 1
set ref_metadata {Property for [0:1:1:1]:
Revision : C
PartNumber : NIST PMI FTC 08 ASME1
DescriptionRef : NIST PMI test model downloaded from http://go.usa.gov/mGVm
}

76
tests/metadata/gltf/end Normal file
View File

@ -0,0 +1,76 @@
# Set flag dump_file to 1 in order to regenerate script files with actual data
# used as reference. In this mode all tests intentionally report failure.
set dump_file 0
# Read original file
if { [string length $filename] > 1} {
set path_file [locate_data_file $filename]
if { [catch { ReadFile aDocExport $path_file } catch_result] } {
set err_msg "Error: file was not read - exception "
puts $err_msg
}
}
# mesh the shape before Gltf writing
XGetOneShape a aDocExport
incmesh a 0.1
# write file
WriteGltf aDocExport $imagedir/${casename}_D_First.gltf
set aSize [file size $imagedir/${casename}_D_First.gltf]
# Import created Gltf file and get its metadata.
ReadGltf aDocImport $imagedir/${casename}_D_First.gltf
set aMetaDataBase [ XGetProperties aDocImport ]
set aMetaData [format $aMetaDataBase]
if { $dump_file == 1 } {
set fd_stream [open $dirname/$groupname/$gridname/$casename w]
puts $fd_stream "# !!!! This file is generated automatically, do not edit manually! See end script"
puts $fd_stream "set filename $filename"
puts $fd_stream "set ref_size $aSize"
puts $fd_stream "set check_metadata $check_metadata"
if {$check_metadata == 1} {
puts $fd_stream "set ref_metadata \{$aMetaData\}"
}
close $fd_stream
puts "Error : Running in regeneration mode, comparison was not performed!"
} else {
if {$aSize != $ref_size} {
puts "Error: Wrong file size $aSize instead of $ref_size"
}
if {$check_metadata == 1} {
# Compare metadata in files.
set aMetaDataLines [split ${aMetaData} "\n"]
set aRefMetaDataLines [split ${ref_metadata} "\n"]
set aMetaDataLinesCount [llength $aMetaDataLines]
set aRefMetaDataLinesCount [llength $aRefMetaDataLines]
set aMinLineCount [expr min($aMetaDataLinesCount, $aRefMetaDataLinesCount)]
for {set aLineIndex 0} {$aLineIndex < $aMinLineCount} {incr aLineIndex} {
set aCurrentMetaDataLine [lindex $aMetaDataLines $aLineIndex]
set aCurrentRefMetaDataLine [lindex $aRefMetaDataLines $aLineIndex]
if {$aCurrentMetaDataLine != $aCurrentRefMetaDataLine} {
puts "Error: Incorrect metadata at line $aLineIndex"
puts "Expected: \"$aCurrentRefMetaDataLine\""
puts "Actual: \"$aCurrentMetaDataLine\""
break
}
}
# It is faster to check this condition first, before string-by-string comparison,
# however string-by-string comparison would be more informative in case of error.
if {$aMetaDataLinesCount != $aRefMetaDataLinesCount} {
puts "Error: Line count is metadata doesn't match the expected value."
puts "Expected: $aRefMetaDataLinesCount"
puts "Actual: $aMetaDataLinesCount"
}
}
}
# finalize scenario
Close aDocImport
Close aDocExport
file delete $imagedir/${casename}_D_First.gltf
file delete $imagedir/${casename}_D_First.bin
puts "TEST COMPLETED"

View File

@ -1,3 +0,0 @@
# !!!! This file is generated automatically, do not edit manually! See end script
set filename bug28345_30338.stp
set ref_size 5896

View File

@ -1,3 +0,0 @@
# !!!! This file is generated automatically, do not edit manually! See end script
set filename bug28389_CONFIDENTIAL_SHEET_METAL_F3D.stp
set ref_size 86278

View File

@ -1,3 +0,0 @@
# !!!! This file is generated automatically, do not edit manually! See end script
set filename bug28444_nist_ftc_06_asme1_ct5240_rd.stp
set ref_size 85383

View File

@ -1,3 +0,0 @@
# !!!! This file is generated automatically, do not edit manually! See end script
set filename bug29633_nist_ctc_05_asme1_ap242-1.stp
set ref_size 69902

View File

@ -1,3 +0,0 @@
# !!!! This file is generated automatically, do not edit manually! See end script
set filename bug29803.stp
set ref_size 17032

View File

@ -1,3 +0,0 @@
# !!!! This file is generated automatically, do not edit manually! See end script
set filename sp7_04-do-242.stp
set ref_size 224779

View File

@ -1,3 +0,0 @@
# !!!! This file is generated automatically, do not edit manually! See end script
set filename bug32087_part.stp
set ref_size 15789

View File

@ -1,3 +0,0 @@
# !!!! This file is generated automatically, do not edit manually! See end script
set filename nist_ftc_08_asme1_ap242-2.stp
set ref_size 118200

View File

@ -1,39 +0,0 @@
# Set flag dump_file to 1 in order to regenerate script files with actual data
# used as reference. In this mode all tests intentionally report failure.
set dump_file 0
# Read original file
if { [string length $filename] > 1} {
set path_file [locate_data_file $filename]
if { [catch { ReadFile D $path_file } catch_result] } {
set err_msg "Error: file was not read - exception "
puts $err_msg
}
}
# mesh the shape before Gltf writing
XGetOneShape a D
incmesh a 0.1
# write file
WriteGltf D $imagedir/${casename}_D_First.gltf
set aSize [file size $imagedir/${casename}_D_First.gltf]
if { $dump_file == 1 } {
set fd_stream [open $dirname/$groupname/$gridname/$casename w]
puts $fd_stream "# !!!! This file is generated automatically, do not edit manually! See end script"
puts $fd_stream "set filename $filename"
puts $fd_stream "set ref_size $aSize"
close $fd_stream
puts "Error : Running in regeneration mode, comparison was not performed!"
} else {
if {$aSize != $ref_size} {
puts "Error: Wrong file size $aSize instead of $ref_size"
}
}
# finalize scenario
Close D
file delete $imagedir/${casename}_D_First.gltf
file delete $imagedir/${casename}_D_First.bin
puts "TEST COMPLETED"

View File

@ -1,2 +1,2 @@
001 step
002 gltf_export
002 gltf