mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-09 13:22:24 +03:00
Integration of OCCT 6.5.0 from SVN
This commit is contained in:
750
src/Poly/Poly_CoherentTriangulation.cxx
Executable file
750
src/Poly/Poly_CoherentTriangulation.cxx
Executable file
@@ -0,0 +1,750 @@
|
||||
// File: Poly_CoherentTriangulation.cxx
|
||||
// Created: 08.12.07 13:19
|
||||
// Author: Alexander GRIGORIEV
|
||||
// Copyright: Open CASCADE SAS 2007
|
||||
|
||||
#include <Poly_CoherentTriangulation.hxx>
|
||||
#include <Poly_Triangulation.hxx>
|
||||
#include <Poly_Array1OfTriangle.hxx>
|
||||
#include <NCollection_List.hxx>
|
||||
#include <Precision.hxx>
|
||||
#include <Standard_ProgramError.hxx>
|
||||
#include <TColgp_Array1OfPnt.hxx>
|
||||
#include <TColgp_Array1OfPnt2d.hxx>
|
||||
#include <TShort_Array1OfShortReal.hxx>
|
||||
#include <TShort_HArray1OfShortReal.hxx>
|
||||
|
||||
IMPLEMENT_STANDARD_HANDLE (Poly_CoherentTriangulation, Standard_Transient)
|
||||
IMPLEMENT_STANDARD_RTTIEXT (Poly_CoherentTriangulation, Standard_Transient)
|
||||
|
||||
//=======================================================================
|
||||
//function : Poly_CoherentTriangulation
|
||||
//purpose : Empty constructor
|
||||
//=======================================================================
|
||||
|
||||
Poly_CoherentTriangulation::Poly_CoherentTriangulation
|
||||
(const Handle_NCollection_BaseAllocator& theAlloc)
|
||||
: myAlloc (theAlloc.IsNull() ? NCollection_BaseAllocator::CommonBaseAllocator()
|
||||
: theAlloc),
|
||||
myDeflection (0.)
|
||||
{}
|
||||
|
||||
//=======================================================================
|
||||
//function : Poly_CoherentTriangulation
|
||||
//purpose : Constructor
|
||||
//=======================================================================
|
||||
|
||||
Poly_CoherentTriangulation::Poly_CoherentTriangulation
|
||||
(const Handle(Poly_Triangulation)& theTriangulation,
|
||||
const Handle_NCollection_BaseAllocator& theAlloc)
|
||||
: myAlloc (theAlloc.IsNull() ? NCollection_BaseAllocator::CommonBaseAllocator()
|
||||
: theAlloc)
|
||||
{
|
||||
if (theTriangulation.IsNull() == Standard_False) {
|
||||
const TColgp_Array1OfPnt& arrNodes = theTriangulation->Nodes();
|
||||
const Poly_Array1OfTriangle& arrTriangle = theTriangulation->Triangles();
|
||||
const Standard_Integer nNodes = theTriangulation->NbNodes();
|
||||
const Standard_Integer nTri = theTriangulation->NbTriangles();
|
||||
Standard_Integer i;
|
||||
|
||||
// Copy the nodes
|
||||
for (i = 0; i < nNodes; i++) {
|
||||
const Standard_Integer anOldInd = i + arrNodes.Lower();
|
||||
const Standard_Integer aNewInd = SetNode(arrNodes(anOldInd).XYZ(), i);
|
||||
Poly_CoherentNode& aCopiedNode = myNodes(aNewInd);
|
||||
aCopiedNode.SetIndex(anOldInd);
|
||||
}
|
||||
|
||||
// Copy the triangles
|
||||
for (i = 0; i < nTri; i++) {
|
||||
Standard_Integer iNode[3];
|
||||
arrTriangle(i + arrTriangle.Lower()).Get(iNode[0], iNode[1], iNode[2]);
|
||||
if (iNode[0] != iNode[1] && iNode[1] != iNode[2] && iNode[2] != iNode[0])
|
||||
AddTriangle (iNode[0]-1, iNode[1]-1, iNode[2]-1);
|
||||
}
|
||||
|
||||
// Copy UV coordinates of nodes
|
||||
if (theTriangulation->HasUVNodes()) {
|
||||
const TColgp_Array1OfPnt2d& arrNodes2d = theTriangulation->UVNodes();
|
||||
for (i = 0; i < nNodes; i++) {
|
||||
const gp_Pnt2d& anUV = arrNodes2d(i + arrNodes2d.Lower());
|
||||
myNodes(i).SetUV(anUV.X(), anUV.Y());
|
||||
}
|
||||
}
|
||||
|
||||
// Copy the normals at nodes
|
||||
if (theTriangulation->HasNormals()) {
|
||||
const TShort_Array1OfShortReal& arrNorm = theTriangulation->Normals();
|
||||
for (i = 0; i < nNodes; i++) {
|
||||
const gp_XYZ aNormal (arrNorm(3 * i + 0 + arrNorm.Lower()),
|
||||
arrNorm(3 * i + 1 + arrNorm.Lower()),
|
||||
arrNorm(3 * i + 2 + arrNorm.Lower()));
|
||||
myNodes(i).SetNormal(aNormal);
|
||||
}
|
||||
}
|
||||
myDeflection = theTriangulation->Deflection();
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ~Poly_CoherentTriangulation()
|
||||
//purpose : Destructor
|
||||
//=======================================================================
|
||||
|
||||
Poly_CoherentTriangulation::~Poly_CoherentTriangulation ()
|
||||
{
|
||||
NCollection_Vector<Poly_CoherentNode>::Iterator anIter (myNodes);
|
||||
for (; anIter.More(); anIter.Next()) {
|
||||
anIter.ChangeValue().Clear(myAlloc);
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : GetTriangulation
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Handle_Poly_Triangulation Poly_CoherentTriangulation::GetTriangulation() const
|
||||
{
|
||||
Handle(Poly_Triangulation) aResult;
|
||||
const Standard_Integer nNodes = NNodes();
|
||||
const Standard_Integer nTriangles = NTriangles();
|
||||
if (nNodes > 0 && nTriangles > 0) {
|
||||
aResult = new Poly_Triangulation(nNodes, nTriangles, Standard_True);
|
||||
const Handle(TShort_HArray1OfShortReal) harrNormal =
|
||||
new TShort_HArray1OfShortReal(1, 3 * nNodes);
|
||||
Standard_ShortReal * arrNormal = &harrNormal->ChangeValue(1);
|
||||
|
||||
TColgp_Array1OfPnt& arrNodes = aResult->ChangeNodes();
|
||||
TColgp_Array1OfPnt2d& arrNodesUV = aResult->ChangeUVNodes();
|
||||
Poly_Array1OfTriangle& arrTriangle = aResult->ChangeTriangles();
|
||||
NCollection_Vector<Standard_Integer> vecNodeId;
|
||||
Standard_Integer i, aCount(0);
|
||||
Standard_Boolean hasUV (Standard_False);
|
||||
Standard_Boolean hasNormals (Standard_False);
|
||||
|
||||
// Copy the nodes (3D and 2D coordinates)
|
||||
for (i = 0; i < myNodes.Length(); i++) {
|
||||
const Poly_CoherentNode& aNode = myNodes(i);
|
||||
if (aNode.IsFreeNode())
|
||||
vecNodeId.SetValue(i, 0);
|
||||
else {
|
||||
const gp_XYZ aNormal = aNode.GetNormal();
|
||||
arrNormal[3 * aCount + 0] = static_cast<Standard_ShortReal>(aNormal.X());
|
||||
arrNormal[3 * aCount + 1] = static_cast<Standard_ShortReal>(aNormal.Y());
|
||||
arrNormal[3 * aCount + 2] = static_cast<Standard_ShortReal>(aNormal.Z());
|
||||
|
||||
vecNodeId.SetValue(i, ++aCount);
|
||||
arrNodes.SetValue(aCount, aNode);
|
||||
|
||||
arrNodesUV.SetValue(aCount, gp_Pnt2d(aNode.GetU(), aNode.GetV()));
|
||||
if (aNode.GetU()*aNode.GetU() + aNode.GetV()*aNode.GetV() >
|
||||
Precision::Confusion())
|
||||
hasUV = Standard_True;
|
||||
if (aNormal.SquareModulus() > Precision::Confusion())
|
||||
hasNormals = Standard_True;
|
||||
}
|
||||
}
|
||||
if (hasUV == Standard_False)
|
||||
aResult->RemoveUVNodes();
|
||||
|
||||
// Copy the triangles
|
||||
aCount = 0;
|
||||
NCollection_Vector<Poly_CoherentTriangle>::Iterator anIterT (myTriangles);
|
||||
for (; anIterT.More(); anIterT.Next()) {
|
||||
const Poly_CoherentTriangle& aTri = anIterT.Value();
|
||||
if (aTri.IsEmpty() == Standard_False) {
|
||||
const Poly_Triangle aPolyTriangle (vecNodeId(aTri.Node(0)),
|
||||
vecNodeId(aTri.Node(1)),
|
||||
vecNodeId(aTri.Node(2)));
|
||||
arrTriangle.SetValue(++aCount, aPolyTriangle);
|
||||
}
|
||||
}
|
||||
if (hasNormals)
|
||||
aResult->SetNormals (harrNormal);
|
||||
|
||||
aResult->Deflection(myDeflection);
|
||||
}
|
||||
|
||||
return aResult;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : GetFreeNodes
|
||||
//purpose : Create a list of free nodes.
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean Poly_CoherentTriangulation::GetFreeNodes
|
||||
(NCollection_List<Standard_Integer>& lstNodes) const
|
||||
{
|
||||
lstNodes.Clear();
|
||||
Standard_Integer i;
|
||||
for (i = 0; i < myNodes.Length(); i++) {
|
||||
const Poly_CoherentNode& aNode = myNodes(i);
|
||||
if (aNode.IsFreeNode())
|
||||
lstNodes.Append(i);
|
||||
}
|
||||
return !lstNodes.IsEmpty();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : RemoveDegenerated
|
||||
//purpose : Find and remove degenerated triangles in Triangulation.
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean Poly_CoherentTriangulation::RemoveDegenerated
|
||||
(const Standard_Real theTol,
|
||||
NCollection_List<Poly_CoherentTriangulation::TwoIntegers> * pLstRemovedNode)
|
||||
{
|
||||
Standard_Boolean aResult(Standard_False);
|
||||
const Standard_Real aTol2 = theTol * theTol;
|
||||
const Standard_Integer ind0[] = {2, 0, 1, 2, 0};
|
||||
const Standard_Integer * ind = &ind0[1];
|
||||
if (pLstRemovedNode)
|
||||
pLstRemovedNode->Clear();
|
||||
|
||||
//NCollection_Vector<Poly_CoherentTriangle>::Iterator anIterT(myTriangles);
|
||||
Poly_CoherentTriangulation::IteratorOfTriangle anIterT(this);
|
||||
for (; anIterT.More(); anIterT.Next()) {
|
||||
Poly_CoherentTriangle& aTri = anIterT.ChangeValue();
|
||||
Poly_CoherentNode * pNode[3] = {
|
||||
&ChangeNode(aTri.Node(0)),
|
||||
&ChangeNode(aTri.Node(1)),
|
||||
&ChangeNode(aTri.Node(2))
|
||||
};
|
||||
const Standard_Real aLen2[3] = {
|
||||
pNode[2]->Subtracted(* pNode[1]).SquareModulus(),
|
||||
pNode[0]->Subtracted(* pNode[2]).SquareModulus(),
|
||||
pNode[1]->Subtracted(* pNode[0]).SquareModulus()
|
||||
};
|
||||
for (Standard_Integer i = 0; i < 3; i++) {
|
||||
if (aLen2[i] < aTol2) {
|
||||
const Standard_Integer im1(aTri.Node(ind[i-1]));
|
||||
const Standard_Integer ip1(aTri.Node(ind[i+1]));
|
||||
|
||||
// Disconnect from both neighbours
|
||||
Poly_CoherentTriangle * pTriConn[2] = {
|
||||
const_cast<Poly_CoherentTriangle *>(aTri.GetConnectedTri(ind[i-1])),
|
||||
const_cast<Poly_CoherentTriangle *>(aTri.GetConnectedTri(ind[i+1]))
|
||||
};
|
||||
RemoveTriangle(aTri);
|
||||
|
||||
// Reconnect all triangles from Node(ind[i+1]) to Node(ind[i-1])
|
||||
Poly_CoherentTriPtr::Iterator anIterConn =
|
||||
pNode[ind[i+1]]->TriangleIterator();
|
||||
for (; anIterConn.More(); anIterConn.Next()) {
|
||||
Poly_CoherentTriangle& aTriConn = anIterConn.ChangeValue();
|
||||
if (&aTriConn != &aTri) {
|
||||
if (aTriConn.Node(0) == ip1)
|
||||
aTriConn.myNodes[0] = im1;
|
||||
else if (aTriConn.Node(1) == ip1)
|
||||
aTriConn.myNodes[1] = im1;
|
||||
else if (aTriConn.Node(2) == ip1)
|
||||
aTriConn.myNodes[2] = im1;
|
||||
pNode[ind[i+1]]->RemoveTriangle(aTriConn, myAlloc);
|
||||
pNode[ind[i-1]]->AddTriangle(aTriConn, myAlloc);
|
||||
}
|
||||
}
|
||||
// Set the new mutual connection between the neighbours of the
|
||||
// removed degenerated triangle.
|
||||
if (pTriConn[0] && pTriConn[1]) {
|
||||
pTriConn[0]->SetConnection(* pTriConn[1]);
|
||||
}
|
||||
if (pLstRemovedNode) {
|
||||
pLstRemovedNode->Append(TwoIntegers(ip1, im1));
|
||||
}
|
||||
aResult = Standard_True;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return aResult;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : IteratorOfTriangle::IteratorOfTriangle
|
||||
//purpose : Constructor
|
||||
//=======================================================================
|
||||
|
||||
Poly_CoherentTriangulation::IteratorOfTriangle::IteratorOfTriangle
|
||||
(const Handle_Poly_CoherentTriangulation& theTri)
|
||||
{
|
||||
if (!theTri.IsNull()) {
|
||||
Init(theTri->myTriangles);
|
||||
while (More()) {
|
||||
const Poly_CoherentTriangle& aTri = Value();
|
||||
if (aTri.IsEmpty() == Standard_False)
|
||||
break;
|
||||
Poly_BaseIteratorOfCoherentTriangle::Next();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : IteratorOfTriangle::Next
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void Poly_CoherentTriangulation::IteratorOfTriangle::Next()
|
||||
{
|
||||
Poly_BaseIteratorOfCoherentTriangle::Next();
|
||||
while (More()) {
|
||||
const Poly_CoherentTriangle& aTri = Value();
|
||||
if (aTri.IsEmpty() == Standard_False)
|
||||
break;
|
||||
Poly_BaseIteratorOfCoherentTriangle::Next();
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : IteratorOfNode::IteratorOfNode
|
||||
//purpose : Constructor
|
||||
//=======================================================================
|
||||
|
||||
Poly_CoherentTriangulation::IteratorOfNode::IteratorOfNode
|
||||
(const Handle_Poly_CoherentTriangulation& theTri)
|
||||
{
|
||||
if (!theTri.IsNull()) {
|
||||
Init(theTri->myNodes);
|
||||
while (More()) {
|
||||
if (Value().IsFreeNode() == Standard_False)
|
||||
break;
|
||||
Poly_BaseIteratorOfCoherentNode::Next();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : IteratorOfNode::Next
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void Poly_CoherentTriangulation::IteratorOfNode::Next()
|
||||
{
|
||||
Poly_BaseIteratorOfCoherentNode::Next();
|
||||
while (More()) {
|
||||
if (Value().IsFreeNode() == Standard_False)
|
||||
break;
|
||||
Poly_BaseIteratorOfCoherentNode::Next();
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : IteratorOfLink::IteratorOfLink
|
||||
//purpose : Constructor
|
||||
//=======================================================================
|
||||
|
||||
Poly_CoherentTriangulation::IteratorOfLink::IteratorOfLink
|
||||
(const Handle_Poly_CoherentTriangulation& theTri)
|
||||
{
|
||||
if (!theTri.IsNull()) {
|
||||
Init(theTri->myLinks);
|
||||
while (More()) {
|
||||
if (Value().IsEmpty() == Standard_False)
|
||||
break;
|
||||
Poly_BaseIteratorOfCoherentLink::Next();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : IteratorOfLink::Next
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void Poly_CoherentTriangulation::IteratorOfLink::Next()
|
||||
{
|
||||
Poly_BaseIteratorOfCoherentLink::Next();
|
||||
while (More()) {
|
||||
if (Value().IsEmpty() == Standard_False)
|
||||
break;
|
||||
Poly_BaseIteratorOfCoherentLink::Next();
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : NNodes
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Integer Poly_CoherentTriangulation::NNodes () const
|
||||
{
|
||||
Standard_Integer aCount(0);
|
||||
NCollection_Vector<Poly_CoherentNode>::Iterator anIter (myNodes);
|
||||
for (; anIter.More(); anIter.Next())
|
||||
if (anIter.Value().IsFreeNode() == Standard_False)
|
||||
aCount++;
|
||||
return aCount;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : NTriangles
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Integer Poly_CoherentTriangulation::NTriangles () const
|
||||
{
|
||||
Standard_Integer aCount(0);
|
||||
NCollection_Vector<Poly_CoherentTriangle>::Iterator anIter (myTriangles);
|
||||
for (; anIter.More(); anIter.Next()) {
|
||||
const Poly_CoherentTriangle& aTri = anIter.Value();
|
||||
if (aTri.IsEmpty() == Standard_False)
|
||||
aCount++;
|
||||
}
|
||||
return aCount;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : NLinks
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Integer Poly_CoherentTriangulation::NLinks () const
|
||||
{
|
||||
Standard_Integer aCount(0);
|
||||
NCollection_Vector<Poly_CoherentLink>::Iterator anIter (myLinks);
|
||||
for (; anIter.More(); anIter.Next()) {
|
||||
if (anIter.Value().IsEmpty() == Standard_False)
|
||||
aCount++;
|
||||
}
|
||||
return aCount;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SetNode
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Integer Poly_CoherentTriangulation::SetNode
|
||||
(const gp_XYZ& thePnt,
|
||||
const Standard_Integer iNode)
|
||||
{
|
||||
Standard_Integer aResult = myNodes.Length();
|
||||
if (iNode < 0)
|
||||
myNodes.Append(Poly_CoherentNode(thePnt));
|
||||
else {
|
||||
myNodes.SetValue(iNode, Poly_CoherentNode(thePnt));
|
||||
aResult = iNode;
|
||||
}
|
||||
return aResult;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : RemoveTriangle
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean Poly_CoherentTriangulation::RemoveTriangle
|
||||
(Poly_CoherentTriangle& theTriangle)
|
||||
{
|
||||
Standard_Boolean aResult(Standard_False);
|
||||
for (Standard_Integer i = 0; i < 3; i++) {
|
||||
if (theTriangle.Node(i) >= 0) {
|
||||
Poly_CoherentNode& aNode = myNodes(theTriangle.Node(i));
|
||||
if (aNode.RemoveTriangle(theTriangle, myAlloc)) {
|
||||
theTriangle.myNodes[i] = -1;
|
||||
aResult = Standard_True;
|
||||
}
|
||||
// If Links exist in this Triangulation, remove or update a Link
|
||||
Poly_CoherentLink * aLink =
|
||||
const_cast<Poly_CoherentLink *>(theTriangle.mypLink[i]);
|
||||
if (aLink) {
|
||||
const Poly_CoherentTriangle * pTriOpp = theTriangle.GetConnectedTri(i);
|
||||
Standard_Boolean toRemoveLink(Standard_True);
|
||||
if (pTriOpp != 0L) {
|
||||
// A neighbour is detected. If a Link exists on it, update it,
|
||||
// otherwise remove this link
|
||||
for (Standard_Integer j = 0; j < 3; j++) {
|
||||
if (aLink == pTriOpp->GetLink(j)) {
|
||||
if (aLink->OppositeNode(0) == theTriangle.Node(i)) {
|
||||
aLink->myOppositeNode[0] = 0L;
|
||||
toRemoveLink = Standard_False;
|
||||
} else if (aLink->OppositeNode(1) == theTriangle.Node(i)) {
|
||||
aLink->myOppositeNode[1] = 0L;
|
||||
toRemoveLink = Standard_False;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (toRemoveLink)
|
||||
RemoveLink(* aLink);
|
||||
}
|
||||
}
|
||||
theTriangle.RemoveConnection(i);
|
||||
}
|
||||
return aResult;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : AddTriangle
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Poly_CoherentTriangle * Poly_CoherentTriangulation::AddTriangle
|
||||
(const Standard_Integer iNode0,
|
||||
const Standard_Integer iNode1,
|
||||
const Standard_Integer iNode2)
|
||||
{
|
||||
Poly_CoherentTriangle * pTriangle = 0L;
|
||||
if (iNode0 >= 0 && iNode1 >= 0 && iNode2 >= 0)
|
||||
{
|
||||
pTriangle = & myTriangles.Append(Poly_CoherentTriangle());
|
||||
ReplaceNodes(*pTriangle, iNode0, iNode1, iNode2);
|
||||
}
|
||||
return pTriangle;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ReplaceNodes
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean Poly_CoherentTriangulation::ReplaceNodes
|
||||
(Poly_CoherentTriangle& theTriangle,
|
||||
const Standard_Integer iNode0,
|
||||
const Standard_Integer iNode1,
|
||||
const Standard_Integer iNode2)
|
||||
{
|
||||
if (!theTriangle.IsEmpty())
|
||||
RemoveTriangle(theTriangle);
|
||||
if (iNode0 >= 0 && iNode1 >= 0 && iNode2 >= 0)
|
||||
{
|
||||
theTriangle = Poly_CoherentTriangle (iNode0, iNode1, iNode2);
|
||||
for (Standard_Integer i = 0; i < 3; i++) {
|
||||
Poly_CoherentNode& aNode = myNodes(theTriangle.Node(i));
|
||||
Poly_CoherentTriPtr::Iterator anIterT = aNode.TriangleIterator();
|
||||
for (; anIterT.More(); anIterT.Next()) {
|
||||
anIterT.ChangeValue().SetConnection(theTriangle);
|
||||
}
|
||||
aNode.AddTriangle(theTriangle, myAlloc);
|
||||
}
|
||||
|
||||
// If Links exist in this Triangulation, create or update a Link
|
||||
if (myLinks.Length() > 0) {
|
||||
for (Standard_Integer i = 0; i < 3; i++) {
|
||||
const Poly_CoherentTriangle * pTriOpp = theTriangle.GetConnectedTri(i);
|
||||
Standard_Boolean toAddLink(Standard_True);
|
||||
if (pTriOpp != 0L) {
|
||||
// A neighbour is detected. If a Link exists on it, update it,
|
||||
// otherwise create a new link.
|
||||
for (Standard_Integer j = 0; j < 3; j++) {
|
||||
if (theTriangle.Node(i) == pTriOpp->GetConnectedNode(j)) {
|
||||
Poly_CoherentLink * aLink =
|
||||
const_cast<Poly_CoherentLink *>(pTriOpp->GetLink(j));
|
||||
if (aLink != 0L) {
|
||||
if (aLink->OppositeNode(0) == pTriOpp->Node(j)) {
|
||||
aLink->myOppositeNode[1] = theTriangle.Node(i);
|
||||
toAddLink = Standard_False;
|
||||
} else if (aLink->OppositeNode(1) == pTriOpp->Node(j)) {
|
||||
aLink->myOppositeNode[0] = theTriangle.Node(i);
|
||||
toAddLink = Standard_False;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (toAddLink) {
|
||||
// No neighbor on this side, the new Link is created.
|
||||
AddLink (theTriangle, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
return Standard_True;
|
||||
}
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : RemoveLink
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void Poly_CoherentTriangulation::RemoveLink (Poly_CoherentLink& theLink)
|
||||
{
|
||||
const Poly_CoherentTriangle * pTri[2] = { 0L, 0L };
|
||||
if (FindTriangle (theLink, pTri)) {
|
||||
for (Standard_Integer i = 0; i < 2; i++) {
|
||||
const Standard_Integer iNode = theLink.OppositeNode(i);
|
||||
if (iNode >= 0 && pTri[i] != 0L) {
|
||||
if (iNode == pTri[i]->Node(0))
|
||||
const_cast<Poly_CoherentTriangle *>(pTri[i])->mypLink[0] = 0L;
|
||||
else if (iNode == pTri[i]->Node(1))
|
||||
const_cast<Poly_CoherentTriangle *>(pTri[i])->mypLink[1] = 0L;
|
||||
else if (iNode == pTri[i]->Node(2))
|
||||
const_cast<Poly_CoherentTriangle *>(pTri[i])->mypLink[2] = 0L;
|
||||
else
|
||||
Standard_ProgramError("Poly_CoherentTriangulation::RemoveLink: "
|
||||
" wrong connectivity between triangles");
|
||||
}
|
||||
}
|
||||
}
|
||||
theLink = Poly_CoherentLink();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : AddLink
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Poly_CoherentLink * Poly_CoherentTriangulation::AddLink
|
||||
(const Poly_CoherentTriangle& theTri,
|
||||
const Standard_Integer theConn)
|
||||
{
|
||||
Poly_CoherentLink * pLink = 0L;
|
||||
if (theTri.IsEmpty() == Standard_False) {
|
||||
pLink = &myLinks.Append(Poly_CoherentLink (theTri, theConn));
|
||||
const_cast<Poly_CoherentTriangle&>(theTri).mypLink[theConn] = pLink;
|
||||
const Poly_CoherentTriangle* pTriOpp = theTri.GetConnectedTri(theConn);
|
||||
|
||||
if(!pTriOpp) return pLink;
|
||||
if(pTriOpp->IsEmpty()) return pLink;
|
||||
|
||||
if (pTriOpp) {
|
||||
if (pTriOpp->Node(0) == theTri.GetConnectedNode(theConn))
|
||||
const_cast<Poly_CoherentTriangle *>(pTriOpp)->mypLink[0] = pLink;
|
||||
else if (pTriOpp->Node(1) == theTri.GetConnectedNode(theConn))
|
||||
const_cast<Poly_CoherentTriangle *>(pTriOpp)->mypLink[1] = pLink;
|
||||
else if (pTriOpp->Node(2) == theTri.GetConnectedNode(theConn))
|
||||
const_cast<Poly_CoherentTriangle *>(pTriOpp)->mypLink[2] = pLink;
|
||||
else
|
||||
Standard_ProgramError::Raise("Poly_CoherentTriangulation::AddLink: "
|
||||
"Bad connectivity of triangles");
|
||||
}
|
||||
}
|
||||
return pLink;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FindTriangle
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean Poly_CoherentTriangulation::FindTriangle
|
||||
(const Poly_CoherentLink& theLink,
|
||||
const Poly_CoherentTriangle* pTri[2]) const
|
||||
{
|
||||
pTri[0] = 0L;
|
||||
pTri[1] = 0L;
|
||||
const Standard_Integer iNode0 = theLink.Node(0);
|
||||
if (theLink.IsEmpty() == Standard_False &&
|
||||
iNode0 < myNodes.Length() && theLink.Node(1) < myNodes.Length())
|
||||
{
|
||||
Poly_CoherentTriPtr::Iterator anIter0 = myNodes(iNode0).TriangleIterator();
|
||||
for (; anIter0.More(); anIter0.Next()) {
|
||||
const Poly_CoherentTriangle& aTri = anIter0.Value();
|
||||
if (aTri.Node(0) == iNode0) {
|
||||
if (aTri.Node(1) == theLink.Node(1))
|
||||
pTri[0] = &aTri;
|
||||
else if (aTri.Node(2) == theLink.Node(1))
|
||||
pTri[1] = &aTri;
|
||||
} else if (aTri.Node(1) == iNode0) {
|
||||
if (aTri.Node(2) == theLink.Node(1))
|
||||
pTri[0] = &aTri;
|
||||
else if (aTri.Node(0) == theLink.Node(1))
|
||||
pTri[1] = &aTri;
|
||||
} else if (aTri.Node(2) == iNode0) {
|
||||
if (aTri.Node(0) == theLink.Node(1))
|
||||
pTri[0] = &aTri;
|
||||
else if (aTri.Node(1) == theLink.Node(1))
|
||||
pTri[1] = &aTri;
|
||||
} else
|
||||
Standard_ProgramError("Poly_CoherentTriangulation::FindTriangle : "
|
||||
" Data incoherence detected");
|
||||
if (pTri[0] && pTri[1])
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (pTri[0] != 0L || pTri[1] != 0L);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ComputeLinks
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Integer Poly_CoherentTriangulation::ComputeLinks ()
|
||||
{
|
||||
myLinks.Clear();
|
||||
NCollection_Vector<Poly_CoherentTriangle>::Iterator anIter (myTriangles);
|
||||
for (; anIter.More(); anIter.Next()) {
|
||||
const Poly_CoherentTriangle& aTriangle = anIter.Value();
|
||||
|
||||
if(aTriangle.IsEmpty()) continue;
|
||||
|
||||
if (aTriangle.Node(0) < aTriangle.Node(1))
|
||||
AddLink (aTriangle, 2);
|
||||
if (aTriangle.Node(1) < aTriangle.Node(2))
|
||||
AddLink (aTriangle, 0);
|
||||
if (aTriangle.Node(2) < aTriangle.Node(0))
|
||||
AddLink (aTriangle, 1);
|
||||
}
|
||||
// Above algorithm does not create all boundary links, so
|
||||
// it is necessary to check triangles and add absentee links
|
||||
anIter.Init(myTriangles);
|
||||
Standard_Integer i;
|
||||
for (; anIter.More(); anIter.Next()) {
|
||||
Poly_CoherentTriangle& aTriangle = anIter.ChangeValue();
|
||||
|
||||
if(aTriangle.IsEmpty()) continue;
|
||||
|
||||
for (i = 0; i < 3; ++i) {
|
||||
if (aTriangle.mypLink[i] == 0L) {
|
||||
AddLink(aTriangle, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
return myLinks.Length();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ClearLinks
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void Poly_CoherentTriangulation::ClearLinks ()
|
||||
{
|
||||
myLinks.Clear();
|
||||
NCollection_Vector<Poly_CoherentTriangle>::Iterator anIter (myTriangles);
|
||||
for (; anIter.More(); anIter.Next()) {
|
||||
Poly_CoherentTriangle& aTriangle = anIter.ChangeValue();
|
||||
aTriangle.mypLink[0] = 0L;
|
||||
aTriangle.mypLink[1] = 0L;
|
||||
aTriangle.mypLink[2] = 0L;
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Clone
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Handle(Poly_CoherentTriangulation) Poly_CoherentTriangulation::Clone
|
||||
(const Handle_NCollection_BaseAllocator& theAlloc) const
|
||||
{
|
||||
Handle(Poly_CoherentTriangulation) newTri;
|
||||
|
||||
if (NTriangles() != 0 && NNodes() != 0) {
|
||||
Handle(Poly_Triangulation) theTriangulation = GetTriangulation();
|
||||
newTri = new Poly_CoherentTriangulation(theTriangulation, theAlloc);
|
||||
newTri->SetDeflection(theTriangulation->Deflection());
|
||||
}
|
||||
|
||||
return newTri;
|
||||
}
|
||||
//=======================================================================
|
||||
//function : Dump
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void Poly_CoherentTriangulation::Dump (Standard_OStream& theStream) const
|
||||
{
|
||||
for (Standard_Integer iNode = 0; iNode < myNodes.Length(); iNode++) {
|
||||
const Poly_CoherentNode& aNode = myNodes(iNode);
|
||||
if (aNode.IsFreeNode())
|
||||
continue;
|
||||
theStream << "Node " << iNode;
|
||||
aNode.Dump(theStream);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user