mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-14 13:30:48 +03:00
Integration of OCCT 6.5.0 from SVN
This commit is contained in:
14
src/Poly/FILES
Executable file
14
src/Poly/FILES
Executable file
@@ -0,0 +1,14 @@
|
||||
Handle_Poly_CoherentTriangulation.hxx
|
||||
Poly_CoherentTriangulation.hxx
|
||||
Poly_CoherentTriangle.hxx
|
||||
Poly_CoherentTriPtr.hxx
|
||||
Poly_CoherentNode.hxx
|
||||
Poly_CoherentLink.hxx
|
||||
Poly_CoherentTriangulation.cxx
|
||||
Poly_CoherentTriangle.cxx
|
||||
Poly_CoherentTriPtr.cxx
|
||||
Poly_CoherentNode.cxx
|
||||
Poly_CoherentLink.cxx
|
||||
Poly_MakeLoops.hxx
|
||||
Poly_MakeLoops.cxx
|
||||
Poly_ListOfTriangulation.hxx
|
18
src/Poly/Handle_Poly_CoherentTriangulation.hxx
Executable file
18
src/Poly/Handle_Poly_CoherentTriangulation.hxx
Executable file
@@ -0,0 +1,18 @@
|
||||
// File: Handle_Poly_CoherentTriangulation.hxx
|
||||
// Created: 23.04.08 19:00
|
||||
// Author: Alexander GRIGORIEV
|
||||
// Copyright: Open Cascade 2008
|
||||
|
||||
|
||||
#ifndef Handle_Poly_CoherentTriangulation_HeaderFile
|
||||
#define Handle_Poly_CoherentTriangulation_HeaderFile
|
||||
|
||||
#include <Standard_DefineHandle.hxx>
|
||||
#include <Standard_Transient.hxx>
|
||||
|
||||
class Poly_CoherentTriangulation;
|
||||
|
||||
//! Definition of HANDLE object using Standard_DefineHandle.hxx
|
||||
DEFINE_STANDARD_HANDLE (Poly_CoherentTriangulation, Standard_Transient)
|
||||
|
||||
#endif
|
164
src/Poly/Poly.cdl
Executable file
164
src/Poly/Poly.cdl
Executable file
@@ -0,0 +1,164 @@
|
||||
|
||||
-- -- File: Poly.cdl
|
||||
-- Created: Mon Mar 6 09:38:50 1995
|
||||
-- Author: Laurent PAINNOT
|
||||
-- <lpa@metrox>
|
||||
---Copyright: Matra Datavision 1995
|
||||
|
||||
|
||||
|
||||
package Poly
|
||||
|
||||
---Purpose: This package provides classes and services to
|
||||
-- handle :
|
||||
--
|
||||
-- * 3D triangular polyhedrons.
|
||||
--
|
||||
-- * 3D polygons.
|
||||
--
|
||||
-- * 2D polygon.
|
||||
--
|
||||
-- * Tools to dump, save and restore those objects.
|
||||
|
||||
uses
|
||||
|
||||
MMgt,
|
||||
TCollection,
|
||||
TColStd,
|
||||
gp,
|
||||
TColgp,
|
||||
TShort
|
||||
|
||||
is
|
||||
|
||||
class Triangle;
|
||||
---Purpose: A triangle is a triplet of integers (indices of
|
||||
-- the nodes).
|
||||
|
||||
class Array1OfTriangle
|
||||
instantiates Array1 from TCollection(Triangle from Poly);
|
||||
|
||||
class HArray1OfTriangle
|
||||
instantiates HArray1 from TCollection(Triangle from Poly,
|
||||
Array1OfTriangle from Poly);
|
||||
|
||||
class Triangulation;
|
||||
---Purpose: A Triangulation is a 3D polyhedron made of
|
||||
-- triangles. It is made of a nodes which are
|
||||
-- indexed. Nodes have a 3d value and a 2d value.
|
||||
-- Triangles are triplet of node indices.
|
||||
--
|
||||
-- This is a Transient class.
|
||||
|
||||
|
||||
class Polygon3D;
|
||||
---Purpose: A Polygon3D is made of indexed nodes.
|
||||
-- Nodes have a 3d value.
|
||||
|
||||
class Polygon2D;
|
||||
---Purpose: A Polygon2D is made of indexed nodes.
|
||||
-- Nodes have a 2d value.
|
||||
|
||||
class PolygonOnTriangulation;
|
||||
---Purpose: A polygonOnTriangulation is made of node indices
|
||||
-- referencing a triangulation.
|
||||
|
||||
|
||||
--
|
||||
-- Tools to use triangulations
|
||||
--
|
||||
|
||||
class Connect;
|
||||
---Purpose: Computes and stores the link from nodes to
|
||||
-- triangles and from triangles to neighbouring
|
||||
-- triangles.
|
||||
-- This tool is obsolete, replaced by Poly_CoherentTriangulation
|
||||
|
||||
--
|
||||
-- Data types for the Coherent Triangulation data model
|
||||
--
|
||||
imported CogerentTriangulation;
|
||||
imported CoherentTriangle;
|
||||
imported CoherentNode;
|
||||
imported CoherentLink;
|
||||
imported CoherentTriPtr;
|
||||
imported ListOfTriangulation;
|
||||
|
||||
imported MakeLoops;
|
||||
---Purpose: Algorithm to make minimal loops in a graph
|
||||
|
||||
--
|
||||
-- Package methods
|
||||
--
|
||||
|
||||
Catenate (lstTri: ListOfTriangulation from Poly)
|
||||
returns Triangulation from Poly;
|
||||
---Purpose: Join several triangulations to one new triangulation object.
|
||||
-- The new triangulation is just a mechanical sum of input
|
||||
-- triangulations, without node sharing. UV coordinates are
|
||||
-- dropped in the result.
|
||||
|
||||
Write(T : Triangulation from Poly;
|
||||
OS : in out OStream;
|
||||
Compact : Boolean = Standard_True);
|
||||
|
||||
---Purpose: Writes the content of the triangulation <T> on the
|
||||
-- stream <OS>. If <Compact> is true this is a "save"
|
||||
-- format intended to be read back with the Read
|
||||
-- method. If compact is False it is a "Dump" format
|
||||
-- intended to be informative.
|
||||
|
||||
Write(P : Polygon3D from Poly;
|
||||
OS : in out OStream;
|
||||
Compact : Boolean = Standard_True);
|
||||
|
||||
---Purpose: Writes the content of the 3D polygon <P> on the
|
||||
-- stream <OS>. If <Compact> is true this is a "save"
|
||||
-- format intended to be read back with the Read
|
||||
-- method. If compact is False it is a "Dump" format
|
||||
-- intended to be informative.
|
||||
|
||||
Write(P : Polygon2D from Poly;
|
||||
OS : in out OStream;
|
||||
Compact : Boolean = Standard_True);
|
||||
|
||||
---Purpose: Writes the content of the 2D polygon <P> on the
|
||||
-- stream <OS>. If <Compact> is true this is a "save"
|
||||
-- format intended to be read back with the Read
|
||||
-- method. If compact is False it is a "Dump" format
|
||||
-- intended to be informative.
|
||||
|
||||
|
||||
Dump(T : Triangulation from Poly;
|
||||
OS : in out OStream);
|
||||
---Purpose: Dumps the triangulation. This is a call to the
|
||||
-- previous method with Comapct set to False.
|
||||
|
||||
Dump(P : Polygon3D from Poly;
|
||||
OS : in out OStream);
|
||||
---Purpose: Dumps the 3D polygon. This is a call to the
|
||||
-- previous method with Comapct set to False.
|
||||
|
||||
Dump(P : Polygon2D from Poly;
|
||||
OS : in out OStream);
|
||||
---Purpose: Dumps the 2D polygon. This is a call to the
|
||||
-- previous method with Comapct set to False.
|
||||
|
||||
|
||||
ReadTriangulation(IS : in out IStream)
|
||||
returns Triangulation from Poly;
|
||||
---Purpose: Reads a triangulation from the stream <IS>.
|
||||
|
||||
ReadPolygon3D(IS : in out IStream)
|
||||
returns Polygon3D from Poly;
|
||||
---Purpose: Reads a 3d polygon from the stream <IS>.
|
||||
|
||||
ReadPolygon2D(IS : in out IStream)
|
||||
returns Polygon2D from Poly;
|
||||
---Purpose: Reads a 2D polygon from the stream <IS>.
|
||||
|
||||
ComputeNormals(Tri : Triangulation from Poly);
|
||||
---Purpose: Compute node normals for face triangulation
|
||||
-- as mean normal of surrounding triangles
|
||||
|
||||
end Poly;
|
495
src/Poly/Poly.cxx
Executable file
495
src/Poly/Poly.cxx
Executable file
@@ -0,0 +1,495 @@
|
||||
// File: Poly.cxx
|
||||
// Created: Mon Mar 6 11:02:24 1995
|
||||
// Author: Laurent PAINNOT
|
||||
// <lpa@metrox>
|
||||
|
||||
#include <Standard_Stream.hxx>
|
||||
#include <Poly.ixx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <gp_Pnt2d.hxx>
|
||||
#include <Poly_Triangle.hxx>
|
||||
#include <TColgp_Array1OfPnt.hxx>
|
||||
#include <TColgp_Array1OfPnt.hxx>
|
||||
#include <TColStd_Array1OfReal.hxx>
|
||||
#include <Poly_Array1OfTriangle.hxx>
|
||||
#include <Poly_ListOfTriangulation.hxx>
|
||||
|
||||
#include <Poly_Polygon3D.hxx>
|
||||
#include <Poly_Polygon2D.hxx>
|
||||
#include <Precision.hxx>
|
||||
#include <TShort_Array1OfShortReal.hxx>
|
||||
#include <TShort_HArray1OfShortReal.hxx>
|
||||
|
||||
//=======================================================================
|
||||
//function : Catenate
|
||||
//purpose : Join several triangulations to one new triangulation object
|
||||
//=======================================================================
|
||||
|
||||
Handle(Poly_Triangulation) Poly::Catenate
|
||||
(const Poly_ListOfTriangulation& lstTri)
|
||||
{
|
||||
Standard_Integer nNodes(0);
|
||||
Standard_Integer nTrian(0);
|
||||
|
||||
// Sum up the total number of nodes.
|
||||
Poly_ListOfTriangulation::Iterator anIter(lstTri);
|
||||
for (; anIter.More(); anIter.Next()) {
|
||||
const Handle(Poly_Triangulation)& aTri = anIter.Value();
|
||||
if (aTri.IsNull() == Standard_False) {
|
||||
nNodes += aTri->NbNodes();
|
||||
nTrian += aTri->NbTriangles();
|
||||
}
|
||||
}
|
||||
|
||||
Handle(Poly_Triangulation) aResult;
|
||||
if (nNodes > 0) {
|
||||
aResult = new Poly_Triangulation(nNodes, nTrian, Standard_False);
|
||||
Standard_Integer i, iNode[3];
|
||||
nNodes = 0;
|
||||
nTrian = 0;
|
||||
TColgp_Array1OfPnt& arrNode = aResult->ChangeNodes();
|
||||
Poly_Array1OfTriangle& arrTrian = aResult->ChangeTriangles();
|
||||
for (anIter.Init(lstTri); anIter.More(); anIter.Next()) {
|
||||
const Handle(Poly_Triangulation)& aTri = anIter.Value();
|
||||
if (aTri.IsNull() == Standard_False) {
|
||||
const TColgp_Array1OfPnt& srcNode = aTri->Nodes();
|
||||
const Poly_Array1OfTriangle& srcTrian = aTri->Triangles();
|
||||
const Standard_Integer nbNodes = aTri->NbNodes();
|
||||
const Standard_Integer nbTrian = aTri->NbTriangles();
|
||||
for (i = 1; i <= nbNodes; i++) {
|
||||
arrNode.SetValue(i + nNodes, srcNode(i));
|
||||
}
|
||||
for (i = 1; i <= nbTrian; i++) {
|
||||
srcTrian(i).Get(iNode[0], iNode[1], iNode[2]);
|
||||
arrTrian.SetValue(i + nTrian, Poly_Triangle(iNode[0] + nNodes,
|
||||
iNode[1] + nNodes,
|
||||
iNode[2] + nNodes));
|
||||
}
|
||||
nNodes += nbNodes;
|
||||
nTrian += nbTrian;
|
||||
}
|
||||
}
|
||||
}
|
||||
return aResult;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Write
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void Poly::Write(const Handle(Poly_Triangulation)& T,
|
||||
Standard_OStream& OS,
|
||||
const Standard_Boolean Compact)
|
||||
{
|
||||
OS << "Poly_Triangulation\n";
|
||||
if (Compact) {
|
||||
OS << T->NbNodes() << " " << T->NbTriangles() << " ";
|
||||
OS << ((T->HasUVNodes()) ? "1" : "0") << "\n";
|
||||
}
|
||||
else {
|
||||
OS << setw(8) << T->NbNodes() << " Nodes\n";
|
||||
OS << setw(8) << T->NbTriangles() << " Triangles\n";
|
||||
OS << ((T->HasUVNodes()) ? "with" : "without") << " UV nodes\n";
|
||||
}
|
||||
|
||||
// write the deflection
|
||||
|
||||
if (!Compact) OS << "Deflection : ";
|
||||
OS << T->Deflection() << "\n";
|
||||
|
||||
// write the 3d nodes
|
||||
|
||||
if (!Compact) OS << "\n3D Nodes :\n";
|
||||
|
||||
Standard_Integer i, nbNodes = T->NbNodes();
|
||||
const TColgp_Array1OfPnt& Nodes = T->Nodes();
|
||||
for (i = 1; i <= nbNodes; i++) {
|
||||
if (!Compact) OS << setw(10) << i << " : ";
|
||||
if (!Compact) OS << setw(17);
|
||||
OS << Nodes(i).X() << " ";
|
||||
if (!Compact) OS << setw(17);
|
||||
OS << Nodes(i).Y() << " ";
|
||||
if (!Compact) OS << setw(17);
|
||||
OS << Nodes(i).Z() << "\n";
|
||||
}
|
||||
|
||||
if (T->HasUVNodes()) {
|
||||
if (!Compact) OS << "\nUV Nodes :\n";
|
||||
const TColgp_Array1OfPnt2d& UVNodes = T->UVNodes();
|
||||
for (i = 1; i <= nbNodes; i++) {
|
||||
if (!Compact) OS << setw(10) << i << " : ";
|
||||
if (!Compact) OS << setw(17);
|
||||
OS << UVNodes(i).X() << " ";
|
||||
if (!Compact) OS << setw(17);
|
||||
OS << UVNodes(i).Y() << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (!Compact) OS << "\nTriangles :\n";
|
||||
Standard_Integer nbTriangles = T->NbTriangles();
|
||||
Standard_Integer n1, n2, n3;
|
||||
const Poly_Array1OfTriangle& Triangles = T->Triangles();
|
||||
for (i = 1; i <= nbTriangles; i++) {
|
||||
if (!Compact) OS << setw(10) << i << " : ";
|
||||
Triangles(i).Get(n1, n2, n3);
|
||||
if (!Compact) OS << setw(10);
|
||||
OS << n1 << " ";
|
||||
if (!Compact) OS << setw(10);
|
||||
OS << n2 << " ";
|
||||
if (!Compact) OS << setw(10);
|
||||
OS << n3 << "\n";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Write
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void Poly::Write(const Handle(Poly_Polygon3D)& P,
|
||||
Standard_OStream& OS,
|
||||
const Standard_Boolean Compact)
|
||||
{
|
||||
OS << "Poly_Polygon3D\n";
|
||||
if (Compact) {
|
||||
OS << P->NbNodes() << " ";
|
||||
OS << ((P->HasParameters()) ? "1" : "0") << "\n";
|
||||
}
|
||||
else {
|
||||
OS << setw(8) << P->NbNodes() << " Nodes\n";
|
||||
OS << ((P->HasParameters()) ? "with" : "without") << " parameters\n";
|
||||
}
|
||||
|
||||
// write the deflection
|
||||
|
||||
if (!Compact) OS << "Deflection : ";
|
||||
OS << P->Deflection() << "\n";
|
||||
|
||||
// write the nodes
|
||||
|
||||
if (!Compact) OS << "\nNodes :\n";
|
||||
|
||||
Standard_Integer i, nbNodes = P->NbNodes();
|
||||
const TColgp_Array1OfPnt& Nodes = P->Nodes();
|
||||
for (i = 1; i <= nbNodes; i++) {
|
||||
if (!Compact) OS << setw(10) << i << " : ";
|
||||
if (!Compact) OS << setw(17);
|
||||
OS << Nodes(i).X() << " ";
|
||||
if (!Compact) OS << setw(17);
|
||||
OS << Nodes(i).Y() << " ";
|
||||
if (!Compact) OS << setw(17);
|
||||
OS << Nodes(i).Z() << "\n";
|
||||
}
|
||||
|
||||
if (P->HasParameters()) {
|
||||
if (!Compact) OS << "\nParameters :\n";
|
||||
const TColStd_Array1OfReal& Param = P->Parameters();
|
||||
for (i = 1; i <= nbNodes; i++) {
|
||||
OS << Param(i) << " ";
|
||||
}
|
||||
OS <<"\n";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : Write
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void Poly::Write(const Handle(Poly_Polygon2D)& P,
|
||||
Standard_OStream& OS,
|
||||
const Standard_Boolean Compact)
|
||||
{
|
||||
OS << "Poly_Polygon2D\n";
|
||||
if (Compact) {
|
||||
OS << P->NbNodes() << " ";
|
||||
}
|
||||
else {
|
||||
OS << setw(8) << P->NbNodes() << " Nodes\n";
|
||||
}
|
||||
|
||||
// write the deflection
|
||||
|
||||
if (!Compact) OS << "Deflection : ";
|
||||
OS << P->Deflection() << "\n";
|
||||
|
||||
// write the nodes
|
||||
|
||||
if (!Compact) OS << "\nNodes :\n";
|
||||
|
||||
Standard_Integer i, nbNodes = P->NbNodes();
|
||||
const TColgp_Array1OfPnt2d& Nodes = P->Nodes();
|
||||
for (i = 1; i <= nbNodes; i++) {
|
||||
if (!Compact) OS << setw(10) << i << " : ";
|
||||
if (!Compact) OS << setw(17);
|
||||
OS << Nodes(i).X() << " ";
|
||||
if (!Compact) OS << setw(17);
|
||||
OS << Nodes(i).Y() << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : Dump
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void Poly::Dump(const Handle(Poly_Triangulation)& T, Standard_OStream& OS)
|
||||
{
|
||||
Poly::Write(T,OS,Standard_False);
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : Dump
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void Poly::Dump(const Handle(Poly_Polygon3D)& P, Standard_OStream& OS)
|
||||
{
|
||||
Poly::Write(P,OS,Standard_False);
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : Dump
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void Poly::Dump(const Handle(Poly_Polygon2D)& P, Standard_OStream& OS)
|
||||
{
|
||||
Poly::Write(P,OS,Standard_False);
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : ReadTriangulation
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Handle(Poly_Triangulation) Poly::ReadTriangulation(Standard_IStream& IS)
|
||||
{
|
||||
// Read a triangulation
|
||||
|
||||
char line[100];
|
||||
IS >> line;
|
||||
if (strcmp(line,"Poly_Triangulation")) {
|
||||
cout << "Not a Triangulation in the file" << endl;
|
||||
return Handle(Poly_Triangulation)();
|
||||
}
|
||||
|
||||
Standard_Integer nbNodes, nbTriangles;
|
||||
Standard_Boolean hasUV;
|
||||
IS >> nbNodes >> nbTriangles >> hasUV;
|
||||
|
||||
Standard_Real d;
|
||||
IS >> d;
|
||||
|
||||
// read the 3d nodes
|
||||
Standard_Real x,y,z;
|
||||
Standard_Integer i;
|
||||
TColgp_Array1OfPnt Nodes(1, nbNodes);
|
||||
TColgp_Array1OfPnt2d UVNodes(1, nbNodes);
|
||||
|
||||
for (i = 1; i <= nbNodes; i++) {
|
||||
IS >> x >> y >> z;
|
||||
Nodes(i).SetCoord(x,y,z);
|
||||
}
|
||||
|
||||
// read the UV points if necessary
|
||||
|
||||
if (hasUV) {
|
||||
for (i = 1; i <= nbNodes; i++) {
|
||||
IS >> x >> y;
|
||||
UVNodes(i).SetCoord(x,y);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// read the triangles
|
||||
Standard_Integer n1,n2,n3;
|
||||
Poly_Array1OfTriangle Triangles(1, nbTriangles);
|
||||
for (i = 1; i <= nbTriangles; i++) {
|
||||
IS >> n1 >> n2 >> n3;
|
||||
Triangles(i).Set(n1,n2,n3);
|
||||
}
|
||||
|
||||
|
||||
Handle(Poly_Triangulation) T;
|
||||
|
||||
if (hasUV) T = new Poly_Triangulation(Nodes,UVNodes,Triangles);
|
||||
else T = new Poly_Triangulation(Nodes,Triangles);
|
||||
|
||||
T->Deflection(d);
|
||||
|
||||
return T;
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : ReadPolygon3D
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Handle(Poly_Polygon3D) Poly::ReadPolygon3D(Standard_IStream& IS)
|
||||
{
|
||||
// Read a 3d polygon
|
||||
|
||||
char line[100];
|
||||
IS >> line;
|
||||
if (strcmp(line,"Poly_Polygon3D")) {
|
||||
cout << "Not a Polygon3D in the file" << endl;
|
||||
return Handle(Poly_Polygon3D)();
|
||||
}
|
||||
|
||||
Standard_Integer nbNodes;
|
||||
IS >> nbNodes;
|
||||
|
||||
Standard_Boolean hasparameters;
|
||||
IS >> hasparameters;
|
||||
|
||||
Standard_Real d;
|
||||
IS >> d;
|
||||
|
||||
// read the nodes
|
||||
Standard_Real x,y,z;
|
||||
Standard_Integer i;
|
||||
TColgp_Array1OfPnt Nodes(1, nbNodes);
|
||||
|
||||
for (i = 1; i <= nbNodes; i++) {
|
||||
IS >> x >> y >> z;
|
||||
Nodes(i).SetCoord(x,y,z);
|
||||
}
|
||||
|
||||
TColStd_Array1OfReal Param(1,nbNodes);
|
||||
if (hasparameters) {
|
||||
for (i = 1; i <= nbNodes; i++) {
|
||||
IS >> Param(i);
|
||||
}
|
||||
}
|
||||
|
||||
Handle(Poly_Polygon3D) P;
|
||||
if (!hasparameters)
|
||||
P = new Poly_Polygon3D(Nodes);
|
||||
else
|
||||
P = new Poly_Polygon3D(Nodes, Param);
|
||||
|
||||
P->Deflection(d);
|
||||
|
||||
return P;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ReadPolygon3D
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Handle(Poly_Polygon2D) Poly::ReadPolygon2D(Standard_IStream& IS)
|
||||
{
|
||||
// Read a 2d polygon
|
||||
|
||||
char line[100];
|
||||
IS >> line;
|
||||
if (strcmp(line,"Poly_Polygon2D")) {
|
||||
cout << "Not a Polygon2D in the file" << endl;
|
||||
return Handle(Poly_Polygon2D)();
|
||||
}
|
||||
|
||||
Standard_Integer nbNodes;
|
||||
IS >> nbNodes;
|
||||
|
||||
Standard_Real d;
|
||||
IS >> d;
|
||||
|
||||
// read the nodes
|
||||
Standard_Real x,y;
|
||||
Standard_Integer i;
|
||||
TColgp_Array1OfPnt2d Nodes(1, nbNodes);
|
||||
|
||||
for (i = 1; i <= nbNodes; i++) {
|
||||
IS >> x >> y;
|
||||
Nodes(i).SetCoord(x,y);
|
||||
}
|
||||
|
||||
Handle(Poly_Polygon2D) P =
|
||||
new Poly_Polygon2D(Nodes);
|
||||
|
||||
P->Deflection(d);
|
||||
|
||||
return P;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ComputeNormals
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void Poly::ComputeNormals(const Handle(Poly_Triangulation)& Tri)
|
||||
{
|
||||
const TColgp_Array1OfPnt& arrNodes = Tri->Nodes();
|
||||
const Poly_Array1OfTriangle & arrTri = Tri->Triangles();
|
||||
Standard_Integer nbNormVal = Tri->NbNodes() * 3;
|
||||
const Handle(TShort_HArray1OfShortReal) Normals =
|
||||
new TShort_HArray1OfShortReal(1, nbNormVal);
|
||||
Normals->Init(0.F);
|
||||
|
||||
Standard_ShortReal * arrNormal = &(Normals->ChangeValue(1));
|
||||
|
||||
Standard_Real aCoord[3];
|
||||
Standard_Integer iNode[3] = {0, 0, 0};
|
||||
Standard_Integer iN, iTri;
|
||||
const Standard_Real eps2 = Precision::Confusion()*Precision::Confusion();
|
||||
|
||||
for (iTri = 1; iTri <= arrTri.Length(); iTri++) {
|
||||
// Get the nodes of the current triangle
|
||||
arrTri(iTri).Get (iNode[0], iNode[1], iNode[2]);
|
||||
const gp_XYZ aVec[2] = {
|
||||
arrNodes(iNode[1]).XYZ() - arrNodes(iNode[0]).XYZ(),
|
||||
arrNodes(iNode[2]).XYZ() - arrNodes(iNode[0]).XYZ()
|
||||
};
|
||||
|
||||
// Find the normal vector of the current triangle
|
||||
gp_XYZ aNorm = aVec[0] ^ aVec[1];
|
||||
const Standard_Real aMod = aNorm.SquareModulus();
|
||||
if (aMod > eps2) {
|
||||
aNorm /= sqrt(aMod);
|
||||
aNorm.Coord (aCoord[0], aCoord[1], aCoord[2]);
|
||||
iNode[0] = (iNode[0]-1)*3;
|
||||
iNode[1] = (iNode[1]-1)*3;
|
||||
iNode[2] = (iNode[2]-1)*3;
|
||||
arrNormal[iNode[0]+0] += (Standard_ShortReal)aCoord[0];
|
||||
arrNormal[iNode[0]+1] += (Standard_ShortReal)aCoord[1];
|
||||
arrNormal[iNode[0]+2] += (Standard_ShortReal)aCoord[2];
|
||||
arrNormal[iNode[1]+0] += (Standard_ShortReal)aCoord[0];
|
||||
arrNormal[iNode[1]+1] += (Standard_ShortReal)aCoord[1];
|
||||
arrNormal[iNode[1]+2] += (Standard_ShortReal)aCoord[2];
|
||||
arrNormal[iNode[2]+0] += (Standard_ShortReal)aCoord[0];
|
||||
arrNormal[iNode[2]+1] += (Standard_ShortReal)aCoord[1];
|
||||
arrNormal[iNode[2]+2] += (Standard_ShortReal)aCoord[2];
|
||||
}
|
||||
}
|
||||
// Normalize all vectors
|
||||
for (iN = 0; iN < nbNormVal; iN+=3) {
|
||||
Standard_Real aMod (arrNormal[iN+0]*arrNormal[iN+0] +
|
||||
arrNormal[iN+1]*arrNormal[iN+1] +
|
||||
arrNormal[iN+2]*arrNormal[iN+2]);
|
||||
if (aMod < eps2) {
|
||||
arrNormal[iN+0] = 0.f;
|
||||
arrNormal[iN+1] = 0.f;
|
||||
arrNormal[iN+2] = 1.f;
|
||||
} else {
|
||||
aMod = sqrt(aMod);
|
||||
arrNormal[iN+0] = Standard_ShortReal(arrNormal[iN+0]/aMod);
|
||||
arrNormal[iN+1] = Standard_ShortReal(arrNormal[iN+1]/aMod);
|
||||
arrNormal[iN+2] = Standard_ShortReal(arrNormal[iN+2]/aMod);
|
||||
}
|
||||
}
|
||||
|
||||
Tri->SetNormals(Normals);
|
||||
}
|
53
src/Poly/Poly_CoherentLink.cxx
Executable file
53
src/Poly/Poly_CoherentLink.cxx
Executable file
@@ -0,0 +1,53 @@
|
||||
// File: Poly_CoherentLink.cxx
|
||||
// Created: 03.01.08 09:27
|
||||
// Author: Alexander GRIGORIEV
|
||||
// Copyright: Open Cascade 2008
|
||||
|
||||
|
||||
#include <Poly_CoherentLink.hxx>
|
||||
#include <Poly_CoherentTriangle.hxx>
|
||||
#include <Standard_ProgramError.hxx>
|
||||
|
||||
//=======================================================================
|
||||
//function : Poly_CoherentLink()
|
||||
//purpose : Empty Constructor
|
||||
//=======================================================================
|
||||
|
||||
Poly_CoherentLink::Poly_CoherentLink ()
|
||||
: myAttribute (0L)
|
||||
{
|
||||
myNode[0] = -1;
|
||||
myNode[1] = -1;
|
||||
myOppositeNode[0] = -1;
|
||||
myOppositeNode[1] = -1;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Poly_CoherentLink()
|
||||
//purpose : Constructor
|
||||
//=======================================================================
|
||||
|
||||
Poly_CoherentLink::Poly_CoherentLink (const Poly_CoherentTriangle& theTri,
|
||||
Standard_Integer iSide)
|
||||
: myAttribute (0L)
|
||||
{
|
||||
static const Standard_Integer ind[] = { 1, 2, 0, 1 };
|
||||
Standard_ProgramError_Raise_if(iSide < 0 || iSide > 2,
|
||||
"Poly_CoherentLink::Poly_CoherentLink: "
|
||||
"Wrong iSide parameter");
|
||||
const Standard_Integer aNodeInd[2] = {
|
||||
theTri.Node(ind[iSide+0]),
|
||||
theTri.Node(ind[iSide+1])
|
||||
};
|
||||
if (aNodeInd[0] < aNodeInd[1]) {
|
||||
myNode[0] = aNodeInd[0];
|
||||
myNode[1] = aNodeInd[1];
|
||||
myOppositeNode[0] = theTri.Node(iSide);
|
||||
myOppositeNode[1] = theTri.GetConnectedNode(iSide);
|
||||
} else {
|
||||
myNode[0] = aNodeInd[1];
|
||||
myNode[1] = aNodeInd[0];
|
||||
myOppositeNode[0] = theTri.GetConnectedNode(iSide);
|
||||
myOppositeNode[1] = theTri.Node(iSide);
|
||||
}
|
||||
}
|
124
src/Poly/Poly_CoherentLink.hxx
Executable file
124
src/Poly/Poly_CoherentLink.hxx
Executable file
@@ -0,0 +1,124 @@
|
||||
// File: Poly_CoherentLink.hxx
|
||||
// Created: 25.12.07 12:47
|
||||
// Author: Alexander GRIGORIEV
|
||||
// Copyright: Open Cascade 2007
|
||||
|
||||
|
||||
#ifndef Poly_CoherentLink_HeaderFile
|
||||
#define Poly_CoherentLink_HeaderFile
|
||||
|
||||
#include <Standard_TypeDef.hxx>
|
||||
|
||||
class Poly_CoherentTriangle;
|
||||
class Poly_CoherentTriangulation;
|
||||
|
||||
/**
|
||||
* Link between two mesh nodes that is created by existing triangle(s).
|
||||
* Keeps reference to the opposite node of each incident triangle.
|
||||
* The referred node with index "0" is always on the left side of the link,
|
||||
* the one with the index "1" is always on the right side.
|
||||
* It is possible to find both incident triangles using the method
|
||||
* Poly_CoherentTriangulation::FindTriangle().
|
||||
* <p>
|
||||
* Any Link can store an arbitrary pointer that is called Attribute.
|
||||
*/
|
||||
|
||||
class Poly_CoherentLink
|
||||
{
|
||||
public:
|
||||
// ---------- PUBLIC METHODS ----------
|
||||
|
||||
/**
|
||||
* Empty constructor.
|
||||
*/
|
||||
Standard_EXPORT Poly_CoherentLink ();
|
||||
|
||||
/**
|
||||
* Constructor. Creates a Link that has no reference to 'opposite nodes'.
|
||||
* This constructor is useful to create temporary object that is not
|
||||
* inserted into any existing triangulation.
|
||||
*/
|
||||
inline Poly_CoherentLink (const Standard_Integer iNode0,
|
||||
const Standard_Integer iNode1)
|
||||
: myAttribute (0L)
|
||||
{
|
||||
myNode[0] = iNode0; myNode[1] = iNode1;
|
||||
myOppositeNode[0] = -1; myOppositeNode[1] = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor, takes a triangle and a side. A link is created always such
|
||||
* that myNode[0] < myNode[1]. Unlike the previous constructor, this one
|
||||
* assigns the 'opposite node' fields. This constructor is used when a
|
||||
* link is inserted into a Poly_CoherentTriangulation structure.
|
||||
* @param theTri
|
||||
* Triangle containing the link that is created
|
||||
* @param iSide
|
||||
* Can be 0, 1 or 2. Index of the node
|
||||
*/
|
||||
Standard_EXPORT Poly_CoherentLink (const Poly_CoherentTriangle& theTri,
|
||||
Standard_Integer iSide);
|
||||
|
||||
/**
|
||||
* Return the node index in the current triangulation.
|
||||
* @param ind
|
||||
* 0 or 1 making distinction of the two nodes that constitute the Link.
|
||||
* Node(0) always returns a smaller number than Node(1).
|
||||
*/
|
||||
inline Standard_Integer Node (const Standard_Integer ind) const
|
||||
{ return myNode[ind & 0x1]; }
|
||||
|
||||
/**
|
||||
* Return the opposite node (belonging to the left or right incident triangle)
|
||||
* index in the current triangulation.
|
||||
* @param ind
|
||||
* 0 or 1 making distinction of the two involved triangles: 0 on the left,
|
||||
* 1 on the right side of the Link.
|
||||
*/
|
||||
inline Standard_Integer OppositeNode (const Standard_Integer ind) const
|
||||
{ return myOppositeNode[ind & 0x1]; }
|
||||
|
||||
/**
|
||||
* Query the attribute of the Link.
|
||||
*/
|
||||
inline Standard_Address GetAttribute () const
|
||||
{ return myAttribute; }
|
||||
|
||||
/**
|
||||
* Set the attribute of the Link.
|
||||
*/
|
||||
inline void SetAttribute (const Standard_Address theAtt)
|
||||
{ myAttribute = theAtt; }
|
||||
|
||||
/**
|
||||
* Query the status of the link - if it is an invalid one.
|
||||
* An invalid link has Node members equal to -1.
|
||||
*/
|
||||
inline Standard_Boolean IsEmpty () const
|
||||
{ return myNode[0] < 0 || myNode[1] < 0; }
|
||||
|
||||
/**
|
||||
* Invalidate this Link.
|
||||
*/
|
||||
inline void Nullify ()
|
||||
{
|
||||
myNode[0] = -1; myNode[1] = -1;
|
||||
myOppositeNode[0] = -1; myOppositeNode[1] = -1;
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
// ---------- PROTECTED METHODS ----------
|
||||
|
||||
|
||||
|
||||
private:
|
||||
// ---------- PRIVATE FIELDS ----------
|
||||
Standard_Integer myNode[2];
|
||||
Standard_Integer myOppositeNode[2];
|
||||
Standard_Address myAttribute;
|
||||
|
||||
friend class Poly_CoherentTriangulation;
|
||||
};
|
||||
|
||||
#endif
|
104
src/Poly/Poly_CoherentNode.cxx
Executable file
104
src/Poly/Poly_CoherentNode.cxx
Executable file
@@ -0,0 +1,104 @@
|
||||
// File: Poly_CoherentNode.cxx
|
||||
// Created: 14.12.07 07:32
|
||||
// Author: Alexander GRIGORIEV
|
||||
// Copyright: Open Cascade 2007
|
||||
|
||||
|
||||
#include <Poly_CoherentNode.hxx>
|
||||
#include <Poly_CoherentTriangle.hxx>
|
||||
|
||||
#ifdef WNT
|
||||
#pragma warning(disable:4291 4996)
|
||||
#endif
|
||||
|
||||
//=======================================================================
|
||||
//function : Clear
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void Poly_CoherentNode::Clear (const Handle_NCollection_BaseAllocator& theAlloc)
|
||||
{
|
||||
Poly_CoherentTriPtr::RemoveList (myTriangles, theAlloc);
|
||||
myUV[0] = Precision::Infinite();
|
||||
myUV[1] = Precision::Infinite();
|
||||
myNormal[0] = 0.f;
|
||||
myNormal[1] = 0.f;
|
||||
myNormal[2] = 0.f;
|
||||
SetCoord(0., 0., 0.);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SetNormal
|
||||
//purpose : Define the normal vector in the Node.
|
||||
//=======================================================================
|
||||
|
||||
void Poly_CoherentNode::SetNormal (const gp_XYZ& theVector)
|
||||
{
|
||||
myNormal[0] = static_cast<Standard_ShortReal>(theVector.X());
|
||||
myNormal[1] = static_cast<Standard_ShortReal>(theVector.Y());
|
||||
myNormal[2] = static_cast<Standard_ShortReal>(theVector.Z());
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : AddTriangle
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void Poly_CoherentNode::AddTriangle
|
||||
(const Poly_CoherentTriangle& theTri,
|
||||
const Handle_NCollection_BaseAllocator& theAlloc)
|
||||
{
|
||||
if (myTriangles == NULL)
|
||||
myTriangles = new (theAlloc) Poly_CoherentTriPtr(theTri);
|
||||
else
|
||||
myTriangles->Prepend(&theTri, theAlloc);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : RemoveTriangle
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean Poly_CoherentNode::RemoveTriangle
|
||||
(const Poly_CoherentTriangle& theTri,
|
||||
const Handle_NCollection_BaseAllocator& theAlloc)
|
||||
{
|
||||
Standard_Boolean aResult(Standard_False);
|
||||
if (&myTriangles->GetTriangle() == &theTri) {
|
||||
Poly_CoherentTriPtr * aLostPtr = myTriangles;
|
||||
if (myTriangles == &myTriangles->Next())
|
||||
myTriangles = 0L;
|
||||
else
|
||||
myTriangles = &myTriangles->Next();
|
||||
Poly_CoherentTriPtr::Remove(aLostPtr, theAlloc);
|
||||
aResult = Standard_True;
|
||||
} else {
|
||||
Poly_CoherentTriPtr::Iterator anIter(* myTriangles);
|
||||
for (anIter.Next(); anIter.More(); anIter.Next())
|
||||
if (&anIter.Value() == &theTri) {
|
||||
Poly_CoherentTriPtr::Remove
|
||||
(const_cast<Poly_CoherentTriPtr *>(&anIter.PtrValue()), theAlloc);
|
||||
aResult = Standard_True;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return aResult;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Dump
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void Poly_CoherentNode::Dump(Standard_OStream& theStream) const
|
||||
{
|
||||
char buf[256];
|
||||
sprintf (buf, " X =%9.4f; Y =%9.4f; Z =%9.4f", X(), Y(), Z());
|
||||
theStream << buf << endl;
|
||||
Poly_CoherentTriPtr::Iterator anIter(* myTriangles);
|
||||
for (; anIter.More(); anIter.Next()) {
|
||||
const Poly_CoherentTriangle& aTri = anIter.Value();
|
||||
sprintf (buf, " %5d %5d %5d", aTri.Node(0),aTri.Node(1),aTri.Node(2));
|
||||
theStream << buf << endl;
|
||||
}
|
||||
}
|
157
src/Poly/Poly_CoherentNode.hxx
Executable file
157
src/Poly/Poly_CoherentNode.hxx
Executable file
@@ -0,0 +1,157 @@
|
||||
// File: Poly_CoherentNode.hxx
|
||||
// Created: 08.12.07 10:45
|
||||
// Author: Alexander GRIGORIEV
|
||||
// Copyright: Open Cascade 2007
|
||||
|
||||
|
||||
#ifndef Poly_CoherentNode_HeaderFile
|
||||
#define Poly_CoherentNode_HeaderFile
|
||||
|
||||
#include <gp_XYZ.hxx>
|
||||
#include <Poly_CoherentTriPtr.hxx>
|
||||
#include <Precision.hxx>
|
||||
|
||||
class NCollection_BaseAllocator;
|
||||
|
||||
/**
|
||||
* Node of coherent triangulation. Contains:
|
||||
* <ul>
|
||||
* <li>Coordinates of a 3D point defining the node location</li>
|
||||
* <li>2D point coordinates</li>
|
||||
* <li>List of triangles that use this Node</li>
|
||||
* <li>Integer index, normally the index of the node in the original
|
||||
* triangulation</li>
|
||||
* </ul>
|
||||
*/
|
||||
|
||||
class Poly_CoherentNode : public gp_XYZ
|
||||
{
|
||||
public:
|
||||
// ---------- PUBLIC METHODS ----------
|
||||
|
||||
|
||||
/**
|
||||
* Empty constructor.
|
||||
*/
|
||||
inline Poly_CoherentNode ()
|
||||
: gp_XYZ (0., 0., 0.),
|
||||
myTriangles (0L),
|
||||
myIndex (-1)
|
||||
{ myUV[0] = Precision::Infinite(); myUV[1] = Precision::Infinite(); }
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
inline Poly_CoherentNode (const gp_XYZ& thePnt)
|
||||
: gp_XYZ (thePnt),
|
||||
myTriangles (0L),
|
||||
myIndex (-1)
|
||||
{ myUV[0] = Precision::Infinite(); myUV[1] = Precision::Infinite(); myNormal[0] = 0.f; myNormal[1] = 0.f; myNormal[2] = 0.f; }
|
||||
|
||||
/**
|
||||
* Set the UV coordinates of the Node.
|
||||
*/
|
||||
inline void SetUV (const Standard_Real theU,
|
||||
const Standard_Real theV)
|
||||
{ myUV[0] = theU; myUV[1] = theV; }
|
||||
|
||||
/**
|
||||
* Get U coordinate of the Node.
|
||||
*/
|
||||
inline Standard_Real GetU () const
|
||||
{ return myUV[0]; }
|
||||
|
||||
/**
|
||||
* Get V coordinate of the Node.
|
||||
*/
|
||||
inline Standard_Real GetV () const
|
||||
{ return myUV[1]; }
|
||||
|
||||
/**
|
||||
* Define the normal vector in the Node.
|
||||
*/
|
||||
Standard_EXPORT void SetNormal (const gp_XYZ& theVector);
|
||||
|
||||
/**
|
||||
* Query if the Node contains a normal vector.
|
||||
*/
|
||||
inline Standard_Boolean HasNormal () const
|
||||
{ return ((myNormal[0]*myNormal[0] + myNormal[1]*myNormal[1] +
|
||||
myNormal[2]*myNormal[2]) > Precision::Confusion()); }
|
||||
|
||||
/**
|
||||
* Get the stored normal in the node.
|
||||
*/
|
||||
inline gp_XYZ GetNormal () const
|
||||
{ return gp_XYZ (myNormal[0], myNormal[1], myNormal[2]); }
|
||||
|
||||
/**
|
||||
* Set the value of node Index.
|
||||
*/
|
||||
inline void SetIndex (const Standard_Integer theIndex)
|
||||
{ myIndex = theIndex; }
|
||||
|
||||
/**
|
||||
* Get the value of node Index.
|
||||
*/
|
||||
inline Standard_Integer GetIndex () const
|
||||
{ return myIndex; }
|
||||
|
||||
/**
|
||||
* Check if this is a free node, i.e., a node without a single
|
||||
* incident triangle.
|
||||
*/
|
||||
inline Standard_Boolean IsFreeNode () const
|
||||
{ return myTriangles == 0L; }
|
||||
|
||||
/**
|
||||
* Reset the Node to void.
|
||||
*/
|
||||
Standard_EXPORT void Clear (const Handle_NCollection_BaseAllocator&);
|
||||
|
||||
/**
|
||||
* Connect a triangle to this Node.
|
||||
*/
|
||||
Standard_EXPORT void AddTriangle
|
||||
(const Poly_CoherentTriangle& theTri,
|
||||
const Handle_NCollection_BaseAllocator& theA);
|
||||
|
||||
/**
|
||||
* Disconnect a triangle from this Node.
|
||||
*/
|
||||
Standard_EXPORT Standard_Boolean
|
||||
RemoveTriangle
|
||||
(const Poly_CoherentTriangle& theTri,
|
||||
const Handle_NCollection_BaseAllocator& theA);
|
||||
|
||||
/**
|
||||
* Create an iterator of incident triangles.
|
||||
*/
|
||||
inline Poly_CoherentTriPtr::Iterator
|
||||
TriangleIterator () const
|
||||
{ return * myTriangles; }
|
||||
|
||||
Standard_EXPORT void Dump (Standard_OStream& theStream) const;
|
||||
|
||||
// /**
|
||||
// * Destructor.
|
||||
// */
|
||||
// Standard_EXPORT virtual ~Poly_CoherentNode ();
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
// ---------- PROTECTED METHODS ----------
|
||||
|
||||
|
||||
|
||||
private:
|
||||
// ---------- PRIVATE FIELDS ----------
|
||||
|
||||
Standard_Real myUV[2];
|
||||
Poly_CoherentTriPtr * myTriangles;
|
||||
Standard_Integer myIndex;
|
||||
Standard_ShortReal myNormal[3];
|
||||
};
|
||||
|
||||
#endif
|
107
src/Poly/Poly_CoherentTriPtr.cxx
Executable file
107
src/Poly/Poly_CoherentTriPtr.cxx
Executable file
@@ -0,0 +1,107 @@
|
||||
// File: Poly_CoherentTriPtr.cxx
|
||||
// Created: 08.12.07 12:33
|
||||
// Author: Alexander GRIGORIEV
|
||||
// Copyright: Open Cascade 2007
|
||||
|
||||
|
||||
#include <Poly_CoherentTriPtr.hxx>
|
||||
|
||||
#ifdef WNT
|
||||
#pragma warning(disable:4291)
|
||||
#endif
|
||||
|
||||
//=======================================================================
|
||||
//function : Iterator::Next
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void Poly_CoherentTriPtr::Iterator::Next ()
|
||||
{
|
||||
if (myCurrent)
|
||||
{
|
||||
myCurrent = myCurrent->myNext;
|
||||
if (myCurrent == myFirst)
|
||||
myCurrent = 0L;
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Append
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void Poly_CoherentTriPtr::Append
|
||||
(const Poly_CoherentTriangle * pTri,
|
||||
const Handle_NCollection_BaseAllocator& theAlloc)
|
||||
{
|
||||
Handle(NCollection_BaseAllocator) anAlloc = theAlloc;
|
||||
if (theAlloc.IsNull())
|
||||
anAlloc = NCollection_BaseAllocator::CommonBaseAllocator();
|
||||
Poly_CoherentTriPtr * aNewPtr = new (anAlloc) Poly_CoherentTriPtr(* pTri);
|
||||
aNewPtr->myNext = myNext;
|
||||
myNext->myPrevious = aNewPtr;
|
||||
aNewPtr->myPrevious = this;
|
||||
myNext = aNewPtr;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Prepend
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void Poly_CoherentTriPtr::Prepend
|
||||
(const Poly_CoherentTriangle * pTri,
|
||||
const Handle_NCollection_BaseAllocator& theAlloc)
|
||||
{
|
||||
Handle(NCollection_BaseAllocator) anAlloc = theAlloc;
|
||||
if (theAlloc.IsNull())
|
||||
anAlloc = NCollection_BaseAllocator::CommonBaseAllocator();
|
||||
Poly_CoherentTriPtr * aNewPtr = new (anAlloc) Poly_CoherentTriPtr(* pTri);
|
||||
aNewPtr->myPrevious = myPrevious;
|
||||
myPrevious->myNext = aNewPtr;
|
||||
aNewPtr->myNext = this;
|
||||
myPrevious = aNewPtr;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Remove
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void Poly_CoherentTriPtr::Remove
|
||||
(Poly_CoherentTriPtr * thePtr,
|
||||
const Handle_NCollection_BaseAllocator& theAlloc)
|
||||
{
|
||||
Handle(NCollection_BaseAllocator) anAlloc = theAlloc;
|
||||
if (theAlloc.IsNull())
|
||||
anAlloc = NCollection_BaseAllocator::CommonBaseAllocator();
|
||||
if (thePtr->myNext && thePtr->myPrevious) {
|
||||
thePtr->myPrevious->myNext = thePtr->myNext;
|
||||
thePtr->myNext->myPrevious = thePtr->myPrevious;
|
||||
thePtr->myNext = thePtr;
|
||||
thePtr->myPrevious = thePtr;
|
||||
}
|
||||
anAlloc->Free(thePtr);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : RemoveList
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void Poly_CoherentTriPtr::RemoveList
|
||||
(Poly_CoherentTriPtr * thePtr,
|
||||
const Handle_NCollection_BaseAllocator& theAlloc)
|
||||
{
|
||||
Handle(NCollection_BaseAllocator) anAlloc = theAlloc;
|
||||
if (theAlloc.IsNull())
|
||||
anAlloc = NCollection_BaseAllocator::CommonBaseAllocator();
|
||||
Poly_CoherentTriPtr * aPtr = thePtr;
|
||||
do {
|
||||
if (aPtr == 0L)
|
||||
break;
|
||||
Poly_CoherentTriPtr * aLostPtr = aPtr;
|
||||
aPtr = aPtr->myNext;
|
||||
anAlloc->Free(aLostPtr);
|
||||
} while (aPtr != thePtr);
|
||||
}
|
178
src/Poly/Poly_CoherentTriPtr.hxx
Executable file
178
src/Poly/Poly_CoherentTriPtr.hxx
Executable file
@@ -0,0 +1,178 @@
|
||||
// File: Poly_CoherentTriPtr.hxx
|
||||
// Created: 08.12.07 11:52
|
||||
// Author: Alexander GRIGORIEV
|
||||
// Copyright: Open Cascade 2007
|
||||
|
||||
|
||||
#ifndef Poly_CoherentTriPtr_HeaderFile
|
||||
#define Poly_CoherentTriPtr_HeaderFile
|
||||
|
||||
#include <NCollection_BaseAllocator.hxx>
|
||||
|
||||
class Poly_CoherentTriangle;
|
||||
|
||||
#ifdef WNT
|
||||
#pragma warning (push)
|
||||
#pragma warning(disable:4355 4291) //'this' : used in base member initializer list
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Implementation of both list node for Poly_CoherentTriangle type and
|
||||
* round double-linked list of these nodes.
|
||||
*/
|
||||
|
||||
class Poly_CoherentTriPtr
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Iterator class for this list of triangles. Because the list is round,
|
||||
* an iteration can be started from any member and it finishes before taking
|
||||
* this member again. The iteration sense is always forward (Next).
|
||||
*/
|
||||
class Iterator {
|
||||
public:
|
||||
//! Empty constructor
|
||||
inline Iterator ()
|
||||
: myFirst (0L),
|
||||
myCurrent (0L)
|
||||
{}
|
||||
//! Constructor
|
||||
inline Iterator (const Poly_CoherentTriPtr& thePtr)
|
||||
: myFirst (&thePtr),
|
||||
myCurrent (&thePtr)
|
||||
{}
|
||||
//! Query the triangle that started the current iteration.
|
||||
inline const Poly_CoherentTriangle * First () const
|
||||
{ return myFirst ? &myFirst->GetTriangle() : 0L; }
|
||||
//! Query if there is available triangle pointer on this iteration
|
||||
inline Standard_Boolean More () const
|
||||
{ return myCurrent != 0L; }
|
||||
//! Go to the next iteration.
|
||||
Standard_EXPORT void Next ();
|
||||
//! Get the current iterated triangle
|
||||
inline const Poly_CoherentTriangle& Value () const
|
||||
{ return myCurrent->GetTriangle(); }
|
||||
//! Get the current iterated triangle (mutable)
|
||||
inline Poly_CoherentTriangle& ChangeValue () const
|
||||
{ return const_cast<Poly_CoherentTriangle&>(myCurrent->GetTriangle()); }
|
||||
//! Get the current iterated pointer to triangle
|
||||
inline const Poly_CoherentTriPtr& PtrValue() const
|
||||
{ return * myCurrent; }
|
||||
private:
|
||||
const Poly_CoherentTriPtr * myFirst;
|
||||
const Poly_CoherentTriPtr * myCurrent;
|
||||
};
|
||||
|
||||
// ---------- PUBLIC METHODS ----------
|
||||
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
inline Poly_CoherentTriPtr (const Poly_CoherentTriangle& theTri)
|
||||
: mypTriangle (&theTri),
|
||||
myNext (this),
|
||||
myPrevious (this)
|
||||
{}
|
||||
|
||||
/**
|
||||
* Operator new for dynamic allocations
|
||||
*/
|
||||
void* operator new (Standard_Size theSize,
|
||||
const Handle(NCollection_BaseAllocator)& theAllocator)
|
||||
{
|
||||
return theAllocator->Allocate(theSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Query the stored pointer to Triangle.
|
||||
*/
|
||||
inline const Poly_CoherentTriangle&
|
||||
GetTriangle () const
|
||||
{ return * mypTriangle; }
|
||||
|
||||
/**
|
||||
* Initialize this instance with a pointer to triangle.
|
||||
*/
|
||||
inline void SetTriangle (const Poly_CoherentTriangle * pTri)
|
||||
{ mypTriangle = pTri; }
|
||||
|
||||
/**
|
||||
* Query the next pointer in the list.
|
||||
*/
|
||||
inline Poly_CoherentTriPtr&
|
||||
Next () const
|
||||
{ return * myNext; }
|
||||
|
||||
/**
|
||||
* Query the previous pointer in the list.
|
||||
*/
|
||||
inline Poly_CoherentTriPtr&
|
||||
Previous () const
|
||||
{ return * myPrevious; }
|
||||
|
||||
/**
|
||||
* Append a pointer to triangle into the list after the current instance.
|
||||
* @param pTri
|
||||
* Triangle that is to be included in the list after this one.
|
||||
* @param theA
|
||||
* Allocator where the new pointer instance is created.
|
||||
*/
|
||||
Standard_EXPORT void Append (const Poly_CoherentTriangle * pTri,
|
||||
const Handle_NCollection_BaseAllocator& theA);
|
||||
|
||||
/**
|
||||
* Prepend a pointer to triangle into the list before the current instance.
|
||||
* @param pTri
|
||||
* Triangle that is to be included in the list before this one.
|
||||
* @param theA
|
||||
* Allocator where the new pointer instance is created.
|
||||
*/
|
||||
Standard_EXPORT void Prepend (const Poly_CoherentTriangle * pTri,
|
||||
const Handle_NCollection_BaseAllocator& theA);
|
||||
|
||||
/**
|
||||
* Remove a pointer to triangle from its list.
|
||||
* @param thePtr
|
||||
* This class instance that should be removed from its list.
|
||||
* @param theA
|
||||
* Allocator where the current pointer instance was created.
|
||||
*/
|
||||
Standard_EXPORT static void
|
||||
Remove (Poly_CoherentTriPtr * thePtr,
|
||||
const Handle_NCollection_BaseAllocator& theA);
|
||||
|
||||
/**
|
||||
* Remove the list containing the given pointer to triangle.
|
||||
*/
|
||||
Standard_EXPORT static void
|
||||
RemoveList (Poly_CoherentTriPtr * thePtr,
|
||||
const Handle_NCollection_BaseAllocator&);
|
||||
|
||||
protected:
|
||||
// ---------- PROTECTED METHODS ----------
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
inline Poly_CoherentTriPtr (const Poly_CoherentTriangle * pTri)
|
||||
: mypTriangle (pTri),
|
||||
myNext (this),
|
||||
myPrevious (this)
|
||||
{}
|
||||
|
||||
private:
|
||||
// ---------- PRIVATE FIELDS ----------
|
||||
|
||||
const Poly_CoherentTriangle * mypTriangle;
|
||||
Poly_CoherentTriPtr * myNext;
|
||||
Poly_CoherentTriPtr * myPrevious;
|
||||
|
||||
friend class Iterator;
|
||||
};
|
||||
|
||||
#ifdef WNT
|
||||
#pragma warning (pop)
|
||||
#endif
|
||||
|
||||
#endif
|
280
src/Poly/Poly_CoherentTriangle.cxx
Executable file
280
src/Poly/Poly_CoherentTriangle.cxx
Executable file
@@ -0,0 +1,280 @@
|
||||
// File: Poly_CoherentTriangle.cxx
|
||||
// Created: 25.11.07 13:54
|
||||
// Author: Alexander GRIGORIEV
|
||||
// Copyright: Open Cascade 2007
|
||||
|
||||
|
||||
#include <Poly_CoherentTriangle.hxx>
|
||||
#include <Standard_ProgramError.hxx>
|
||||
|
||||
//=======================================================================
|
||||
//function : Poly_CoherentTriangle()
|
||||
//purpose : Empty Constructor
|
||||
//=======================================================================
|
||||
|
||||
Poly_CoherentTriangle::Poly_CoherentTriangle ()
|
||||
: myNConnections (0)
|
||||
{
|
||||
myNodes[0] = -1;
|
||||
myNodes[1] = -1;
|
||||
myNodes[2] = -1;
|
||||
myNodesOnConnected[0] = -1;
|
||||
myNodesOnConnected[1] = -1;
|
||||
myNodesOnConnected[2] = -1;
|
||||
mypConnected[0] = 0L;
|
||||
mypConnected[1] = 0L;
|
||||
mypConnected[2] = 0L;
|
||||
mypLink[0] = 0L;
|
||||
mypLink[1] = 0L;
|
||||
mypLink[2] = 0L;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Poly_CoherentTriangle()
|
||||
//purpose : Constructor
|
||||
//=======================================================================
|
||||
|
||||
Poly_CoherentTriangle::Poly_CoherentTriangle (const Standard_Integer iNode0,
|
||||
const Standard_Integer iNode1,
|
||||
const Standard_Integer iNode2)
|
||||
: myNConnections (0)
|
||||
{
|
||||
myNodes[0] = iNode0;
|
||||
myNodes[1] = iNode1;
|
||||
myNodes[2] = iNode2;
|
||||
myNodesOnConnected[0] = -1;
|
||||
myNodesOnConnected[1] = -1;
|
||||
myNodesOnConnected[2] = -1;
|
||||
mypConnected[0] = 0L;
|
||||
mypConnected[1] = 0L;
|
||||
mypConnected[2] = 0L;
|
||||
mypLink[0] = 0L;
|
||||
mypLink[1] = 0L;
|
||||
mypLink[2] = 0L;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SetConnection
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean Poly_CoherentTriangle::SetConnection
|
||||
(const Standard_Integer iConn,
|
||||
Poly_CoherentTriangle& theTr)
|
||||
{
|
||||
Standard_Boolean aResult(Standard_False);
|
||||
static const Standard_Integer II[] = { 2, 0, 1, 2, 0 };
|
||||
|
||||
if (theTr.Node(0) == myNodes[II[iConn+2]]) {
|
||||
if (theTr.Node(2) == myNodes[II[iConn]]) {
|
||||
RemoveConnection(iConn);
|
||||
myNodesOnConnected[iConn] = theTr.Node(1);
|
||||
mypConnected[iConn] = &theTr;
|
||||
myNConnections++;
|
||||
theTr.RemoveConnection(1);
|
||||
theTr.myNodesOnConnected[1] = myNodes[iConn];
|
||||
theTr.mypConnected[1] = this;
|
||||
theTr.myNConnections++;
|
||||
aResult = Standard_True;
|
||||
}
|
||||
} else if (theTr.Node(1) == myNodes[II[iConn+2]]) {
|
||||
if (theTr.Node(0) == myNodes[II[iConn]]) {
|
||||
RemoveConnection(iConn);
|
||||
myNodesOnConnected[iConn] = theTr.Node(2);
|
||||
mypConnected[iConn] = &theTr;
|
||||
myNConnections++;
|
||||
theTr.RemoveConnection(2);
|
||||
theTr.myNodesOnConnected[2] = myNodes[iConn];
|
||||
theTr.mypConnected[2] = this;
|
||||
theTr.myNConnections++;
|
||||
aResult = Standard_True;
|
||||
}
|
||||
} else if (theTr.Node(2) == myNodes[II[iConn+2]]) {
|
||||
if (theTr.Node(1) == myNodes[II[iConn]]) {
|
||||
RemoveConnection(iConn);
|
||||
myNodesOnConnected[iConn] = theTr.Node(0);
|
||||
mypConnected[iConn] = &theTr;
|
||||
myNConnections++;
|
||||
theTr.RemoveConnection(0);
|
||||
theTr.myNodesOnConnected[0] = myNodes[iConn];
|
||||
theTr.mypConnected[0] = this;
|
||||
theTr.myNConnections++;
|
||||
aResult = Standard_True;
|
||||
}
|
||||
}
|
||||
return aResult;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SetConnection
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean Poly_CoherentTriangle::SetConnection
|
||||
(Poly_CoherentTriangle& theTr)
|
||||
{
|
||||
Standard_Boolean aResult(Standard_False);
|
||||
if (myNodes[0] == theTr.Node(0)) {
|
||||
if (myNodes[1] == theTr.Node(2) && mypConnected[2] != &theTr) {
|
||||
RemoveConnection(2);
|
||||
myNodesOnConnected[2] = theTr.Node(1);
|
||||
mypConnected[2] = &theTr;
|
||||
myNConnections++;
|
||||
theTr.RemoveConnection(1);
|
||||
theTr.myNodesOnConnected[1] = myNodes[2];
|
||||
theTr.mypConnected[1] = this;
|
||||
theTr.myNConnections++;
|
||||
aResult = Standard_True;
|
||||
} else if (myNodes[2] == theTr.Node(1) && mypConnected[1] != &theTr) {
|
||||
RemoveConnection(1);
|
||||
myNodesOnConnected[1] = theTr.Node(2);
|
||||
mypConnected[1] = &theTr;
|
||||
myNConnections++;
|
||||
theTr.RemoveConnection(2);
|
||||
theTr.myNodesOnConnected[2] = myNodes[1];
|
||||
theTr.mypConnected[2] = this;
|
||||
theTr.myNConnections++;
|
||||
aResult = Standard_True;
|
||||
}
|
||||
} else if (myNodes[0] == theTr.Node(1)) {
|
||||
if (myNodes[1] == theTr.Node(0) && mypConnected[2] != &theTr) {
|
||||
RemoveConnection(2);
|
||||
myNodesOnConnected[2] = theTr.Node(2);
|
||||
mypConnected[2] = &theTr;
|
||||
myNConnections++;
|
||||
theTr.RemoveConnection(2);
|
||||
theTr.myNodesOnConnected[2] = myNodes[2];
|
||||
theTr.mypConnected[2] = this;
|
||||
theTr.myNConnections++;
|
||||
aResult = Standard_True;
|
||||
} else if (myNodes[2] == theTr.Node(2) && mypConnected[1] != &theTr) {
|
||||
RemoveConnection(1);
|
||||
myNodesOnConnected[1] = theTr.Node(0);
|
||||
mypConnected[1] = &theTr;
|
||||
myNConnections++;
|
||||
theTr.RemoveConnection(0);
|
||||
theTr.myNodesOnConnected[0] = myNodes[1];
|
||||
theTr.mypConnected[0] = this;
|
||||
theTr.myNConnections++;
|
||||
aResult = Standard_True;
|
||||
}
|
||||
} else if (myNodes[0] == theTr.Node(2)) {
|
||||
if (myNodes[1] == theTr.Node(1) && mypConnected[2] != &theTr) {
|
||||
RemoveConnection(2);
|
||||
myNodesOnConnected[2] = theTr.Node(0);
|
||||
mypConnected[2] = &theTr;
|
||||
myNConnections++;
|
||||
theTr.RemoveConnection(0);
|
||||
theTr.myNodesOnConnected[0] = myNodes[2];
|
||||
theTr.mypConnected[0] = this;
|
||||
theTr.myNConnections++;
|
||||
aResult = Standard_True;
|
||||
} else if (myNodes[2] == theTr.Node(0) && mypConnected[1] != &theTr) {
|
||||
RemoveConnection(1);
|
||||
myNodesOnConnected[1] = theTr.Node(1);
|
||||
mypConnected[1] = &theTr;
|
||||
myNConnections++;
|
||||
theTr.RemoveConnection(1);
|
||||
theTr.myNodesOnConnected[1] = myNodes[1];
|
||||
theTr.mypConnected[1] = this;
|
||||
theTr.myNConnections++;
|
||||
aResult = Standard_True;
|
||||
}
|
||||
} else if (mypConnected[0] != &theTr) {
|
||||
if (myNodes[1] == theTr.Node(0) && myNodes[2] == theTr.Node(2)) {
|
||||
RemoveConnection(0);
|
||||
myNodesOnConnected[0] = theTr.Node(1);
|
||||
mypConnected[0] = &theTr;
|
||||
myNConnections++;
|
||||
theTr.RemoveConnection(1);
|
||||
theTr.myNodesOnConnected[1] = myNodes[0];
|
||||
theTr.mypConnected[1] = this;
|
||||
theTr.myNConnections++;
|
||||
aResult = Standard_True;
|
||||
} else if (myNodes[1] == theTr.Node(2) && myNodes[2] == theTr.Node(1)) {
|
||||
RemoveConnection(0);
|
||||
myNodesOnConnected[0] = theTr.Node(0);
|
||||
mypConnected[0] = &theTr;
|
||||
myNConnections++;
|
||||
theTr.RemoveConnection(0);
|
||||
theTr.myNodesOnConnected[0] = myNodes[0];
|
||||
theTr.mypConnected[0] = this;
|
||||
theTr.myNConnections++;
|
||||
aResult = Standard_True;
|
||||
} else if (myNodes[1] == theTr.Node(1) && myNodes[2] == theTr.Node(0)) {
|
||||
RemoveConnection(0);
|
||||
myNodesOnConnected[0] = theTr.Node(2);
|
||||
mypConnected[0] = &theTr;
|
||||
myNConnections++;
|
||||
theTr.RemoveConnection(2);
|
||||
theTr.myNodesOnConnected[2] = myNodes[0];
|
||||
theTr.mypConnected[2] = this;
|
||||
theTr.myNConnections++;
|
||||
aResult = Standard_True;
|
||||
}
|
||||
}
|
||||
return aResult;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : RemoveConnection
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void Poly_CoherentTriangle::RemoveConnection(const Standard_Integer iConn)
|
||||
{
|
||||
Poly_CoherentTriangle * pConnectedTri =
|
||||
const_cast<Poly_CoherentTriangle *> (mypConnected[iConn]);
|
||||
if (pConnectedTri) {
|
||||
Standard_Integer iConn1(0);
|
||||
if (pConnectedTri->mypConnected[0] != this) {
|
||||
if (pConnectedTri->mypConnected[1] == this)
|
||||
iConn1 = 1;
|
||||
else if (pConnectedTri->mypConnected[2] == this)
|
||||
iConn1 = 2;
|
||||
else
|
||||
Standard_ProgramError::Raise("Poly_CoherentTriangle::RemoveConnection: "
|
||||
"wrong connection between triangles");
|
||||
}
|
||||
pConnectedTri->mypConnected[iConn1] = 0L;
|
||||
pConnectedTri->myNodesOnConnected[iConn1] = -1;
|
||||
pConnectedTri->myNConnections--;
|
||||
mypConnected[iConn] = 0L;
|
||||
myNodesOnConnected[iConn] = -1;
|
||||
myNConnections--;
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : RemoveConnection
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean Poly_CoherentTriangle::RemoveConnection
|
||||
(Poly_CoherentTriangle& theTri)
|
||||
{
|
||||
const Standard_Integer iConn = FindConnection(theTri);
|
||||
if (iConn >= 0)
|
||||
RemoveConnection(iConn);
|
||||
return (iConn >= 0);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FindConnection
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Integer Poly_CoherentTriangle::FindConnection
|
||||
(const Poly_CoherentTriangle& theTri) const
|
||||
{
|
||||
Standard_Integer aResult;
|
||||
if (mypConnected[0] == &theTri)
|
||||
aResult = 0;
|
||||
else if (mypConnected[1] == &theTri)
|
||||
aResult = 1;
|
||||
else if (mypConnected[2] == &theTri)
|
||||
aResult = 2;
|
||||
else
|
||||
aResult = -1;
|
||||
return aResult;
|
||||
}
|
157
src/Poly/Poly_CoherentTriangle.hxx
Executable file
157
src/Poly/Poly_CoherentTriangle.hxx
Executable file
@@ -0,0 +1,157 @@
|
||||
// File: Poly_CoherentTriangle.hxx
|
||||
// Created: 24.11.07 14:36
|
||||
// Author: Alexander GRIGORIEV
|
||||
// Copyright: Open Cascade 2007
|
||||
|
||||
|
||||
#ifndef Poly_CoherentTriangle_HeaderFile
|
||||
#define Poly_CoherentTriangle_HeaderFile
|
||||
|
||||
#include <Standard_TypeDef.hxx>
|
||||
|
||||
class Poly_CoherentTrianguation;
|
||||
class Poly_CoherentLink;
|
||||
|
||||
/**
|
||||
* Data class used in Poly_CoherentTriangultion.
|
||||
* Implements a triangle with references to its neighbours.
|
||||
*/
|
||||
|
||||
class Poly_CoherentTriangle
|
||||
{
|
||||
public:
|
||||
// ---------- PUBLIC METHODS ----------
|
||||
|
||||
/**
|
||||
* Empty constructor.
|
||||
*/
|
||||
Standard_EXPORT Poly_CoherentTriangle ();
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
Standard_EXPORT Poly_CoherentTriangle (const Standard_Integer iNode0,
|
||||
const Standard_Integer iNode1,
|
||||
const Standard_Integer iNode2);
|
||||
|
||||
/**
|
||||
* Query the node index in the position given by the parameter 'ind'
|
||||
*/
|
||||
inline Standard_Integer Node (const Standard_Integer ind) const
|
||||
{ return myNodes[ind]; }
|
||||
|
||||
// /**
|
||||
// * Set the Node at the given position 'ind'.
|
||||
// */
|
||||
// inline void SetNode (const Standard_Integer ind,
|
||||
// const Standard_Integer iNode)
|
||||
// { myNodes[ind] = iNode; }
|
||||
|
||||
/**
|
||||
* Query if this is a valid triangle.
|
||||
*/
|
||||
inline Standard_Boolean IsEmpty () const
|
||||
{ return myNodes[0] < 0 || myNodes[1] < 0 || myNodes[2] < 0; }
|
||||
|
||||
/**
|
||||
* Create connection with another triangle theTri.
|
||||
* This method creates both connections: in this triangle and in theTri. You
|
||||
* do not need to call the same method on triangle theTr.
|
||||
* @param iConn
|
||||
* Can be 0, 1 or 2 - index of the node that is opposite to the connection
|
||||
* (shared link).
|
||||
* @param theTr
|
||||
* Triangle that is connected on the given link.
|
||||
* @return
|
||||
* True if successful, False if the connection is rejected
|
||||
* due to improper topology.
|
||||
*/
|
||||
Standard_EXPORT Standard_Boolean
|
||||
SetConnection (const Standard_Integer iConn,
|
||||
Poly_CoherentTriangle& theTr);
|
||||
|
||||
/**
|
||||
* Create connection with another triangle theTri.
|
||||
* This method creates both connections: in this triangle and in theTri.
|
||||
* This method is slower than the previous one, because it makes analysis
|
||||
* what sides of both triangles are connected.
|
||||
* @param theTri
|
||||
* Triangle that is connected.
|
||||
* @return
|
||||
* True if successful, False if the connection is rejected
|
||||
* due to improper topology.
|
||||
*/
|
||||
Standard_EXPORT Standard_Boolean
|
||||
SetConnection (Poly_CoherentTriangle& theTri);
|
||||
|
||||
/**
|
||||
* Remove the connection with the given index.
|
||||
* @param iConn
|
||||
* Can be 0, 1 or 2 - index of the node that is opposite to the connection
|
||||
* (shared link).
|
||||
*/
|
||||
Standard_EXPORT void RemoveConnection(const Standard_Integer iConn);
|
||||
|
||||
/**
|
||||
* Remove the connection with the given Triangle.
|
||||
* @return
|
||||
* True if successfuol or False if the connection has not been found.
|
||||
*/
|
||||
Standard_EXPORT Standard_Boolean
|
||||
RemoveConnection(Poly_CoherentTriangle& theTri);
|
||||
|
||||
/**
|
||||
* Query the number of connected triangles.
|
||||
*/
|
||||
inline Standard_Integer NConnections () const
|
||||
{ return myNConnections; }
|
||||
|
||||
/**
|
||||
* Query the connected node on the given side.
|
||||
* Returns -1 if there is no connection on the specified side.
|
||||
*/
|
||||
inline Standard_Integer GetConnectedNode(const Standard_Integer iConn) const
|
||||
{ return myNodesOnConnected[iConn]; }
|
||||
|
||||
/**
|
||||
* Query the connected triangle on the given side.
|
||||
* Returns NULL if there is no connection on the specified side.
|
||||
*/
|
||||
inline const Poly_CoherentTriangle *
|
||||
GetConnectedTri (const Standard_Integer iConn) const
|
||||
{ return mypConnected[iConn]; }
|
||||
|
||||
/**
|
||||
* Query the Link associate with the given side of the Triangle.
|
||||
* May return NULL if there are no links in the triangulation.
|
||||
*/
|
||||
inline const Poly_CoherentLink *
|
||||
GetLink (const Standard_Integer iLink) const
|
||||
{ return mypLink[iLink]; }
|
||||
|
||||
/**
|
||||
* Retuns the index of the connection with the given triangle, or -1 if not
|
||||
* found.
|
||||
*/
|
||||
Standard_EXPORT Standard_Integer
|
||||
FindConnection (const Poly_CoherentTriangle&) const;
|
||||
|
||||
protected:
|
||||
// ---------- PROTECTED METHODS ----------
|
||||
|
||||
|
||||
|
||||
private:
|
||||
// ---------- PRIVATE FIELDS ----------
|
||||
|
||||
Standard_Integer myNConnections;
|
||||
Standard_Integer myNodes[3];
|
||||
Standard_Integer myNodesOnConnected[3];
|
||||
const Poly_CoherentTriangle * mypConnected[3];
|
||||
const Poly_CoherentLink * mypLink[3];
|
||||
|
||||
friend class Poly_CoherentTriangulation;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
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);
|
||||
}
|
||||
}
|
405
src/Poly/Poly_CoherentTriangulation.hxx
Executable file
405
src/Poly/Poly_CoherentTriangulation.hxx
Executable file
@@ -0,0 +1,405 @@
|
||||
// File: Poly_CoherentTriangulation.hxx
|
||||
// Created: 24.11.07 14:24
|
||||
// Author: Alexander GRIGORIEV
|
||||
// Copyright: Open Cascade 2007
|
||||
|
||||
|
||||
#ifndef Poly_CoherentTriangulation_HeaderFile
|
||||
#define Poly_CoherentTriangulation_HeaderFile
|
||||
|
||||
#include <Handle_Poly_Triangulation.hxx>
|
||||
#include <Poly_CoherentNode.hxx>
|
||||
#include <Poly_CoherentTriangle.hxx>
|
||||
#include <Poly_CoherentLink.hxx>
|
||||
#include <NCollection_Vector.hxx>
|
||||
|
||||
class Handle_Poly_CoherentTriangulation;
|
||||
class Poly_CoherentTriangulation;
|
||||
template <class A> class NCollection_List;
|
||||
|
||||
typedef NCollection_Vector<Poly_CoherentTriangle>::Iterator
|
||||
Poly_BaseIteratorOfCoherentTriangle;
|
||||
typedef NCollection_Vector<Poly_CoherentNode>::Iterator
|
||||
Poly_BaseIteratorOfCoherentNode;
|
||||
typedef NCollection_Vector<Poly_CoherentLink>::Iterator
|
||||
Poly_BaseIteratorOfCoherentLink;
|
||||
|
||||
/**
|
||||
* Triangulation structure that allows to:
|
||||
* <ul>
|
||||
* <li>Store the connectivity of each triangle with up to 3 neighbouring ones
|
||||
* and with the corresponding 3rd nodes on them,</li>
|
||||
* <li>Store the connectivity of each node with all triangles that share this
|
||||
* node</li>
|
||||
* <li>Add nodes and triangles to the structure,</li>
|
||||
* <li>Find all triangles sharing a single or a couple of nodes</li>
|
||||
* <li>Remove triangles from structure</li>
|
||||
* <li>Optionally create Links between pairs of nodes according to the current
|
||||
* triangulation.
|
||||
* <li>Convert from/to Poly_Triangulation structure.</li>
|
||||
* </ul>
|
||||
* This class is useful for algorithms that need to analyse and/or edit a
|
||||
* triangulated mesh -- for example for mesh refining. The connectivity model
|
||||
* follows the idea that all Triangles in a mesh should have coherent orientation
|
||||
* like on a surface of a solid body. Connections between more than 2 triangles
|
||||
* are not suppoorted.
|
||||
* @section Poly_CoherentTriangulation Architecture
|
||||
* The data types used in this structure are:
|
||||
* <ul>
|
||||
* <li><b>Poly_CoherentNode</b>: Inherits go_XYZ therefore provides the full
|
||||
* public API of gp_XYZ. Contains references to all incident triangles. You
|
||||
* can add new nodes but you cannot remove existing ones. However each node
|
||||
* that has no referenced triangle is considered as "free" (use the method
|
||||
* IsFreeNode() to check this). Free nodes are not available to further
|
||||
* processing, particularly they are not exported in Poly_Triangulation.
|
||||
* </li>
|
||||
* <li><b>Poly_CoherentTriangle</b>: Main data type. Refers three Nodes, three
|
||||
* connected Triangles, three opposite (connected) Nodes and three Links.
|
||||
* If there is boundary then 1, 2 or 3 references to Triangles/connected
|
||||
* Nodes/Links are assigned to NULL (for pointers) or -1 (for integer
|
||||
* node index).
|
||||
* <br>
|
||||
* You can find a triangle by one node using its triangle iterator or by
|
||||
* two nodes - creating a temporary Poly_CoherentLink and calling the method
|
||||
* FindTriangle().
|
||||
* <br>
|
||||
* Triangles can be removed but they are never deleted from
|
||||
* the containing array. Removed triangles have all nodes equal to -1. You
|
||||
* can use the method IsEmpty() to check that.
|
||||
* </li>
|
||||
* <li><b>Poly_CoherentLink</b>: Auxiliary data type. Normally the array of
|
||||
* Links is empty, because for many algorithms it is sufficient to define
|
||||
* only Triangles. You can explicitly create the Links at least once,
|
||||
* calling the method ComputeLinks(). Each Link is oriented couple of
|
||||
* Poly_CoherentNode (directed to the ascending Node index). It refers
|
||||
* two connected triangulated Nodes - on the left and on the right,
|
||||
* therefore a Poly_CoherentLink instance refers the full set of nodes
|
||||
* that constitute a couple of connected Triangles. A boundary Link has
|
||||
* either the first (left) or the second (right) connected node index
|
||||
* equal to -1.
|
||||
* <br>
|
||||
* When the array of Links is created, all subsequent calls to AddTriangle
|
||||
* and RemoveTriangle try to preserve the connectivity Triangle-Link in
|
||||
* addition to the connectivity Triangle-Triangle. Particularly, new Links
|
||||
* are created by method AddTriangle() and existing ones are removed by
|
||||
* method RemoveTriangle(), in each case whenever necessary.
|
||||
* <br>
|
||||
* Similarly to Poly_CoherentTriangle, a Link can be removed but not
|
||||
* destroyed separately from others. Removed Link can be recogniosed using
|
||||
* the method IsEmpty(). To destroy all Links, call the method ClearLinks(),
|
||||
* this method also nullifies Link references in all Triangles.
|
||||
* </li>
|
||||
* All objects (except for free Nodes and empty Triangles and Links) can be
|
||||
* visited by the corresponding Iterator. Direct access is provided only for
|
||||
* Nodes (needed to resolve Node indexed commonly used as reference). Triangles
|
||||
* and Links can be retrieved by their index only internally, the public API
|
||||
* provides only references or pointers to C++ objects. If you need a direct
|
||||
* access to Triangles and Links, you can subclass Poly_CoherentTriangulation
|
||||
* and use the protected API for your needs.
|
||||
* <br>
|
||||
* Memory management: All data objects are stored in NCollection_Vector
|
||||
* containers that prove to be efficient for the performance. In addition
|
||||
* references to triangles are stored in ring lists, with an instance of such
|
||||
* list per Poly_CoherentNode. These lists are allocated in a memory allocator
|
||||
* that is provided in the constructor of Poly_CoherentTriangulation. By default
|
||||
* the standard OCCT allocator (aka NCollection_BaseAllocator) is used. But if
|
||||
* you need to increase the performance you can use NCollection_IncAllocator
|
||||
* instead.
|
||||
* </ul>
|
||||
*/
|
||||
|
||||
class Poly_CoherentTriangulation : public Standard_Transient
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Subclass Iterator - allows to iterate all triangles skipping those that
|
||||
* have been removed.
|
||||
*/
|
||||
class IteratorOfTriangle : public Poly_BaseIteratorOfCoherentTriangle
|
||||
{
|
||||
public:
|
||||
//! Constructor
|
||||
Standard_EXPORT IteratorOfTriangle
|
||||
(const Handle_Poly_CoherentTriangulation& theTri);
|
||||
//! Make step
|
||||
Standard_EXPORT virtual void Next ();
|
||||
};
|
||||
|
||||
/**
|
||||
* Subclass Iterator - allows to iterate all nodes skipping the free ones.
|
||||
*/
|
||||
class IteratorOfNode : public Poly_BaseIteratorOfCoherentNode
|
||||
{
|
||||
public:
|
||||
//! Constructor
|
||||
Standard_EXPORT IteratorOfNode
|
||||
(const Handle_Poly_CoherentTriangulation& theTri);
|
||||
//! Make step
|
||||
Standard_EXPORT virtual void Next ();
|
||||
};
|
||||
|
||||
/**
|
||||
* Subclass Iterator - allows to iterate all links skipping invalid ones.
|
||||
*/
|
||||
class IteratorOfLink : public Poly_BaseIteratorOfCoherentLink
|
||||
{
|
||||
public:
|
||||
//! Constructor
|
||||
Standard_EXPORT IteratorOfLink
|
||||
(const Handle_Poly_CoherentTriangulation& theTri);
|
||||
//! Make step
|
||||
Standard_EXPORT virtual void Next ();
|
||||
};
|
||||
|
||||
//! Couple of integer indices (used in RemoveDegenerated()).
|
||||
struct TwoIntegers
|
||||
{
|
||||
Standard_Integer myValue[2];
|
||||
TwoIntegers() {}
|
||||
TwoIntegers(Standard_Integer i0, Standard_Integer i1) {
|
||||
myValue[0] = i0; myValue[1] = i1;
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
// ---------- PUBLIC METHODS ----------
|
||||
|
||||
|
||||
/**
|
||||
* Empty constructor.
|
||||
*/
|
||||
Standard_EXPORT Poly_CoherentTriangulation
|
||||
(const Handle_NCollection_BaseAllocator& theAlloc = 0L);
|
||||
|
||||
/**
|
||||
* Constructor. It does not create Links, you should call ComputeLinks
|
||||
* following this constructor if you need these links.
|
||||
*/
|
||||
Standard_EXPORT Poly_CoherentTriangulation
|
||||
(const Handle_Poly_Triangulation& theTriangulation,
|
||||
const Handle_NCollection_BaseAllocator& theAlloc = 0L);
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
Standard_EXPORT virtual ~Poly_CoherentTriangulation ();
|
||||
|
||||
/**
|
||||
* Create an instance of Poly_Triangulation from this object.
|
||||
*/
|
||||
Standard_EXPORT Handle_Poly_Triangulation
|
||||
GetTriangulation () const;
|
||||
|
||||
/**
|
||||
* Find and remove degenerated triangles in Triangulation.
|
||||
* @param theTol
|
||||
* Tolerance for the degeneration case. If any two nodes of a triangle have
|
||||
* the distance less than this tolerance, this triangle is considered
|
||||
* degenerated and therefore removed by this method.
|
||||
* @param pLstRemovedNode
|
||||
* Optional parameter. If defined, then it will receive the list of arrays
|
||||
* where the first number is the index of removed node and the seond -
|
||||
* the index of remaining node to which the mesh was reconnected.
|
||||
*/
|
||||
Standard_EXPORT Standard_Boolean RemoveDegenerated
|
||||
(const Standard_Real theTol,
|
||||
NCollection_List<TwoIntegers> * pLstRemovedNode = 0L);
|
||||
|
||||
/**
|
||||
* Create a list of free nodes. These nodes may appear as a result of any
|
||||
* custom mesh decimation or RemoveDegenerated() call. This analysis is
|
||||
* necessary if you support additional data structures based on the
|
||||
* triangulation (e.g., edges on the surface boundary).
|
||||
* @param lstNodes
|
||||
* <tt>[out]</tt> List that receives the indices of free nodes.
|
||||
*/
|
||||
Standard_EXPORT Standard_Boolean GetFreeNodes
|
||||
(NCollection_List<Standard_Integer>& lstNodes) const;
|
||||
|
||||
/**
|
||||
* Query the index of the last node in the triangulation
|
||||
*/
|
||||
inline Standard_Integer MaxNode () const
|
||||
{ return myNodes.Length() - 1; }
|
||||
|
||||
/**
|
||||
* Query the index of the last triangle in the triangulation
|
||||
*/
|
||||
inline Standard_Integer MaxTriangle () const
|
||||
{ return myTriangles.Length() - 1; }
|
||||
|
||||
/**
|
||||
* Set the Deflection value as the parameter of the given triangulation.
|
||||
*/
|
||||
inline void SetDeflection(const Standard_Real theDefl)
|
||||
{ myDeflection = theDefl; }
|
||||
|
||||
/**
|
||||
* Query the Deflection parameter (default value 0. -- if never initialized)
|
||||
*/
|
||||
inline Standard_Real Deflection () const
|
||||
{ return myDeflection; }
|
||||
|
||||
/**
|
||||
* Initialize a node
|
||||
* @param thePoint
|
||||
* 3D Coordinates of the node.
|
||||
* @param iN
|
||||
* Index of the node. If negative (default), the node is added to the
|
||||
* end of the current array of nodes.
|
||||
* @return
|
||||
* Index of the added node.
|
||||
*/
|
||||
Standard_EXPORT Standard_Integer SetNode (const gp_XYZ& thePnt,
|
||||
const Standard_Integer iN= -1);
|
||||
|
||||
/**
|
||||
* Get the node at the given index 'i'.
|
||||
*/
|
||||
inline const Poly_CoherentNode& Node (const Standard_Integer i) const
|
||||
{ return myNodes.Value(i); }
|
||||
|
||||
/**
|
||||
* Get the node at the given index 'i'.
|
||||
*/
|
||||
inline Poly_CoherentNode& ChangeNode (const Standard_Integer i)
|
||||
{ return myNodes.ChangeValue(i); }
|
||||
|
||||
/**
|
||||
* Query the total number of active nodes (i.e. nodes used by 1 or more
|
||||
* triangles)
|
||||
*/
|
||||
Standard_EXPORT Standard_Integer NNodes () const;
|
||||
|
||||
/**
|
||||
* Get the triangle at the given index 'i'.
|
||||
*/
|
||||
inline const Poly_CoherentTriangle& Triangle (const Standard_Integer i) const
|
||||
{ return myTriangles.Value(i); }
|
||||
|
||||
/**
|
||||
* Query the total number of active triangles (i.e. triangles that refer
|
||||
* nodes, non-empty ones)
|
||||
*/
|
||||
Standard_EXPORT Standard_Integer NTriangles () const;
|
||||
|
||||
/**
|
||||
* Query the total number of active Links.
|
||||
*/
|
||||
Standard_EXPORT Standard_Integer NLinks () const;
|
||||
|
||||
/**
|
||||
* Removal of a single triangle from the triangulation.
|
||||
*/
|
||||
Standard_EXPORT Standard_Boolean RemoveTriangle(Poly_CoherentTriangle& theTr);
|
||||
|
||||
/**
|
||||
* Removal of a single link from the triangulation.
|
||||
*/
|
||||
Standard_EXPORT void RemoveLink (Poly_CoherentLink& theLink);
|
||||
|
||||
/**
|
||||
* Add a triangle to the triangulation.
|
||||
* @return
|
||||
* Pointer to the added triangle instance or NULL if an error occurred.
|
||||
*/
|
||||
Standard_EXPORT Poly_CoherentTriangle *
|
||||
AddTriangle (const Standard_Integer iNode0,
|
||||
const Standard_Integer iNode1,
|
||||
const Standard_Integer iNode2);
|
||||
|
||||
/**
|
||||
* Replace nodes in the given triangle.
|
||||
* @return
|
||||
* True if operation succeeded.
|
||||
*/
|
||||
Standard_EXPORT Standard_Boolean ReplaceNodes
|
||||
(Poly_CoherentTriangle& theTriangle,
|
||||
const Standard_Integer iNode0,
|
||||
const Standard_Integer iNode1,
|
||||
const Standard_Integer iNode2);
|
||||
|
||||
/**
|
||||
* Add a single link to triangulation, based on a triangle and its side index.
|
||||
* This method does not check for coincidence with already present links.
|
||||
* @param theTri
|
||||
* Triangle that contains the link to be added.
|
||||
* @param theConn
|
||||
* Index of the side (i.e., 0, 1 0r 2) defining the added link.
|
||||
*/
|
||||
Standard_EXPORT Poly_CoherentLink *
|
||||
AddLink (const Poly_CoherentTriangle& theTri,
|
||||
const Standard_Integer theConn);
|
||||
|
||||
/**
|
||||
* Find one or two triangles that share the given couple of nodes.
|
||||
* @param theLink
|
||||
* Link (in fact, just a couple of nodes) on which the triangle is
|
||||
* searched.
|
||||
* @param pTri
|
||||
* <tt>[out]</tt> Array of two pointers to triangle. pTri[0] stores the
|
||||
* triangle to the left of the link, while pTri[1] stores the one to the
|
||||
* right of the link.
|
||||
* @return
|
||||
* True if at least one triangle is found and output as pTri.
|
||||
*/
|
||||
Standard_EXPORT Standard_Boolean FindTriangle
|
||||
(const Poly_CoherentLink& theLink,
|
||||
const Poly_CoherentTriangle* pTri[2]) const;
|
||||
|
||||
/**
|
||||
* (Re)Calculate all links in this Triangulation.
|
||||
*/
|
||||
Standard_EXPORT Standard_Integer ComputeLinks ();
|
||||
|
||||
/**
|
||||
* Clear all Links data from the Triangulation data.
|
||||
*/
|
||||
Standard_EXPORT void ClearLinks ();
|
||||
|
||||
/**
|
||||
* Query the allocator of elements, this allocator can be used for other
|
||||
* objects
|
||||
*/
|
||||
inline const Handle_NCollection_BaseAllocator&
|
||||
Allocator () const
|
||||
{
|
||||
return myAlloc;
|
||||
}
|
||||
/**
|
||||
* Create a copy of this Triangulation, using the given allocator.
|
||||
*/
|
||||
Standard_EXPORT Handle_Poly_CoherentTriangulation Clone
|
||||
(const Handle_NCollection_BaseAllocator& theAlloc) const;
|
||||
|
||||
/**
|
||||
* Debugging output.
|
||||
*/
|
||||
Standard_EXPORT void Dump (Standard_OStream&) const;
|
||||
|
||||
protected:
|
||||
// ---------- PROTECTED METHODS ----------
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
// ---------- PROTECTED FIELDS ----------
|
||||
|
||||
NCollection_Vector<Poly_CoherentTriangle> myTriangles;
|
||||
NCollection_Vector<Poly_CoherentNode> myNodes;
|
||||
NCollection_Vector<Poly_CoherentLink> myLinks;
|
||||
Handle_NCollection_BaseAllocator myAlloc;
|
||||
Standard_Real myDeflection;
|
||||
|
||||
public:
|
||||
// Declaration of CASCADE RTTI
|
||||
DEFINE_STANDARD_RTTI (Poly_CoherentTriangulation)
|
||||
|
||||
friend class IteratorOfTriangle;
|
||||
friend class IteratorOfNode;
|
||||
friend class IteratorOfLink;
|
||||
};
|
||||
|
||||
#include <Handle_Poly_CoherentTriangulation.hxx>
|
||||
|
||||
#endif
|
133
src/Poly/Poly_Connect.cdl
Executable file
133
src/Poly/Poly_Connect.cdl
Executable file
@@ -0,0 +1,133 @@
|
||||
-- File: Poly_Connect.cdl
|
||||
-- Created: Mon Mar 6 15:16:16 1995
|
||||
-- Author: Laurent PAINNOT
|
||||
-- <lpa@metrox>
|
||||
---Copyright: Matra Datavision 1995
|
||||
|
||||
|
||||
class Connect from Poly
|
||||
|
||||
---Purpose:
|
||||
-- Provides an algorithm to explore, inside a triangulation, the
|
||||
-- adjacency data for a node or a triangle.
|
||||
-- Adjacency data for a node consists of triangles which
|
||||
-- contain the node.
|
||||
-- Adjacency data for a triangle consists of:
|
||||
-- - the 3 adjacent triangles which share an edge of the triangle,
|
||||
-- - and the 3 nodes which are the other nodes of these adjacent triangles.
|
||||
-- Example
|
||||
-- Inside a triangulation, a triangle T
|
||||
-- has nodes n1, n2 and n3.
|
||||
-- It has adjacent triangles AT1, AT2 and AT3 where:
|
||||
-- - AT1 shares the nodes n2 and n3,
|
||||
-- - AT2 shares the nodes n3 and n1,
|
||||
-- - AT3 shares the nodes n1 and n2.
|
||||
-- It has adjacent nodes an1, an2 and an3 where:
|
||||
-- - an1 is the third node of AT1,
|
||||
-- - an2 is the third node of AT2,
|
||||
-- - an3 is the third node of AT3.
|
||||
-- So triangle AT1 is composed of nodes n2, n3 and an1.
|
||||
-- There are two ways of using this algorithm.
|
||||
-- - From a given node you can look for one triangle that
|
||||
-- passes through the node, then look for the triangles
|
||||
-- adjacent to this triangle, then the adjacent nodes. You
|
||||
-- can thus explore the triangulation step by step (functions
|
||||
-- Triangle, Triangles and Nodes).
|
||||
-- - From a given node you can look for all the triangles
|
||||
-- that pass through the node (iteration method, using the
|
||||
-- functions Initialize, More, Next and Value).
|
||||
-- A Connect object can be seen as a tool which analyzes a
|
||||
-- triangulation and translates it into a series of triangles. By
|
||||
-- doing this, it provides an interface with other tools and
|
||||
-- applications working on basic triangles, and which do not
|
||||
-- work directly with a Poly_Triangulation.
|
||||
|
||||
uses
|
||||
|
||||
Array1OfInteger from TColStd,
|
||||
Triangulation from Poly
|
||||
|
||||
is
|
||||
|
||||
Create (T : Triangulation from Poly) returns Connect from Poly;
|
||||
---Purpose: Constructs an algorithm to explore the adjacency data of
|
||||
-- nodes or triangles for the triangulation T.
|
||||
|
||||
Triangulation(me) returns Triangulation from Poly;
|
||||
---Purpose: Returns the triangulation analyzed by this tool.
|
||||
---C++: inline
|
||||
|
||||
Triangle(me; N : Integer) returns Integer;
|
||||
---Purpose: Returns the index of a triangle containing the node at
|
||||
-- index N in the nodes table specific to the triangulation analyzed by this tool
|
||||
---C++: inline
|
||||
|
||||
Triangles(me; T: Integer; t1, t2, t3: out Integer);
|
||||
---Purpose: Returns in t1, t2 and t3, the indices of the 3 triangles
|
||||
-- adjacent to the triangle at index T in the triangles table
|
||||
-- specific to the triangulation analyzed by this tool.
|
||||
-- Warning
|
||||
-- Null indices are returned when there are fewer than 3
|
||||
-- adjacent triangles.
|
||||
|
||||
Nodes(me; T: Integer; n1, n2, n3: out Integer);
|
||||
---Purpose: Returns, in n1, n2 and n3, the indices of the 3 nodes
|
||||
-- adjacent to the triangle referenced at index T in the
|
||||
-- triangles table specific to the triangulation analyzed by this tool.
|
||||
-- Warning
|
||||
-- Null indices are returned when there are fewer than 3 adjacent nodes.
|
||||
|
||||
Initialize(me: in out; N: Integer);
|
||||
---Purpose: Initializes an iterator to search for all the triangles
|
||||
-- containing the node referenced at index N in the nodes
|
||||
-- table, for the triangulation analyzed by this tool.
|
||||
-- The iterator is managed by the following functions:
|
||||
-- - More, which checks if there are still elements in the iterator
|
||||
-- - Next, which positions the iterator on the next element
|
||||
-- - Value, which returns the current element.
|
||||
-- The use of such an iterator provides direct access to the
|
||||
-- triangles around a particular node, i.e. it avoids iterating on
|
||||
-- all the component triangles of a triangulation.
|
||||
-- Example
|
||||
-- Poly_Connect C(Tr);
|
||||
-- for
|
||||
-- (C.Initialize(n1);C.More();C.Next())
|
||||
-- {
|
||||
-- t = C.Value();
|
||||
-- }
|
||||
|
||||
More(me) returns Boolean;
|
||||
---Purpose: Returns true if there is another element in the iterator
|
||||
-- defined with the function Initialize (i.e. if there is another
|
||||
-- triangle containing the given node).
|
||||
---C++: inline
|
||||
|
||||
|
||||
Next(me: in out)
|
||||
---Purpose: Advances the iterator defined with the function Initialize to
|
||||
-- access the next triangle.
|
||||
-- Note: There is no action if the iterator is empty (i.e. if the
|
||||
-- function More returns false).-
|
||||
is static;
|
||||
|
||||
|
||||
Value(me) returns Integer;
|
||||
---Purpose: Returns the index of the current triangle to which the
|
||||
-- iterator, defined with the function Initialize, points. This is
|
||||
-- an index in the triangles table specific to the triangulation
|
||||
-- analyzed by this tool
|
||||
|
||||
|
||||
fields
|
||||
|
||||
myTriangulation : Triangulation from Poly;
|
||||
myTriangles : Array1OfInteger from TColStd;
|
||||
myAdjacents : Array1OfInteger from TColStd;
|
||||
mytr : Integer from Standard;
|
||||
myfirst : Integer from Standard;
|
||||
mynode : Integer from Standard;
|
||||
myothernode : Integer from Standard;
|
||||
mysense : Boolean from Standard;
|
||||
mymore : Boolean from Standard;
|
||||
|
||||
end Connect;
|
280
src/Poly/Poly_Connect.cxx
Executable file
280
src/Poly/Poly_Connect.cxx
Executable file
@@ -0,0 +1,280 @@
|
||||
// File: Poly_Connect.cxx
|
||||
// Created: Mon Mar 6 16:30:09 1995
|
||||
// Author: Laurent PAINNOT
|
||||
// <lpa@metrox>
|
||||
|
||||
|
||||
#include <Poly_Connect.ixx>
|
||||
#include <Poly_Triangle.hxx>
|
||||
|
||||
#include <Standard.hxx>
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : Poly_Connect
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
// this structure records one of the edges starting from a node
|
||||
|
||||
//typedef struct polyedge {
|
||||
struct polyedge {
|
||||
polyedge* next; // the next edge in the list
|
||||
Standard_Integer nd; // the second node of the edge
|
||||
Standard_Integer nt[2]; // the two adjacent triangles
|
||||
Standard_Integer nn[2]; // the two adjacent nodes
|
||||
void* operator new(size_t aSize)
|
||||
{return (void*)(Standard::Allocate(aSize));}
|
||||
// void operator delete(void* aNode, size_t aSize) {
|
||||
void operator delete(void* aNode) {
|
||||
Standard_Address anAdress = (Standard_Address)aNode;
|
||||
Standard::Free(anAdress);
|
||||
}
|
||||
};
|
||||
|
||||
Poly_Connect::Poly_Connect(const Handle(Poly_Triangulation)& T) :
|
||||
myTriangulation(T),
|
||||
myTriangles(1,T->NbNodes()),
|
||||
myAdjacents(1,6*T->NbTriangles())
|
||||
{
|
||||
myTriangles.Init(0);
|
||||
myAdjacents.Init(0);
|
||||
Standard_Integer nbNodes = myTriangulation->NbNodes();
|
||||
Standard_Integer nbTriangles = myTriangulation->NbTriangles();
|
||||
|
||||
// We first build an array of the list of edges connected to the nodes
|
||||
|
||||
|
||||
|
||||
// create an array to store the edges starting from the vertices
|
||||
|
||||
Standard_Integer i;
|
||||
// the last node is not used because edges are stored at the lower node index
|
||||
polyedge** edges = new polyedge*[nbNodes];
|
||||
for (i = 0; i < nbNodes; i++) edges[i] = 0;
|
||||
|
||||
|
||||
// loop on the triangles
|
||||
Standard_Integer j,k,n[3],n1,n2;
|
||||
const Poly_Array1OfTriangle& triangles = myTriangulation->Triangles();
|
||||
|
||||
for (i = 1; i <= nbTriangles; i++) {
|
||||
|
||||
// get the nodes
|
||||
triangles(i).Get(n[0],n[1],n[2]);
|
||||
|
||||
// Update the myTriangles array
|
||||
myTriangles(n[0]) = i;
|
||||
myTriangles(n[1]) = i;
|
||||
myTriangles(n[2]) = i;
|
||||
|
||||
// update the edge lists
|
||||
for (j = 0; j < 3; j++) {
|
||||
k = (j+1) % 3; // the following node of the edge
|
||||
if (n[j] <= n[k]) {
|
||||
n1 = n[j];
|
||||
n2 = n[k];
|
||||
}
|
||||
else {
|
||||
n1 = n[k];
|
||||
n2 = n[j];
|
||||
}
|
||||
|
||||
// edge from n1 to n2 with n1 < n2
|
||||
// insert in the list of n1
|
||||
|
||||
polyedge* ced = edges[n1];
|
||||
while (ced != 0) {
|
||||
// the edge already exists
|
||||
if (ced->nd == n2)
|
||||
break;
|
||||
else
|
||||
ced = ced->next;
|
||||
}
|
||||
|
||||
if (ced == 0) {
|
||||
// create the edge if not found
|
||||
ced = new polyedge;
|
||||
ced->next = edges[n1];
|
||||
edges[n1] = ced;
|
||||
ced->nd = n2;
|
||||
ced->nt[0] = i;
|
||||
ced->nn[0] = n[3-j-k]; // the third node
|
||||
ced->nt[1] = 0;
|
||||
ced->nn[1] = 0;
|
||||
}
|
||||
else {
|
||||
// just mark the adjacency if found
|
||||
ced->nt[1] = i;
|
||||
ced->nn[1] = n[3-j-k]; // the third node
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// now complete the myAdjacents array
|
||||
|
||||
Standard_Integer index = 1;
|
||||
for (i = 1; i <= nbTriangles; i++) {
|
||||
|
||||
// get the nodes
|
||||
triangles(i).Get(n[0],n[1],n[2]);
|
||||
|
||||
// fore each edge
|
||||
for (j = 0; j < 3; j++) {
|
||||
k = (j+1) % 3; // the following node of the edge
|
||||
if (n[j] <= n[k]) {
|
||||
n1 = n[j];
|
||||
n2 = n[k];
|
||||
}
|
||||
else {
|
||||
n1 = n[k];
|
||||
n2 = n[j];
|
||||
}
|
||||
|
||||
// edge from n1 to n2 with n1 < n2
|
||||
// find in the list of n1
|
||||
|
||||
polyedge* ced = edges[n1];
|
||||
while (ced->nd != n2)
|
||||
ced = ced->next;
|
||||
|
||||
// Find the adjacent triangle
|
||||
Standard_Integer l = 0;
|
||||
if (ced->nt[0] == i) l = 1;
|
||||
|
||||
myAdjacents(index) = ced->nt[l];
|
||||
myAdjacents(index+3) = ced->nn[l];
|
||||
index++;
|
||||
}
|
||||
index += 3;
|
||||
}
|
||||
|
||||
// destroy the edges array
|
||||
for (i = 0; i < nbNodes; i++) {
|
||||
polyedge* ced = edges[i];
|
||||
while (ced != 0) {
|
||||
polyedge* tmp = ced->next;
|
||||
delete ced;
|
||||
ced = tmp;
|
||||
}
|
||||
}
|
||||
delete [] edges;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Triangles
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void Poly_Connect::Triangles(const Standard_Integer T,
|
||||
Standard_Integer& t1,
|
||||
Standard_Integer& t2,
|
||||
Standard_Integer& t3) const
|
||||
{
|
||||
Standard_Integer index = 6*(T-1);
|
||||
t1 = myAdjacents(index+1);
|
||||
t2 = myAdjacents(index+2);
|
||||
t3 = myAdjacents(index+3);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Nodes
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void Poly_Connect::Nodes(const Standard_Integer T,
|
||||
Standard_Integer& n1,
|
||||
Standard_Integer& n2,
|
||||
Standard_Integer& n3) const
|
||||
{
|
||||
Standard_Integer index = 6*(T-1);
|
||||
n1 = myAdjacents(index+4);
|
||||
n2 = myAdjacents(index+5);
|
||||
n3 = myAdjacents(index+6);
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : Initialize
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void Poly_Connect::Initialize(const Standard_Integer N)
|
||||
{
|
||||
mynode = N;
|
||||
myfirst = Triangle(N);
|
||||
mytr = myfirst;
|
||||
|
||||
Standard_Integer i, no[3];
|
||||
const Poly_Array1OfTriangle& triangles = myTriangulation->Triangles();
|
||||
triangles(myfirst).Get(no[0], no[1], no[2]);
|
||||
for (i = 0; i < 3; i++)
|
||||
if (no[i] == mynode) break;
|
||||
myothernode = no[(i+2)%3];
|
||||
mysense = Standard_True;
|
||||
mymore = Standard_True;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Next
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void Poly_Connect::Next()
|
||||
{
|
||||
Standard_Integer i, j;
|
||||
static Standard_Integer n[3];
|
||||
static Standard_Integer t[3];
|
||||
const Poly_Array1OfTriangle& triangles = myTriangulation->Triangles();
|
||||
Triangles(mytr, t[0], t[1], t[2]);
|
||||
if (mysense) {
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (t[i] != 0) {
|
||||
triangles(t[i]).Get(n[0], n[1], n[2]);
|
||||
for (j = 0; j < 3; j++) {
|
||||
if ((n[j] == mynode) && (n[(j+1)%3] == myothernode)) {
|
||||
mytr = t[i];
|
||||
myothernode = n[(j+2)%3];
|
||||
mymore = (mytr != myfirst);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// sinon, depart vers la gauche.
|
||||
triangles(myfirst).Get(n[0], n[1], n[2]);
|
||||
for (i = 0; i < 3; i++)
|
||||
if (n[i] == mynode) break;
|
||||
myothernode = n[(i+1)%3];
|
||||
mysense = Standard_False;
|
||||
mytr = myfirst;
|
||||
Triangles(mytr, t[0], t[1], t[2]);
|
||||
}
|
||||
if (!mysense) {
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (t[i] != 0) {
|
||||
triangles(t[i]).Get(n[0], n[1], n[2]);
|
||||
for (j = 0; j < 3; j++) {
|
||||
if ((n[j] == mynode) && (n[(j+2)%3] == myothernode)) {
|
||||
mytr = t[i];
|
||||
myothernode = n[(j+1)%3];
|
||||
mymore = Standard_True;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
mymore = Standard_False;
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : Value
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Integer Poly_Connect::Value() const
|
||||
{
|
||||
return mytr;
|
||||
}
|
34
src/Poly/Poly_Connect.lxx
Executable file
34
src/Poly/Poly_Connect.lxx
Executable file
@@ -0,0 +1,34 @@
|
||||
// File: Poly_Connect.lxx
|
||||
// Created: Mon Mar 6 16:25:53 1995
|
||||
// Author: Laurent PAINNOT
|
||||
// <lpa@metrox>
|
||||
|
||||
//=======================================================================
|
||||
//function : Triangulation
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Handle(Poly_Triangulation) Poly_Connect::Triangulation() const
|
||||
{
|
||||
return myTriangulation;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Triangle
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Integer Poly_Connect::Triangle(const Standard_Integer N) const
|
||||
{
|
||||
return myTriangles(N);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : More
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Boolean Poly_Connect::More() const
|
||||
{
|
||||
return (mymore);
|
||||
}
|
19
src/Poly/Poly_ListOfTriangulation.hxx
Executable file
19
src/Poly/Poly_ListOfTriangulation.hxx
Executable file
@@ -0,0 +1,19 @@
|
||||
// File: Poly_ListOfTriangulation.hxx
|
||||
// Created: 21.04.08 11:12
|
||||
// Author: Alexander GRIGORIEV
|
||||
// Copyright: Open Cascade 2008
|
||||
|
||||
|
||||
#ifndef Poly_ListOfTriangulation_HeaderFile
|
||||
#define Poly_ListOfTriangulation_HeaderFile
|
||||
|
||||
#include <NCollection_List.hxx>
|
||||
#include <Handle_Poly_Triangulation.hxx>
|
||||
|
||||
/**
|
||||
* List of Poly_Triangulation instances.
|
||||
*/
|
||||
|
||||
typedef NCollection_List<Handle_Poly_Triangulation> Poly_ListOfTriangulation;
|
||||
|
||||
#endif
|
694
src/Poly/Poly_MakeLoops.cxx
Executable file
694
src/Poly/Poly_MakeLoops.cxx
Executable file
@@ -0,0 +1,694 @@
|
||||
// File: Poly_MakeLoops.cxx
|
||||
// Created: 22.10.2009
|
||||
// Author: Mikhail SAZONOV
|
||||
// Copyright: Open Cascade 2009
|
||||
|
||||
#include <Poly_MakeLoops.hxx>
|
||||
#include <NCollection_IncAllocator.hxx>
|
||||
#include <NCollection_DataMap.hxx>
|
||||
#include <gp_Dir.hxx>
|
||||
#include <gp_Dir2d.hxx>
|
||||
|
||||
#ifdef _DEBUG
|
||||
static Standard_Integer doDebug = 0;
|
||||
#endif
|
||||
|
||||
//=======================================================================
|
||||
//function : Poly_MakeLoops
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Poly_MakeLoops::Poly_MakeLoops(const Helper* theHelper,
|
||||
const Handle_NCollection_BaseAllocator& theAlloc)
|
||||
: myHelper (theHelper),
|
||||
myAlloc (theAlloc),
|
||||
myMapLink (4000, myAlloc),
|
||||
myLoops (myAlloc),
|
||||
myStartIndices (4000)
|
||||
{
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Reset
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void Poly_MakeLoops::Reset
|
||||
(const Helper* theHelper,
|
||||
const Handle_NCollection_BaseAllocator& theAlloc)
|
||||
{
|
||||
myHelper = theHelper;
|
||||
myMapLink.Clear();
|
||||
myLoops.Clear(theAlloc);
|
||||
myStartIndices.Clear();
|
||||
myAlloc = theAlloc;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : AddLink
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void Poly_MakeLoops::AddLink(const Link& theLink)
|
||||
{
|
||||
if (theLink.node1 == theLink.node2)
|
||||
return;
|
||||
Standard_Integer aInd = myMapLink.Add(theLink);
|
||||
Link& aLink = const_cast<Link&>(myMapLink(aInd));
|
||||
aLink.flags |= theLink.flags;
|
||||
#ifdef _DEBUG
|
||||
myHelper->OnAddLink (aInd, aLink);
|
||||
#endif
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ReplaceLink
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void Poly_MakeLoops::ReplaceLink(const Link& theLink, const Link& theNewLink)
|
||||
{
|
||||
if (theNewLink.node1 == theNewLink.node2)
|
||||
return;
|
||||
Standard_Integer aInd = myMapLink.Add(theLink);
|
||||
if (aInd > 0)
|
||||
{
|
||||
Link aLink;
|
||||
// replace with a null link first (workaround exception)
|
||||
myMapLink.Substitute(aInd, aLink);
|
||||
aLink = theNewLink;
|
||||
// and now put there the final value of link
|
||||
myMapLink.Substitute(aInd, aLink);
|
||||
#ifdef _DEBUG
|
||||
myHelper->OnAddLink (aInd, aLink);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SetLinkOrientation
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Poly_MakeLoops::LinkFlag Poly_MakeLoops::SetLinkOrientation
|
||||
(const Link& theLink,
|
||||
const LinkFlag theOrient)
|
||||
{
|
||||
Standard_Integer aInd = myMapLink.FindIndex(theLink);
|
||||
LinkFlag aOri = LF_None;
|
||||
if (aInd > 0)
|
||||
{
|
||||
Link& aLink = const_cast<Link&>(myMapLink(aInd));
|
||||
aOri = (LinkFlag) (aLink.flags & LF_Both);
|
||||
aLink.flags = theOrient;
|
||||
#ifdef _DEBUG
|
||||
myHelper->OnAddLink (aInd, aLink);
|
||||
#endif
|
||||
}
|
||||
return aOri;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FindLink
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Poly_MakeLoops::Link Poly_MakeLoops::FindLink(const Link& theLink) const
|
||||
{
|
||||
Standard_Integer aInd = myMapLink.FindIndex(theLink);
|
||||
Poly_MakeLoops::Link aLink;
|
||||
if (aInd > 0)
|
||||
aLink = myMapLink(aInd);
|
||||
return aLink;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Perform
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Integer Poly_MakeLoops::Perform()
|
||||
{
|
||||
// prepare the set of start indices
|
||||
myStartIndices.Clear();
|
||||
Standard_Integer i;
|
||||
for (i = 1; i <= myMapLink.Extent(); i++)
|
||||
{
|
||||
const Link& aLink = myMapLink(i);
|
||||
if (aLink.flags & LF_Fwd)
|
||||
myStartIndices.Add(i);
|
||||
if (aLink.flags & LF_Rev)
|
||||
myStartIndices.Add(-i);
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
if (doDebug)
|
||||
showBoundaryBreaks();
|
||||
#endif
|
||||
|
||||
Standard_Integer aResult = 0;
|
||||
|
||||
Handle(NCollection_IncAllocator) aTempAlloc = new NCollection_IncAllocator(4000);
|
||||
Handle(NCollection_IncAllocator) aTempAlloc1 = new NCollection_IncAllocator(4000);
|
||||
|
||||
// two pass loop
|
||||
Standard_Integer aPassNum, nbLoopsOnPass2 = 0;
|
||||
for (aPassNum=0; aPassNum < 2; aPassNum++)
|
||||
{
|
||||
myHangIndices.Clear();
|
||||
// main loop
|
||||
while (!myStartIndices.IsEmpty())
|
||||
{
|
||||
Standard_Integer aIndexS = myStartIndices.Top();
|
||||
|
||||
aTempAlloc->Reset();
|
||||
NCollection_IndexedMap<Standard_Integer> aContour (100, aTempAlloc);
|
||||
Standard_Integer aStartNumber = findContour (aIndexS, aContour, aTempAlloc, aTempAlloc1);
|
||||
#ifdef _DEBUG
|
||||
if (aStartNumber > 1)
|
||||
if (doDebug)
|
||||
{
|
||||
cout << "--- found contour with hanging links:" << endl;
|
||||
for (i = 1; i <= aContour.Extent(); i++)
|
||||
cout << " " << aContour(i);
|
||||
cout << endl;
|
||||
}
|
||||
#endif
|
||||
if (aStartNumber == 0)
|
||||
{ // error
|
||||
aResult |= RC_Failure;
|
||||
return aResult;
|
||||
}
|
||||
if (aStartNumber <= aContour.Extent())
|
||||
{
|
||||
// there is a closed loop in the contour
|
||||
if (aPassNum == 1)
|
||||
nbLoopsOnPass2++;
|
||||
acceptContour (aContour, aStartNumber);
|
||||
}
|
||||
if (aStartNumber > 1)
|
||||
{
|
||||
// it is required to mark hanging edges
|
||||
Standard_Integer aNode;
|
||||
if (aStartNumber <= aContour.Extent())
|
||||
// mark hanging edges starting from the first one till a bifurcation
|
||||
aNode = getFirstNode(aIndexS);
|
||||
else
|
||||
{
|
||||
// open contour - mark from the end back till a bifurcation
|
||||
aIndexS = aContour(aStartNumber - 1);
|
||||
aNode = getLastNode(aIndexS);
|
||||
}
|
||||
markHangChain(aNode, aIndexS);
|
||||
}
|
||||
}
|
||||
|
||||
if (aPassNum == 0)
|
||||
{
|
||||
// move hanging links to start indices to make the second pass
|
||||
TColStd_MapIteratorOfPackedMapOfInteger it(myHangIndices);
|
||||
for (; it.More(); it.Next())
|
||||
myStartIndices.Add(it.Key());
|
||||
}
|
||||
}
|
||||
#ifdef _DEBUG
|
||||
if (doDebug && nbLoopsOnPass2)
|
||||
cout << "MakeLoops: " << nbLoopsOnPass2
|
||||
<< " contours accepted on the second pass" << endl;
|
||||
#endif
|
||||
|
||||
if (!myLoops.IsEmpty())
|
||||
aResult |= RC_LoopsDone;
|
||||
if (!myHangIndices.IsEmpty())
|
||||
aResult |= RC_HangingLinks;
|
||||
return aResult;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : findContour
|
||||
//purpose : Collects edges in chain until they form a closed contour.
|
||||
// Returns the index in the map theContour where the loop starts.
|
||||
// It may return the number greater than the extent of the map by 1,
|
||||
// what means that the contour is open
|
||||
//=======================================================================
|
||||
|
||||
Standard_Integer Poly_MakeLoops::findContour
|
||||
(Standard_Integer theIndexS,
|
||||
NCollection_IndexedMap<Standard_Integer> &theContour,
|
||||
const Handle_NCollection_BaseAllocator& theTempAlloc,
|
||||
const Handle_NCollection_IncAllocator& theTempAlloc1) const
|
||||
{
|
||||
theContour.Clear();
|
||||
Standard_Integer aStartIndex = 0;
|
||||
Standard_Integer aIndexS = theIndexS;
|
||||
NCollection_DataMap<Standard_Integer,Standard_Integer> aNodeLink(100, theTempAlloc);
|
||||
Standard_Integer aLastNode = getLastNode (aIndexS);
|
||||
|
||||
for (;;) {
|
||||
theContour.Add(aIndexS);
|
||||
aNodeLink.Bind(getFirstNode(aIndexS), aIndexS);
|
||||
|
||||
Standard_Integer aIndex = Abs (aIndexS);
|
||||
|
||||
// collect the list of links from this node able to participate
|
||||
// in this contour
|
||||
theTempAlloc1->Reset();
|
||||
NCollection_List<Standard_Integer> aLstIndS (theTempAlloc1);
|
||||
const ListOfLink& aLinks = myHelper->GetAdjacentLinks (aLastNode);
|
||||
Poly_MakeLoops::ListOfLink::Iterator itLinks (aLinks);
|
||||
for (; itLinks.More(); itLinks.Next()) {
|
||||
Standard_Integer aInd = myMapLink.FindIndex(itLinks.Value());
|
||||
if (aInd == 0 || aInd == aIndex)
|
||||
continue;
|
||||
// determine the orientation in which the link is to be taken
|
||||
Standard_Integer aIndS = aInd;
|
||||
Standard_Integer aNode1 = getFirstNode(aInd);
|
||||
if (aNode1 != aLastNode)
|
||||
aIndS = -aIndS;
|
||||
|
||||
if (canLinkBeTaken(aIndS))
|
||||
aLstIndS.Append(aIndS);
|
||||
}
|
||||
|
||||
if (aLstIndS.IsEmpty()) {
|
||||
// no more ways: open contour
|
||||
aStartIndex = theContour.Extent() + 1;
|
||||
break;
|
||||
}
|
||||
|
||||
Standard_Integer aIndexSNext = 0;
|
||||
if (aLstIndS.First() == aLstIndS.Last())
|
||||
// only one possible way
|
||||
aIndexSNext = aLstIndS.First();
|
||||
else
|
||||
// find the most left way
|
||||
aIndexSNext = chooseLeftWay (aLastNode, aIndexS, aLstIndS);
|
||||
|
||||
aIndexS = aIndexSNext;
|
||||
|
||||
if (aIndexS == 0)
|
||||
{
|
||||
// no more ways: open contour
|
||||
aStartIndex = theContour.Extent() + 1;
|
||||
break;
|
||||
}
|
||||
if (theContour.Contains(aIndexS))
|
||||
{
|
||||
// entering the loop second time, stop search
|
||||
aStartIndex = theContour.FindIndex (aIndexS);
|
||||
break;
|
||||
}
|
||||
if (theContour.Contains (-aIndexS))
|
||||
{
|
||||
// leaving the loop, stop search
|
||||
aStartIndex = theContour.FindIndex (-aIndexS) + 1;
|
||||
break;
|
||||
}
|
||||
|
||||
aLastNode = getLastNode (aIndexS);
|
||||
|
||||
if (aNodeLink.IsBound(aLastNode))
|
||||
{
|
||||
// closing the loop, stop search
|
||||
theContour.Add(aIndexS);
|
||||
aStartIndex = theContour.FindIndex(aNodeLink.Find(aLastNode));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return aStartIndex;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : acceptContour
|
||||
//purpose : Builds a wire from a given set of edge indices (starting with
|
||||
// theStartNumber) and appends it to the result list.
|
||||
// Also updates the start indices.
|
||||
//=======================================================================
|
||||
|
||||
void Poly_MakeLoops::acceptContour
|
||||
(const NCollection_IndexedMap<Standard_Integer>& theContour,
|
||||
Standard_Integer theStartNumber)
|
||||
{
|
||||
// append a new loop to the result
|
||||
Loop anEmptyLoop(myAlloc);
|
||||
myLoops.Append(anEmptyLoop);
|
||||
Loop& aLoop = myLoops.ChangeValue(myLoops.Length());
|
||||
|
||||
// build a loop, mark links as taken,
|
||||
// remove them from the set of start indices
|
||||
Standard_Integer i;
|
||||
for (i = theStartNumber; i <= theContour.Extent(); i++)
|
||||
{
|
||||
Standard_Integer aIndexS = theContour(i); // index with sign
|
||||
Standard_Integer aIndex = Abs (aIndexS);
|
||||
const Link& aLink = myMapLink(aIndex);
|
||||
Link aOrientedLink = aLink;
|
||||
if (aIndexS < 0)
|
||||
aOrientedLink.Reverse();
|
||||
aLoop.Append(aOrientedLink);
|
||||
// remove from start set
|
||||
myStartIndices.Remove(aIndexS);
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : getFirstNode
|
||||
//purpose : Returns the first node of the given link
|
||||
// taking into account its orientation (the sign of index)
|
||||
//=======================================================================
|
||||
|
||||
Standard_Integer Poly_MakeLoops::getFirstNode(Standard_Integer theIndexS) const
|
||||
{
|
||||
Standard_Integer aIndex = Abs(theIndexS);
|
||||
const Link& aLink = myMapLink(aIndex);
|
||||
if (theIndexS > 0)
|
||||
return aLink.node1;
|
||||
return aLink.node2;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : getLastNode
|
||||
//purpose : Returns the last node of the given link
|
||||
// taking into account its orientation (the sign of index)
|
||||
//=======================================================================
|
||||
|
||||
Standard_Integer Poly_MakeLoops::getLastNode(int theIndexS) const
|
||||
{
|
||||
Standard_Integer aIndex = Abs(theIndexS);
|
||||
const Link& aLink = myMapLink(aIndex);
|
||||
if (theIndexS > 0)
|
||||
return aLink.node2;
|
||||
return aLink.node1;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : markHangChain
|
||||
//purpose : Marks hanging links starting from the given node.
|
||||
// Also removes such links from the start indices.
|
||||
//=======================================================================
|
||||
|
||||
void Poly_MakeLoops::markHangChain(Standard_Integer theNode, Standard_Integer theIndexS)
|
||||
{
|
||||
Standard_Integer aNode1 = theNode;
|
||||
Standard_Integer aIndexS = theIndexS;
|
||||
Standard_Integer aIndex = Abs(aIndexS);
|
||||
Standard_Boolean isOut = (aNode1 == getFirstNode(aIndexS));
|
||||
for (;;)
|
||||
{
|
||||
// check if the current link is hanging:
|
||||
// if it is outcoming from aNode1 then count the number of
|
||||
// other incoming links and vise versa;
|
||||
// if the number is zero than it is hanging
|
||||
const ListOfLink& aLinks = myHelper->GetAdjacentLinks (aNode1);
|
||||
Standard_Integer nEdges = 0;
|
||||
Poly_MakeLoops::ListOfLink::Iterator itLinks (aLinks);
|
||||
for (; itLinks.More() && nEdges == 0; itLinks.Next())
|
||||
{
|
||||
const Link &aL = itLinks.Value();
|
||||
Standard_Integer aInd = myMapLink.FindIndex(aL);
|
||||
if (aInd == 0 || aInd == aIndex)
|
||||
continue;
|
||||
if (isOut && aNode1 == aL.node1 ||
|
||||
!isOut && aNode1 == aL.node2)
|
||||
aInd = -aInd;
|
||||
if (canLinkBeTaken(aInd))
|
||||
nEdges++;
|
||||
}
|
||||
if (nEdges > 0)
|
||||
// leave this chain
|
||||
break;
|
||||
|
||||
// mark the current link as hanging
|
||||
myStartIndices.Remove(aIndexS);
|
||||
myHangIndices.Add(aIndexS);
|
||||
|
||||
// get other node of the link and the next link
|
||||
if (isOut)
|
||||
aNode1 = getLastNode(aIndexS);
|
||||
else
|
||||
aNode1 = getFirstNode(aIndexS);
|
||||
const ListOfLink& aNextLinks = myHelper->GetAdjacentLinks (aNode1);
|
||||
Standard_Integer aNextIndexS = 0;
|
||||
for (itLinks.Init(aNextLinks); itLinks.More(); itLinks.Next())
|
||||
{
|
||||
const Link &aL = itLinks.Value();
|
||||
Standard_Integer aInd = myMapLink.FindIndex(aL);
|
||||
if (aInd == 0 || aInd == aIndex)
|
||||
continue;
|
||||
if (isOut && aNode1 == aL.node2 ||
|
||||
!isOut && aNode1 == aL.node1)
|
||||
aInd = -aInd;
|
||||
if (canLinkBeTaken(aInd))
|
||||
{
|
||||
if (aNextIndexS == 0)
|
||||
aNextIndexS = aInd;
|
||||
else
|
||||
{
|
||||
// more than 1 ways, stop the chain
|
||||
aNextIndexS = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (aNextIndexS == 0)
|
||||
break;
|
||||
aIndexS = aNextIndexS;
|
||||
aIndex = Abs(aIndexS);
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : canLinkBeTaken
|
||||
//purpose : Returns True if the link appointed by the index can participate
|
||||
// in a loop in given orientation (it is the sign of index).
|
||||
// Remark: A boundary edge can be taken only once
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean Poly_MakeLoops::canLinkBeTaken(Standard_Integer theIndexS) const
|
||||
{
|
||||
return myStartIndices.Contains(theIndexS);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : showBoundaryBreaks
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
#ifdef _DEBUG
|
||||
void Poly_MakeLoops::showBoundaryBreaks() const
|
||||
{
|
||||
// collect nodes of boundary links
|
||||
TColStd_PackedMapOfInteger aNodesMap;
|
||||
Standard_Integer i;
|
||||
for (i = 1; i <= myMapLink.Extent(); i++)
|
||||
{
|
||||
const Link& aLink = myMapLink(i);
|
||||
Standard_Integer aFlags = aLink.flags & LF_Both;
|
||||
if (aFlags && aFlags != LF_Both)
|
||||
{
|
||||
// take only oriented links
|
||||
aNodesMap.Add(aLink.node1);
|
||||
aNodesMap.Add(aLink.node2);
|
||||
}
|
||||
}
|
||||
|
||||
// check each node if the number of input and output links are equal
|
||||
Standard_Boolean isFirst = Standard_True;
|
||||
TColStd_MapIteratorOfPackedMapOfInteger it(aNodesMap);
|
||||
for (; it.More(); it.Next())
|
||||
{
|
||||
Standard_Integer aNode = it.Key();
|
||||
Standard_Integer nb = 0;
|
||||
const ListOfLink& aLinks = myHelper->GetAdjacentLinks(aNode);
|
||||
Poly_MakeLoops::ListOfLink::Iterator itLinks (aLinks);
|
||||
for (; itLinks.More(); itLinks.Next())
|
||||
{
|
||||
const Poly_MakeLoops::Link& aLink = itLinks.Value();
|
||||
if (myMapLink.FindIndex(aLink) == 0)
|
||||
continue;
|
||||
Standard_Integer aFlags = aLink.flags & LF_Both;
|
||||
if (aFlags && aFlags != LF_Both)
|
||||
{
|
||||
if (aNode == aLink.node1) // output?
|
||||
{
|
||||
if (aFlags & LF_Fwd)
|
||||
nb++; // yes, output
|
||||
else
|
||||
nb--; // reversed, so input
|
||||
}
|
||||
else if (aNode == aLink.node2) // input?
|
||||
{
|
||||
if (aFlags & LF_Fwd)
|
||||
nb--; // yes, input
|
||||
else
|
||||
nb++; // reversed, so output
|
||||
}
|
||||
else
|
||||
// inconsistent
|
||||
nb += 100;
|
||||
}
|
||||
}
|
||||
if (nb != 0)
|
||||
{
|
||||
// indicate this node
|
||||
if (isFirst)
|
||||
{
|
||||
isFirst = Standard_False;
|
||||
cout << "boundary breaks are found in the following nodes:" << endl;
|
||||
}
|
||||
cout << aNode << " ";
|
||||
}
|
||||
}
|
||||
if (!isFirst)
|
||||
cout << endl;
|
||||
}
|
||||
#endif
|
||||
|
||||
//=======================================================================
|
||||
//function : GetHangingLinks
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void Poly_MakeLoops::GetHangingLinks(ListOfLink& theLinks) const
|
||||
{
|
||||
TColStd_MapIteratorOfPackedMapOfInteger it(myHangIndices);
|
||||
for (; it.More(); it.Next())
|
||||
{
|
||||
Standard_Integer aIndexS = it.Key();
|
||||
Link aLink = myMapLink(Abs(aIndexS));
|
||||
if (aIndexS < 0)
|
||||
aLink.Reverse();
|
||||
theLinks.Append(aLink);
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Poly_MakeLoops3D
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Poly_MakeLoops3D::Poly_MakeLoops3D(const Helper* theHelper,
|
||||
const Handle_NCollection_BaseAllocator& theAlloc)
|
||||
: Poly_MakeLoops (theHelper, theAlloc)
|
||||
{
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Poly_MakeLoops3D::chooseLeftWay
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Integer Poly_MakeLoops3D::chooseLeftWay
|
||||
(const Standard_Integer theNode,
|
||||
const Standard_Integer theSegIndex,
|
||||
const NCollection_List<Standard_Integer>& theLstIndS) const
|
||||
{
|
||||
Standard_Real aAngleMin = ::PI * 2;
|
||||
gp_Dir aNormal;
|
||||
const Helper* aHelper = getHelper();
|
||||
if (!aHelper->GetNormal (theNode, aNormal))
|
||||
return theLstIndS.First();
|
||||
|
||||
Link aLink = getLink(theSegIndex);
|
||||
gp_Dir aTgtRef;
|
||||
if (!aHelper->GetLastTangent (aLink, aTgtRef))
|
||||
return theLstIndS.First();
|
||||
|
||||
// project tangent vector to the plane orthogonal to normal
|
||||
// to get the reference direction
|
||||
gp_XYZ aTgtRefXYZ = aNormal.XYZ().CrossCrossed (aTgtRef.XYZ(), aNormal.XYZ());
|
||||
if (aTgtRefXYZ.SquareModulus() < 1e-14)
|
||||
// a problem with defining reference direction, take first way
|
||||
return theLstIndS.First();
|
||||
aTgtRef = aTgtRefXYZ;
|
||||
|
||||
// find the way with minimal angle to the reference direction
|
||||
// (the angle is in range ]-PI;PI])
|
||||
Standard_Integer aResIndex = 0;
|
||||
NCollection_List<Standard_Integer>::Iterator aItI (theLstIndS);
|
||||
for (; aItI.More(); aItI.Next())
|
||||
{
|
||||
Standard_Integer aIndS = aItI.Value();
|
||||
|
||||
aLink = getLink(aIndS);
|
||||
gp_Dir aTgt;
|
||||
if (!aHelper->GetFirstTangent (aLink, aTgt))
|
||||
continue;
|
||||
|
||||
gp_XYZ aTgtXYZ = aNormal.XYZ().CrossCrossed (aTgt.XYZ(), aNormal.XYZ());
|
||||
if (aTgtXYZ.SquareModulus() < 1e-14)
|
||||
// skip a problem way
|
||||
continue;
|
||||
aTgt = aTgtXYZ;
|
||||
|
||||
Standard_Real aAngle = aTgt.AngleWithRef(aTgtRef, aNormal);
|
||||
if (aAngle < 1e-4 - ::PI)
|
||||
aAngle = ::PI;
|
||||
if (aAngle < aAngleMin)
|
||||
{
|
||||
aAngleMin = aAngle;
|
||||
aResIndex = aIndS;
|
||||
}
|
||||
}
|
||||
return aResIndex == 0 ? theLstIndS.First() : aResIndex;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Poly_MakeLoops2D
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Poly_MakeLoops2D::Poly_MakeLoops2D(const Standard_Boolean theLeftWay,
|
||||
const Helper* theHelper,
|
||||
const Handle_NCollection_BaseAllocator& theAlloc)
|
||||
: Poly_MakeLoops (theHelper, theAlloc),
|
||||
myRightWay(!theLeftWay)
|
||||
{
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Poly_MakeLoops2D::chooseLeftWay
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Integer Poly_MakeLoops2D::chooseLeftWay
|
||||
(const Standard_Integer /*theNode*/,
|
||||
const Standard_Integer theSegIndex,
|
||||
const NCollection_List<Standard_Integer>& theLstIndS) const
|
||||
{
|
||||
Standard_Real aAngleMin = ::PI * 2;
|
||||
const Helper* aHelper = getHelper();
|
||||
Link aLink = getLink(theSegIndex);
|
||||
gp_Dir2d aTgtRef;
|
||||
if (!aHelper->GetLastTangent (aLink, aTgtRef))
|
||||
// a problem with defining reference direction, take first way
|
||||
return theLstIndS.First();
|
||||
|
||||
// find the way with minimal angle to the reference direction
|
||||
// (the angle is in range ]-PI;PI])
|
||||
Standard_Integer aResIndex = 0;
|
||||
NCollection_List<Standard_Integer>::Iterator aItI (theLstIndS);
|
||||
for (; aItI.More(); aItI.Next())
|
||||
{
|
||||
Standard_Integer aIndS = aItI.Value();
|
||||
|
||||
aLink = getLink(aIndS);
|
||||
gp_Dir2d aTgt;
|
||||
if (!aHelper->GetFirstTangent (aLink, aTgt))
|
||||
// skip a problem way
|
||||
continue;
|
||||
|
||||
Standard_Real aAngle = aTgt.Angle(aTgtRef);
|
||||
if (myRightWay)
|
||||
aAngle = -aAngle;
|
||||
if (aAngle < 1e-4 - ::PI)
|
||||
aAngle = ::PI;
|
||||
if (aAngle < aAngleMin)
|
||||
{
|
||||
aAngleMin = aAngle;
|
||||
aResIndex = aIndS;
|
||||
}
|
||||
}
|
||||
return aResIndex == 0 ? theLstIndS.First() : aResIndex;
|
||||
}
|
354
src/Poly/Poly_MakeLoops.hxx
Executable file
354
src/Poly/Poly_MakeLoops.hxx
Executable file
@@ -0,0 +1,354 @@
|
||||
// File: Poly_MakeLoops.hxx
|
||||
// Created: 22.10.2009
|
||||
// Author: Mikhail SAZONOV
|
||||
// Copyright: Open Cascade 2009
|
||||
|
||||
#ifndef Poly_MakeLoops_HeaderFile
|
||||
#define Poly_MakeLoops_HeaderFile
|
||||
|
||||
#include <NCollection_Sequence.hxx>
|
||||
#include <NCollection_IndexedMap.hxx>
|
||||
#include <TColStd_PackedMapOfInteger.hxx>
|
||||
#include <TColStd_MapIteratorOfPackedMapOfInteger.hxx>
|
||||
#include <NCollection_BaseAllocator.hxx>
|
||||
#include <NCollection_List.hxx>
|
||||
|
||||
class Handle_NCollection_IncAllocator;
|
||||
|
||||
/**
|
||||
* Make loops from a set of connected links. A link is represented by
|
||||
* a pair of integer indices of nodes.
|
||||
*/
|
||||
class Poly_MakeLoops
|
||||
{
|
||||
public:
|
||||
//! Orientation flags that can be attached to a link
|
||||
enum LinkFlag {
|
||||
LF_None = 0,
|
||||
LF_Fwd = 1, // forward orientation
|
||||
LF_Rev = 2, // reversed orientation
|
||||
LF_Both = 3, // both ways oriented
|
||||
LF_Reversed = 4 // means the link is reversed
|
||||
};
|
||||
|
||||
//! The Link structure
|
||||
struct Link
|
||||
{
|
||||
Standard_Integer node1, node2;
|
||||
Standard_Integer flags;
|
||||
|
||||
Link()
|
||||
: node1(0), node2(0), flags(0) {}
|
||||
|
||||
Link(Standard_Integer theNode1, Standard_Integer theNode2)
|
||||
: node1(theNode1), node2(theNode2), flags(0) {}
|
||||
|
||||
void Reverse()
|
||||
{
|
||||
flags ^= Poly_MakeLoops::LF_Reversed;
|
||||
}
|
||||
|
||||
Standard_Boolean IsReversed() const
|
||||
{
|
||||
return flags & Poly_MakeLoops::LF_Reversed;
|
||||
}
|
||||
|
||||
void Nullify()
|
||||
{
|
||||
node1 = node2 = 0;
|
||||
}
|
||||
|
||||
Standard_Boolean IsNull() const
|
||||
{
|
||||
return node1 == 0 || node2 == 0;
|
||||
}
|
||||
};
|
||||
|
||||
// Define the Loop as a list of links
|
||||
typedef NCollection_List<Link> ListOfLink;
|
||||
typedef ListOfLink Loop;
|
||||
|
||||
//! The abstract helper class
|
||||
class Helper
|
||||
{
|
||||
public:
|
||||
//! returns the links adjacent to the given node
|
||||
virtual const ListOfLink& GetAdjacentLinks (Standard_Integer theNode) const = 0;
|
||||
//! hook function called from AddLink in _DEBUG mode
|
||||
virtual void OnAddLink (Standard_Integer /*theNum*/, const Link& /*theLink*/) const {}
|
||||
};
|
||||
|
||||
//! This class implements a heap of integers. The most effective usage
|
||||
//! of it is first to add there all items, and then get top item and remove
|
||||
//! any items till it becomes empty.
|
||||
class HeapOfInteger
|
||||
{
|
||||
public:
|
||||
HeapOfInteger (const Standard_Integer theNbPreAllocated = 1)
|
||||
: myMap (theNbPreAllocated),
|
||||
myIterReady (Standard_False) {}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
myMap.Clear();
|
||||
myIterReady = Standard_False;
|
||||
}
|
||||
|
||||
void Add (const Standard_Integer theValue)
|
||||
{
|
||||
myMap.Add (theValue);
|
||||
myIterReady = Standard_False;
|
||||
}
|
||||
|
||||
Standard_Integer Top()
|
||||
{
|
||||
if (!myIterReady)
|
||||
{
|
||||
myIter.Initialize (myMap);
|
||||
myIterReady = Standard_True;
|
||||
}
|
||||
return myIter.Key();
|
||||
}
|
||||
|
||||
Standard_Boolean Contains (const Standard_Integer theValue) const
|
||||
{
|
||||
return myMap.Contains (theValue);
|
||||
}
|
||||
|
||||
void Remove (const Standard_Integer theValue)
|
||||
{
|
||||
if (myIterReady && myIter.More() && myIter.Key() == theValue)
|
||||
myIter.Next();
|
||||
myMap.Remove (theValue);
|
||||
}
|
||||
|
||||
Standard_Boolean IsEmpty()
|
||||
{
|
||||
if (!myIterReady)
|
||||
{
|
||||
myIter.Initialize (myMap);
|
||||
myIterReady = Standard_True;
|
||||
}
|
||||
return !myIter.More();
|
||||
}
|
||||
|
||||
private:
|
||||
TColStd_PackedMapOfInteger myMap;
|
||||
TColStd_MapIteratorOfPackedMapOfInteger myIter;
|
||||
Standard_Boolean myIterReady;
|
||||
};
|
||||
|
||||
public:
|
||||
// PUBLIC METHODS
|
||||
|
||||
//! Constructor. If helper is NULL then the algorithm will
|
||||
//! probably return a wrong result
|
||||
Standard_EXPORT Poly_MakeLoops(const Helper* theHelper,
|
||||
const Handle_NCollection_BaseAllocator& theAlloc = 0L);
|
||||
|
||||
//! It is to reset the algorithm to the initial state.
|
||||
Standard_EXPORT void Reset
|
||||
(const Helper* theHelper,
|
||||
const Handle_NCollection_BaseAllocator& theAlloc = 0L);
|
||||
|
||||
//! Adds a link to the set. theOrient defines which orientations of the link
|
||||
//! are allowed.
|
||||
Standard_EXPORT void AddLink(const Link& theLink);
|
||||
|
||||
//! Replace one link with another (e.g. to change order of nodes)
|
||||
Standard_EXPORT void ReplaceLink(const Link& theLink, const Link& theNewLink);
|
||||
|
||||
//! Set a new value of orientation of a link already added earlier.
|
||||
//! It can be used with LF_None to exclude the link from consideration.
|
||||
//! Returns the old value of orienation.
|
||||
Standard_EXPORT LinkFlag SetLinkOrientation
|
||||
(const Link& theLink,
|
||||
const LinkFlag theOrient);
|
||||
|
||||
//! Find the link stored in algo by value
|
||||
Standard_EXPORT Link FindLink(const Link& theLink) const;
|
||||
|
||||
enum ResultCode
|
||||
{
|
||||
RC_LoopsDone = 1,
|
||||
RC_HangingLinks = 2,
|
||||
RC_Failure = 4
|
||||
};
|
||||
|
||||
//! Does the work. Returns the collection of result codes
|
||||
Standard_EXPORT Standard_Integer Perform();
|
||||
|
||||
//! Returns the number of loops in the result
|
||||
Standard_Integer GetNbLoops() const
|
||||
{
|
||||
return myLoops.Length();
|
||||
}
|
||||
|
||||
//! Returns the loop of the given index
|
||||
const Loop& GetLoop(Standard_Integer theIndex) const
|
||||
{
|
||||
return myLoops.Value(theIndex);
|
||||
}
|
||||
|
||||
//! Returns the number of detected hanging chains
|
||||
Standard_Integer GetNbHanging() const
|
||||
{
|
||||
return myHangIndices.Extent();
|
||||
}
|
||||
|
||||
//! Fills in the list of hanging links
|
||||
void GetHangingLinks(ListOfLink& theLinks) const;
|
||||
|
||||
protected:
|
||||
virtual Standard_Integer chooseLeftWay
|
||||
(const Standard_Integer theNode,
|
||||
const Standard_Integer theSegIndex,
|
||||
const NCollection_List<Standard_Integer>& theLstIndS) const = 0;
|
||||
|
||||
const Helper* getHelper () const
|
||||
{
|
||||
return myHelper;
|
||||
}
|
||||
|
||||
Link getLink (const Standard_Integer theSegIndex) const
|
||||
{
|
||||
Link aLink = myMapLink(Abs(theSegIndex));
|
||||
if (theSegIndex < 0)
|
||||
aLink.Reverse();
|
||||
return aLink;
|
||||
}
|
||||
#ifdef _DEBUG
|
||||
void showBoundaryBreaks() const;
|
||||
#endif
|
||||
|
||||
private:
|
||||
int findContour(Standard_Integer theIndexS, NCollection_IndexedMap<Standard_Integer>& theContour,
|
||||
const Handle_NCollection_BaseAllocator& theTempAlloc,
|
||||
const Handle_NCollection_IncAllocator& theTempAlloc1) const;
|
||||
void acceptContour(const NCollection_IndexedMap<Standard_Integer>& theContour,
|
||||
Standard_Integer theStartNumber);
|
||||
Standard_Integer getFirstNode(Standard_Integer theIndexS) const;
|
||||
Standard_Integer getLastNode(Standard_Integer theIndexS) const;
|
||||
void markHangChain(Standard_Integer theNode, Standard_Integer theIndexS);
|
||||
Standard_Boolean canLinkBeTaken(Standard_Integer theIndexS) const;
|
||||
|
||||
// FIELDS
|
||||
const Helper* myHelper;
|
||||
Handle_NCollection_BaseAllocator myAlloc;
|
||||
NCollection_IndexedMap<Link> myMapLink;
|
||||
NCollection_Sequence<Loop> myLoops;
|
||||
HeapOfInteger myStartIndices;
|
||||
TColStd_PackedMapOfInteger myHangIndices;
|
||||
};
|
||||
|
||||
/**
|
||||
* HashCode method is needed for maps
|
||||
*/
|
||||
inline Standard_Integer HashCode(const Poly_MakeLoops::Link& theKey,
|
||||
int theLimit)
|
||||
{
|
||||
return HashCode(theKey.node1 + theKey.node2, theLimit);
|
||||
}
|
||||
|
||||
/**
|
||||
* IsEqual method is needed for maps
|
||||
*/
|
||||
inline Standard_Boolean IsEqual(const Poly_MakeLoops::Link& theKey1,
|
||||
const Poly_MakeLoops::Link& theKey2)
|
||||
{
|
||||
return (theKey1.node1 == theKey2.node1 &&
|
||||
theKey1.node2 == theKey2.node2 ||
|
||||
theKey1.node1 == theKey2.node2 &&
|
||||
theKey1.node2 == theKey2.node1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation for 3D space
|
||||
*/
|
||||
class gp_Dir;
|
||||
class Poly_MakeLoops3D: public Poly_MakeLoops
|
||||
{
|
||||
public:
|
||||
//! The abstract helper class
|
||||
class Helper: public Poly_MakeLoops::Helper
|
||||
{
|
||||
public:
|
||||
// all the following methods should return False if
|
||||
// it is impossible to return a valid direction
|
||||
|
||||
//! returns the tangent vector at the first node of a link
|
||||
virtual Standard_Boolean GetFirstTangent(const Link& theLink,
|
||||
gp_Dir& theDir) const = 0;
|
||||
|
||||
//! returns the tangent vector at the last node of a link
|
||||
virtual Standard_Boolean GetLastTangent(const Link& theLink,
|
||||
gp_Dir& theDir) const = 0;
|
||||
|
||||
//! returns the normal to the surface at a given node
|
||||
virtual Standard_Boolean GetNormal(Standard_Integer theNode,
|
||||
gp_Dir& theDir) const = 0;
|
||||
};
|
||||
|
||||
//! Constructor. If helper is NULL then the algorithm will
|
||||
//! probably return a wrong result
|
||||
Standard_EXPORT Poly_MakeLoops3D(const Helper* theHelper,
|
||||
const Handle_NCollection_BaseAllocator& theAlloc);
|
||||
|
||||
protected:
|
||||
Standard_EXPORT virtual Standard_Integer chooseLeftWay
|
||||
(const Standard_Integer theNode,
|
||||
const Standard_Integer theSegIndex,
|
||||
const NCollection_List<Standard_Integer>& theLstIndS) const;
|
||||
const Helper* getHelper () const
|
||||
{
|
||||
return static_cast<const Poly_MakeLoops3D::Helper*>
|
||||
(Poly_MakeLoops::getHelper());
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Implementation for 2D space
|
||||
*/
|
||||
class gp_Dir2d;
|
||||
class Poly_MakeLoops2D: public Poly_MakeLoops
|
||||
{
|
||||
public:
|
||||
//! The abstract helper class
|
||||
class Helper: public Poly_MakeLoops::Helper
|
||||
{
|
||||
public:
|
||||
// all the following methods should return False if
|
||||
// it is impossible to return a valid direction
|
||||
|
||||
//! returns the tangent vector at the first node of a link
|
||||
virtual Standard_Boolean GetFirstTangent(const Link& theLink,
|
||||
gp_Dir2d& theDir) const = 0;
|
||||
|
||||
//! returns the tangent vector at the last node of a link
|
||||
virtual Standard_Boolean GetLastTangent(const Link& theLink,
|
||||
gp_Dir2d& theDir) const = 0;
|
||||
};
|
||||
|
||||
//! Constructor. If helper is NULL then the algorithm will
|
||||
//! probably return a wrong result
|
||||
Standard_EXPORT Poly_MakeLoops2D(const Standard_Boolean theLeftWay,
|
||||
const Helper* theHelper,
|
||||
const Handle_NCollection_BaseAllocator& theAlloc);
|
||||
|
||||
protected:
|
||||
Standard_EXPORT virtual Standard_Integer chooseLeftWay
|
||||
(const Standard_Integer theNode,
|
||||
const Standard_Integer theSegIndex,
|
||||
const NCollection_List<Standard_Integer>& theLstIndS) const;
|
||||
const Helper* getHelper () const
|
||||
{
|
||||
return static_cast<const Poly_MakeLoops2D::Helper*>
|
||||
(Poly_MakeLoops::getHelper());
|
||||
}
|
||||
|
||||
private:
|
||||
//! this flag says that chooseLeftWay must choose the right way instead
|
||||
Standard_Boolean myRightWay;
|
||||
};
|
||||
|
||||
#endif
|
72
src/Poly/Poly_Polygon2D.cdl
Executable file
72
src/Poly/Poly_Polygon2D.cdl
Executable file
@@ -0,0 +1,72 @@
|
||||
-- File: Poly_Polygon2D.cdl
|
||||
-- Created: Thu Mar 9 16:29:00 1995
|
||||
-- Author: Laurent PAINNOT
|
||||
-- <lpa@metrox>
|
||||
---Copyright: Matra Datavision 1995
|
||||
|
||||
|
||||
|
||||
class Polygon2D from Poly inherits TShared from MMgt
|
||||
|
||||
---Purpose: Provides a polygon in 2D space (for example, in the
|
||||
-- parametric space of a surface). It is generally an
|
||||
-- approximate representation of a curve.
|
||||
-- A Polygon2D is defined by a table of nodes. Each node is
|
||||
-- a 2D point. If the polygon is closed, the point of closure is
|
||||
-- repeated at the end of the table of nodes.
|
||||
|
||||
|
||||
uses Array1OfPnt2d from TColgp
|
||||
|
||||
raises NullObject from Standard
|
||||
|
||||
is
|
||||
|
||||
Create(Nodes: Array1OfPnt2d from TColgp)
|
||||
returns mutable Polygon2D from Poly;
|
||||
---Purpose: Constructs a 2D polygon defined by the table of points, <Nodes>.
|
||||
|
||||
Deflection(me) returns Real;
|
||||
---Purpose: Returns the deflection of this polygon.
|
||||
-- Deflection is used in cases where the polygon is an
|
||||
-- approximate representation of a curve. Deflection
|
||||
-- represents the maximum distance permitted between any
|
||||
-- point on the curve and the corresponding point on the polygon.
|
||||
-- By default the deflection value is equal to 0. An algorithm
|
||||
-- using this 2D polygon with a deflection value equal to 0
|
||||
-- considers that it is working with a true polygon and not with
|
||||
-- an approximate representation of a curve. The Deflection
|
||||
-- function is used to modify the deflection value of this polygon.
|
||||
-- The deflection value can be used by any algorithm working with 2D polygons.
|
||||
-- For example:
|
||||
-- - An algorithm may use a unique deflection value for all
|
||||
-- its polygons. In this case it is not necessary to use the
|
||||
-- Deflection function.
|
||||
-- - Or an algorithm may want to attach a different
|
||||
-- deflection to each polygon. In this case, the Deflection
|
||||
-- function is used to set a value on each polygon, and
|
||||
-- later to fetch the value.
|
||||
|
||||
Deflection(me : mutable; D : Real);
|
||||
---Purpose: Sets the deflection of this polygon to D
|
||||
|
||||
NbNodes(me) returns Integer;
|
||||
---Purpose: Returns the number of nodes in this polygon.
|
||||
-- Note: If the polygon is closed, the point of closure is
|
||||
-- repeated at the end of its table of nodes. Thus, on a closed
|
||||
-- triangle, the function NbNodes returns 4.
|
||||
---C++: inline
|
||||
|
||||
Nodes(me) returns Array1OfPnt2d from TColgp
|
||||
---Purpose: Returns the table of nodes for this polygon.
|
||||
---C++: return const &
|
||||
raises NullObject from Standard;
|
||||
|
||||
|
||||
fields
|
||||
|
||||
myDeflection: Real;
|
||||
myNbNodes: Integer;
|
||||
myNodes: Array1OfPnt2d from TColgp;
|
||||
|
||||
end Polygon2D;
|
54
src/Poly/Poly_Polygon2D.cxx
Executable file
54
src/Poly/Poly_Polygon2D.cxx
Executable file
@@ -0,0 +1,54 @@
|
||||
// File: Poly_Polygon2D.cxx
|
||||
// Created: Thu Mar 9 16:36:49 1995
|
||||
// Author: Laurent PAINNOT
|
||||
// <lpa@metrox>
|
||||
|
||||
|
||||
#include <Poly_Polygon2D.ixx>
|
||||
#include <gp_Pnt2d.hxx>
|
||||
|
||||
//=======================================================================
|
||||
//function : Poly_Polygon2D
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Poly_Polygon2D::Poly_Polygon2D(const TColgp_Array1OfPnt2d& Nodes):
|
||||
myDeflection(0.),
|
||||
myNodes(1, Nodes.Length())
|
||||
{
|
||||
Standard_Integer i, j= 1;
|
||||
for (i = Nodes.Lower(); i <= Nodes.Upper(); i++)
|
||||
myNodes(j++) = Nodes(i);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Deflection
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Real Poly_Polygon2D::Deflection() const
|
||||
{
|
||||
return myDeflection;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Deflection
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void Poly_Polygon2D::Deflection(const Standard_Real D)
|
||||
{
|
||||
myDeflection = D;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Nodes
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
const TColgp_Array1OfPnt2d& Poly_Polygon2D::Nodes() const
|
||||
{
|
||||
return myNodes;
|
||||
}
|
||||
|
||||
|
16
src/Poly/Poly_Polygon2D.lxx
Executable file
16
src/Poly/Poly_Polygon2D.lxx
Executable file
@@ -0,0 +1,16 @@
|
||||
// File: Poly_Polygon2D.lxx
|
||||
// Created: Thu Mar 9 16:38:18 1995
|
||||
// Author: Laurent PAINNOT
|
||||
// <lpa@metrox>
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : NbNodes
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Integer Poly_Polygon2D::NbNodes() const
|
||||
{
|
||||
return myNodes.Length();
|
||||
}
|
||||
|
86
src/Poly/Poly_Polygon3D.cdl
Executable file
86
src/Poly/Poly_Polygon3D.cdl
Executable file
@@ -0,0 +1,86 @@
|
||||
-- File: Poly_Polygon3D.cdl
|
||||
-- Created: Tue Mar 7 11:19:36 1995
|
||||
-- Author: Laurent PAINNOT
|
||||
-- <lpa@metrox>
|
||||
---Copyright: Matra Datavision 1995
|
||||
|
||||
|
||||
class Polygon3D from Poly inherits TShared from MMgt
|
||||
|
||||
---Purpose: This class Provides a polygon in 3D space. It is generally an approximate representation of a curve.
|
||||
-- A Polygon3D is defined by a table of nodes. Each node is
|
||||
-- a 3D point. If the polygon is closed, the point of closure is
|
||||
-- repeated at the end of the table of nodes.
|
||||
-- If the polygon is an approximate representation of a curve,
|
||||
-- you can associate with each of its nodes the value of the
|
||||
-- parameter of the corresponding point on the curve.
|
||||
|
||||
uses Array1OfPnt from TColgp,
|
||||
Array1OfReal from TColStd,
|
||||
HArray1OfReal from TColStd
|
||||
|
||||
raises NullObject from Standard
|
||||
|
||||
is
|
||||
|
||||
Create(Nodes: Array1OfPnt from TColgp)
|
||||
returns mutable Polygon3D from Poly;
|
||||
---Purpose: onstructs a 3D polygon defined by the table of points, Nodes.
|
||||
|
||||
Create(Nodes: Array1OfPnt from TColgp;
|
||||
Parameters: Array1OfReal from TColStd)
|
||||
returns mutable Polygon3D from Poly;
|
||||
---Purpose: Constructs a 3D polygon defined by
|
||||
-- the table of points, Nodes, and the parallel table of
|
||||
-- parameters, Parameters, where each value of the table
|
||||
-- Parameters is the parameter of the corresponding point
|
||||
-- on the curve approximated by the constructed polygon.
|
||||
-- Warning
|
||||
-- Both the Nodes and Parameters tables must have the
|
||||
-- same bounds. This property is not checked at construction time.
|
||||
|
||||
Deflection(me) returns Real;
|
||||
---Purpose: Returns the deflection of this polygon
|
||||
Deflection(me : mutable; D : Real);
|
||||
---Purpose: Sets the deflection of this polygon to D. See more on deflection in Poly_Polygon2D
|
||||
|
||||
NbNodes(me) returns Integer;
|
||||
---Purpose: Returns the number of nodes in this polygon.
|
||||
-- Note: If the polygon is closed, the point of closure is
|
||||
-- repeated at the end of its table of nodes. Thus, on a closed
|
||||
-- triangle the function NbNodes returns 4.
|
||||
---C++: inline
|
||||
|
||||
Nodes(me) returns Array1OfPnt from TColgp
|
||||
---Purpose: Returns the table of nodes for this polygon.
|
||||
---C++: return const &
|
||||
raises NullObject from Standard;
|
||||
|
||||
|
||||
HasParameters(me) returns Boolean from Standard;
|
||||
---Purpose: Returns the table of the parameters associated with each node in this polygon.
|
||||
-- HasParameters function checks if parameters are associated with the nodes of this polygon.
|
||||
|
||||
Parameters(me) returns Array1OfReal from TColStd
|
||||
---Purpose: Returns true if parameters are associated with the nodes
|
||||
-- in this polygon.
|
||||
---C++: return const &
|
||||
raises NullObject from Standard;
|
||||
|
||||
ChangeParameters(me) returns Array1OfReal from TColStd
|
||||
---Purpose: Returns the table of the parameters associated with each node in this polygon.
|
||||
-- ChangeParameters function returnes the array as shared. Therefore if the table is selected by
|
||||
-- reference you can, by simply modifying it, directly modify
|
||||
-- the data structure of this polygon.
|
||||
---C++: return &
|
||||
raises NullObject from Standard;
|
||||
|
||||
|
||||
|
||||
fields
|
||||
|
||||
myDeflection: Real from Standard;
|
||||
myNodes: Array1OfPnt from TColgp;
|
||||
myParameters: HArray1OfReal from TColStd;
|
||||
|
||||
end Polygon3D;
|
106
src/Poly/Poly_Polygon3D.cxx
Executable file
106
src/Poly/Poly_Polygon3D.cxx
Executable file
@@ -0,0 +1,106 @@
|
||||
// File: Poly_Polygon3D.cxx
|
||||
// Created: Tue Mar 7 14:43:28 1995
|
||||
// Author: Laurent PAINNOT
|
||||
// <lpa@metrox>
|
||||
|
||||
|
||||
#include <Poly_Polygon3D.ixx>
|
||||
#include <gp_Pnt.hxx>
|
||||
|
||||
//=======================================================================
|
||||
//function : Poly_Polygon3D
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Poly_Polygon3D::Poly_Polygon3D(const TColgp_Array1OfPnt& Nodes):
|
||||
myDeflection(0.),
|
||||
myNodes(1, Nodes.Length())
|
||||
{
|
||||
Standard_Integer i, j= 1;
|
||||
for (i = Nodes.Lower(); i <= Nodes.Upper(); i++)
|
||||
myNodes(j++) = Nodes(i);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Poly_Polygon3D
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Poly_Polygon3D::Poly_Polygon3D(const TColgp_Array1OfPnt& Nodes,
|
||||
const TColStd_Array1OfReal& P):
|
||||
myDeflection(0.),
|
||||
myNodes(1, Nodes.Length())
|
||||
|
||||
{
|
||||
myParameters = new TColStd_HArray1OfReal(1, P.Length());
|
||||
Standard_Integer i, j= 1;
|
||||
for (i = Nodes.Lower(); i <= Nodes.Upper(); i++) {
|
||||
myNodes(j) = Nodes(i);
|
||||
myParameters->SetValue(j, P(i));
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : Deflection
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Real Poly_Polygon3D::Deflection() const
|
||||
{
|
||||
return myDeflection;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Deflection
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void Poly_Polygon3D::Deflection(const Standard_Real D)
|
||||
{
|
||||
myDeflection = D;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Nodes
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
const TColgp_Array1OfPnt& Poly_Polygon3D::Nodes() const
|
||||
{
|
||||
return myNodes;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : HasParameters
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean Poly_Polygon3D::HasParameters() const
|
||||
{
|
||||
return !myParameters.IsNull();
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : Parameters
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
const TColStd_Array1OfReal& Poly_Polygon3D::Parameters() const
|
||||
{
|
||||
return myParameters->Array1();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ChangeParameters
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
TColStd_Array1OfReal& Poly_Polygon3D::ChangeParameters() const
|
||||
{
|
||||
return myParameters->ChangeArray1();
|
||||
}
|
||||
|
||||
|
15
src/Poly/Poly_Polygon3D.lxx
Executable file
15
src/Poly/Poly_Polygon3D.lxx
Executable file
@@ -0,0 +1,15 @@
|
||||
// File: Poly_Polygon3D.lxx
|
||||
// Created: Thu Mar 9 16:50:45 1995
|
||||
// Author: Laurent PAINNOT
|
||||
// <lpa@metrox>
|
||||
|
||||
//=======================================================================
|
||||
//function : NbNodes
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Integer Poly_Polygon3D::NbNodes() const
|
||||
{
|
||||
return myNodes.Length();
|
||||
}
|
||||
|
94
src/Poly/Poly_PolygonOnTriangulation.cdl
Executable file
94
src/Poly/Poly_PolygonOnTriangulation.cdl
Executable file
@@ -0,0 +1,94 @@
|
||||
-- File: Poly_PolygonOnTriangulation.cdl
|
||||
-- Created: Wed Feb 21 10:09:23 1996
|
||||
-- Author: Laurent PAINNOT
|
||||
-- <lpa@nonox>
|
||||
---Copyright: Matra Datavision 1996
|
||||
|
||||
|
||||
class PolygonOnTriangulation from Poly inherits TShared from MMgt
|
||||
|
||||
---Purpose: This class provides a polygon in 3D space, based on the triangulation
|
||||
-- of a surface. It may be the approximate representation of a
|
||||
-- curve on the surface, or more generally the shape.
|
||||
-- A PolygonOnTriangulation is defined by a table of
|
||||
-- nodes. Each node is an index in the table of nodes specific
|
||||
-- to a triangulation, and represents a point on the surface. If
|
||||
-- the polygon is closed, the index of the point of closure is
|
||||
-- repeated at the end of the table of nodes.
|
||||
-- If the polygon is an approximate representation of a curve
|
||||
-- on a surface, you can associate with each of its nodes the
|
||||
-- value of the parameter of the corresponding point on the
|
||||
-- curve.represents a 3d Polygon
|
||||
|
||||
|
||||
uses Array1OfInteger from TColStd,
|
||||
Array1OfReal from TColStd,
|
||||
HArray1OfReal from TColStd,
|
||||
Triangulation from Poly
|
||||
|
||||
raises NullObject from Standard
|
||||
|
||||
is
|
||||
|
||||
Create(Nodes: Array1OfInteger from TColStd)
|
||||
returns mutable PolygonOnTriangulation from Poly;
|
||||
---Purpose: Constructs a 3D polygon on the triangulation of a shape,
|
||||
-- defined by the table of nodes, <Nodes>.
|
||||
|
||||
Create(Nodes : Array1OfInteger from TColStd;
|
||||
Parameters: Array1OfReal from TColStd)
|
||||
returns mutable PolygonOnTriangulation from Poly;
|
||||
---Purpose:
|
||||
-- Constructs a 3D polygon on the triangulation of a shape, defined by:
|
||||
-- - the table of nodes, Nodes, and the table of parameters, <Parameters>.
|
||||
-- where:
|
||||
-- - a node value is an index in the table of nodes specific
|
||||
-- to an existing triangulation of a shape
|
||||
-- - and a parameter value is the value of the parameter of
|
||||
-- the corresponding point on the curve approximated by
|
||||
-- the constructed polygon.
|
||||
-- Warning
|
||||
-- The tables Nodes and Parameters must be the same size.
|
||||
-- This property is not checked at construction time.
|
||||
|
||||
Deflection(me) returns Real;
|
||||
---Purpose: Returns the deflection of this polygon
|
||||
Deflection(me : mutable; D : Real);
|
||||
---Purpose: Sets the deflection of this polygon to D.
|
||||
-- See more on deflection in Poly_Polygones2D.
|
||||
|
||||
NbNodes(me) returns Integer;
|
||||
---Purpose:
|
||||
-- Returns the number of nodes for this polygon.
|
||||
-- Note: If the polygon is closed, the point of closure is
|
||||
-- repeated at the end of its table of nodes. Thus, on a closed
|
||||
-- triangle, the function NbNodes returns 4.
|
||||
---C++: inline
|
||||
|
||||
Nodes(me) returns Array1OfInteger from TColStd
|
||||
---Purpose: Returns the table of nodes for this polygon. A node value
|
||||
-- is an index in the table of nodes specific to an existing
|
||||
-- triangulation of a shape.
|
||||
---C++: return const &
|
||||
raises NullObject from Standard;
|
||||
|
||||
|
||||
HasParameters(me) returns Boolean from Standard;
|
||||
---Purpose:
|
||||
-- Returns true if parameters are associated with the nodes in this polygon.
|
||||
Parameters(me) returns HArray1OfReal from TColStd
|
||||
--- Purpose: Returns the table of the parameters associated with each node in this polygon.
|
||||
-- Warning
|
||||
-- Use the function HasParameters to check if parameters
|
||||
-- are associated with the nodes in this polygon.
|
||||
--
|
||||
raises NullObject from Standard;
|
||||
|
||||
|
||||
fields
|
||||
|
||||
myDeflection : Real from Standard;
|
||||
myNodes : Array1OfInteger from TColStd;
|
||||
myParameters : HArray1OfReal from TColStd;
|
||||
|
||||
end PolygonOnTriangulation;
|
87
src/Poly/Poly_PolygonOnTriangulation.cxx
Executable file
87
src/Poly/Poly_PolygonOnTriangulation.cxx
Executable file
@@ -0,0 +1,87 @@
|
||||
// File: Poly_PolygonOnTriangulation.cxx
|
||||
// Created: Tue Feb 20 14:43:28 1996
|
||||
// Author: Laurent PAINNOT
|
||||
// <lpa@nonox>
|
||||
|
||||
#include <Poly_PolygonOnTriangulation.ixx>
|
||||
|
||||
//=======================================================================
|
||||
//function : Poly_PolygonOnTriangulation
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Poly_PolygonOnTriangulation::Poly_PolygonOnTriangulation
|
||||
(const TColStd_Array1OfInteger& Nodes) :
|
||||
myDeflection(0.0),
|
||||
myNodes(1, Nodes.Length())
|
||||
{
|
||||
myNodes = Nodes;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Poly_PolygonOnTriangulation
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Poly_PolygonOnTriangulation::Poly_PolygonOnTriangulation
|
||||
(const TColStd_Array1OfInteger& Nodes,
|
||||
const TColStd_Array1OfReal& Parameters):
|
||||
myDeflection(0.0),
|
||||
myNodes(1, Nodes.Length())
|
||||
{
|
||||
myNodes = Nodes;
|
||||
myParameters = new TColStd_HArray1OfReal(1, Parameters.Length());
|
||||
myParameters->ChangeArray1() = Parameters;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Deflection
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Real Poly_PolygonOnTriangulation::Deflection() const
|
||||
{
|
||||
return myDeflection;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Deflection
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void Poly_PolygonOnTriangulation::Deflection(const Standard_Real D)
|
||||
{
|
||||
myDeflection = D;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Nodes
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
const TColStd_Array1OfInteger& Poly_PolygonOnTriangulation::Nodes() const
|
||||
{
|
||||
return myNodes;
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : HasParameters
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean Poly_PolygonOnTriangulation::HasParameters() const
|
||||
{
|
||||
return (!myParameters.IsNull());
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Parameters
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Handle(TColStd_HArray1OfReal) Poly_PolygonOnTriangulation::Parameters() const
|
||||
{
|
||||
return myParameters;
|
||||
}
|
||||
|
10
src/Poly/Poly_PolygonOnTriangulation.lxx
Executable file
10
src/Poly/Poly_PolygonOnTriangulation.lxx
Executable file
@@ -0,0 +1,10 @@
|
||||
//=======================================================================
|
||||
//function : NbNodes
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Integer Poly_PolygonOnTriangulation::NbNodes() const
|
||||
{
|
||||
return myNodes.Length();
|
||||
}
|
||||
|
64
src/Poly/Poly_Triangle.cdl
Executable file
64
src/Poly/Poly_Triangle.cdl
Executable file
@@ -0,0 +1,64 @@
|
||||
-- File: Poly_Triangle.cdl
|
||||
-- Created: Mon Mar 6 09:50:53 1995
|
||||
-- Author: Laurent PAINNOT
|
||||
-- <lpa@metrox>
|
||||
---Copyright: Matra Datavision 1995
|
||||
|
||||
|
||||
class Triangle from Poly
|
||||
|
||||
---Purpose: Describes a component triangle of a triangulation
|
||||
-- (Poly_Triangulation object).
|
||||
-- A Triangle is defined by a triplet of nodes. Each node is an
|
||||
-- index in the table of nodes specific to an existing
|
||||
-- triangulation of a shape, and represents a point on the surface.
|
||||
|
||||
raises
|
||||
OutOfRange from Standard
|
||||
|
||||
is
|
||||
|
||||
Create returns Triangle from Poly;
|
||||
---Purpose: Constructs a triangle and sets all indices to zero.
|
||||
|
||||
Create(N1,N2,N3 : Integer)
|
||||
returns Triangle from Poly;
|
||||
---Purpose: Constructs a triangle and sets its three indices
|
||||
-- to N1, N2 and N3 respectively, where these node values
|
||||
-- are indices in the table of nodes specific to an existing
|
||||
-- triangulation of a shape.
|
||||
Set(me : in out; N1,N2,N3 : Integer);
|
||||
---Purpose: Sets the value of the three nodes of this triangle to N1, N2 and N3 respectively.
|
||||
|
||||
Set(me : in out; Index, Node : Integer)
|
||||
---Purpose: Sets the value of the Indexth node of this triangle to Node.
|
||||
-- Raises OutOfRange if Index is not in 1,2,3
|
||||
raises
|
||||
OutOfRange from Standard;
|
||||
---C++: inline
|
||||
|
||||
Get(me; N1,N2,N3 : in out Integer);
|
||||
--- Purpose: Returns the node indices of this triangle in N1, N2 and N3.
|
||||
|
||||
Value(me; Index : Integer) returns Integer
|
||||
---Purpose: Get the node of given Index.
|
||||
-- Raises OutOfRange from Standard if Index is not in 1,2,3
|
||||
raises
|
||||
OutOfRange from Standard;
|
||||
---C++: inline
|
||||
---C++: alias operator()
|
||||
|
||||
ChangeValue(me : in out; Index : Integer) returns Integer
|
||||
---Purpose: Get the node of given Index.
|
||||
-- Raises OutOfRange if Index is not in 1,2,3
|
||||
raises
|
||||
OutOfRange from Standard;
|
||||
---C++: inline
|
||||
---C++: return &
|
||||
---C++: alias operator()
|
||||
|
||||
fields
|
||||
|
||||
myNodes : Integer [3];
|
||||
|
||||
end Triangle;
|
60
src/Poly/Poly_Triangle.cxx
Executable file
60
src/Poly/Poly_Triangle.cxx
Executable file
@@ -0,0 +1,60 @@
|
||||
// File: Poly_Triangle.cxx
|
||||
// Created: Mon Mar 6 10:47:39 1995
|
||||
// Author: Laurent PAINNOT
|
||||
// <lpa@metrox>
|
||||
|
||||
|
||||
#include <Poly_Triangle.ixx>
|
||||
|
||||
//=======================================================================
|
||||
//function : Poly_Triangle
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Poly_Triangle::Poly_Triangle()
|
||||
{
|
||||
myNodes[0] = myNodes[1] = myNodes[2] = 0;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Poly_Triangle
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Poly_Triangle::Poly_Triangle(const Standard_Integer N1,
|
||||
const Standard_Integer N2,
|
||||
const Standard_Integer N3)
|
||||
{
|
||||
myNodes[0] = N1;
|
||||
myNodes[1] = N2;
|
||||
myNodes[2] = N3;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Set
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void Poly_Triangle::Set(const Standard_Integer N1,
|
||||
const Standard_Integer N2,
|
||||
const Standard_Integer N3)
|
||||
{
|
||||
myNodes[0] = N1;
|
||||
myNodes[1] = N2;
|
||||
myNodes[2] = N3;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Get
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void Poly_Triangle::Get(Standard_Integer& N1,
|
||||
Standard_Integer& N2,
|
||||
Standard_Integer& N3) const
|
||||
{
|
||||
N1 = myNodes[0];
|
||||
N2 = myNodes[1];
|
||||
N3 = myNodes[2];
|
||||
}
|
||||
|
41
src/Poly/Poly_Triangle.lxx
Executable file
41
src/Poly/Poly_Triangle.lxx
Executable file
@@ -0,0 +1,41 @@
|
||||
// File: Poly_Triangle.lxx
|
||||
// Created: Mon Mar 6 10:47:04 1995
|
||||
// Author: Laurent PAINNOT
|
||||
// <lpa@metrox>
|
||||
|
||||
#include <Standard_OutOfRange.hxx>
|
||||
|
||||
//=======================================================================
|
||||
//function : Set
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline void Poly_Triangle::Set(const Standard_Integer Index, const Standard_Integer Node)
|
||||
{
|
||||
Standard_OutOfRange_Raise_if(Index < 1 || Index > 3,NULL);
|
||||
myNodes[Index-1] = Node;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Value
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Integer Poly_Triangle::Value(const Standard_Integer Index) const
|
||||
{
|
||||
Standard_OutOfRange_Raise_if(Index < 1 || Index > 3,NULL);
|
||||
return myNodes[Index-1];
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ChangeValue
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Integer& Poly_Triangle::ChangeValue
|
||||
(const Standard_Integer Index)
|
||||
{
|
||||
Standard_OutOfRange_Raise_if(Index < 1 || Index > 3,NULL);
|
||||
return myNodes[Index-1];
|
||||
}
|
||||
|
180
src/Poly/Poly_Triangulation.cdl
Executable file
180
src/Poly/Poly_Triangulation.cdl
Executable file
@@ -0,0 +1,180 @@
|
||||
-- File: Poly_Triangulation.cdl
|
||||
-- Created: Mon Mar 6 09:57:02 1995
|
||||
-- Author: Laurent PAINNOT
|
||||
-- <lpa@metrox>
|
||||
---Copyright: Matra Datavision 1995
|
||||
|
||||
|
||||
class Triangulation from Poly inherits TShared from MMgt
|
||||
|
||||
---Purpose: Provides a triangulation for a surface, a set of surfaces, or
|
||||
-- more generally a shape.
|
||||
-- A triangulation consists of an approximate representation
|
||||
-- of the actual shape, using a collection of points and
|
||||
-- triangles. The points are located on the surface. The
|
||||
-- edges of the triangles connect adjacent points with a
|
||||
-- straight line that approximates the true curve on the surface.
|
||||
-- A triangulation comprises:
|
||||
-- - A table of 3D nodes (3D points on the surface).
|
||||
-- - A table of triangles. Each triangle (Poly_Triangle
|
||||
-- object) comprises a triplet of indices in the table of 3D
|
||||
-- nodes specific to the triangulation.
|
||||
-- - A table of 2D nodes (2D points), parallel to the table of
|
||||
-- 3D nodes. This table is optional. If it exists, the
|
||||
-- coordinates of a 2D point are the (u, v) parameters
|
||||
-- of the corresponding 3D point on the surface
|
||||
-- approximated by the triangulation.
|
||||
-- - A deflection (optional), which maximizes the distance
|
||||
-- from a point on the surface to the corresponding point
|
||||
-- on its approximate triangulation.
|
||||
-- In many cases, algorithms do not need to work with the
|
||||
-- exact representation of a surface. A triangular
|
||||
-- representation induces simpler and more robust adjusting,
|
||||
-- faster performances, and the results are as good.
|
||||
|
||||
uses
|
||||
HArray1OfPnt2d from TColgp,
|
||||
Array1OfPnt from TColgp,
|
||||
Array1OfPnt2d from TColgp,
|
||||
Array1OfTriangle from Poly,
|
||||
HArray1OfShortReal from TShort,
|
||||
Array1OfShortReal from TShort
|
||||
|
||||
raises
|
||||
DomainError from Standard,
|
||||
NullObject from Standard
|
||||
|
||||
is
|
||||
|
||||
Create(nbNodes, nbTriangles: Integer; UVNodes: Boolean)
|
||||
returns mutable Triangulation from Poly;
|
||||
---Purpose: Constructs a triangulation from a set of triangles. The
|
||||
-- triangulation is initialized without a triangle or a node, but capable of
|
||||
-- containing nbNodes nodes, and nbTriangles
|
||||
-- triangles. Here the UVNodes flag indicates whether
|
||||
-- 2D nodes will be associated with 3D ones, (i.e. to
|
||||
-- enable a 2D representation).
|
||||
|
||||
Create(Nodes: Array1OfPnt from TColgp;
|
||||
Triangles: Array1OfTriangle from Poly)
|
||||
returns mutable Triangulation from Poly;
|
||||
---Purpose: Constructs a triangulation from a set of triangles. The
|
||||
-- triangulation is initialized with 3D points from Nodes and triangles
|
||||
-- from Triangles.
|
||||
|
||||
Create(Nodes: Array1OfPnt from TColgp;
|
||||
UVNodes: Array1OfPnt2d from TColgp;
|
||||
Triangles: Array1OfTriangle from Poly)
|
||||
returns mutable Triangulation from Poly;
|
||||
---Purpose: Constructs a triangulation from a set of triangles. The
|
||||
-- triangulation is initialized with 3D points from Nodes, 2D points from
|
||||
-- UVNodes and triangles from Triangles, where
|
||||
-- coordinates of a 2D point from UVNodes are the
|
||||
-- (u, v) parameters of the corresponding 3D point
|
||||
-- from Nodes on the surface approximated by the
|
||||
-- constructed triangulation.
|
||||
|
||||
Deflection(me) returns Real;
|
||||
---Purpose: Returns the deflection of this triangulation.
|
||||
Deflection(me : mutable; D : Real);
|
||||
---Purpose: Sets the deflection of this triangulation to D.
|
||||
-- See more on deflection in Polygon2D
|
||||
RemoveUVNodes(me : mutable);
|
||||
---Purpose: Deallocates the UV nodes.
|
||||
|
||||
NbNodes(me) returns Integer;
|
||||
---Purpose: Returns the number of nodes for this triangulation.
|
||||
-- Null if the nodes are not yet defined.
|
||||
---C++: inline
|
||||
|
||||
|
||||
NbTriangles(me) returns Integer;
|
||||
---Purpose: Returns the number of triangles for this triangulation.
|
||||
-- Null if the Triangles are not yet defined.
|
||||
---C++: inline
|
||||
|
||||
HasUVNodes(me) returns Boolean;
|
||||
---Purpose: Returns true if 2D nodes are associated with 3D nodes for
|
||||
-- this triangulation.
|
||||
---C++: inline
|
||||
|
||||
|
||||
Nodes(me) returns Array1OfPnt from TColgp
|
||||
---Purpose: Returns the table of 3D nodes (3D points) for this triangulation.
|
||||
---C++: return const &
|
||||
raises NullObject from Standard;
|
||||
|
||||
ChangeNodes(me : mutable) returns Array1OfPnt from TColgp
|
||||
---Purpose: Returns the table of 3D nodes (3D points) for this triangulation.
|
||||
-- The returned array is
|
||||
-- shared. Therefore if the table is selected by reference, you
|
||||
-- can, by simply modifying it, directly modify the data
|
||||
-- structure of this triangulation.
|
||||
---C++: return &
|
||||
raises NullObject from Standard;
|
||||
|
||||
UVNodes(me) returns Array1OfPnt2d from TColgp
|
||||
---Purpose: Returns the table of 2D nodes (2D points) associated with
|
||||
-- each 3D node of this triangulation.
|
||||
-- The function HasUVNodes checks if 2D nodes
|
||||
-- are associated with the 3D nodes of this triangulation.
|
||||
-- Const reference on the 2d nodes values.
|
||||
---C++: return const &
|
||||
raises NullObject from Standard;
|
||||
|
||||
ChangeUVNodes(me : mutable) returns Array1OfPnt2d from TColgp
|
||||
---Purpose: Returns the table of 2D nodes (2D points) associated with
|
||||
-- each 3D node of this triangulation.
|
||||
-- Function ChangeUVNodes shares the returned array.
|
||||
-- Therefore if the table is selected by reference,
|
||||
-- you can, by simply modifying it, directly modify the data
|
||||
-- structure of this triangulation.
|
||||
---C++: return &
|
||||
raises NullObject from Standard;
|
||||
|
||||
Triangles(me) returns Array1OfTriangle from Poly
|
||||
---Purpose: Returns the table of triangles for this triangulation.
|
||||
---C++: return const &
|
||||
raises NullObject from Standard;
|
||||
|
||||
ChangeTriangles(me : mutable) returns Array1OfTriangle from Poly
|
||||
---Purpose: Returns the table of triangles for this triangulation.
|
||||
-- Function ChangeUVNodes shares the returned array.
|
||||
-- Therefore if the table is selected by reference,
|
||||
-- you can, by simply modifying it, directly modify the data
|
||||
-- structure of this triangulation.
|
||||
---C++: return &
|
||||
raises NullObject from Standard;
|
||||
|
||||
SetNormals(me : mutable; theNormals : HArray1OfShortReal from TShort)
|
||||
---Purpose: Sets the table of node normals.
|
||||
-- raises exception if length of theNormals != 3*NbNodes
|
||||
raises DomainError from Standard;
|
||||
|
||||
Normals(me) returns Array1OfShortReal from TShort
|
||||
---C++: return const &
|
||||
-- raises exception if array of normals is empty or
|
||||
-- its length != 3*NbNodes
|
||||
raises NullObject from Standard;
|
||||
|
||||
ChangeNormals(me : mutable) returns Array1OfShortReal from TShort
|
||||
---C++: return &
|
||||
-- raises exception if array of normals is empty or
|
||||
-- its length != 3*NbNodes
|
||||
raises NullObject from Standard;
|
||||
|
||||
HasNormals(me) returns Boolean from Standard;
|
||||
|
||||
fields
|
||||
|
||||
myDeflection : Real;
|
||||
myNbNodes : Integer;
|
||||
myNbTriangles : Integer;
|
||||
myNodes : Array1OfPnt from TColgp;
|
||||
myUVNodes : HArray1OfPnt2d from TColgp;
|
||||
myTriangles : Array1OfTriangle from Poly;
|
||||
|
||||
---- Optional normals ---
|
||||
myNormals : HArray1OfShortReal from TShort;
|
||||
|
||||
end Triangulation;
|
227
src/Poly/Poly_Triangulation.cxx
Executable file
227
src/Poly/Poly_Triangulation.cxx
Executable file
@@ -0,0 +1,227 @@
|
||||
// File: Poly_Triangulation.cxx
|
||||
// Created: Mon Mar 6 10:54:09 1995
|
||||
// Author: Laurent PAINNOT
|
||||
// <lpa@metrox>
|
||||
|
||||
|
||||
#include <Poly_Triangulation.ixx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <Poly_Triangle.hxx>
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : Poly_Triangulation
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Poly_Triangulation::Poly_Triangulation(const Standard_Integer NbNodes,
|
||||
const Standard_Integer NbTriangles,
|
||||
const Standard_Boolean UVNodes) :
|
||||
myDeflection(0),
|
||||
myNbNodes(NbNodes),
|
||||
myNbTriangles(NbTriangles),
|
||||
myNodes(1, NbNodes),
|
||||
myTriangles(1, NbTriangles)
|
||||
{
|
||||
if (UVNodes) myUVNodes = new TColgp_HArray1OfPnt2d(1, myNbNodes);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Poly_Triangulation
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Poly_Triangulation::Poly_Triangulation(const TColgp_Array1OfPnt& Nodes,
|
||||
const Poly_Array1OfTriangle& Triangles) :
|
||||
myDeflection(0),
|
||||
myNbNodes(Nodes.Length()),
|
||||
myNbTriangles(Triangles.Length()),
|
||||
myNodes(1, Nodes.Length()),
|
||||
myTriangles(1, Triangles.Length())
|
||||
{
|
||||
myNodes = Nodes;
|
||||
myTriangles = Triangles;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : Poly_Triangulation
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Poly_Triangulation::Poly_Triangulation(const TColgp_Array1OfPnt& Nodes,
|
||||
const TColgp_Array1OfPnt2d& UVNodes,
|
||||
const Poly_Array1OfTriangle& Triangles) :
|
||||
myDeflection(0),
|
||||
myNbNodes(Nodes.Length()),
|
||||
myNbTriangles(Triangles.Length()),
|
||||
myNodes(1, Nodes.Length()),
|
||||
myTriangles(1, Triangles.Length())
|
||||
{
|
||||
myNodes = Nodes;
|
||||
myTriangles = Triangles;
|
||||
myUVNodes = new TColgp_HArray1OfPnt2d(1, myNbNodes);
|
||||
myUVNodes->ChangeArray1() = UVNodes;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Deflection
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Real Poly_Triangulation::Deflection() const
|
||||
{
|
||||
return myDeflection;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Deflection
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void Poly_Triangulation::Deflection(const Standard_Real D)
|
||||
{
|
||||
myDeflection = D;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : RemoveUVNodes
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void Poly_Triangulation::RemoveUVNodes()
|
||||
{
|
||||
myUVNodes.Nullify();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Nodes
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
const TColgp_Array1OfPnt& Poly_Triangulation::Nodes() const
|
||||
{
|
||||
return myNodes;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ChangeNodes
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
TColgp_Array1OfPnt& Poly_Triangulation::ChangeNodes()
|
||||
{
|
||||
return myNodes;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : UVNodes
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
const TColgp_Array1OfPnt2d& Poly_Triangulation::UVNodes() const
|
||||
{
|
||||
return myUVNodes->Array1();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ChangeUVNodes
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
TColgp_Array1OfPnt2d& Poly_Triangulation::ChangeUVNodes()
|
||||
{
|
||||
return myUVNodes->ChangeArray1();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Triangles
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
const Poly_Array1OfTriangle& Poly_Triangulation::Triangles() const
|
||||
{
|
||||
return myTriangles;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ChangeTriangles
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Poly_Array1OfTriangle& Poly_Triangulation::ChangeTriangles()
|
||||
{
|
||||
return myTriangles;
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : SetNormals
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void Poly_Triangulation::SetNormals
|
||||
(const Handle(TShort_HArray1OfShortReal)& theNormals)
|
||||
{
|
||||
|
||||
if(theNormals.IsNull() || theNormals->Length() != 3*myNbNodes) {
|
||||
Standard_DomainError::Raise("Poly_Triangulation::SetNormals : wrong length");
|
||||
}
|
||||
|
||||
myNormals = theNormals;
|
||||
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Normals
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
const TShort_Array1OfShortReal& Poly_Triangulation::Normals() const
|
||||
{
|
||||
|
||||
if(myNormals.IsNull() || myNormals->Length() != 3*myNbNodes) {
|
||||
Standard_NullObject::Raise("Poly_Triangulation::Normals : "
|
||||
"wrong length or null array");
|
||||
}
|
||||
|
||||
return myNormals->Array1();
|
||||
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ChangeNormals
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
TShort_Array1OfShortReal& Poly_Triangulation::ChangeNormals()
|
||||
{
|
||||
|
||||
if(myNormals.IsNull() || myNormals->Length() != 3*myNbNodes) {
|
||||
Standard_NullObject::Raise("Poly_Triangulation::ChangeNormals : "
|
||||
"wrong length or null array");
|
||||
}
|
||||
|
||||
return myNormals->ChangeArray1();
|
||||
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : HasNormals
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean Poly_Triangulation::HasNormals() const
|
||||
{
|
||||
|
||||
if(myNormals.IsNull() || myNormals->Length() != 3*myNbNodes) {
|
||||
return Standard_False;
|
||||
}
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
|
||||
|
35
src/Poly/Poly_Triangulation.lxx
Executable file
35
src/Poly/Poly_Triangulation.lxx
Executable file
@@ -0,0 +1,35 @@
|
||||
// File: Poly_Triangulation.lxx
|
||||
// Created: Mon Mar 6 10:53:09 1995
|
||||
// Author: Laurent PAINNOT
|
||||
// <lpa@metrox>
|
||||
|
||||
//=======================================================================
|
||||
//function : NbNodes
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Integer Poly_Triangulation::NbNodes() const
|
||||
{
|
||||
return myNbNodes;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : NbTriangles
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Integer Poly_Triangulation::NbTriangles() const
|
||||
{
|
||||
return myNbTriangles;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : HasUVNodes
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Boolean Poly_Triangulation::HasUVNodes() const
|
||||
{
|
||||
return !myUVNodes.IsNull();
|
||||
}
|
||||
|
Reference in New Issue
Block a user