1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-07 18:30:55 +03:00
occt/src/Poly/Poly_CoherentTriangulation.cxx
abv 857ffd5e57 0024814: Avoid using explicit names of Handle classes
Sources corrected replacing Handle_XXX by Handle(XXX)
2014-04-22 18:36:12 +04:00

761 lines
27 KiB
C++

// Created on: 2007-12-08
// Created by: Alexander GRIGORIEV
// Copyright (c) 2007-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 <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::Raise("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::Raise("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);
}
}