Loading files
// Created on: 1999-03-08
// Created by: Fabrice SERVANT
// Copyright (c) 1999-1999 Matra Datavision
// Copyright (c) 1999-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <IntPolyh_Triangle.hxx>
#include <cstdio>
#define MyTolerance 10.0e-7
#define MyConfusionPrecision 10.0e-12
#define SquareMyConfusionPrecision 10.0e-24
static void GetInfoTA(const int numP1,
const int numP2,
const int numTA,
const IntPolyh_ArrayOfTriangles& TTriangles,
int& numP3b,
int& P3bIndex,
int& Edge2b,
int& Edge3b);
static void NewTriangle(const int P1,
const int P2,
const int P3,
IntPolyh_ArrayOfTriangles& TTriangles,
const occ::handle<Adaptor3d_Surface>& MySurface,
IntPolyh_ArrayOfPoints& TPoints);
static void NewEdge(const int P1,
const int P2,
const int T1,
const int T2,
IntPolyh_ArrayOfEdges& TEdges);
static void OldEdge(const int EdgeN,
const int NumTri,
const int NewTriNum,
IntPolyh_ArrayOfEdges& TEdges);
//=======================================================================
// function : ComputeDeflection
// purpose : Computes the deflection of the triangle.
// It is computed as a distance between triangles plane and
// barycenter of the triangle in UV space.
//=======================================================================
double IntPolyh_Triangle::ComputeDeflection(const occ::handle<Adaptor3d_Surface>& theSurface,
const IntPolyh_ArrayOfPoints& TPoints)
{
myDeflection = 0.;
//
const IntPolyh_Point& P1 = TPoints[myPoints[0]];
const IntPolyh_Point& P2 = TPoints[myPoints[1]];
const IntPolyh_Point& P3 = TPoints[myPoints[2]];
//
{
// check if the triangle is not degenerated - no more than one point
// has a degenerated flag
int iDeg = (P1.Degenerated() ? 1 : 0) + (P2.Degenerated() ? 1 : 0) + (P3.Degenerated() ? 1 : 0);
if (iDeg > 1)
{
myIsDegenerated = true;
return myDeflection;
}
}
//
// Plane of the triangle
IntPolyh_Point NormaleTri;
NormaleTri.Cross(P2 - P1, P3 - P1);
double SqNorm = NormaleTri.SquareModulus();
if (SqNorm < SquareMyConfusionPrecision)
{
// The triangle is degenerated
myIsDegenerated = true;
return myDeflection;
}
//
// Compute point on the surface
double Gu = (P1.U() + P2.U() + P3.U()) / 3.0;
double Gv = (P1.V() + P2.V() + P3.V()) / 3.0;
gp_Pnt PtXYZ = theSurface->Value(Gu, Gv);
// Point on the surface
IntPolyh_Point BarycentreReel(PtXYZ.X(), PtXYZ.Y(), PtXYZ.Z(), Gu, Gv);
// compute distance to plane
NormaleTri = NormaleTri / sqrt(SqNorm);
myDeflection = std::abs(NormaleTri.Dot(BarycentreReel - P1));
return myDeflection;
}
//=================================================================================================
int IntPolyh_Triangle::GetNextTriangle(const int theTriangle,
const int theEdgeNum,
const IntPolyh_ArrayOfEdges& TEdges) const
{
int aNextTriangle = -1;
if (theEdgeNum < 1 || theEdgeNum > 3)
{
return aNextTriangle;
}
//
const IntPolyh_Edge& anEdge = TEdges[myEdges[theEdgeNum - 1]];
aNextTriangle =
((anEdge.FirstTriangle() == theTriangle) ? anEdge.SecondTriangle() : anEdge.FirstTriangle());
return aNextTriangle;
}
//=================================================================================================
void IntPolyh_Triangle::LinkEdges2Triangle(const IntPolyh_ArrayOfEdges& TEdges,
const int theEdge1,
const int theEdge2,
const int theEdge3)
{
if (theEdge1 < 0 || theEdge2 < 0 || theEdge3 < 0)
{
return;
}
//
myEdges[0] = theEdge1;
myEdges[1] = theEdge2;
myEdges[2] = theEdge3;
//
myEdgesOrientations[0] = ((TEdges[myEdges[0]].FirstPoint() == myPoints[0]) ? 1 : -1);
myEdgesOrientations[1] = ((TEdges[myEdges[1]].FirstPoint() == myPoints[1]) ? 1 : -1);
myEdgesOrientations[2] = ((TEdges[myEdges[2]].FirstPoint() == myPoints[2]) ? 1 : -1);
}
//=================================================================================================
void GetInfoTA(const int numP1,
const int numP2,
const int numTA,
const IntPolyh_ArrayOfTriangles& TTriangles,
int& numP3b,
int& P3bIndex,
int& Edge2b,
int& Edge3b)
{
/// On veut savoir quel est le troisieme point du triangle
/// adjacent (TriAdj) et quel sont les edges partant de ce point
const IntPolyh_Triangle& TriAdj = TTriangles[numTA];
int P1b = TriAdj.FirstPoint();
int P2b = TriAdj.SecondPoint();
int P3b = TriAdj.ThirdPoint();
if ((P1b != numP1) && (P1b != numP2))
{
numP3b = P1b;
P3bIndex = 1;
if (P2b == numP1)
{
/// P1bP2b==numP3bnumP1:Edge3b donc dans ce cas
Edge3b = TriAdj.FirstEdge();
/// Donc P1bP3b==numP3bnumP2:Edge2b
Edge2b = TriAdj.ThirdEdge();
}
else
{
Edge2b = TriAdj.FirstEdge();
Edge3b = TriAdj.ThirdEdge();
}
}
else if ((P2b != numP1) && (P2b != numP2))
{
numP3b = P2b;
P3bIndex = 2;
if (P1b == numP1)
{
/// P2bP1b==numP3bnumP1:Edge3b donc dans ce cas
Edge3b = TriAdj.FirstEdge();
/// Donc P2bP3b==numP3bnumP2:Edge2b
Edge2b = TriAdj.SecondEdge();
}
else
{
Edge2b = TriAdj.FirstEdge();
Edge3b = TriAdj.SecondEdge();
}
}
else if ((P3b != numP1) && (P3b != numP2))
{
numP3b = P3b;
P3bIndex = 3;
if (P2b == numP1)
{
/// P3bP2b==numP3bnumP1:Edge3b donc dans ce cas
Edge3b = TriAdj.SecondEdge();
/// Donc P3bP1b==numP3bnumP2:Edge2b
Edge2b = TriAdj.ThirdEdge();
}
else
{
Edge2b = TriAdj.SecondEdge();
Edge3b = TriAdj.ThirdEdge();
}
}
}
//=================================================================================================
void NewTriangle(const int P1,
const int P2,
const int P3,
IntPolyh_ArrayOfTriangles& TTriangles,
const occ::handle<Adaptor3d_Surface>& MySurface,
IntPolyh_ArrayOfPoints& TPoints)
{
const int FinTT = TTriangles.NbItems();
TTriangles[FinTT].SetFirstPoint(P1);
TTriangles[FinTT].SetSecondPoint(P2);
TTriangles[FinTT].SetThirdPoint(P3);
TTriangles[FinTT].ComputeDeflection(MySurface, TPoints);
TTriangles.IncrementNbItems();
}
//=================================================================================================
void NewEdge(const int P1, const int P2, const int T1, const int T2, IntPolyh_ArrayOfEdges& TEdges)
{
const int FinTE = TEdges.NbItems();
TEdges[FinTE].SetFirstPoint(P1);
TEdges[FinTE].SetSecondPoint(P2);
TEdges[FinTE].SetFirstTriangle(T1);
TEdges[FinTE].SetSecondTriangle(T2);
TEdges.IncrementNbItems();
}
//=================================================================================================
void OldEdge(const int EdgeN, const int NumTri, const int NewTriNum, IntPolyh_ArrayOfEdges& TEdges)
{
if (TEdges[EdgeN].FirstTriangle() == NumTri)
{
TEdges[EdgeN].SetFirstTriangle(NewTriNum);
}
else
{
TEdges[EdgeN].SetSecondTriangle(NewTriNum);
}
}
//=================================================================================================
void IntPolyh_Triangle::MiddleRefinement(const int NumTri,
const occ::handle<Adaptor3d_Surface>& MySurface,
IntPolyh_ArrayOfPoints& TPoints,
IntPolyh_ArrayOfTriangles& TTriangles,
IntPolyh_ArrayOfEdges& TEdges)
{
int FinTE = TEdges.NbItems();
int FinTT = TTriangles.NbItems();
// Refinement of the mesh by the middle of the largest dimensions
int numP1 = FirstPoint();
int numP2 = SecondPoint();
int numP3 = ThirdPoint();
const IntPolyh_Point& P1 = TPoints[numP1];
const IntPolyh_Point& P2 = TPoints[numP2];
const IntPolyh_Point& P3 = TPoints[numP3];
// compute the largest dimension
double L12 = P1.SquareDistance(P2);
double L23 = P2.SquareDistance(P3);
double L31 = P3.SquareDistance(P1);
if ((L12 > L23) && (L12 > L31))
{
const int FinTP = TPoints.NbItems();
(TPoints[FinTP]).Middle(MySurface, P1, P2);
/// les nouveaux triangles
int T1, T2, T3, T4;
T1 = FinTT;
NewTriangle(numP2, numP3, FinTP, TTriangles, MySurface, TPoints);
FinTT++;
T2 = FinTT;
NewTriangle(numP3, numP1, FinTP, TTriangles, MySurface, TPoints);
FinTT++;
///***AFFINAGE DU TRIANGLE ADJACENT***
int numTA = GetNextTriangle(NumTri, 1, TEdges);
if (numTA >= 0)
{
int numP3b = -1;
int P3bIndex = -1;
int Edge2b = -1;
int Edge3b = -1;
GetInfoTA(numP1, numP2, numTA, TTriangles, numP3b, P3bIndex, Edge2b, Edge3b);
T3 = FinTT;
NewTriangle(numP2, numP3b, FinTP, TTriangles, MySurface, TPoints);
FinTT++;
T4 = FinTT;
NewTriangle(numP3b, numP1, FinTP, TTriangles, MySurface, TPoints);
/// On cree les nouveaux edges
int E1, E2, E3, E4;
E1 = FinTE;
NewEdge(numP1, FinTP, T2, T4, TEdges);
FinTE++;
E2 = FinTE;
NewEdge(FinTP, numP2, T1, T3, TEdges);
FinTE++;
E3 = FinTE;
NewEdge(FinTP, numP3, T1, T2, TEdges);
FinTE++;
E4 = FinTE;
NewEdge(FinTP, numP3b, T3, T4, TEdges);
/// On met a jour les anciens edges
OldEdge(myEdges[1], NumTri, T1, TEdges);
OldEdge(myEdges[2], NumTri, T2, TEdges);
OldEdge(Edge2b, numTA, T3, TEdges);
OldEdge(Edge3b, numTA, T4, TEdges);
/// On remplit les nouveaux triangles avec les edges
TTriangles[T1].LinkEdges2Triangle(TEdges, myEdges[1], E3, E2);
TTriangles[T2].LinkEdges2Triangle(TEdges, myEdges[2], E1, E3);
TTriangles[T3].LinkEdges2Triangle(TEdges, Edge2b, E4, E2);
TTriangles[T4].LinkEdges2Triangle(TEdges, Edge3b, E1, E4);
/// On tue le triangle adjacent
TTriangles[numTA].SetDeflection(-1.0);
TTriangles[numTA].SetIntersectionPossible(false);
}
else
{ /// seulement deux nouveaux triangles
// on cree les nouveaux edges avec T1 et T2
int E1, E2, E3;
E1 = FinTE;
NewEdge(numP1, FinTP, T2, -1, TEdges);
FinTE++;
E2 = FinTE;
NewEdge(FinTP, numP2, T1, -1, TEdges);
FinTE++;
E3 = FinTE;
NewEdge(FinTP, numP3, T1, T2, TEdges);
/// On met a jour les anciens edges
OldEdge(myEdges[1], NumTri, T1, TEdges);
OldEdge(myEdges[2], NumTri, T2, TEdges);
/// On remplit les nouveaux triangles avec les edges
TTriangles[T1].LinkEdges2Triangle(TEdges, myEdges[1], E3, E2);
TTriangles[T2].LinkEdges2Triangle(TEdges, myEdges[2], E1, E3);
}
}
else if ((L23 > L31) && (L23 > L12))
{
const int FinTP = TPoints.NbItems();
(TPoints[FinTP]).Middle(MySurface, P2, P3);
/// les nouveaux triangles
int T1, T2, T3, T4;
T1 = FinTT;
NewTriangle(numP1, numP2, FinTP, TTriangles, MySurface, TPoints);
FinTT++;
T2 = FinTT;
NewTriangle(numP3, numP1, FinTP, TTriangles, MySurface, TPoints);
FinTT++;
///*RAFFINAGE DU TRIANGLE ADJACENT***
int numTA = GetNextTriangle(NumTri, 2, TEdges);
if (numTA >= 0)
{
int numP1b = -1;
int P1bIndex = -1;
int Edge1b = -1;
int Edge3b = -1;
GetInfoTA(numP2, numP3, numTA, TTriangles, numP1b, P1bIndex, Edge3b, Edge1b);
T3 = FinTT;
NewTriangle(numP2, numP1b, FinTP, TTriangles, MySurface, TPoints);
FinTT++;
T4 = FinTT;
NewTriangle(numP1b, numP3, FinTP, TTriangles, MySurface, TPoints);
/// Nouveaux Edges
int E1, E2, E3, E4;
E1 = FinTE;
NewEdge(numP2, FinTP, T1, T3, TEdges);
FinTE++;
E2 = FinTE;
NewEdge(FinTP, numP3, T2, T4, TEdges);
FinTE++;
E3 = FinTE;
NewEdge(FinTP, numP1, T1, T2, TEdges);
FinTE++;
E4 = FinTE;
NewEdge(FinTP, numP1b, T3, T4, TEdges);
/// On met a jour les anciens edges
OldEdge(myEdges[0], NumTri, T1, TEdges);
OldEdge(myEdges[2], NumTri, T2, TEdges);
OldEdge(Edge1b, numTA, T3, TEdges);
OldEdge(Edge3b, numTA, T4, TEdges);
/// On remplit les nouveaux triangles avec les edges
TTriangles[T1].LinkEdges2Triangle(TEdges, myEdges[0], E1, E3);
TTriangles[T2].LinkEdges2Triangle(TEdges, myEdges[2], E3, E2);
TTriangles[T3].LinkEdges2Triangle(TEdges, Edge1b, E4, E1);
TTriangles[T4].LinkEdges2Triangle(TEdges, Edge3b, E2, E4);
/// On tue le triangle adjacent
TTriangles[numTA].SetDeflection(-1.0);
TTriangles[numTA].SetIntersectionPossible(false);
}
else
{ /// seulement deux nouveaux triangles
/// Nouveaux Edges
int E1, E2, E3;
E1 = FinTE;
NewEdge(numP2, FinTP, T1, -1, TEdges);
FinTE++;
E2 = FinTE;
NewEdge(FinTP, numP3, T2, -1, TEdges);
FinTE++;
E3 = FinTE;
NewEdge(FinTP, numP1, T1, T2, TEdges);
/// On met a jour les anciens edges
OldEdge(myEdges[0], NumTri, T1, TEdges);
OldEdge(myEdges[2], NumTri, T2, TEdges);
/// On remplit les nouveaux triangles avec les edges
TTriangles[T1].LinkEdges2Triangle(TEdges, myEdges[0], E1, E3);
TTriangles[T2].LinkEdges2Triangle(TEdges, myEdges[2], E3, E2);
}
}
else
{
const int FinTP = TPoints.NbItems();
(TPoints[FinTP]).Middle(MySurface, P3, P1);
int T1, T2, T3, T4;
T1 = FinTT;
NewTriangle(numP1, numP2, FinTP, TTriangles, MySurface, TPoints);
FinTT++;
T2 = FinTT;
NewTriangle(numP2, numP3, FinTP, TTriangles, MySurface, TPoints);
FinTT++;
///*RAFFINAGE DU TRIANGLE ADJACENT***
int numTA = GetNextTriangle(NumTri, 3, TEdges);
if (numTA >= 0)
{
int numP2b = -1;
int P2bIndex = -1;
int Edge1b = -1;
int Edge2b = -1;
GetInfoTA(numP3, numP1, numTA, TTriangles, numP2b, P2bIndex, Edge1b, Edge2b);
T3 = FinTT;
NewTriangle(numP1, numP2b, FinTP, TTriangles, MySurface, TPoints);
FinTT++;
T4 = FinTT;
NewTriangle(numP2b, numP3, FinTP, TTriangles, MySurface, TPoints);
/// Nouveaux Edges
int E1, E2, E3, E4;
E1 = FinTE;
NewEdge(numP2, FinTP, T1, T2, TEdges);
FinTE++;
E2 = FinTE;
NewEdge(FinTP, numP3, T2, T4, TEdges);
FinTE++;
E3 = FinTE;
NewEdge(FinTP, numP2b, T4, T3, TEdges);
FinTE++;
E4 = FinTE;
NewEdge(FinTP, numP1, T1, T3, TEdges);
/// On met a jour les anciens edges
OldEdge(myEdges[0], NumTri, T1, TEdges);
OldEdge(myEdges[1], NumTri, T2, TEdges);
OldEdge(Edge1b, numTA, T3, TEdges);
OldEdge(Edge2b, numTA, T4, TEdges);
/// On remplit les nouveaux triangles avec les edges
TTriangles[T1].LinkEdges2Triangle(TEdges, myEdges[0], E1, E4);
TTriangles[T2].LinkEdges2Triangle(TEdges, myEdges[1], E2, E1);
TTriangles[T3].LinkEdges2Triangle(TEdges, Edge1b, E3, E4);
TTriangles[T4].LinkEdges2Triangle(TEdges, Edge2b, E2, E3);
/// On tue le triangle adjacent
TTriangles[numTA].SetDeflection(-1.0);
TTriangles[numTA].SetIntersectionPossible(false);
}
else
{ /// seulement deux nouveaux triangles
/// Nouveaux Edges
int E1, E2, E4;
E1 = FinTE;
NewEdge(numP2, FinTP, T1, T2, TEdges);
FinTE++;
E2 = FinTE;
NewEdge(FinTP, numP3, T2, -1, TEdges);
FinTE++;
E4 = FinTE;
NewEdge(FinTP, numP1, T1, -1, TEdges);
/// On met a jour les anciens edges
OldEdge(myEdges[0], NumTri, T1, TEdges);
OldEdge(myEdges[1], NumTri, T2, TEdges);
/// On remplit les nouveaux triangles avec les edges
TTriangles[T1].LinkEdges2Triangle(TEdges, myEdges[0], E1, E4);
TTriangles[T2].LinkEdges2Triangle(TEdges, myEdges[1], E2, E1);
}
}
TPoints.IncrementNbItems();
// make the triangle obsolete
myDeflection = -1.0;
myIsIntersectionPossible = false;
}
//=================================================================================================
void IntPolyh_Triangle::MultipleMiddleRefinement(const double theRefineCriterion,
const Bnd_Box& theBox,
const int theTriangleNumber,
const occ::handle<Adaptor3d_Surface>& theSurface,
IntPolyh_ArrayOfPoints& TPoints,
IntPolyh_ArrayOfTriangles& TTriangles,
IntPolyh_ArrayOfEdges& TEdges)
{
// Number of triangles before refinement of current triangle
const int FinTTInit = TTriangles.NbItems();
// Criteria to stop splitting - double of the initial number of triangles,
// i.e. allow each triangle to be split at least once. Add a constant
// to allow the splits of triangles to be checked.
const int MaxNbTT = 2 * FinTTInit + 1000;
// Split the current triangle
MiddleRefinement(theTriangleNumber, theSurface, TPoints, TTriangles, TEdges);
// Refine the new triangles
for (int i = FinTTInit; i < TTriangles.NbItems() && i < MaxNbTT; ++i)
{
IntPolyh_Triangle& aTriangle = TTriangles[i];
if (theBox.IsOut(aTriangle.BoundingBox(TPoints)))
{
aTriangle.SetIntersectionPossible(false);
}
else if (aTriangle.Deflection() > theRefineCriterion)
{
aTriangle.MiddleRefinement(i, theSurface, TPoints, TTriangles, TEdges);
}
}
}
//=================================================================================================
void IntPolyh_Triangle::SetEdgeAndOrientation(const IntPolyh_Edge& theEdge, const int theEdgeIndex)
{
// Points on the edge - pe1, pe2
int pe1 = theEdge.FirstPoint(), pe2 = theEdge.SecondPoint();
//
// We have points on the triangle - p1, p2 and p3;
// And points on the edge - pe1, pe2;
// By comparing these points we should define which
// edge it is for the triangle and its orientation on it:
// e1 = p1->p2;
// e2 = p2->p3;
// e3 = p3->p1;
// In case the order of points on the edge is forward,
// the orientation is positive, otherwise it is negative.
for (int i = 0, i1 = 1; i < 3; ++i, ++i1)
{
if (i1 > 2)
{
i1 = 0;
}
//
if (pe1 == myPoints[i] && pe2 == myPoints[i1])
{
myEdges[i] = theEdgeIndex;
myEdgesOrientations[i] = 1;
break;
}
if (pe1 == myPoints[i1] && pe2 == myPoints[i])
{
myEdges[i] = theEdgeIndex;
myEdgesOrientations[i] = -1;
break;
}
}
}
//=================================================================================================
const Bnd_Box& IntPolyh_Triangle::BoundingBox(const IntPolyh_ArrayOfPoints& thePoints)
{
if (myBox.IsVoid())
{
const IntPolyh_Point& aP1 = thePoints[myPoints[0]];
const IntPolyh_Point& aP2 = thePoints[myPoints[1]];
const IntPolyh_Point& aP3 = thePoints[myPoints[2]];
myBox.Add(gp_Pnt(aP1.X(), aP1.Y(), aP1.Z()));
myBox.Add(gp_Pnt(aP2.X(), aP2.Y(), aP2.Z()));
myBox.Add(gp_Pnt(aP3.X(), aP3.Y(), aP3.Z()));
myBox.SetGap(myDeflection + Precision::Confusion());
}
return myBox;
}
//=================================================================================================
void IntPolyh_Triangle::Dump(const int i) const
{
printf("\nTriangle(%3d) : Points %5d %5d %5d Edges %5d %5d %5d deflection: %8f "
"intersection possible %8d intersection: %5d\n",
i,
myPoints[0],
myPoints[1],
myPoints[2],
myEdges[0],
myEdges[1],
myEdges[2],
myDeflection,
(myIsIntersectionPossible ? 1 : 0),
(myHasIntersection ? 1 : 0));
}
3d097a032This file is pinned to the selected release. Download the original to open it in your design tool.