1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-14 13:30:48 +03:00

0032086: Visualization - support deferred data loading

1) Extend Poly_Triangulation by mesh purpose, possibility to be cleared and late-load deferred data interfaces.
2) Update BRep_TFace to store list of triangulations istead of single one. And also active one. Update getter and setter of single triangulation and add new methods to interaction with whole triangulations list.
3) Update BRep_Tool to get single triangulation of face according to the input mesh purpose or whole triangulations list.
4) Update BRep_Builder to make face by not only single triangulation but whole triangulations list with specified active one.
5) Add new methods to BRepTools to interact with shape triangulations (Load/Unload/Activate/LoadAll/UnloadAllTriangulation(s))
6) Add new 'tlateload'command for shape to load/unload/activate triangulations.
7) Update 'trinfo' command by '-lods' options to print detailaed information about LODs of this shape
8) Support empty triangulations by selection. Use bounding box selection in this case.
9) Add new 'outdisplist' option to XDispaly command to print list of displayed objects to output variable but not to theDI
10) Add new '-noecho' option to vdisplay command to skip printing of displayed objects to theDI
11) Create new RWMesh_TriangulationSource as mesh data wrapper for delayed triangulation loading.
12) Create new RWMesh_TriangulationReader as base interface for reading primitive array from the buffer.
13) Cache nodes/triangles number defined in glTF file
14) Use RWMesh_TriangulationSource class as base of RWGltf_GltfLatePrimitiveArray one and RWMesh_TriangulationReader class as base of RWGltf_TriangulationReader one
15) Add possibilty to support of LODs by glTF reader. It is possible to skip data loading and load them later
16) Add new '-skiplateloading' (to skip triangulation loading), '-keeplate' (to keep information about deferred storage to load/unload triangulation later),
'-toprintdebuginfo' (to print additional debug information) options to ReadGltf command
17) Add new test of glTF late loading
This commit is contained in:
osa
2021-02-26 18:01:11 +03:00
committed by bugmaster
parent 6387996871
commit e816dce36e
46 changed files with 2475 additions and 800 deletions

View File

@@ -59,80 +59,88 @@ Select3D_SensitiveTriangulation::Select3D_SensitiveTriangulation (const Handle(S
const Standard_Boolean theIsInterior)
: Select3D_SensitiveSet (theOwnerId),
myTriangul (theTrg),
myInitLocation (theInitLoc)
myInitLocation (theInitLoc),
myPrimitivesNb (0)
{
myInvInitLocation = myInitLocation.Transformation().Inverted();
mySensType = theIsInterior ? Select3D_TOS_INTERIOR : Select3D_TOS_BOUNDARY;
Standard_Integer aNbTriangles (myTriangul->NbTriangles());
Standard_Integer aNbTriangles = 0;
gp_XYZ aCenter (0.0, 0.0, 0.0);
myPrimitivesNb = theIsInterior ? aNbTriangles : NbOfFreeEdges (theTrg);
myBVHPrimIndexes = new TColStd_HArray1OfInteger(0, myPrimitivesNb - 1);
TColStd_Array1OfInteger& aBVHPrimIdxs = myBVHPrimIndexes->ChangeArray1();
if (!theIsInterior)
if (!theTrg->HasGeometry())
{
Standard_Integer anEdgeIdx = 1;
myFreeEdges = new TColStd_HArray1OfInteger (1, 2 * myPrimitivesNb);
TColStd_Array1OfInteger& aFreeEdges = myFreeEdges->ChangeArray1();
Poly_Connect aPoly (myTriangul);
Standard_Integer aTriangle[3];
Standard_Integer aTrNodeIdx[3];
for (Standard_Integer aTriangleIdx = 1; aTriangleIdx <= aNbTriangles; aTriangleIdx++)
if (myTriangul->HasCachedMinMax())
{
aPoly.Triangles (aTriangleIdx, aTriangle[0], aTriangle[1], aTriangle[2]);
myTriangul->Triangle (aTriangleIdx).Get (aTrNodeIdx[0], aTrNodeIdx[1], aTrNodeIdx[2]);
const gp_Pnt aTriNodes[3] = { myTriangul->Node (aTrNodeIdx[0]), myTriangul->Node (aTrNodeIdx[1]), myTriangul->Node (aTrNodeIdx[2]) };
aCenter += (aTriNodes[0].XYZ() + aTriNodes[1].XYZ()+ aTriNodes[2].XYZ()) / 3.0;
for (Standard_Integer aVertIdx = 0; aVertIdx < 3; aVertIdx++)
aCenter = 0.5 * (myTriangul->CachedMinMax().CornerMin().XYZ()
+ myTriangul->CachedMinMax().CornerMax().XYZ());
}
}
else
{
aNbTriangles = myTriangul->NbTriangles();
myPrimitivesNb = theIsInterior ? aNbTriangles : NbOfFreeEdges (theTrg);
myBVHPrimIndexes = new TColStd_HArray1OfInteger(0, myPrimitivesNb - 1);
TColStd_Array1OfInteger& aBVHPrimIdxs = myBVHPrimIndexes->ChangeArray1();
if (!theIsInterior)
{
Standard_Integer anEdgeIdx = 1;
myFreeEdges = new TColStd_HArray1OfInteger (1, 2 * myPrimitivesNb);
TColStd_Array1OfInteger& aFreeEdges = myFreeEdges->ChangeArray1();
Poly_Connect aPoly (myTriangul);
Standard_Integer aTriangle[3];
Standard_Integer aTrNodeIdx[3];
for (Standard_Integer aTriangleIdx = 1; aTriangleIdx <= aNbTriangles; aTriangleIdx++)
{
Standard_Integer aNextVert = (aVertIdx + 1) % 3;
if (aTriangle[aVertIdx] == 0)
aPoly.Triangles (aTriangleIdx, aTriangle[0], aTriangle[1], aTriangle[2]);
myTriangul->Triangle (aTriangleIdx).Get (aTrNodeIdx[0], aTrNodeIdx[1], aTrNodeIdx[2]);
const gp_Pnt aTriNodes[3] = { myTriangul->Node (aTrNodeIdx[0]), myTriangul->Node (aTrNodeIdx[1]), myTriangul->Node (aTrNodeIdx[2]) };
aCenter += (aTriNodes[0].XYZ() + aTriNodes[1].XYZ()+ aTriNodes[2].XYZ()) / 3.0;
for (Standard_Integer aVertIdx = 0; aVertIdx < 3; aVertIdx++)
{
aFreeEdges (anEdgeIdx) = aTrNodeIdx[aVertIdx];
aFreeEdges (anEdgeIdx+1) = aTrNodeIdx[aNextVert];
anEdgeIdx += 2;
Standard_Integer aNextVert = (aVertIdx + 1) % 3;
if (aTriangle[aVertIdx] == 0)
{
aFreeEdges (anEdgeIdx) = aTrNodeIdx[aVertIdx];
aFreeEdges (anEdgeIdx+1) = aTrNodeIdx[aNextVert];
anEdgeIdx += 2;
}
}
}
}
}
else
{
Standard_Integer aTrNodeIdx[3];
for (Standard_Integer aTrIdx = 1; aTrIdx <= aNbTriangles; aTrIdx++)
else
{
myTriangul->Triangle (aTrIdx).Get (aTrNodeIdx[0], aTrNodeIdx[1], aTrNodeIdx[2]);
const gp_Pnt aTriNodes[3] = { myTriangul->Node (aTrNodeIdx[0]), myTriangul->Node (aTrNodeIdx[1]), myTriangul->Node (aTrNodeIdx[2]) };
aCenter += (aTriNodes[0].XYZ() + aTriNodes[1].XYZ()+ aTriNodes[2].XYZ()) / 3.0;
Standard_Integer aTrNodeIdx[3];
for (Standard_Integer aTrIdx = 1; aTrIdx <= aNbTriangles; aTrIdx++)
{
myTriangul->Triangle (aTrIdx).Get (aTrNodeIdx[0], aTrNodeIdx[1], aTrNodeIdx[2]);
const gp_Pnt aTriNodes[3] = { myTriangul->Node (aTrNodeIdx[0]), myTriangul->Node (aTrNodeIdx[1]), myTriangul->Node (aTrNodeIdx[2]) };
aCenter += (aTriNodes[0].XYZ() + aTriNodes[1].XYZ()+ aTriNodes[2].XYZ()) / 3.0;
}
}
if (theIsInterior)
{
for (Standard_Integer aTriangleIdx = 1; aTriangleIdx <= aNbTriangles; ++aTriangleIdx)
{
aBVHPrimIdxs(aTriangleIdx - 1) = aTriangleIdx - 1;
}
}
else
{
Standard_Integer aStartIdx = myFreeEdges->Lower();
Standard_Integer anEndIdx = myFreeEdges->Upper();
for (Standard_Integer aFreeEdgesIdx = aStartIdx; aFreeEdgesIdx <= anEndIdx; aFreeEdgesIdx += 2)
{
aBVHPrimIdxs((aFreeEdgesIdx - aStartIdx) / 2) = (aFreeEdgesIdx - aStartIdx) / 2;
}
}
}
if (aNbTriangles != 0)
{
aCenter /= aNbTriangles;
}
myCDG3D = gp_Pnt (aCenter);
myBndBox.Clear();
for (Standard_Integer aNodeIdx = 1; aNodeIdx <= myTriangul->NbNodes(); ++aNodeIdx)
{
const gp_Pnt aNode = myTriangul->Node (aNodeIdx);
myBndBox.Add (SelectMgr_Vec3 (aNode.X(), aNode.Y(), aNode.Z()));
}
if (theIsInterior)
{
for (Standard_Integer aTriangleIdx = 1; aTriangleIdx <= aNbTriangles; ++aTriangleIdx)
{
aBVHPrimIdxs (aTriangleIdx - 1) = aTriangleIdx - 1;
}
}
else
{
Standard_Integer aStartIdx = myFreeEdges->Lower();
Standard_Integer anEndIdx = myFreeEdges->Upper();
for (Standard_Integer aFreeEdgesIdx = aStartIdx; aFreeEdgesIdx <= anEndIdx; aFreeEdgesIdx += 2)
{
aBVHPrimIdxs ((aFreeEdgesIdx - aStartIdx) / 2) = (aFreeEdgesIdx - aStartIdx) / 2;
}
}
computeBoundingBox();
}
//=======================================================================
@@ -149,26 +157,30 @@ Select3D_SensitiveTriangulation::Select3D_SensitiveTriangulation (const Handle(S
myTriangul (theTrg),
myInitLocation (theInitLoc),
myCDG3D (theCOG),
myFreeEdges (theFreeEdges)
myFreeEdges (theFreeEdges),
myPrimitivesNb (0)
{
myInvInitLocation = myInitLocation.Transformation().Inverted();
mySensType = theIsInterior ? Select3D_TOS_INTERIOR : Select3D_TOS_BOUNDARY;
myPrimitivesNb = theIsInterior ? theTrg->NbTriangles() : theFreeEdges->Length() / 2;
myBVHPrimIndexes = new TColStd_HArray1OfInteger(0, myPrimitivesNb - 1);
if (theIsInterior)
if (theTrg->HasGeometry())
{
for (Standard_Integer aTriangleIdx = 1; aTriangleIdx <= myPrimitivesNb; ++aTriangleIdx)
myPrimitivesNb = theIsInterior ? theTrg->NbTriangles() : theFreeEdges->Length() / 2;
myBVHPrimIndexes = new TColStd_HArray1OfInteger(0, myPrimitivesNb - 1);
if (theIsInterior)
{
myBVHPrimIndexes->SetValue (aTriangleIdx - 1, aTriangleIdx - 1);
for (Standard_Integer aTriangleIdx = 1; aTriangleIdx <= myPrimitivesNb; ++aTriangleIdx)
{
myBVHPrimIndexes->SetValue (aTriangleIdx - 1, aTriangleIdx - 1);
}
}
}
else
{
Standard_Integer aStartIdx = myFreeEdges->Lower();
Standard_Integer anEndIdx = myFreeEdges->Upper();
for (Standard_Integer aFreeEdgesIdx = aStartIdx; aFreeEdgesIdx <= anEndIdx; aFreeEdgesIdx += 2)
else
{
myBVHPrimIndexes->SetValue ((aFreeEdgesIdx - aStartIdx) / 2, (aFreeEdgesIdx - aStartIdx) / 2);
Standard_Integer aStartIdx = myFreeEdges->Lower();
Standard_Integer anEndIdx = myFreeEdges->Upper();
for (Standard_Integer aFreeEdgesIdx = aStartIdx; aFreeEdgesIdx <= anEndIdx; aFreeEdgesIdx += 2)
{
myBVHPrimIndexes->SetValue ((aFreeEdgesIdx - aStartIdx) / 2, (aFreeEdgesIdx - aStartIdx) / 2);
}
}
}
}
@@ -226,6 +238,37 @@ Select3D_BndBox3d Select3D_SensitiveTriangulation::Box (const Standard_Integer t
return Select3D_BndBox3d (aMinPnt, aMaxPnt);
}
// =======================================================================
// function : Matches
// purpose :
// =======================================================================
Standard_Boolean Select3D_SensitiveTriangulation::Matches (SelectBasics_SelectingVolumeManager& theMgr,
SelectBasics_PickResult& thePickResult)
{
if (myTriangul->HasGeometry())
{
return Select3D_SensitiveSet::Matches (theMgr, thePickResult);
}
Select3D_BndBox3d aBndBox = BoundingBox();
if (!aBndBox.IsValid())
{
return false;
}
if (!theMgr.IsOverlapAllowed()) // check for inclusion
{
bool isInside = true;
return theMgr.Overlaps (aBndBox.CornerMin(), aBndBox.CornerMax(), &isInside) && isInside;
}
if (!theMgr.Overlaps (aBndBox.CornerMin(), aBndBox.CornerMax(), thePickResult)) // check for overlap
{
return false;
}
thePickResult.SetDistToGeomCenter (theMgr.DistToGeometryCenter (myCDG3D));
return true;
}
//=======================================================================
// function : Center
// purpose : Returns geometry center of triangle/edge with index theIdx
@@ -430,24 +473,43 @@ Select3D_BndBox3d Select3D_SensitiveTriangulation::applyTransformation()
//=======================================================================
Select3D_BndBox3d Select3D_SensitiveTriangulation::BoundingBox()
{
if (myBndBox.IsValid())
return applyTransformation();
const Standard_Integer aLower = 1;
const Standard_Integer anUpper = myTriangul->NbNodes();
Select3D_BndBox3d aBndBox;
for (Standard_Integer aNodeIdx = aLower; aNodeIdx <= anUpper; ++aNodeIdx)
if (!myBndBox.IsValid())
{
const gp_Pnt aNode = myTriangul->Node (aNodeIdx);
const SelectMgr_Vec3 aNodeTransf = SelectMgr_Vec3 (aNode.X(), aNode.Y(), aNode.Z());
aBndBox.Add (aNodeTransf);
computeBoundingBox();
}
myBndBox = aBndBox;
return applyTransformation();
}
// =======================================================================
// function : computeBoundingBox
// purpose :
// =======================================================================
void Select3D_SensitiveTriangulation::computeBoundingBox()
{
myBndBox.Clear();
if (myTriangul->HasCachedMinMax())
{
// Use cached MeshData_Data bounding box if it exists
Bnd_Box aCachedBox = myTriangul->CachedMinMax();
myBndBox.Add (SelectMgr_Vec3 (aCachedBox.CornerMin().X(),
aCachedBox.CornerMin().Y(),
aCachedBox.CornerMin().Z()));
myBndBox.Add (SelectMgr_Vec3 (aCachedBox.CornerMax().X(),
aCachedBox.CornerMax().Y(),
aCachedBox.CornerMax().Z()));
return;
}
else if (myTriangul->HasGeometry())
{
for (Standard_Integer aNodeIdx = 1; aNodeIdx <= myTriangul->NbNodes(); ++aNodeIdx)
{
const gp_Pnt aNode = myTriangul->Node (aNodeIdx);
myBndBox.Add (SelectMgr_Vec3 (aNode.X(), aNode.Y(), aNode.Z()));
}
}
}
//=======================================================================
// function : CenterOfGeometry
// purpose : Returns center of triangulation. If location transformation

View File

@@ -119,8 +119,15 @@ public:
//! Dumps the content of me into the stream
Standard_EXPORT virtual void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const Standard_OVERRIDE;
//! Checks whether one or more entities of the set overlap current selecting volume.
Standard_EXPORT virtual Standard_Boolean Matches (SelectBasics_SelectingVolumeManager& theMgr,
SelectBasics_PickResult& thePickResult) Standard_OVERRIDE;
protected:
//! Compute bounding box.
void computeBoundingBox();
//! Inner function for transformation application to bounding
//! box of the triangulation
Select3D_BndBox3d applyTransformation();