Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
b079fb987This file is pinned to the selected release. Download the original to open it in your design tool.
// Created on: 2014-10-20
// Created by: Denis BOGOLEPOV
// Copyright (c) 2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <BRepExtrema_TriangleSet.hxx>
#include <BRep_Tool.hxx>
#include <BVH_LinearBuilder.hxx>
#include <Poly_Triangulation.hxx>
IMPLEMENT_STANDARD_RTTIEXT(BRepExtrema_TriangleSet, BVH_PrimitiveSet3d)
//=======================================================================
//function : BRepExtrema_TriangleSet
//purpose : Creates empty triangle set
//=======================================================================
BRepExtrema_TriangleSet::BRepExtrema_TriangleSet()
{
// Set default builder - linear BVH (LBVH)
myBuilder = new BVH_LinearBuilder<Standard_Real, 3> (BVH_Constants_LeafNodeSizeDefault, BVH_Constants_MaxTreeDepth);
}
//=======================================================================
//function : BRepExtrema_TriangleSet
//purpose : Creates triangle set from the given face
//=======================================================================
BRepExtrema_TriangleSet::BRepExtrema_TriangleSet (const BRepExtrema_ShapeList& theFaces)
{
// Set default builder - linear BVH (LBVH)
myBuilder = new BVH_LinearBuilder<Standard_Real, 3> (BVH_Constants_LeafNodeSizeDefault, BVH_Constants_MaxTreeDepth);
Init (theFaces);
}
//=======================================================================
//function : ~BRepExtrema_TriangleSet
//purpose : Releases resources of triangle set
//=======================================================================
BRepExtrema_TriangleSet::~BRepExtrema_TriangleSet()
{
//
}
//=======================================================================
//function : Size
//purpose : Returns total number of triangles
//=======================================================================
Standard_Integer BRepExtrema_TriangleSet::Size() const
{
return static_cast<Standard_Integer> (myTriangles.size());
}
//=======================================================================
//function : Box
//purpose : Returns AABB of the given triangle
//=======================================================================
BVH_Box<Standard_Real, 3> BRepExtrema_TriangleSet::Box (const Standard_Integer theIndex) const
{
const BVH_Vec4i& aTriangle = myTriangles[theIndex];
BVH_Vec3d aMinPnt = myVertexArray[aTriangle.x()].cwiseMin (
myVertexArray[aTriangle.y()].cwiseMin (myVertexArray[aTriangle.z()]));
BVH_Vec3d aMaxPnt = myVertexArray[aTriangle.x()].cwiseMax (
myVertexArray[aTriangle.y()].cwiseMax (myVertexArray[aTriangle.z()]));
return BVH_Box<Standard_Real, 3> (aMinPnt, aMaxPnt);
}
//=======================================================================
//function : Center
//purpose : Returns centroid position along specified axis
//=======================================================================
Standard_Real BRepExtrema_TriangleSet::Center (const Standard_Integer theIndex, const Standard_Integer theAxis) const
{
const BVH_Vec4i& aTriangle = myTriangles[theIndex];
if (theAxis == 0)
{
return (1.0 / 3.0) * (myVertexArray[aTriangle.x()].x() +
myVertexArray[aTriangle.y()].x() +
myVertexArray[aTriangle.z()].x());
}
else if (theAxis == 1)
{
return (1.0 / 3.0) * (myVertexArray[aTriangle.x()].y() +
myVertexArray[aTriangle.y()].y() +
myVertexArray[aTriangle.z()].y());
}
else
{
return (1.0 / 3.0) * (myVertexArray[aTriangle.x()].z() +
myVertexArray[aTriangle.y()].z() +
myVertexArray[aTriangle.z()].z());
}
}
//=======================================================================
//function : Swap
//purpose : Swaps indices of two specified triangles
//=======================================================================
void BRepExtrema_TriangleSet::Swap (const Standard_Integer theIndex1, const Standard_Integer theIndex2)
{
std::swap (myTriangles[theIndex1],
myTriangles[theIndex2]);
}
//=======================================================================
//function : GetFaceID
//purpose : Returns face ID of the given triangle
//=======================================================================
Standard_Integer BRepExtrema_TriangleSet::GetFaceID (const Standard_Integer theIndex) const
{
return myTriangles[theIndex].w();
}
//=======================================================================
//function : GetVertices
//purpose : Returns vertices of the given triangle
//=======================================================================
void BRepExtrema_TriangleSet::GetVertices (const Standard_Integer theIndex,
BVH_Vec3d& theVertex1,
BVH_Vec3d& theVertex2,
BVH_Vec3d& theVertex3) const
{
BVH_Vec4i aTriangle = myTriangles[theIndex];
theVertex1 = myVertexArray[aTriangle.x()];
theVertex2 = myVertexArray[aTriangle.y()];
theVertex3 = myVertexArray[aTriangle.z()];
}
//=======================================================================
//function : Clear
//purpose : Clears triangle set data
//=======================================================================
void BRepExtrema_TriangleSet::Clear()
{
BVH_Array4i anEmptyTriangles;
myTriangles.swap (anEmptyTriangles);
BVH_Array3d anEmptyVertexArray;
myVertexArray.swap (anEmptyVertexArray);
}
//=======================================================================
//function : Init
//purpose : Initializes triangle set
//=======================================================================
Standard_Boolean BRepExtrema_TriangleSet::Init (const BRepExtrema_ShapeList& theFaces)
{
Clear();
for (Standard_Integer aFaceIdx = 0; aFaceIdx < theFaces.Size(); ++aFaceIdx)
{
TopLoc_Location aLocation;
Handle(Poly_Triangulation) aTriangulation =
BRep_Tool::Triangulation (theFaces (aFaceIdx), aLocation);
if (aTriangulation.IsNull())
{
return Standard_False;
}
const Standard_Integer aVertOffset =
static_cast<Standard_Integer> (myVertexArray.size()) - 1;
for (Standard_Integer aVertIdx = 1; aVertIdx <= aTriangulation->NbNodes(); ++aVertIdx)
{
gp_Pnt aVertex = aTriangulation->Node (aVertIdx);
aVertex.Transform (aLocation.Transformation());
myVertexArray.push_back (BVH_Vec3d (aVertex.X(), aVertex.Y(), aVertex.Z()));
}
for (Standard_Integer aTriIdx = 1; aTriIdx <= aTriangulation->NbTriangles(); ++aTriIdx)
{
Standard_Integer aVertex1, aVertex2, aVertex3;
aTriangulation->Triangle (aTriIdx).Get (aVertex1, aVertex2, aVertex3);
myTriangles.push_back (BVH_Vec4i (aVertex1 + aVertOffset,
aVertex2 + aVertOffset,
aVertex3 + aVertOffset,
aFaceIdx));
}
}
MarkDirty(); // needs BVH rebuilding
Standard_ASSERT_RETURN (!BVH().IsNull(),
"Error: Failed to build BVH for primitive set", Standard_False);
return Standard_True;
}