1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-09 18:50:54 +03:00

GLTF Import - Edge and Vertex support #242

Added functionality to import Points and Lines from GLTF format
This commit is contained in:
mzernova 2025-01-05 22:47:18 +00:00
parent 174b985fd5
commit b9429d0708
16 changed files with 317 additions and 65 deletions

View File

@ -15,7 +15,7 @@
#include "RWGltf_GltfJsonParser.hxx" #include "RWGltf_GltfJsonParser.hxx"
#include <BRep_Builder.hxx> #include <BRep_Builder.hxx>
#include <gp_Quaternion.hxx> #include <FSD_Base64.hxx>
#include <Message.hxx> #include <Message.hxx>
#include <Message_Messenger.hxx> #include <Message_Messenger.hxx>
#include <Message_ProgressScope.hxx> #include <Message_ProgressScope.hxx>
@ -24,11 +24,13 @@
#include <OSD_Path.hxx> #include <OSD_Path.hxx>
#include <OSD_ThreadPool.hxx> #include <OSD_ThreadPool.hxx>
#include <Precision.hxx> #include <Precision.hxx>
#include <FSD_Base64.hxx> #include <RWGltf_TriangulationReader.hxx>
#include <TDataStd_NamedData.hxx> #include <TDataStd_NamedData.hxx>
#include <TopExp_Explorer.hxx> #include <TopExp_Explorer.hxx>
#include <TopoDS.hxx> #include <TopoDS.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Iterator.hxx> #include <TopoDS_Iterator.hxx>
#include <gp_Quaternion.hxx>
#include <fstream> #include <fstream>
@ -1581,7 +1583,9 @@ bool RWGltf_GltfJsonParser::gltfParseSceneNodes(TopTools_SequenceOfShape& the
{ {
continue; continue;
} }
else if (myToSkipEmptyNodes && !TopExp_Explorer(aNodeShape, TopAbs_FACE).More()) else if (myToSkipEmptyNodes && !TopExp_Explorer(aNodeShape, TopAbs_FACE).More()
&& !TopExp_Explorer(aNodeShape, TopAbs_EDGE).More()
&& !TopExp_Explorer(aNodeShape, TopAbs_VERTEX).More())
{ {
continue; continue;
} }
@ -1838,7 +1842,8 @@ bool RWGltf_GltfJsonParser::gltfParsePrimArray(TopoDS_Shape& th
return false; return false;
} }
} }
if (aMode != RWGltf_GltfPrimitiveMode_Triangles) if (aMode != RWGltf_GltfPrimitiveMode_Triangles && aMode != RWGltf_GltfPrimitiveMode_Lines
&& aMode != RWGltf_GltfPrimitiveMode_Points)
{ {
Message::SendWarning(TCollection_AsciiString() + "Primitive array within Mesh '" + theMeshId Message::SendWarning(TCollection_AsciiString() + "Primitive array within Mesh '" + theMeshId
+ "' skipped due to unsupported mode"); + "' skipped due to unsupported mode");
@ -1887,21 +1892,15 @@ bool RWGltf_GltfJsonParser::gltfParsePrimArray(TopoDS_Shape& th
{ {
if (myAttribMap != NULL) if (myAttribMap != NULL)
{ {
// sharing just triangulation is not much useful // make a located Shape copy
// Handle(RWGltf_GltfLatePrimitiveArray) aLateData = TopoDS_Shape aShapeCopy = thePrimArrayShape;
// Handle(RWGltf_GltfLatePrimitiveArray)::DownCast (BRep_Tool::Triangulation (TopoDS::Face aShapeCopy.Location(TopLoc_Location(gp_Trsf()));
// (thePrimArrayShape), aDummy)); TopoDS_Face aFaceCopy; BRep_Builder().MakeFace (aFaceCopy,
// aLateData);
// make a located Face copy
TopoDS_Shape aFaceCopy = thePrimArrayShape;
aFaceCopy.Location(TopLoc_Location(gp_Trsf()));
RWMesh_NodeAttributes aShapeAttribs; RWMesh_NodeAttributes aShapeAttribs;
aShapeAttribs.RawName = theMeshName; aShapeAttribs.RawName = theMeshName;
aShapeAttribs.Style.SetMaterial(aMat); aShapeAttribs.Style.SetMaterial(aMat);
myAttribMap->Bind(aFaceCopy, aShapeAttribs); myAttribMap->Bind(aShapeCopy, aShapeAttribs);
myShapeMap[ShapeMapGroup_PrimArray].Bind(aPrimArrayIdWithMat, aFaceCopy); myShapeMap[ShapeMapGroup_PrimArray].Bind(aPrimArrayIdWithMat, aShapeCopy);
thePrimArrayShape = aFaceCopy; thePrimArrayShape = aShapeCopy;
} }
return true; return true;
} }
@ -1978,16 +1977,72 @@ bool RWGltf_GltfJsonParser::gltfParsePrimArray(TopoDS_Shape& th
return false; return false;
} }
} }
else else if (aMode == RWGltf_GltfPrimitiveMode_Triangles)
{ {
aMeshData->SetNbDeferredTriangles(aMeshData->NbDeferredNodes() / 3); aMeshData->SetNbDeferredTriangles(aMeshData->NbDeferredNodes() / 3);
} }
else
{
aMeshData->SetNbDeferredTriangles(0);
}
if (!aMeshData->Data().IsEmpty()) if (!aMeshData->Data().IsEmpty())
{ {
if (aMode != RWGltf_GltfPrimitiveMode_Triangles)
{
Message::SendWarning("Deferred loading is available only for triangulations. Other elements "
"will be loaded immediately.");
Handle(RWGltf_TriangulationReader) aReader = new RWGltf_TriangulationReader();
aReader->SetCoordinateSystemConverter(myCSTrsf);
aMeshData->SetReader(aReader);
aMeshData->LoadDeferredData();
}
TopoDS_Shape aShape;
switch (aMode)
{
case RWGltf_GltfPrimitiveMode_Points: {
BRep_Builder aBuilder;
TopoDS_Compound aVertices;
aBuilder.MakeCompound(aVertices);
for (Standard_Integer aNodeIdx = 1; aNodeIdx <= aMeshData->NbNodes(); ++aNodeIdx)
{
TopoDS_Vertex aVertex;
aBuilder.MakeVertex(aVertex, aMeshData->Node(aNodeIdx), Precision::Confusion());
aBuilder.Add(aVertices, aVertex);
}
aShape = aVertices;
break;
}
case RWGltf_GltfPrimitiveMode_Lines: {
TColgp_Array1OfPnt aNodes(1, aMeshData->NbEdges());
for (Standard_Integer anEdgeIdx = 1; anEdgeIdx <= aMeshData->NbEdges(); ++anEdgeIdx)
{
Standard_Integer aNodeIdx = aMeshData->Edge(anEdgeIdx);
aNodes.SetValue(anEdgeIdx, aMeshData->Node(aNodeIdx));
}
TopoDS_Edge anEdge;
BRep_Builder aBuilder;
Handle(Poly_Polygon3D) aPoly = new Poly_Polygon3D(aNodes);
aBuilder.MakeEdge(anEdge, aPoly);
aShape = anEdge;
break;
}
case RWGltf_GltfPrimitiveMode_Triangles: {
TopoDS_Face aFace; TopoDS_Face aFace;
BRep_Builder aBuilder; BRep_Builder aBuilder;
aBuilder.MakeFace(aFace, aMeshData); aBuilder.MakeFace(aFace, aMeshData);
aShape = aFace;
myFaceList.Append(aFace);
break;
}
default: {
Message::SendFail("Unsupported primitive mode.");
return false;
break;
}
}
if (myAttribMap != NULL && aMeshData->HasStyle()) if (myAttribMap != NULL && aMeshData->HasStyle())
{ {
RWMesh_NodeAttributes aShapeAttribs; RWMesh_NodeAttributes aShapeAttribs;
@ -1997,12 +2052,11 @@ bool RWGltf_GltfJsonParser::gltfParsePrimArray(TopoDS_Shape& th
// aShapeAttribs.Style.SetColorSurf (aMeshData->BaseColor()); // aShapeAttribs.Style.SetColorSurf (aMeshData->BaseColor());
aShapeAttribs.Style.SetMaterial(aMat); aShapeAttribs.Style.SetMaterial(aMat);
myAttribMap->Bind(aFace, aShapeAttribs); myAttribMap->Bind(aShape, aShapeAttribs);
} }
myFaceList.Append(aFace); myShapeMap[ShapeMapGroup_PrimArray].Bind(aPrimArrayId, aShape);
myShapeMap[ShapeMapGroup_PrimArray].Bind(aPrimArrayId, aFace); myShapeMap[ShapeMapGroup_PrimArray].Bind(aPrimArrayIdWithMat, aShape);
myShapeMap[ShapeMapGroup_PrimArray].Bind(aPrimArrayIdWithMat, aFace); thePrimArrayShape = aShape;
thePrimArrayShape = aFace;
} }
return true; return true;
} }
@ -2146,9 +2200,17 @@ bool RWGltf_GltfJsonParser::gltfParseAccessor(
} }
} }
else if (theType == RWGltf_GltfArrayType_Indices) else if (theType == RWGltf_GltfArrayType_Indices)
{
if (theMeshData->PrimitiveMode() == RWGltf_GltfPrimitiveMode_Triangles)
{ {
theMeshData->SetNbDeferredTriangles((Standard_Integer)(aStruct.Count / 3)); theMeshData->SetNbDeferredTriangles((Standard_Integer)(aStruct.Count / 3));
} }
else
{
theMeshData->SetNbDeferredNodes((Standard_Integer)(aStruct.Count));
theMeshData->SetNbDeferredTriangles(0);
}
}
const RWGltf_JsonValue* aBufferView = const RWGltf_JsonValue* aBufferView =
myGltfRoots[RWGltf_GltfRootElement_BufferViews].FindChild(*aBufferViewName); myGltfRoots[RWGltf_GltfRootElement_BufferViews].FindChild(*aBufferViewName);

View File

@ -104,7 +104,8 @@ Handle(Poly_Triangulation) RWGltf_GltfLatePrimitiveArray::LoadStreamData() const
{ {
return Handle(Poly_Triangulation)(); return Handle(Poly_Triangulation)();
} }
Handle(Poly_Triangulation) aResult = createNewEntity();
Handle(RWMesh_TriangulationSource) aResult = new RWMesh_TriangulationSource();
if (!aGltfReader->LoadStreamData(this, aResult)) if (!aGltfReader->LoadStreamData(this, aResult))
{ {
return Handle(Poly_Triangulation)(); return Handle(Poly_Triangulation)();

View File

@ -84,7 +84,7 @@ public:
//! that can be loaded using LoadDeferredData(). //! that can be loaded using LoadDeferredData().
virtual Standard_Boolean HasDeferredData() const Standard_OVERRIDE virtual Standard_Boolean HasDeferredData() const Standard_OVERRIDE
{ {
return !myData.IsEmpty() && RWMesh_TriangulationSource::HasDeferredData(); return !myData.IsEmpty() && (NbDeferredTriangles() > 0 || NbDeferredNodes() > 0);
} }
//! Load primitive array saved as stream buffer to new triangulation object. //! Load primitive array saved as stream buffer to new triangulation object.

View File

@ -584,7 +584,9 @@ bool RWGltf_TriangulationReader::readBuffer(
{ {
const TCollection_AsciiString& aName = theSourceMesh->Id(); const TCollection_AsciiString& aName = theSourceMesh->Id();
if (theSourceMesh->PrimitiveMode() != RWGltf_GltfPrimitiveMode_Triangles) const RWGltf_GltfPrimitiveMode aPrimMode = theSourceMesh->PrimitiveMode();
if (aPrimMode != RWGltf_GltfPrimitiveMode_Triangles && aPrimMode != RWGltf_GltfPrimitiveMode_Lines
&& aPrimMode != RWGltf_GltfPrimitiveMode_Points)
{ {
Message::SendWarning(TCollection_AsciiString("Buffer '") + aName Message::SendWarning(TCollection_AsciiString("Buffer '") + aName
+ "' skipped unsupported primitive array"); + "' skipped unsupported primitive array");
@ -608,37 +610,48 @@ bool RWGltf_TriangulationReader::readBuffer(
return false; return false;
} }
const Standard_Integer aNbTris = (Standard_Integer)(theAccessor.Count / 3); const Standard_Boolean isTriangles = aPrimMode == RWGltf_GltfPrimitiveMode_Triangles;
if (!setNbTriangles(theDestMesh, aNbTris)) const Standard_Integer aCounter = isTriangles ? (Standard_Integer)(theAccessor.Count / 3)
: (Standard_Integer)(theAccessor.Count);
if ((isTriangles && !setNbTriangles(theDestMesh, aCounter))
|| !setNbEdges(theDestMesh, aCounter))
{ {
return false; return false;
} }
const size_t aStride = const size_t aStride =
theAccessor.ByteStride != 0 ? theAccessor.ByteStride : sizeof(uint16_t); theAccessor.ByteStride != 0 ? theAccessor.ByteStride : sizeof(uint16_t);
Standard_ReadBuffer aBuffer(theAccessor.Count * aStride, aStride); Standard_ReadBuffer aBuffer(theAccessor.Count * aStride, aStride);
Standard_Integer aLastTriIndex = 0; Standard_Integer aLastIndex = 0;
for (Standard_Integer aTriIter = 0; aTriIter < aNbTris; ++aTriIter) for (Standard_Integer aTriIter = 0; aTriIter < aCounter; ++aTriIter)
{ {
if (const uint16_t* anIndex0 = aBuffer.ReadChunk<uint16_t>(theStream)) Standard_Integer wasSet = false;
if (isTriangles)
{ {
aVec3.ChangeValue(1) = THE_LOWER_NODE_INDEX + *anIndex0; for (Standard_Integer anIter = 1; anIter <= 3; ++anIter)
}
if (const uint16_t* anIndex1 = aBuffer.ReadChunk<uint16_t>(theStream))
{ {
aVec3.ChangeValue(2) = THE_LOWER_NODE_INDEX + *anIndex1; const uint16_t* anIndex = aBuffer.ReadChunk<uint16_t>(theStream);
} if (anIndex == nullptr)
if (const uint16_t* anIndex2 = aBuffer.ReadChunk<uint16_t>(theStream))
{
aVec3.ChangeValue(3) = THE_LOWER_NODE_INDEX + *anIndex2;
}
else
{ {
reportError(TCollection_AsciiString("Buffer '") + aName + "' reading error."); reportError(TCollection_AsciiString("Buffer '") + aName + "' reading error.");
return false; return false;
} }
aVec3.ChangeValue(anIter) = THE_LOWER_NODE_INDEX + *anIndex;
}
wasSet = setTriangle(theDestMesh, THE_LOWER_TRI_INDEX + aLastIndex, aVec3);
}
else
{
const uint16_t* anIndex = aBuffer.ReadChunk<uint16_t>(theStream);
if (anIndex == nullptr)
{
reportError(TCollection_AsciiString("Buffer '") + aName + "' reading error.");
return false;
}
wasSet = setEdge(theDestMesh,
THE_LOWER_TRI_INDEX + aLastIndex,
THE_LOWER_NODE_INDEX + *anIndex);
}
const Standard_Integer wasSet =
setTriangle(theDestMesh, THE_LOWER_TRI_INDEX + aLastTriIndex, aVec3);
if (!wasSet) if (!wasSet)
{ {
reportError(TCollection_AsciiString("Buffer '") + aName reportError(TCollection_AsciiString("Buffer '") + aName
@ -646,13 +659,13 @@ bool RWGltf_TriangulationReader::readBuffer(
} }
if (wasSet > 0) if (wasSet > 0)
{ {
aLastTriIndex++; aLastIndex++;
} }
} }
const Standard_Integer aNbDegenerate = aNbTris - aLastTriIndex; const Standard_Integer aNbDegenerate = aCounter - aLastIndex;
if (aNbDegenerate > 0) if (aNbDegenerate > 0)
{ {
if (aNbDegenerate == aNbTris) if (aNbDegenerate == aCounter)
{ {
Message::SendWarning(TCollection_AsciiString("Buffer '") + aName Message::SendWarning(TCollection_AsciiString("Buffer '") + aName
+ "' has been skipped (all elements are degenerative in)"); + "' has been skipped (all elements are degenerative in)");
@ -666,7 +679,7 @@ bool RWGltf_TriangulationReader::readBuffer(
+ " degenerate triangles have been skipped while reading glTF triangulation '" + aName + " degenerate triangles have been skipped while reading glTF triangulation '" + aName
+ "'"); + "'");
} }
if (!setNbTriangles(theDestMesh, aLastTriIndex, true)) if (!setNbTriangles(theDestMesh, aLastIndex, true))
{ {
return false; return false;
} }

View File

@ -112,7 +112,7 @@ protected:
const Handle(OSD_FileSystem)& theFileSystem) const; const Handle(OSD_FileSystem)& theFileSystem) const;
protected: protected:
Handle(Poly_Triangulation) myTriangulation; Handle(RWMesh_TriangulationSource) myTriangulation;
}; };
#endif // _RWGltf_TriangulationReader_HeaderFile #endif // _RWGltf_TriangulationReader_HeaderFile

View File

@ -162,3 +162,37 @@ bool RWMesh_TriangulationReader::finalizeLoading(
} }
return true; return true;
} }
// =======================================================================
// function : setNbEdges
// purpose :
// =======================================================================
bool RWMesh_TriangulationReader::setNbEdges(const Handle(Poly_Triangulation)& theMesh,
const Standard_Integer theNbTris,
const Standard_Boolean theToCopyData) const
{
Handle(RWMesh_TriangulationSource) aMesh = Handle(RWMesh_TriangulationSource)::DownCast(theMesh);
if (theNbTris >= 1)
{
aMesh->ResizeEdges(theNbTris, theToCopyData);
return true;
}
return false;
}
// =======================================================================
// function : setEdge
// purpose :
// =======================================================================
Standard_Integer RWMesh_TriangulationReader::setEdge(const Handle(Poly_Triangulation)& theMesh,
const Standard_Integer theIndex,
const Standard_Integer theEdge) const
{
Handle(RWMesh_TriangulationSource) aMesh = Handle(RWMesh_TriangulationSource)::DownCast(theMesh);
if (theEdge < 1 || theEdge > theMesh->NbNodes())
{
return 0;
}
aMesh->SetEdge(theIndex, theEdge);
return 1;
}

View File

@ -283,6 +283,25 @@ protected: //! @name interface for filling triangulation data
return 1; return 1;
} }
//! Resizes array of edges to specified size.
//! @param[in] theMesh triangulation source to be modified
//! @param[in] theNbEdges elements number
//! @param[in] theToCopyData copy old edges into new array
//! @return TRUE in case of success operation
Standard_EXPORT virtual bool setNbEdges(const Handle(Poly_Triangulation)& theMesh,
const Standard_Integer theNbEdges,
const Standard_Boolean theToCopyData = false) const;
//! Adds edge element.
//! @param[in] theMesh triangulation source to be modified
//! @param theIndex edge index starting from 1
//! @param theEdge edge nodes starting from 1
//! @return 0 if node indexes are out of range,
//! 1 in case of success operation.
Standard_EXPORT virtual Standard_Integer setEdge(const Handle(Poly_Triangulation)& theMesh,
const Standard_Integer theIndex,
const Standard_Integer theEdge) const;
protected: protected:
RWMesh_CoordinateSystemConverter myCoordSysConverter; //!< coordinate system converter RWMesh_CoordinateSystemConverter myCoordSysConverter; //!< coordinate system converter
// clang-format off // clang-format off

View File

@ -50,9 +50,25 @@ Standard_Boolean RWMesh_TriangulationSource::loadDeferredData(
{ {
return false; return false;
} }
if (myReader->Load(this, theDestTriangulation, theFileSystem)) Handle(RWMesh_TriangulationSource) aDestTriangulation =
Handle(RWMesh_TriangulationSource)::DownCast(theDestTriangulation);
if (aDestTriangulation.IsNull())
{
return false;
}
if (myReader->Load(this, aDestTriangulation, theFileSystem))
{ {
return true; return true;
} }
return false; return false;
} }
// =======================================================================
// function : ResizeEdges
// purpose :
// =======================================================================
void RWMesh_TriangulationSource::ResizeEdges(Standard_Integer theNbEdges,
Standard_Boolean theToCopyOld)
{
myEdges.Resize(1, theNbEdges, theToCopyOld);
}

View File

@ -15,6 +15,7 @@
#define _RWMesh_TriangulationSource_HeaderFile #define _RWMesh_TriangulationSource_HeaderFile
#include <Poly_Triangulation.hxx> #include <Poly_Triangulation.hxx>
#include <NCollection_Array1.hxx>
class RWMesh_TriangulationReader; class RWMesh_TriangulationReader;
@ -44,6 +45,28 @@ public:
//! Gets access to number of degenerated triangles to collect them during data reading. //! Gets access to number of degenerated triangles to collect them during data reading.
Standard_Integer& ChangeDegeneratedTriNb() { return myStatisticOfDegeneratedTriNb; } Standard_Integer& ChangeDegeneratedTriNb() { return myStatisticOfDegeneratedTriNb; }
//! Returns TRUE if triangulation has some geometry.
virtual Standard_Boolean HasGeometry() const Standard_OVERRIDE
{
return !myNodes.IsEmpty() && (!myTriangles.IsEmpty() || !myEdges.IsEmpty());
}
//! Returns the number of edges for this triangulation.
Standard_Integer NbEdges() const { return myEdges.Length(); }
//! Returns edge at the given index.
//! @param[in] theIndex edge index within [1, NbEdges()] range
//! @return edge node indices, with each node defined within [1, NbNodes()] range
Standard_Integer Edge(Standard_Integer theIndex) const { return myEdges.Value(theIndex); }
//! Sets an edge.
//! @param[in] theIndex edge index within [1, NbEdges()] range
//! @param[in] theEdge edge node indices, with each node defined within [1, NbNodes()] range
void SetEdge(Standard_Integer theIndex, Standard_Integer theEdge)
{
myEdges.SetValue(theIndex, theEdge);
}
public: //! @name late-load deferred data interface public: //! @name late-load deferred data interface
//! Returns number of nodes for deferred loading. //! Returns number of nodes for deferred loading.
//! Note: this is estimated values defined in object header, which might be different from //! Note: this is estimated values defined in object header, which might be different from
@ -66,6 +89,15 @@ public: //! @name late-load deferred data interface
//! Sets number of triangles for deferred loading. //! Sets number of triangles for deferred loading.
void SetNbDeferredTriangles(const Standard_Integer theNbTris) { myNbDefTriangles = theNbTris; } void SetNbDeferredTriangles(const Standard_Integer theNbTris) { myNbDefTriangles = theNbTris; }
//! Returns an internal array of edges.
//! Edge()/SetEdge() should be used instead in portable code.
NCollection_Array1<Standard_Integer>& InternalEdges() { return myEdges; }
//! Method resizing an internal array of triangles.
//! @param[in] theNbTriangles new number of triangles
//! @param[in] theToCopyOld copy old triangles into the new array
Standard_EXPORT void ResizeEdges(Standard_Integer theNbEdges, Standard_Boolean theToCopyOld);
protected: protected:
//! Loads triangulation data from deferred storage using specified shared input file system. //! Loads triangulation data from deferred storage using specified shared input file system.
Standard_EXPORT virtual Standard_Boolean loadDeferredData( Standard_EXPORT virtual Standard_Boolean loadDeferredData(
@ -74,6 +106,7 @@ protected:
protected: protected:
Handle(RWMesh_TriangulationReader) myReader; Handle(RWMesh_TriangulationReader) myReader;
NCollection_Array1<Standard_Integer> myEdges;
Standard_Integer myNbDefNodes; Standard_Integer myNbDefNodes;
Standard_Integer myNbDefTriangles; Standard_Integer myNbDefTriangles;
mutable Standard_Integer myStatisticOfDegeneratedTriNb; mutable Standard_Integer myStatisticOfDegeneratedTriNb;

View File

@ -19,12 +19,46 @@ Close DD
ReadGltf D "$aTmpGltf" ReadGltf D "$aTmpGltf"
XGetOneShape s D XGetOneShape s D
checknbshapes s -face 6 -compound 2 checknbshapes s -face 6 -vertex 8 -compound 11
set THE_REF_DUMP { set THE_REF_DUMP {
ASSEMBLY COMPOUND 0:1:1:1 "empty_tmp.glb" ASSEMBLY COMPOUND 0:1:1:1 "empty_tmp.glb"
INSTANCE COMPOUND 0:1:1:1:1 (refers to 0:1:1:2) "Compound" INSTANCE COMPOUND 0:1:1:1:1 (refers to 0:1:1:2) "Compound"
PART COMPOUND 0:1:1:2 "Compound" INSTANCE COMPOUND 0:1:1:1:2 (refers to 0:1:1:19) "Compound"
ASSEMBLY COMPOUND 0:1:1:2 "Compound"
INSTANCE COMPOUND 0:1:1:2:1 (refers to 0:1:1:3) "Compound"
INSTANCE COMPOUND 0:1:1:2:2 (refers to 0:1:1:5) "Compound"
INSTANCE COMPOUND 0:1:1:2:3 (refers to 0:1:1:7) "Compound"
INSTANCE COMPOUND 0:1:1:2:4 (refers to 0:1:1:9) "Compound"
INSTANCE COMPOUND 0:1:1:2:5 (refers to 0:1:1:11) "Compound"
INSTANCE COMPOUND 0:1:1:2:6 (refers to 0:1:1:13) "Compound"
INSTANCE COMPOUND 0:1:1:2:7 (refers to 0:1:1:15) "Compound"
INSTANCE COMPOUND 0:1:1:2:8 (refers to 0:1:1:17) "Compound"
ASSEMBLY COMPOUND 0:1:1:3 "Compound"
INSTANCE VERTEX 0:1:1:3:1 (refers to 0:1:1:4) "Vertex"
PART VERTEX 0:1:1:4 "Vertex"
ASSEMBLY COMPOUND 0:1:1:5 "Compound"
INSTANCE VERTEX 0:1:1:5:1 (refers to 0:1:1:6) "Vertex"
PART VERTEX 0:1:1:6 "Vertex"
ASSEMBLY COMPOUND 0:1:1:7 "Compound"
INSTANCE VERTEX 0:1:1:7:1 (refers to 0:1:1:8) "Vertex"
PART VERTEX 0:1:1:8 "Vertex"
ASSEMBLY COMPOUND 0:1:1:9 "Compound"
INSTANCE VERTEX 0:1:1:9:1 (refers to 0:1:1:10) "Vertex"
PART VERTEX 0:1:1:10 "Vertex"
ASSEMBLY COMPOUND 0:1:1:11 "Compound"
INSTANCE VERTEX 0:1:1:11:1 (refers to 0:1:1:12) "Vertex"
PART VERTEX 0:1:1:12 "Vertex"
ASSEMBLY COMPOUND 0:1:1:13 "Compound"
INSTANCE VERTEX 0:1:1:13:1 (refers to 0:1:1:14) "Vertex"
PART VERTEX 0:1:1:14 "Vertex"
ASSEMBLY COMPOUND 0:1:1:15 "Compound"
INSTANCE VERTEX 0:1:1:15:1 (refers to 0:1:1:16) "Vertex"
PART VERTEX 0:1:1:16 "Vertex"
ASSEMBLY COMPOUND 0:1:1:17 "Compound"
INSTANCE VERTEX 0:1:1:17:1 (refers to 0:1:1:18) "Vertex"
PART VERTEX 0:1:1:18 "Vertex"
PART COMPOUND 0:1:1:19 "Compound"
Free Shapes: 1 Free Shapes: 1
ASSEMBLY COMPOUND 0:1:1:1 "empty_tmp.glb" ASSEMBLY COMPOUND 0:1:1:1 "empty_tmp.glb"

View File

@ -0,0 +1,39 @@
puts "========"
puts "Data Exchange, RWGltf_CafReader - Edge and Vertex support"
puts "========"
vclear
vclose ALL
Close *
set aTmpGltf "${imagedir}/${casename}_tmp.glb"
vertex v1 2 0 0
vertex v2 2 1 0
vertex v3 3 1 0
vertex v4 3 0 0
polygon3d p1 2 0 0 0 1 1 0
mkedge e1 p1
polygon3d p2 2 0 1 0 1 0 0
mkedge e2 p2
XNewDoc D
XAddShape D e1
XAddShape D e2
XAddShape D v1
XAddShape D v2
XAddShape D v3
XAddShape D v4
SetName D [XFindShape D e1] "edge_1"
SetName D [XFindShape D e2] "edge_2"
SetName D [XFindShape D v1] "vertex_1"
SetName D [XFindShape D v2] "vertex_2"
SetName D [XFindShape D v3] "vertex_3"
SetName D [XFindShape D v4] "vertex_4"
WriteGltf D "$aTmpGltf"
ReadGltf D1 "$aTmpGltf"
XGetOneShape s D1
checknbshapes s -vertex 4 -edge 2

View File

@ -1,6 +1,6 @@
# !!!! This file is generated automatically, do not edit manually! See end script # !!!! This file is generated automatically, do not edit manually! See end script
set filename bug28389_CONFIDENTIAL_SHEET_METAL_F3D.stp set filename bug28389_CONFIDENTIAL_SHEET_METAL_F3D.stp
set ref_size 86338 set ref_size 103329
set check_metadata 1 set check_metadata 1
set ref_metadata {Property for [0:1:1:1]: set ref_metadata {Property for [0:1:1:1]:
yCenterOfGravity : 0.1148447698 yCenterOfGravity : 0.1148447698

View File

@ -1,6 +1,6 @@
# !!!! This file is generated automatically, do not edit manually! See end script # !!!! This file is generated automatically, do not edit manually! See end script
set filename bug28444_nist_ftc_06_asme1_ct5240_rd.stp set filename bug28444_nist_ftc_06_asme1_ct5240_rd.stp
set ref_size 85605 set ref_size 118300
set check_metadata 1 set check_metadata 1
set ref_metadata {Property for [0:1:1:1]: set ref_metadata {Property for [0:1:1:1]:
yCenterOfGravity : 0.0289950044 yCenterOfGravity : 0.0289950044

View File

@ -1,4 +1,4 @@
# !!!! This file is generated automatically, do not edit manually! See end script # !!!! 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 filename bug29525_rev_part_neu_01.prt_converted_from_datakit.stp
set ref_size 81056 set ref_size 90657
set check_metadata 0 set check_metadata 0

View File

@ -1,6 +1,6 @@
# !!!! This file is generated automatically, do not edit manually! See end script # !!!! This file is generated automatically, do not edit manually! See end script
set filename sp7_04-do-242.stp set filename sp7_04-do-242.stp
set ref_size 224869 set ref_size 246373
set check_metadata 1 set check_metadata 1
set ref_metadata {Property for [0:1:1:1]: set ref_metadata {Property for [0:1:1:1]:
PRO_MP_ALT_COGX : - > PRO_MP_ALT_COGX : - >

View File

@ -39,7 +39,8 @@ if { $dump_file == 1 } {
close $fd_stream close $fd_stream
puts "Error : Running in regeneration mode, comparison was not performed!" puts "Error : Running in regeneration mode, comparison was not performed!"
} else { } else {
if {$aSize != $ref_size} { set tolerance [expr {min(max(0.001 * $ref_size, 1), 100)}]
if {abs($aSize - $ref_size) > $tolerance} {
puts "Error: Wrong file size $aSize instead of $ref_size" puts "Error: Wrong file size $aSize instead of $ref_size"
} }