mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-05-16 10:54:53 +03:00
Switching the Boolean Operations algorithm to use the BVH tree instead of UB tree as selection of the elements from BVH tree is usually faster.
3030 lines
110 KiB
C++
3030 lines
110 KiB
C++
// Created on: 1999-03-05
|
|
// 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.
|
|
|
|
// modified by Edward AGAPOV (eap) Tue Jan 22 2002 (bug occ53)
|
|
// - improve SectionLine table management (avoid memory reallocation)
|
|
// - some protection against arrays overflow
|
|
// modified by Edward AGAPOV (eap) Thu Feb 14 2002 (occ139)
|
|
// - make Section Line parts rightly connected (prepend 2nd part to the 1st)
|
|
// - TriangleShape() for debugging purpose
|
|
// Modified by skv - Thu Sep 25 17:42:42 2003 OCC567
|
|
// modified by ofv Thu Apr 8 14:58:13 2004 fip
|
|
|
|
#include <Adaptor3d_HSurface.hxx>
|
|
#include <Bnd_BoundSortBox.hxx>
|
|
#include <Bnd_Box.hxx>
|
|
#include <Bnd_HArray1OfBox.hxx>
|
|
#include <Bnd_Tools.hxx>
|
|
#include <BVH_BoxSet.hxx>
|
|
#include <BVH_LinearBuilder.hxx>
|
|
#include <BVH_Traverse.hxx>
|
|
#include <gp.hxx>
|
|
#include <gp_Pnt.hxx>
|
|
#include <IntPolyh_ListOfCouples.hxx>
|
|
#include <IntPolyh_Couple.hxx>
|
|
#include <IntPolyh_Edge.hxx>
|
|
#include <IntPolyh_MaillageAffinage.hxx>
|
|
#include <IntPolyh_Point.hxx>
|
|
#include <IntPolyh_SectionLine.hxx>
|
|
#include <IntPolyh_StartPoint.hxx>
|
|
#include <IntPolyh_Tools.hxx>
|
|
#include <IntPolyh_Triangle.hxx>
|
|
#include <Precision.hxx>
|
|
#include <TColStd_Array1OfInteger.hxx>
|
|
#include <TColStd_MapOfInteger.hxx>
|
|
#include <TColStd_ListIteratorOfListOfInteger.hxx>
|
|
#include <algorithm>
|
|
#include <NCollection_IndexedDataMap.hxx>
|
|
|
|
typedef NCollection_Array1<Standard_Integer> IntPolyh_ArrayOfInteger;
|
|
typedef NCollection_IndexedDataMap
|
|
<Standard_Integer,
|
|
TColStd_ListOfInteger,
|
|
TColStd_MapIntegerHasher> IntPolyh_IndexedDataMapOfIntegerListOfInteger;
|
|
|
|
|
|
static Standard_Real MyTolerance=10.0e-7;
|
|
static Standard_Real MyConfusionPrecision=10.0e-12;
|
|
static Standard_Real SquareMyConfusionPrecision=10.0e-24;
|
|
//
|
|
static
|
|
inline Standard_Real maxSR(const Standard_Real a,
|
|
const Standard_Real b,
|
|
const Standard_Real c);
|
|
|
|
static
|
|
inline Standard_Real minSR(const Standard_Real a,
|
|
const Standard_Real b,
|
|
const Standard_Real c);
|
|
static
|
|
Standard_Integer project6(const IntPolyh_Point &ax,
|
|
const IntPolyh_Point &p1,
|
|
const IntPolyh_Point &p2,
|
|
const IntPolyh_Point &p3,
|
|
const IntPolyh_Point &q1,
|
|
const IntPolyh_Point &q2,
|
|
const IntPolyh_Point &q3);
|
|
static
|
|
void TestNbPoints(const Standard_Integer ,
|
|
Standard_Integer &NbPoints,
|
|
Standard_Integer &NbPointsTotal,
|
|
const IntPolyh_StartPoint &Pt1,
|
|
const IntPolyh_StartPoint &Pt2,
|
|
IntPolyh_StartPoint &SP1,
|
|
IntPolyh_StartPoint &SP2);
|
|
static
|
|
void CalculPtsInterTriEdgeCoplanaires(const Standard_Integer TriSurfID,
|
|
const IntPolyh_Point &NormaleTri,
|
|
const IntPolyh_Triangle &Tri1,
|
|
const IntPolyh_Triangle &Tri2,
|
|
const IntPolyh_Point &PE1,
|
|
const IntPolyh_Point &PE2,
|
|
const IntPolyh_Point &Edge,
|
|
const Standard_Integer EdgeIndex,
|
|
const IntPolyh_Point &PT1,
|
|
const IntPolyh_Point &PT2,
|
|
const IntPolyh_Point &Cote,
|
|
const Standard_Integer CoteIndex,
|
|
IntPolyh_StartPoint &SP1,
|
|
IntPolyh_StartPoint &SP2,
|
|
Standard_Integer &NbPoints);
|
|
static
|
|
Standard_Boolean CheckCoupleAndGetAngle(const Standard_Integer T1,
|
|
const Standard_Integer T2,
|
|
Standard_Real& Angle,
|
|
IntPolyh_ListOfCouples &TTrianglesContacts);
|
|
static
|
|
Standard_Boolean CheckCoupleAndGetAngle2(const Standard_Integer T1,
|
|
const Standard_Integer T2,
|
|
const Standard_Integer T11,
|
|
const Standard_Integer T22,
|
|
IntPolyh_ListIteratorOfListOfCouples& theItCT11,
|
|
IntPolyh_ListIteratorOfListOfCouples& theItCT22,
|
|
Standard_Real & Angle,
|
|
IntPolyh_ListOfCouples &TTrianglesContacts);
|
|
static
|
|
Standard_Integer CheckNextStartPoint(IntPolyh_SectionLine & SectionLine,
|
|
IntPolyh_ArrayOfTangentZones & TTangentZones,
|
|
IntPolyh_StartPoint & SP,
|
|
const Standard_Boolean Prepend=Standard_False);
|
|
|
|
static
|
|
Standard_Boolean IsDegenerated(const Handle(Adaptor3d_HSurface)& aS,
|
|
const Standard_Integer aIndex,
|
|
const Standard_Real aTol2,
|
|
Standard_Real& aDegX);
|
|
static
|
|
void DegeneratedIndex(const TColStd_Array1OfReal& Xpars,
|
|
const Standard_Integer aNbX,
|
|
const Handle(Adaptor3d_HSurface)& aS,
|
|
const Standard_Integer aIsoDirection,
|
|
Standard_Integer& aI1,
|
|
Standard_Integer& aI2);
|
|
|
|
//=======================================================================
|
|
//class : IntPolyh_BoxBndTree
|
|
//purpose : BVH structure to contain the boxes of triangles
|
|
//=======================================================================
|
|
typedef BVH_BoxSet <Standard_Real, 3, Standard_Integer> IntPolyh_BoxBndTree;
|
|
|
|
//=======================================================================
|
|
//class : IntPolyh_BoxBndTreeSelector
|
|
//purpose : Selector of interfering boxes
|
|
//=======================================================================
|
|
class IntPolyh_BoxBndTreeSelector :
|
|
public BVH_PairTraverse<Standard_Real, 3, IntPolyh_BoxBndTree>
|
|
{
|
|
public:
|
|
typedef BVH_Box<Standard_Real, 3>::BVH_VecNt BVH_Vec3d;
|
|
|
|
//! Auxiliary structure to keep the pair of indices
|
|
struct PairIDs
|
|
{
|
|
PairIDs (const Standard_Integer theId1 = -1,
|
|
const Standard_Integer theId2 = -1)
|
|
: ID1 (theId1), ID2 (theId2)
|
|
{}
|
|
|
|
Standard_Boolean operator< (const PairIDs& theOther) const
|
|
{
|
|
return ID1 < theOther.ID1 ||
|
|
(ID1 == theOther.ID1 && ID2 < theOther.ID2);
|
|
}
|
|
|
|
Standard_Integer ID1;
|
|
Standard_Integer ID2;
|
|
};
|
|
|
|
public:
|
|
|
|
//! Constructor
|
|
IntPolyh_BoxBndTreeSelector ()
|
|
{}
|
|
|
|
//! Rejects the node
|
|
virtual Standard_Boolean RejectNode (const BVH_Vec3d& theCMin1,
|
|
const BVH_Vec3d& theCMax1,
|
|
const BVH_Vec3d& theCMin2,
|
|
const BVH_Vec3d& theCMax2,
|
|
Standard_Real&) const Standard_OVERRIDE
|
|
{
|
|
return BVH_Box<Standard_Real, 3> (theCMin1, theCMax1).IsOut (theCMin2, theCMax2);
|
|
}
|
|
|
|
//! Accepts the element
|
|
virtual Standard_Boolean Accept (const Standard_Integer theID1,
|
|
const Standard_Integer theID2) Standard_OVERRIDE
|
|
{
|
|
if (!myBVHSet1->Box (theID1).IsOut (myBVHSet2->Box (theID2)))
|
|
{
|
|
myPairs.push_back (PairIDs (myBVHSet1->Element (theID1), myBVHSet2->Element (theID2)));
|
|
return Standard_True;
|
|
}
|
|
return Standard_False;
|
|
}
|
|
|
|
//! Returns indices
|
|
const std::vector<PairIDs>& Pairs() const
|
|
{
|
|
return myPairs;
|
|
}
|
|
|
|
//! Sorts the resulting indices
|
|
void Sort()
|
|
{
|
|
std::sort (myPairs.begin(), myPairs.end());
|
|
}
|
|
|
|
private:
|
|
|
|
std::vector<PairIDs> myPairs;
|
|
};
|
|
|
|
//=======================================================================
|
|
//function : GetInterferingTriangles
|
|
//purpose : Returns indices of the triangles with interfering bounding boxes
|
|
//=======================================================================
|
|
static
|
|
void GetInterferingTriangles(IntPolyh_ArrayOfTriangles& theTriangles1,
|
|
const IntPolyh_ArrayOfPoints& thePoints1,
|
|
IntPolyh_ArrayOfTriangles& theTriangles2,
|
|
const IntPolyh_ArrayOfPoints& thePoints2,
|
|
IntPolyh_IndexedDataMapOfIntegerListOfInteger& theCouples)
|
|
{
|
|
// Use linear builder for BVH construction
|
|
opencascade::handle<BVH_LinearBuilder<Standard_Real, 3>> aLBuilder =
|
|
new BVH_LinearBuilder<Standard_Real, 3> (10);
|
|
|
|
// To find the triangles with interfering bounding boxes
|
|
// use the BVH structure
|
|
IntPolyh_BoxBndTree aBBTree1 (aLBuilder), aBBTree2 (aLBuilder);
|
|
|
|
// 1. Fill the trees with the boxes of the surfaces triangles
|
|
for (Standard_Integer i = 0; i < 2; ++i)
|
|
{
|
|
IntPolyh_BoxBndTree &aBBTree = !i ? aBBTree1 : aBBTree2;
|
|
IntPolyh_ArrayOfTriangles& aTriangles = !i ? theTriangles1 : theTriangles2;
|
|
const IntPolyh_ArrayOfPoints& aPoints = !i ? thePoints1 : thePoints2;
|
|
|
|
const Standard_Integer aNbT = aTriangles.NbItems();
|
|
aBBTree.SetSize (aNbT);
|
|
for (Standard_Integer j = 0; j < aNbT; ++j)
|
|
{
|
|
IntPolyh_Triangle& aT = aTriangles[j];
|
|
if (!aT.IsIntersectionPossible() || aT.IsDegenerated())
|
|
continue;
|
|
|
|
aBBTree.Add (j, Bnd_Tools::Bnd2BVH (aT.BoundingBox(aPoints)));
|
|
}
|
|
|
|
if (!aBBTree.Size())
|
|
return;
|
|
}
|
|
// 2. Construct BVH trees
|
|
aBBTree1.Build();
|
|
aBBTree2.Build();
|
|
|
|
// 3. Perform selection of the interfering triangles
|
|
IntPolyh_BoxBndTreeSelector aSelector;
|
|
aSelector.SetBVHSets (&aBBTree1, &aBBTree2);
|
|
aSelector.Select();
|
|
aSelector.Sort();
|
|
|
|
const std::vector<IntPolyh_BoxBndTreeSelector::PairIDs>& aPairs = aSelector.Pairs();
|
|
const Standard_Integer aNbPairs = static_cast<Standard_Integer>(aPairs.size());
|
|
|
|
for (Standard_Integer i = 0; i < aNbPairs; ++i)
|
|
{
|
|
const IntPolyh_BoxBndTreeSelector::PairIDs& aPair = aPairs[i];
|
|
TColStd_ListOfInteger* pTriangles2 = theCouples.ChangeSeek (aPair.ID1);
|
|
if (!pTriangles2)
|
|
pTriangles2 = &theCouples( theCouples.Add (aPair.ID1, TColStd_ListOfInteger()));
|
|
pTriangles2->Append (aPair.ID2);
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : IntPolyh_MaillageAffinage
|
|
//purpose :
|
|
//=======================================================================
|
|
IntPolyh_MaillageAffinage::IntPolyh_MaillageAffinage
|
|
(const Handle(Adaptor3d_HSurface)& Surface1,
|
|
const Handle(Adaptor3d_HSurface)& Surface2,
|
|
const Standard_Integer )
|
|
:
|
|
MaSurface1(Surface1),
|
|
MaSurface2(Surface2),
|
|
NbSamplesU1(10),
|
|
NbSamplesU2(10),
|
|
NbSamplesV1(10),
|
|
NbSamplesV2(10),
|
|
FlecheMax1(0.0),
|
|
FlecheMax2(0.0),
|
|
FlecheMin1(0.0),
|
|
FlecheMin2(0.0),
|
|
myEnlargeZone(Standard_False)
|
|
{
|
|
}
|
|
//=======================================================================
|
|
//function : IntPolyh_MaillageAffinage
|
|
//purpose :
|
|
//=======================================================================
|
|
IntPolyh_MaillageAffinage::IntPolyh_MaillageAffinage
|
|
(const Handle(Adaptor3d_HSurface)& Surface1,
|
|
const Standard_Integer NbSU1,
|
|
const Standard_Integer NbSV1,
|
|
const Handle(Adaptor3d_HSurface)& Surface2,
|
|
const Standard_Integer NbSU2,
|
|
const Standard_Integer NbSV2,
|
|
const Standard_Integer )
|
|
:
|
|
MaSurface1(Surface1),
|
|
MaSurface2(Surface2),
|
|
NbSamplesU1(NbSU1),
|
|
NbSamplesU2(NbSU2),
|
|
NbSamplesV1(NbSV1),
|
|
NbSamplesV2(NbSV2),
|
|
FlecheMax1(0.0),
|
|
FlecheMax2(0.0),
|
|
FlecheMin1(0.0),
|
|
FlecheMin2(0.0),
|
|
myEnlargeZone(Standard_False)
|
|
{
|
|
}
|
|
//=======================================================================
|
|
//function : MakeSampling
|
|
//purpose :
|
|
//=======================================================================
|
|
void IntPolyh_MaillageAffinage::MakeSampling(const Standard_Integer SurfID,
|
|
TColStd_Array1OfReal& theUPars,
|
|
TColStd_Array1OfReal& theVPars)
|
|
{
|
|
if (SurfID == 1)
|
|
IntPolyh_Tools::MakeSampling(MaSurface1, NbSamplesU1, NbSamplesV1, myEnlargeZone, theUPars, theVPars);
|
|
else
|
|
IntPolyh_Tools::MakeSampling(MaSurface2, NbSamplesU2, NbSamplesV2, myEnlargeZone, theUPars, theVPars);
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : FillArrayOfPnt
|
|
//purpose : Compute points on one surface and fill an array of points
|
|
//=======================================================================
|
|
void IntPolyh_MaillageAffinage::FillArrayOfPnt
|
|
(const Standard_Integer SurfID)
|
|
{
|
|
// Make sampling
|
|
TColStd_Array1OfReal aUpars, aVpars;
|
|
MakeSampling(SurfID, aUpars, aVpars);
|
|
// Fill array of points
|
|
FillArrayOfPnt(SurfID, aUpars, aVpars);
|
|
}
|
|
//=======================================================================
|
|
//function : FillArrayOfPnt
|
|
//purpose : Compute points on one surface and fill an array of points
|
|
// FILL AN ARRAY OF POINTS
|
|
//=======================================================================
|
|
void IntPolyh_MaillageAffinage::FillArrayOfPnt
|
|
(const Standard_Integer SurfID,
|
|
const Standard_Boolean isShiftFwd)
|
|
{
|
|
// Make sampling
|
|
TColStd_Array1OfReal aUpars, aVpars;
|
|
MakeSampling(SurfID, aUpars, aVpars);
|
|
// Fill array of points
|
|
FillArrayOfPnt(SurfID, isShiftFwd, aUpars, aVpars);
|
|
}
|
|
//=======================================================================
|
|
//function : FillArrayOfPnt
|
|
//purpose : Compute points on one surface and fill an array of points
|
|
//=======================================================================
|
|
void IntPolyh_MaillageAffinage::FillArrayOfPnt
|
|
(const Standard_Integer SurfID,
|
|
const TColStd_Array1OfReal& Upars,
|
|
const TColStd_Array1OfReal& Vpars,
|
|
const Standard_Real *theDeflTol)
|
|
{
|
|
Standard_Boolean bDegI, bDeg;
|
|
Standard_Integer aNbU, aNbV, iCnt, i, j;
|
|
Standard_Integer aID1, aID2, aJD1, aJD2;
|
|
Standard_Real aTol, aU, aV, aX, aY, aZ;
|
|
gp_Pnt aP;
|
|
//
|
|
aNbU=(SurfID==1)? NbSamplesU1 : NbSamplesU2;
|
|
aNbV=(SurfID==1)? NbSamplesV1 : NbSamplesV2;
|
|
Bnd_Box& aBox = (SurfID==1) ? MyBox1 : MyBox2;
|
|
Handle(Adaptor3d_HSurface)& aS=(SurfID==1)? MaSurface1:MaSurface2;
|
|
IntPolyh_ArrayOfPoints &TPoints=(SurfID==1)? TPoints1:TPoints2;
|
|
//
|
|
aJD1=0;
|
|
aJD2=0;
|
|
aID1=0;
|
|
aID2=0;
|
|
DegeneratedIndex(Vpars, aNbV, aS, 1, aJD1, aJD2);
|
|
if (!(aJD1 || aJD2)) {
|
|
DegeneratedIndex(Upars, aNbU, aS, 2, aID1, aID2);
|
|
}
|
|
//
|
|
TPoints.Init(aNbU*aNbV);
|
|
iCnt=0;
|
|
for(i=1; i<=aNbU; ++i){
|
|
bDegI=(aID1==i || aID2==i);
|
|
aU=Upars(i);
|
|
for(j=1; j<=aNbV; ++j){
|
|
aV=Vpars(j);
|
|
aP=aS->Value(aU, aV);
|
|
aP.Coord(aX, aY, aZ);
|
|
IntPolyh_Point& aIP=TPoints[iCnt];
|
|
aIP.Set(aX, aY, aZ, aU, aV);
|
|
//
|
|
bDeg=bDegI || (aJD1==j || aJD2==j);
|
|
if (bDeg) {
|
|
aIP.SetDegenerated(bDeg);
|
|
}
|
|
++iCnt;
|
|
aBox.Add(aP);
|
|
}
|
|
}
|
|
//
|
|
TPoints.SetNbItems(iCnt);
|
|
//
|
|
aTol = !theDeflTol ? IntPolyh_Tools::ComputeDeflection(aS, Upars, Vpars) : *theDeflTol;
|
|
aTol *= 1.2;
|
|
|
|
Standard_Real a1,a2,a3,b1,b2,b3;
|
|
//
|
|
aBox.Get(a1,a2,a3,b1,b2,b3);
|
|
aBox.Update(a1-aTol,a2-aTol,a3-aTol,b1+aTol,b2+aTol,b3+aTol);
|
|
aBox.Enlarge(MyTolerance);
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : FillArrayOfPnt
|
|
//purpose :
|
|
//=======================================================================
|
|
void IntPolyh_MaillageAffinage::FillArrayOfPnt(const Standard_Integer SurfID,
|
|
const Standard_Boolean isShiftFwd,
|
|
const IntPolyh_ArrayOfPointNormal& thePointsNorm,
|
|
const TColStd_Array1OfReal& theUPars,
|
|
const TColStd_Array1OfReal& theVPars,
|
|
const Standard_Real theDeflTol)
|
|
{
|
|
Handle(Adaptor3d_HSurface) aS = (SurfID == 1) ? MaSurface1 : MaSurface2;
|
|
IntPolyh_ArrayOfPoints& TPoints = (SurfID == 1) ? TPoints1 : TPoints2;
|
|
Standard_Integer aNbU = (SurfID == 1) ? NbSamplesU1 : NbSamplesU2;
|
|
Standard_Integer aNbV = (SurfID == 1) ? NbSamplesV1 : NbSamplesV2;
|
|
Bnd_Box& aBox = (SurfID==1) ? MyBox1 : MyBox2;
|
|
|
|
Standard_Integer aJD1(0), aJD2(0), aID1(0), aID2(0);
|
|
DegeneratedIndex(theVPars, aNbV, aS, 1, aJD1, aJD2);
|
|
if (!(aJD1 || aJD2))
|
|
DegeneratedIndex(theUPars, aNbU, aS, 2, aID1, aID2);
|
|
|
|
Standard_Boolean bDegI, bDeg;
|
|
Standard_Integer iCnt(0), i, j;
|
|
Standard_Real aX, aY, aZ, aU, aV;
|
|
|
|
TPoints.Init(thePointsNorm.NbItems());
|
|
|
|
for (i = 1; i <= aNbU; ++i)
|
|
{
|
|
aU = theUPars(i);
|
|
bDegI = (aID1 == i || aID2 == i);
|
|
for (j = 1; j <= aNbV; ++j)
|
|
{
|
|
aV = theVPars(j);
|
|
|
|
const IntPolyh_PointNormal& aPN = thePointsNorm.Value(iCnt);
|
|
gp_Vec aNorm = aPN.Normal.Multiplied(1.5*theDeflTol);
|
|
if (!isShiftFwd)
|
|
aNorm.Reverse();
|
|
gp_Pnt aP = aPN.Point.Translated(aNorm);
|
|
|
|
IntPolyh_Point& aIP = TPoints[iCnt];
|
|
aP.Coord(aX, aY, aZ);
|
|
aIP.Set(aX, aY, aZ, aU, aV);
|
|
bDeg = bDegI || (aJD1 == j || aJD2 == j);
|
|
if (bDeg)
|
|
aIP.SetDegenerated(bDeg);
|
|
|
|
++iCnt;
|
|
aBox.Add(aP);
|
|
}
|
|
}
|
|
|
|
TPoints.SetNbItems(iCnt);
|
|
|
|
// Update box
|
|
Standard_Real Tol = theDeflTol*1.2;
|
|
Standard_Real a1,a2,a3,b1,b2,b3;
|
|
aBox.Get(a1,a2,a3,b1,b2,b3);
|
|
aBox.Update(a1-Tol,a2-Tol,a3-Tol,b1+Tol,b2+Tol,b3+Tol);
|
|
aBox.Enlarge(MyTolerance);
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : FillArrayOfPnt
|
|
//purpose : Compute points on one surface and fill an array of points
|
|
//=======================================================================
|
|
void IntPolyh_MaillageAffinage::FillArrayOfPnt
|
|
(const Standard_Integer SurfID,
|
|
const Standard_Boolean isShiftFwd,
|
|
const TColStd_Array1OfReal& Upars,
|
|
const TColStd_Array1OfReal& Vpars,
|
|
const Standard_Real *theDeflTol)
|
|
{
|
|
Handle(Adaptor3d_HSurface) aS = (SurfID == 1) ? MaSurface1 : MaSurface2;
|
|
// Compute the tolerance
|
|
Standard_Real aTol = theDeflTol != NULL ? * theDeflTol :
|
|
IntPolyh_Tools::ComputeDeflection(aS, Upars, Vpars);
|
|
// Fill array of point normal
|
|
IntPolyh_ArrayOfPointNormal aPoints;
|
|
IntPolyh_Tools::FillArrayOfPointNormal(aS, Upars, Vpars, aPoints);
|
|
|
|
// Fill array of points
|
|
FillArrayOfPnt(1, isShiftFwd, aPoints, Upars, Vpars, aTol);
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : CommonBox
|
|
//purpose :
|
|
//=======================================================================
|
|
void IntPolyh_MaillageAffinage::CommonBox()
|
|
{
|
|
Standard_Real XMin, YMin, ZMin, XMax, YMax, ZMax;
|
|
CommonBox(GetBox(1), GetBox(2), XMin, YMin, ZMin, XMax, YMax, ZMax);
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : CommonBox
|
|
//purpose : Compute the common box witch is the intersection
|
|
// of the two bounding boxes, and mark the points of
|
|
// the two surfaces that are inside.
|
|
// REJECTION BOUNDING BOXES
|
|
// DETERMINATION OF THE COMMON BOX
|
|
//=======================================================================
|
|
void IntPolyh_MaillageAffinage::CommonBox (const Bnd_Box &,
|
|
const Bnd_Box &,
|
|
Standard_Real &XMin,
|
|
Standard_Real &YMin,
|
|
Standard_Real &ZMin,
|
|
Standard_Real &XMax,
|
|
Standard_Real &YMax,
|
|
Standard_Real &ZMax)
|
|
{
|
|
Standard_Real x10,y10,z10,x11,y11,z11;
|
|
Standard_Real x20,y20,z20,x21,y21,z21;
|
|
|
|
MyBox1.Get(x10,y10,z10,x11,y11,z11);
|
|
MyBox2.Get(x20,y20,z20,x21,y21,z21);
|
|
XMin = 0.;
|
|
YMin = 0.;
|
|
ZMin = 0.;
|
|
XMax = 0.;
|
|
YMax = 0.;
|
|
ZMax = 0.;
|
|
|
|
if((x10>x21)||(x20>x11)||(y10>y21)||(y20>y11)||(z10>z21)||(z20>z11)) {
|
|
}
|
|
else {
|
|
if(x11<=x21) XMax=x11; else { if(x21<=x11) XMax=x21;}
|
|
if(x20<=x10) XMin=x10; else { if(x10<=x20) XMin=x20;}
|
|
if(y11<=y21) YMax=y11; else { if(y21<=y11) YMax=y21;}
|
|
if(y20<=y10) YMin=y10; else { if(y10<=y20) YMin=y20;}
|
|
if(z11<=z21) ZMax=z11; else { if(z21<=z11) ZMax=z21;}
|
|
if(z20<=z10) ZMin=z10; else { if(z10<=z20) ZMin=z20;}
|
|
|
|
if(((XMin==XMax)&&(!(YMin==YMax)&&!(ZMin==ZMax)))
|
|
||((YMin==YMax)&&(!(XMin==XMax)&&!(ZMin==ZMax)))//ou exclusif ??
|
|
||((ZMin==ZMax)&&(!(XMin==XMax)&&!(YMin==YMax)))) {
|
|
}
|
|
}
|
|
//
|
|
Standard_Real X,Y,Z;
|
|
X=XMax-XMin;
|
|
Y=YMax-YMin;
|
|
Z=ZMax-ZMin;
|
|
//extension of the box
|
|
if( (X==0)&&(Y!=0) ) X=Y*0.1;
|
|
else if( (X==0)&&(Z!=0) ) X=Z*0.1;
|
|
else X*=0.1;
|
|
|
|
if( (Y==0)&&(X!=0) ) Y=X*0.1;
|
|
else if( (Y==0)&&(Z!=0) ) Y=Z*0.1;
|
|
else Y*=0.1;
|
|
|
|
if( (Z==0)&&(X!=0) ) Z=X*0.1;
|
|
else if( (Z==0)&&(Y!=0) ) Z=Y*0.1;
|
|
else Z*=0.1;
|
|
|
|
|
|
if( (X==0)&&(Y==0)&&(Z==0) ) {
|
|
|
|
|
|
}
|
|
XMin-=X; XMax+=X;
|
|
YMin-=Y; YMax+=Y;
|
|
ZMin-=Z; ZMax+=Z;
|
|
|
|
//Marking of points included in the common
|
|
const Standard_Integer FinTP1 = TPoints1.NbItems();
|
|
// for(Standard_Integer i=0; i<FinTP1; i++) {
|
|
Standard_Integer i ;
|
|
for( i=0; i<FinTP1; i++) {
|
|
IntPolyh_Point & Pt1 = TPoints1[i];
|
|
Standard_Integer r;
|
|
if(Pt1.X()<XMin) {
|
|
r=1;
|
|
}
|
|
else {
|
|
if(Pt1.X()>XMax) {
|
|
r=2;
|
|
} else {
|
|
r=0;
|
|
}
|
|
}
|
|
if(Pt1.Y()<YMin) {
|
|
r|=4;
|
|
}
|
|
else {
|
|
if(Pt1.Y()>YMax) {
|
|
r|=8;
|
|
}
|
|
}
|
|
if(Pt1.Z()<ZMin) {
|
|
r|=16;
|
|
} else {
|
|
if(Pt1.Z()>ZMax) {
|
|
r|=32;
|
|
}
|
|
}
|
|
Pt1.SetPartOfCommon(r);
|
|
}
|
|
|
|
const Standard_Integer FinTP2 = TPoints2.NbItems();
|
|
for(Standard_Integer ii=0; ii<FinTP2; ii++) {
|
|
IntPolyh_Point & Pt2 = TPoints2[ii];
|
|
Standard_Integer rr;
|
|
if(Pt2.X()<XMin) {
|
|
rr=1;
|
|
}
|
|
else {
|
|
if(Pt2.X()>XMax) {
|
|
rr=2;
|
|
} else {
|
|
rr=0;
|
|
}
|
|
}
|
|
if(Pt2.Y()<YMin) {
|
|
rr|=4;
|
|
}
|
|
else {
|
|
if(Pt2.Y()>YMax) {
|
|
rr|=8;
|
|
}
|
|
}
|
|
if(Pt2.Z()<ZMin) {
|
|
rr|=16;
|
|
}
|
|
else {
|
|
if(Pt2.Z()>ZMax) {
|
|
rr|=32;
|
|
}
|
|
}
|
|
Pt2.SetPartOfCommon(rr);
|
|
}
|
|
}
|
|
//=======================================================================
|
|
//function : FillArrayOfEdges
|
|
//purpose : Compute edges from the array of points
|
|
// FILL THE ARRAY OF EDGES
|
|
//=======================================================================
|
|
void IntPolyh_MaillageAffinage::FillArrayOfEdges
|
|
(const Standard_Integer SurfID)
|
|
{
|
|
|
|
IntPolyh_ArrayOfEdges &TEdges=(SurfID==1)? TEdges1:TEdges2;
|
|
IntPolyh_ArrayOfTriangles &TTriangles=(SurfID==1)? TTriangles1:TTriangles2;
|
|
Standard_Integer NbSamplesU=(SurfID==1)? NbSamplesU1:NbSamplesU2;
|
|
Standard_Integer NbSamplesV=(SurfID==1)? NbSamplesV1:NbSamplesV2;
|
|
|
|
//NbEdges = 3 + 3*(NbSamplesV-2) + 3*(NbSamplesU-2) +
|
|
// + 3*(NbSamplesU-2)*(NbSamplesV-2) + (NbSamplesV-1) + (NbSamplesU-1);
|
|
//NbSamplesU and NbSamples cannot be less than 2, so
|
|
Standard_Integer NbEdges = 3*NbSamplesU*NbSamplesV - 2*(NbSamplesU+NbSamplesV) + 1;
|
|
TEdges.Init(NbEdges);
|
|
|
|
Standard_Integer CpteurTabEdges=0;
|
|
|
|
//maillage u0 v0
|
|
TEdges[CpteurTabEdges].SetFirstPoint(0); // U V
|
|
TEdges[CpteurTabEdges].SetSecondPoint(1); // U V+1
|
|
TEdges[CpteurTabEdges].SetSecondTriangle(0);
|
|
TTriangles[0].SetEdgeAndOrientation(TEdges[CpteurTabEdges], CpteurTabEdges);
|
|
CpteurTabEdges++;
|
|
|
|
TEdges[CpteurTabEdges].SetFirstPoint(0); // U V
|
|
TEdges[CpteurTabEdges].SetSecondPoint(NbSamplesV); // U+1 V
|
|
TEdges[CpteurTabEdges].SetFirstTriangle(1);
|
|
TTriangles[1].SetEdgeAndOrientation(TEdges[CpteurTabEdges], CpteurTabEdges);
|
|
CpteurTabEdges++;
|
|
|
|
TEdges[CpteurTabEdges].SetFirstPoint(0); // U V
|
|
TEdges[CpteurTabEdges].SetSecondPoint(NbSamplesV+1); // U+1 V+1
|
|
TEdges[CpteurTabEdges].SetFirstTriangle(0);
|
|
TTriangles[0].SetEdgeAndOrientation(TEdges[CpteurTabEdges], CpteurTabEdges);
|
|
TEdges[CpteurTabEdges].SetSecondTriangle(1);
|
|
TTriangles[1].SetEdgeAndOrientation(TEdges[CpteurTabEdges], CpteurTabEdges);
|
|
CpteurTabEdges++;
|
|
|
|
//maillage surU=u0
|
|
Standard_Integer PntInit=1;
|
|
Standard_Integer BoucleMeshV;
|
|
for(BoucleMeshV=1; BoucleMeshV<NbSamplesV-1;BoucleMeshV++){
|
|
TEdges[CpteurTabEdges].SetFirstPoint(PntInit); // U V
|
|
TEdges[CpteurTabEdges].SetSecondPoint(PntInit+1); // U V+1
|
|
// TEdges[CpteurTabEdges].SetFirstTriangle(-1);
|
|
TEdges[CpteurTabEdges].SetSecondTriangle(BoucleMeshV*2);
|
|
TTriangles[BoucleMeshV*2].SetEdgeAndOrientation(TEdges[CpteurTabEdges], CpteurTabEdges);
|
|
CpteurTabEdges++;
|
|
|
|
TEdges[CpteurTabEdges].SetFirstPoint(PntInit); // U V
|
|
TEdges[CpteurTabEdges].SetSecondPoint(PntInit+NbSamplesV+1); // U+1 V+1
|
|
TEdges[CpteurTabEdges].SetFirstTriangle(BoucleMeshV*2);
|
|
TTriangles[BoucleMeshV*2].SetEdgeAndOrientation(TEdges[CpteurTabEdges], CpteurTabEdges);
|
|
TEdges[CpteurTabEdges].SetSecondTriangle(BoucleMeshV*2+1);
|
|
TTriangles[BoucleMeshV*2+1].SetEdgeAndOrientation(TEdges[CpteurTabEdges], CpteurTabEdges);
|
|
CpteurTabEdges++;
|
|
|
|
TEdges[CpteurTabEdges].SetFirstPoint(PntInit); // U V
|
|
TEdges[CpteurTabEdges].SetSecondPoint(PntInit+NbSamplesV); // U+1 V
|
|
TEdges[CpteurTabEdges].SetFirstTriangle(BoucleMeshV*2+1);
|
|
TTriangles[BoucleMeshV*2+1].SetEdgeAndOrientation(TEdges[CpteurTabEdges], CpteurTabEdges);
|
|
TEdges[CpteurTabEdges].SetSecondTriangle(BoucleMeshV*2-2);
|
|
TTriangles[BoucleMeshV*2-2].SetEdgeAndOrientation(TEdges[CpteurTabEdges], CpteurTabEdges);
|
|
CpteurTabEdges++;
|
|
PntInit++;
|
|
}
|
|
|
|
//maillage sur V=v0
|
|
PntInit=NbSamplesV;
|
|
for(BoucleMeshV=1; BoucleMeshV<NbSamplesU-1;BoucleMeshV++){
|
|
TEdges[CpteurTabEdges].SetFirstPoint(PntInit); // U V
|
|
TEdges[CpteurTabEdges].SetSecondPoint(PntInit+1); // U V+1
|
|
TEdges[CpteurTabEdges].SetFirstTriangle((BoucleMeshV-1)*(NbSamplesV-1)*2+1);
|
|
TTriangles[(BoucleMeshV-1)*(NbSamplesV-1)*2+1].SetEdgeAndOrientation(TEdges[CpteurTabEdges], CpteurTabEdges);
|
|
TEdges[CpteurTabEdges].SetSecondTriangle(BoucleMeshV*(NbSamplesV-1)*2);
|
|
TTriangles[BoucleMeshV*(NbSamplesV-1)*2].SetEdgeAndOrientation(TEdges[CpteurTabEdges], CpteurTabEdges);
|
|
CpteurTabEdges++;
|
|
|
|
TEdges[CpteurTabEdges].SetFirstPoint(PntInit); // U V
|
|
TEdges[CpteurTabEdges].SetSecondPoint(PntInit+NbSamplesV+1); // U+1 V+1
|
|
TEdges[CpteurTabEdges].SetFirstTriangle(BoucleMeshV*(NbSamplesV-1)*2);
|
|
TTriangles[BoucleMeshV*(NbSamplesV-1)*2].SetEdgeAndOrientation(TEdges[CpteurTabEdges], CpteurTabEdges);
|
|
TEdges[CpteurTabEdges].SetSecondTriangle(BoucleMeshV*(NbSamplesV-1)*2+1);
|
|
TTriangles[BoucleMeshV*(NbSamplesV-1)*2+1].SetEdgeAndOrientation(TEdges[CpteurTabEdges], CpteurTabEdges);
|
|
CpteurTabEdges++;
|
|
|
|
TEdges[CpteurTabEdges].SetFirstPoint(PntInit); // U V
|
|
TEdges[CpteurTabEdges].SetSecondPoint(PntInit+NbSamplesV); // U+1 V
|
|
TEdges[CpteurTabEdges].SetFirstTriangle(BoucleMeshV*(NbSamplesV-1)*2+1);
|
|
TTriangles[BoucleMeshV*(NbSamplesV-1)*2+1].SetEdgeAndOrientation(TEdges[CpteurTabEdges], CpteurTabEdges);
|
|
CpteurTabEdges++;
|
|
PntInit+=NbSamplesV;
|
|
}
|
|
|
|
PntInit=NbSamplesV+1;
|
|
//To provide recursion I associate a point with three edges
|
|
for(Standard_Integer BoucleMeshU=1; BoucleMeshU<NbSamplesU-1; BoucleMeshU++){
|
|
for(BoucleMeshV=1; BoucleMeshV<NbSamplesV-1;BoucleMeshV++){
|
|
TEdges[CpteurTabEdges].SetFirstPoint(PntInit); // U V
|
|
TEdges[CpteurTabEdges].SetSecondPoint(PntInit+1); // U V+1
|
|
TEdges[CpteurTabEdges].SetFirstTriangle((NbSamplesV-1)*2*(BoucleMeshU-1)+BoucleMeshV*2+1);
|
|
TTriangles[(NbSamplesV-1)*2*(BoucleMeshU-1)+BoucleMeshV*2+1].SetEdgeAndOrientation(TEdges[CpteurTabEdges], CpteurTabEdges);
|
|
TEdges[CpteurTabEdges].SetSecondTriangle((NbSamplesV-1)*2*BoucleMeshU+BoucleMeshV*2);
|
|
TTriangles[(NbSamplesV-1)*2*BoucleMeshU+BoucleMeshV*2].SetEdgeAndOrientation(TEdges[CpteurTabEdges], CpteurTabEdges);
|
|
CpteurTabEdges++;
|
|
|
|
TEdges[CpteurTabEdges].SetFirstPoint(PntInit); // U V
|
|
TEdges[CpteurTabEdges].SetSecondPoint(PntInit+NbSamplesV+1); // U+1 V+1
|
|
TEdges[CpteurTabEdges].SetFirstTriangle((NbSamplesV-1)*2*BoucleMeshU+BoucleMeshV*2);
|
|
TTriangles[(NbSamplesV-1)*2*BoucleMeshU+BoucleMeshV*2].SetEdgeAndOrientation(TEdges[CpteurTabEdges], CpteurTabEdges);
|
|
TEdges[CpteurTabEdges].SetSecondTriangle((NbSamplesV-1)*2*BoucleMeshU+BoucleMeshV*2+1);
|
|
TTriangles[(NbSamplesV-1)*2*BoucleMeshU+BoucleMeshV*2+1].SetEdgeAndOrientation(TEdges[CpteurTabEdges], CpteurTabEdges);
|
|
CpteurTabEdges++;
|
|
|
|
TEdges[CpteurTabEdges].SetFirstPoint(PntInit); // U V
|
|
TEdges[CpteurTabEdges].SetSecondPoint(PntInit+NbSamplesV); // U+1 V
|
|
TEdges[CpteurTabEdges].SetFirstTriangle((NbSamplesV-1)*2*BoucleMeshU+BoucleMeshV*2+1);
|
|
TTriangles[(NbSamplesV-1)*2*BoucleMeshU+BoucleMeshV*2+1].SetEdgeAndOrientation(TEdges[CpteurTabEdges], CpteurTabEdges);
|
|
TEdges[CpteurTabEdges].SetSecondTriangle((NbSamplesV-1)*2*BoucleMeshU+BoucleMeshV*2-2);
|
|
TTriangles[(NbSamplesV-1)*2*BoucleMeshU+BoucleMeshV*2-2].SetEdgeAndOrientation(TEdges[CpteurTabEdges], CpteurTabEdges);
|
|
CpteurTabEdges++;
|
|
PntInit++;//Pass to the next point
|
|
}
|
|
PntInit++;//Pass the last point of the column
|
|
PntInit++;//Pass the first point of the next column
|
|
}
|
|
|
|
//close mesh on U=u1
|
|
PntInit=(NbSamplesU-1)*NbSamplesV; //point U=u1 V=0
|
|
for(BoucleMeshV=0; BoucleMeshV<NbSamplesV-1; BoucleMeshV++){
|
|
TEdges[CpteurTabEdges].SetFirstPoint(PntInit); //U=u1 V
|
|
TEdges[CpteurTabEdges].SetSecondPoint(PntInit+1); //U=u1 V+1
|
|
TEdges[CpteurTabEdges].SetFirstTriangle((NbSamplesU-2)*(NbSamplesV-1)*2+BoucleMeshV*2+1);
|
|
TTriangles[(NbSamplesU-2)*(NbSamplesV-1)*2+BoucleMeshV*2+1].SetEdgeAndOrientation(TEdges[CpteurTabEdges], CpteurTabEdges);
|
|
CpteurTabEdges++;
|
|
PntInit++;
|
|
}
|
|
|
|
//close mesh on V=v1
|
|
for(BoucleMeshV=0; BoucleMeshV<NbSamplesU-1;BoucleMeshV++){
|
|
TEdges[CpteurTabEdges].SetFirstPoint(NbSamplesV-1+BoucleMeshV*NbSamplesV); // U V=v1
|
|
TEdges[CpteurTabEdges].SetSecondPoint(NbSamplesV-1+(BoucleMeshV+1)*NbSamplesV); //U+1 V=v1
|
|
TEdges[CpteurTabEdges].SetSecondTriangle(BoucleMeshV*2*(NbSamplesV-1)+(NbSamplesV-2)*2);
|
|
TTriangles[BoucleMeshV*2*(NbSamplesV-1)+(NbSamplesV-2)*2].SetEdgeAndOrientation(TEdges[CpteurTabEdges], CpteurTabEdges);
|
|
CpteurTabEdges++;
|
|
}
|
|
TEdges.SetNbItems(CpteurTabEdges);
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : FillArrayOfTriangles
|
|
//purpose : Compute triangles from the array of points, and --
|
|
// mark the triangles that use marked points by the
|
|
// CommonBox function.
|
|
// FILL THE ARRAY OF TRIANGLES
|
|
//=======================================================================
|
|
void IntPolyh_MaillageAffinage::FillArrayOfTriangles
|
|
(const Standard_Integer SurfID)
|
|
{
|
|
Standard_Integer CpteurTabTriangles=0;
|
|
Standard_Integer PntInit=0;
|
|
|
|
IntPolyh_ArrayOfPoints &TPoints=(SurfID==1)? TPoints1:TPoints2;
|
|
IntPolyh_ArrayOfTriangles &TTriangles=(SurfID==1)? TTriangles1:TTriangles2;
|
|
Standard_Integer NbSamplesU=(SurfID==1)? NbSamplesU1:NbSamplesU2;
|
|
Standard_Integer NbSamplesV=(SurfID==1)? NbSamplesV1:NbSamplesV2;
|
|
|
|
TTriangles.Init(2*(NbSamplesU-1)*(NbSamplesV-1));
|
|
//To provide recursion, I associate a point with two triangles
|
|
for(Standard_Integer BoucleMeshU=0; BoucleMeshU<NbSamplesU-1; BoucleMeshU++){
|
|
for(Standard_Integer BoucleMeshV=0; BoucleMeshV<NbSamplesV-1;BoucleMeshV++){
|
|
|
|
// FIRST TRIANGLE
|
|
TTriangles[CpteurTabTriangles].SetFirstPoint(PntInit); // U V
|
|
TTriangles[CpteurTabTriangles].SetSecondPoint(PntInit+1); // U V+1
|
|
TTriangles[CpteurTabTriangles].SetThirdPoint(PntInit+NbSamplesV+1); // U+1 V+1
|
|
|
|
// IF ITS EDGE CONTACTS WITH THE COMMON BOX IP REMAINS = A 1
|
|
if( ( (TPoints[PntInit].PartOfCommon()) & (TPoints[PntInit+1].PartOfCommon()) )
|
|
&&( (TPoints[PntInit+1].PartOfCommon()) & (TPoints[PntInit+NbSamplesV+1].PartOfCommon()))
|
|
&&( (TPoints[PntInit+NbSamplesV+1].PartOfCommon()) & (TPoints[PntInit].PartOfCommon())) )
|
|
//IF NOT IP=0
|
|
TTriangles[CpteurTabTriangles].SetIntersectionPossible(Standard_False);
|
|
|
|
CpteurTabTriangles++;
|
|
|
|
//SECOND TRIANGLE
|
|
TTriangles[CpteurTabTriangles].SetFirstPoint(PntInit); // U V
|
|
TTriangles[CpteurTabTriangles].SetSecondPoint(PntInit+NbSamplesV+1); // U+1 V+1
|
|
TTriangles[CpteurTabTriangles].SetThirdPoint(PntInit+NbSamplesV); // U+1 V
|
|
|
|
|
|
if( ( (TPoints[PntInit].PartOfCommon()) & (TPoints[PntInit+NbSamplesV+1].PartOfCommon()) )
|
|
&&( (TPoints[PntInit+NbSamplesV+1].PartOfCommon()) & (TPoints[PntInit+NbSamplesV].PartOfCommon()))
|
|
&&( (TPoints[PntInit+NbSamplesV].PartOfCommon()) & (TPoints[PntInit].PartOfCommon())) )
|
|
TTriangles[CpteurTabTriangles].SetIntersectionPossible(Standard_False);
|
|
|
|
|
|
CpteurTabTriangles++;
|
|
|
|
PntInit++;//Pass to the next point
|
|
}
|
|
PntInit++;//Pass the last point of the column
|
|
}
|
|
TTriangles.SetNbItems(CpteurTabTriangles);
|
|
const Standard_Integer FinTT = TTriangles.NbItems();
|
|
if (FinTT==0) {
|
|
}
|
|
}
|
|
//=======================================================================
|
|
//function : CommonPartRefinement
|
|
//purpose : Refine systematicaly all marked triangles of both surfaces
|
|
// REFINING OF THE COMMON
|
|
//=======================================================================
|
|
void IntPolyh_MaillageAffinage::CommonPartRefinement()
|
|
{
|
|
Standard_Integer FinInit1 = TTriangles1.NbItems();
|
|
for(Standard_Integer i=0; i<FinInit1; i++) {
|
|
if(TTriangles1[i].IsIntersectionPossible())
|
|
TTriangles1[i].MiddleRefinement(i,MaSurface1,TPoints1,TTriangles1,TEdges1);
|
|
}
|
|
|
|
Standard_Integer FinInit2=TTriangles2.NbItems();
|
|
for(Standard_Integer ii=0; ii<FinInit2; ii++) {
|
|
if(TTriangles2[ii].IsIntersectionPossible())
|
|
TTriangles2[ii].MiddleRefinement(ii,MaSurface2,TPoints2,TTriangles2,TEdges2);
|
|
}
|
|
|
|
}
|
|
//=======================================================================
|
|
//function : LocalSurfaceRefinement
|
|
//purpose : Refine systematicaly all marked triangles of ONE surface
|
|
//=======================================================================
|
|
void IntPolyh_MaillageAffinage::LocalSurfaceRefinement(const Standard_Integer SurfID) {
|
|
//refine locally, but systematically the chosen surface
|
|
if (SurfID==1) {
|
|
const Standard_Integer FinInit1 = TTriangles1.NbItems();
|
|
for(Standard_Integer i=0; i<FinInit1; i++) {
|
|
if(TTriangles1[i].IsIntersectionPossible())
|
|
TTriangles1[i].MiddleRefinement(i,MaSurface1,TPoints1,TTriangles1,TEdges1);
|
|
}
|
|
}
|
|
//
|
|
if (SurfID==2) {
|
|
const Standard_Integer FinInit2 = TTriangles2.NbItems();
|
|
for(Standard_Integer ii=0; ii<FinInit2; ii++) {
|
|
if(TTriangles2[ii].IsIntersectionPossible())
|
|
TTriangles2[ii].MiddleRefinement(ii,MaSurface2,TPoints2,TTriangles2,TEdges2);
|
|
}
|
|
}
|
|
}
|
|
//=======================================================================
|
|
//function : ComputeDeflections
|
|
//purpose : Compute deflection for all triangles of one
|
|
// surface,and sort min and max of deflections
|
|
// REFINING PART
|
|
// Calculation of the deflection of all triangles
|
|
// --> deflection max
|
|
// --> deflection min
|
|
//=======================================================================
|
|
void IntPolyh_MaillageAffinage::ComputeDeflections
|
|
(const Standard_Integer SurfID)
|
|
{
|
|
Handle(Adaptor3d_HSurface) aSurface=(SurfID==1)? MaSurface1:MaSurface2;
|
|
IntPolyh_ArrayOfPoints &TPoints=(SurfID==1)? TPoints1:TPoints2;
|
|
IntPolyh_ArrayOfTriangles &TTriangles=(SurfID==1)? TTriangles1:TTriangles2;
|
|
Standard_Real &FlecheMin=(SurfID==1)? FlecheMin1:FlecheMin2;
|
|
Standard_Real &FlecheMax=(SurfID==1)? FlecheMax1:FlecheMax2;
|
|
|
|
FlecheMax=-RealLast();
|
|
FlecheMin=RealLast();
|
|
const Standard_Integer FinTT = TTriangles.NbItems();
|
|
|
|
for(Standard_Integer i = 0; i < FinTT; i++) {
|
|
IntPolyh_Triangle& aTriangle = TTriangles[i];
|
|
Standard_Real Fleche = aTriangle.ComputeDeflection(aSurface, TPoints);
|
|
if (Fleche > FlecheMax)
|
|
FlecheMax = Fleche;
|
|
if (Fleche < FlecheMin)
|
|
FlecheMin = Fleche;
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : TrianglesDeflectionsRefinement
|
|
//purpose : Refinement of the triangles depending on the deflection
|
|
//=======================================================================
|
|
static
|
|
void TrianglesDeflectionsRefinement(const Handle(Adaptor3d_HSurface)& theS1,
|
|
IntPolyh_ArrayOfTriangles& theTriangles1,
|
|
IntPolyh_ArrayOfEdges& theEdges1,
|
|
IntPolyh_ArrayOfPoints& thePoints1,
|
|
const Standard_Real theFlecheCritique1,
|
|
const Handle(Adaptor3d_HSurface)& theS2,
|
|
IntPolyh_ArrayOfTriangles& theTriangles2,
|
|
IntPolyh_ArrayOfEdges& theEdges2,
|
|
IntPolyh_ArrayOfPoints& thePoints2,
|
|
const Standard_Real theFlecheCritique2)
|
|
{
|
|
// Find the intersecting triangles
|
|
IntPolyh_IndexedDataMapOfIntegerListOfInteger aDMILI;
|
|
GetInterferingTriangles(theTriangles1, thePoints1, theTriangles2, thePoints2, aDMILI);
|
|
//
|
|
// Interfering triangles of second surface
|
|
TColStd_MapOfInteger aMIntS2;
|
|
// Since the number of the triangles may change during refinement,
|
|
// save the number of triangles before refinement
|
|
Standard_Integer FinTT1 = theTriangles1.NbItems();
|
|
Standard_Integer FinTT2 = theTriangles2.NbItems();
|
|
//
|
|
// Analyze interfering triangles
|
|
for (Standard_Integer i_S1 = 0; i_S1 < FinTT1; i_S1++) {
|
|
IntPolyh_Triangle& aTriangle1 = theTriangles1[i_S1];
|
|
if (!aTriangle1.IsIntersectionPossible()) {
|
|
continue;
|
|
}
|
|
//
|
|
const TColStd_ListOfInteger *pLI = aDMILI.Seek(i_S1);
|
|
if (!pLI || pLI->IsEmpty()) {
|
|
// Mark non-interfering triangles of S1 to avoid their repeated usage
|
|
aTriangle1.SetIntersectionPossible(Standard_False);
|
|
continue;
|
|
}
|
|
//
|
|
if (aTriangle1.Deflection() > theFlecheCritique1) {
|
|
aTriangle1.MiddleRefinement(i_S1, theS1, thePoints1, theTriangles1, theEdges1);
|
|
}
|
|
//
|
|
TColStd_ListOfInteger::Iterator Iter(*pLI);
|
|
for (; Iter.More(); Iter.Next()) {
|
|
Standard_Integer i_S2 = Iter.Value();
|
|
if (aMIntS2.Add(i_S2)) {
|
|
IntPolyh_Triangle & aTriangle2 = theTriangles2[i_S2];
|
|
if (aTriangle2.Deflection() > theFlecheCritique2) {
|
|
// Refinement of the larger triangles
|
|
aTriangle2.MiddleRefinement(i_S2, theS2, thePoints2, theTriangles2, theEdges2);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//
|
|
// Mark non-interfering triangles of S2 to avoid their repeated usage
|
|
if (aMIntS2.Extent() < FinTT2) {
|
|
for (Standard_Integer i_S2 = 0; i_S2 < FinTT2; i_S2++) {
|
|
if (!aMIntS2.Contains(i_S2)) {
|
|
theTriangles2[i_S2].SetIntersectionPossible(Standard_False);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//=======================================================================
|
|
//function : LargeTrianglesDeflectionsRefinement
|
|
//purpose : Refinement of the large triangles in case one surface is
|
|
// much smaller then the other.
|
|
//=======================================================================
|
|
static
|
|
void LargeTrianglesDeflectionsRefinement(const Handle(Adaptor3d_HSurface)& theS,
|
|
IntPolyh_ArrayOfTriangles& theTriangles,
|
|
IntPolyh_ArrayOfEdges& theEdges,
|
|
IntPolyh_ArrayOfPoints& thePoints,
|
|
const Bnd_Box& theOppositeBox)
|
|
{
|
|
// Find all triangles of the bigger surface with bounding boxes
|
|
// overlapping the bounding box the other surface
|
|
TColStd_ListOfInteger aLIT;
|
|
Standard_Integer i, aNbT = theTriangles.NbItems();
|
|
for (i = 0; i < aNbT; ++i) {
|
|
IntPolyh_Triangle& aTriangle = theTriangles[i];
|
|
if (!aTriangle.IsIntersectionPossible() || aTriangle.IsDegenerated()) {
|
|
continue;
|
|
}
|
|
//
|
|
const Bnd_Box& aBox = aTriangle.BoundingBox(thePoints);
|
|
if (aBox.IsVoid()) {
|
|
continue;
|
|
}
|
|
//
|
|
if (aBox.IsOut(theOppositeBox)) {
|
|
aTriangle.SetIntersectionPossible(Standard_False);
|
|
continue;
|
|
}
|
|
//
|
|
aLIT.Append(i);
|
|
}
|
|
//
|
|
if (aLIT.IsEmpty()) {
|
|
return;
|
|
}
|
|
//
|
|
// One surface is very small relatively to the other.
|
|
// The criterion of refining for large surface depends on the size of
|
|
// the bounding box of the other - since the criterion should be minimized,
|
|
// the smallest side of the bounding box is taken
|
|
Standard_Real x0, y0, z0, x1, y1, z1;
|
|
theOppositeBox.Get(x0, y0, z0, x1, y1, z1);
|
|
Standard_Real dx = Abs(x1 - x0);
|
|
Standard_Real dy = Abs(y1 - y0);
|
|
Standard_Real diag = Abs(z1 - z0);
|
|
Standard_Real dd = (dx > dy) ? dy : dx;
|
|
if (diag > dd) diag = dd;
|
|
|
|
// calculation of the criterion of refining
|
|
Standard_Real CritereAffinage = 0.0;
|
|
Standard_Real DiagPonderation = 0.5;
|
|
CritereAffinage = diag*DiagPonderation;
|
|
//
|
|
// The deflection of the greater is compared to the size of the smaller
|
|
TColStd_ListIteratorOfListOfInteger Iter(aLIT);
|
|
for (; Iter.More(); Iter.Next()) {
|
|
i = Iter.Value();
|
|
IntPolyh_Triangle & aTriangle = theTriangles[i];
|
|
if (aTriangle.Deflection() > CritereAffinage) {
|
|
aTriangle.MultipleMiddleRefinement(CritereAffinage, theOppositeBox, i,
|
|
theS, thePoints, theTriangles, theEdges);
|
|
}
|
|
else {
|
|
aTriangle.MiddleRefinement(i, theS, thePoints, theTriangles, theEdges);
|
|
}
|
|
}
|
|
}
|
|
//=======================================================================
|
|
//function : TrianglesDeflectionsRefinementBSB
|
|
//purpose : Refine both surfaces using UBTree as rejection.
|
|
// The criterion used to refine a triangle are:
|
|
// - The deflection;
|
|
// - The size of the - bounding boxes (one surface may be
|
|
// very small compared to the other).
|
|
//=======================================================================
|
|
void IntPolyh_MaillageAffinage::TrianglesDeflectionsRefinementBSB()
|
|
{
|
|
// To estimate a surface in general it can be interesting
|
|
// to calculate all deflections
|
|
ComputeDeflections(1);
|
|
// Check deflection at output
|
|
Standard_Real FlecheCritique1;
|
|
if (FlecheMin1 > FlecheMax1) {
|
|
return;
|
|
}
|
|
else {
|
|
// fleche min + (flechemax-flechemin) * 80/100
|
|
FlecheCritique1 = FlecheMin1*0.2 + FlecheMax1*0.8;
|
|
}
|
|
|
|
// Compute deflections for the second surface
|
|
ComputeDeflections(2);
|
|
|
|
//-- Check arrows at output
|
|
Standard_Real FlecheCritique2;
|
|
if (FlecheMin2 > FlecheMax2) {
|
|
return;
|
|
}
|
|
else {
|
|
//fleche min + (flechemax-flechemin) * 80/100
|
|
FlecheCritique2 = FlecheMin2*0.2 + FlecheMax2*0.8;
|
|
}
|
|
|
|
// The greatest of two bounding boxes created in FillArrayOfPoints is found.
|
|
// Then this value is weighted depending on the discretization
|
|
// (NbSamplesU and NbSamplesV)
|
|
Standard_Real diag1, diag2;
|
|
Standard_Real x0, y0, z0, x1, y1, z1;
|
|
|
|
MyBox1.Get(x0, y0, z0, x1, y1, z1);
|
|
x0 -= x1; y0 -= y1; z0 -= z1;
|
|
diag1 = x0*x0 + y0*y0 + z0*z0;
|
|
const Standard_Real NbSamplesUV1 = Standard_Real(NbSamplesU1) * Standard_Real(NbSamplesV1);
|
|
diag1 /= NbSamplesUV1;
|
|
|
|
MyBox2.Get(x0, y0, z0, x1, y1, z1);
|
|
x0 -= x1; y0 -= y1; z0 -= z1;
|
|
diag2 = x0*x0 + y0*y0 + z0*z0;
|
|
const Standard_Real NbSamplesUV2 = Standard_Real(NbSamplesU2) * Standard_Real(NbSamplesV2);
|
|
diag2 /= NbSamplesUV2;
|
|
|
|
// The surface with the greatest bounding box is "discretized"
|
|
if (diag1 < diag2) {
|
|
// second is discretized
|
|
if (FlecheCritique2 < diag1) {
|
|
// The corresponding sizes are not too disproportional
|
|
TrianglesDeflectionsRefinement(MaSurface1, TTriangles1, TEdges1, TPoints1, FlecheCritique1,
|
|
MaSurface2, TTriangles2, TEdges2, TPoints2, FlecheCritique2);
|
|
}
|
|
else {
|
|
// second surface is much larger then the first
|
|
LargeTrianglesDeflectionsRefinement(MaSurface2, TTriangles2, TEdges2, TPoints2, MyBox1);
|
|
}
|
|
}
|
|
else {
|
|
// first is discretized
|
|
if (FlecheCritique1 < diag2) {
|
|
// The corresponding sizes are not too disproportional
|
|
TrianglesDeflectionsRefinement(MaSurface2, TTriangles2, TEdges2, TPoints2, FlecheCritique2,
|
|
MaSurface1, TTriangles1, TEdges1, TPoints1, FlecheCritique1);
|
|
}
|
|
else {
|
|
// first surface is much larger then the second
|
|
LargeTrianglesDeflectionsRefinement(MaSurface1, TTriangles1, TEdges1, TPoints1, MyBox2);
|
|
}
|
|
}
|
|
}
|
|
//=======================================================================
|
|
//function : maxSR
|
|
//purpose : This function is used for the function project6
|
|
//=======================================================================
|
|
inline Standard_Real maxSR(const Standard_Real a,
|
|
const Standard_Real b,
|
|
const Standard_Real c)
|
|
{
|
|
Standard_Real t = a;
|
|
if (b > t) t = b;
|
|
if (c > t) t = c;
|
|
return t;
|
|
}
|
|
//=======================================================================
|
|
//function : minSR
|
|
//purpose : This function is used for the function project6
|
|
//=======================================================================
|
|
inline Standard_Real minSR(const Standard_Real a,
|
|
const Standard_Real b,
|
|
const Standard_Real c)
|
|
{
|
|
Standard_Real t = a;
|
|
if (b < t) t = b;
|
|
if (c < t) t = c;
|
|
return t;
|
|
}
|
|
//=======================================================================
|
|
//function : project6
|
|
//purpose : This function is used for the function TriContact
|
|
//=======================================================================
|
|
Standard_Integer project6(const IntPolyh_Point &ax,
|
|
const IntPolyh_Point &p1,
|
|
const IntPolyh_Point &p2,
|
|
const IntPolyh_Point &p3,
|
|
const IntPolyh_Point &q1,
|
|
const IntPolyh_Point &q2,
|
|
const IntPolyh_Point &q3)
|
|
{
|
|
Standard_Real P1 = ax.Dot(p1);
|
|
Standard_Real P2 = ax.Dot(p2);
|
|
Standard_Real P3 = ax.Dot(p3);
|
|
Standard_Real Q1 = ax.Dot(q1);
|
|
Standard_Real Q2 = ax.Dot(q2);
|
|
Standard_Real Q3 = ax.Dot(q3);
|
|
|
|
Standard_Real mx1 = maxSR(P1, P2, P3);
|
|
Standard_Real mn1 = minSR(P1, P2, P3);
|
|
Standard_Real mx2 = maxSR(Q1, Q2, Q3);
|
|
Standard_Real mn2 = minSR(Q1, Q2, Q3);
|
|
|
|
if (mn1 > mx2) return 0;
|
|
if (mn2 > mx1) return 0;
|
|
return 1;
|
|
}
|
|
//=======================================================================
|
|
//function : TriContact
|
|
//purpose : This fonction Check if two triangles are in
|
|
// contact or no, return 1 if yes, return 0
|
|
// if no.
|
|
//=======================================================================
|
|
Standard_Integer IntPolyh_MaillageAffinage::TriContact
|
|
(const IntPolyh_Point &P1,
|
|
const IntPolyh_Point &P2,
|
|
const IntPolyh_Point &P3,
|
|
const IntPolyh_Point &Q1,
|
|
const IntPolyh_Point &Q2,
|
|
const IntPolyh_Point &Q3,
|
|
Standard_Real &Angle) const
|
|
{
|
|
/**
|
|
The first triangle is (p1,p2,p3). The other is (q1,q2,q3).
|
|
The edges are (e1,e2,e3) and (f1,f2,f3).
|
|
The normals are n1 and m1
|
|
Outwards are (g1,g2,g3) and (h1,h2,h3).*/
|
|
|
|
if(maxSR(P1.X(),P2.X(),P3.X())<minSR(Q1.X(),Q2.X(),Q3.X())) return(0);
|
|
if(maxSR(P1.Y(),P2.Y(),P3.Y())<minSR(Q1.Y(),Q2.Y(),Q3.Y())) return(0);
|
|
if(maxSR(P1.Z(),P2.Z(),P3.Z())<minSR(Q1.Z(),Q2.Z(),Q3.Z())) return(0);
|
|
|
|
if(minSR(P1.X(),P2.X(),P3.X())>maxSR(Q1.X(),Q2.X(),Q3.X())) return(0);
|
|
if(minSR(P1.Y(),P2.Y(),P3.Y())>maxSR(Q1.Y(),Q2.Y(),Q3.Y())) return(0);
|
|
if(minSR(P1.Z(),P2.Z(),P3.Z())>maxSR(Q1.Z(),Q2.Z(),Q3.Z())) return(0);
|
|
|
|
IntPolyh_Point p1, p2, p3;
|
|
IntPolyh_Point q1, q2, q3;
|
|
IntPolyh_Point e1, e2, e3;
|
|
IntPolyh_Point f1, f2, f3;
|
|
IntPolyh_Point g1, g2, g3;
|
|
IntPolyh_Point h1, h2, h3;
|
|
IntPolyh_Point n1, m1;
|
|
IntPolyh_Point z;
|
|
|
|
IntPolyh_Point ef11, ef12, ef13;
|
|
IntPolyh_Point ef21, ef22, ef23;
|
|
IntPolyh_Point ef31, ef32, ef33;
|
|
|
|
z.SetX(0.0); z.SetY(0.0); z.SetZ(0.0);
|
|
|
|
|
|
p1.SetX(P1.X() - P1.X()); p1.SetY(P1.Y() - P1.Y()); p1.SetZ(P1.Z() - P1.Z());
|
|
p2.SetX(P2.X() - P1.X()); p2.SetY(P2.Y() - P1.Y()); p2.SetZ(P2.Z() - P1.Z());
|
|
p3.SetX(P3.X() - P1.X()); p3.SetY(P3.Y() - P1.Y()); p3.SetZ(P3.Z() - P1.Z());
|
|
|
|
q1.SetX(Q1.X() - P1.X()); q1.SetY(Q1.Y() - P1.Y()); q1.SetZ(Q1.Z() - P1.Z());
|
|
q2.SetX(Q2.X() - P1.X()); q2.SetY(Q2.Y() - P1.Y()); q2.SetZ(Q2.Z() - P1.Z());
|
|
q3.SetX(Q3.X() - P1.X()); q3.SetY(Q3.Y() - P1.Y()); q3.SetZ(Q3.Z() - P1.Z());
|
|
|
|
e1.SetX(p2.X() - p1.X()); e1.SetY(p2.Y() - p1.Y()); e1.SetZ(p2.Z() - p1.Z());
|
|
e2.SetX(p3.X() - p2.X()); e2.SetY(p3.Y() - p2.Y()); e2.SetZ(p3.Z() - p2.Z());
|
|
e3.SetX(p1.X() - p3.X()); e3.SetY(p1.Y() - p3.Y()); e3.SetZ(p1.Z() - p3.Z());
|
|
|
|
f1.SetX(q2.X() - q1.X()); f1.SetY(q2.Y() - q1.Y()); f1.SetZ(q2.Z() - q1.Z());
|
|
f2.SetX(q3.X() - q2.X()); f2.SetY(q3.Y() - q2.Y()); f2.SetZ(q3.Z() - q2.Z());
|
|
f3.SetX(q1.X() - q3.X()); f3.SetY(q1.Y() - q3.Y()); f3.SetZ(q1.Z() - q3.Z());
|
|
|
|
n1.Cross(e1, e2); //normal to the first triangle
|
|
m1.Cross(f1, f2); //normal to the second triangle
|
|
|
|
g1.Cross(e1, n1);
|
|
g2.Cross(e2, n1);
|
|
g3.Cross(e3, n1);
|
|
h1.Cross(f1, m1);
|
|
h2.Cross(f2, m1);
|
|
h3.Cross(f3, m1);
|
|
|
|
ef11.Cross(e1, f1);
|
|
ef12.Cross(e1, f2);
|
|
ef13.Cross(e1, f3);
|
|
ef21.Cross(e2, f1);
|
|
ef22.Cross(e2, f2);
|
|
ef23.Cross(e2, f3);
|
|
ef31.Cross(e3, f1);
|
|
ef32.Cross(e3, f2);
|
|
ef33.Cross(e3, f3);
|
|
|
|
// Now the testing is done
|
|
|
|
if (!project6(n1, p1, p2, p3, q1, q2, q3)) return 0; //T2 is not higher or lower than T1
|
|
if (!project6(m1, p1, p2, p3, q1, q2, q3)) return 0; //T1 is not higher of lower than T2
|
|
|
|
if (!project6(ef11, p1, p2, p3, q1, q2, q3)) return 0;
|
|
if (!project6(ef12, p1, p2, p3, q1, q2, q3)) return 0;
|
|
if (!project6(ef13, p1, p2, p3, q1, q2, q3)) return 0;
|
|
if (!project6(ef21, p1, p2, p3, q1, q2, q3)) return 0;
|
|
if (!project6(ef22, p1, p2, p3, q1, q2, q3)) return 0;
|
|
if (!project6(ef23, p1, p2, p3, q1, q2, q3)) return 0;
|
|
if (!project6(ef31, p1, p2, p3, q1, q2, q3)) return 0;
|
|
if (!project6(ef32, p1, p2, p3, q1, q2, q3)) return 0;
|
|
if (!project6(ef33, p1, p2, p3, q1, q2, q3)) return 0;
|
|
|
|
if (!project6(g1, p1, p2, p3, q1, q2, q3)) return 0; //T2 is outside of T1 in the plane of T1
|
|
if (!project6(g2, p1, p2, p3, q1, q2, q3)) return 0; //T2 is outside of T1 in the plane of T1
|
|
if (!project6(g3, p1, p2, p3, q1, q2, q3)) return 0; //T2 is outside of T1 in the plane of T1
|
|
if (!project6(h1, p1, p2, p3, q1, q2, q3)) return 0; //T1 is outside of T2 in the plane of T2
|
|
if (!project6(h2, p1, p2, p3, q1, q2, q3)) return 0; //T1 is outside of T2 in the plane of T2
|
|
if (!project6(h3, p1, p2, p3, q1, q2, q3)) return 0; //T1 is outside of T2 in the plane of T2
|
|
|
|
//Calculation of cosinus angle between two normals
|
|
Standard_Real SqModn1=-1.0;
|
|
Standard_Real SqModm1=-1.0;
|
|
SqModn1=n1.SquareModulus();
|
|
if (SqModn1>SquareMyConfusionPrecision){
|
|
SqModm1=m1.SquareModulus();
|
|
}
|
|
if (SqModm1>SquareMyConfusionPrecision) {
|
|
Angle=(n1.Dot(m1))/(sqrt(SqModn1)*sqrt(SqModm1));
|
|
}
|
|
return 1;
|
|
}
|
|
//=======================================================================
|
|
//function : TestNbPoints
|
|
//purpose : This function is used by StartingPointsResearch() to control
|
|
// the number of points found keep the result in conformity (1 or 2 points)
|
|
// void TestNbPoints(const Standard_Integer TriSurfID,
|
|
//=======================================================================
|
|
void TestNbPoints(const Standard_Integer ,
|
|
Standard_Integer &NbPoints,
|
|
Standard_Integer &NbPointsTotal,
|
|
const IntPolyh_StartPoint &Pt1,
|
|
const IntPolyh_StartPoint &Pt2,
|
|
IntPolyh_StartPoint &SP1,
|
|
IntPolyh_StartPoint &SP2)
|
|
{
|
|
// already checked in TriangleEdgeContact
|
|
// if( (NbPoints==2)&&(Pt1.CheckSameSP(Pt2)) ) NbPoints=1;
|
|
|
|
if(NbPoints>2) {
|
|
|
|
}
|
|
else {
|
|
if ( (NbPoints==1)&&(NbPointsTotal==0) ) {
|
|
SP1=Pt1;
|
|
NbPointsTotal=1;
|
|
}
|
|
else if ( (NbPoints==1)&&(NbPointsTotal==1) ) {
|
|
if(Pt1.CheckSameSP(SP1)!=1) {
|
|
SP2=Pt1;
|
|
NbPointsTotal=2;
|
|
}
|
|
}
|
|
else if( (NbPoints==1)&&(NbPointsTotal==2) ) {
|
|
if ( (SP1.CheckSameSP(Pt1))||(SP2.CheckSameSP(Pt1)) )
|
|
NbPointsTotal=2;
|
|
else NbPointsTotal=3;
|
|
}
|
|
else if( (NbPoints==2)&&(NbPointsTotal==0) ) {
|
|
SP1=Pt1;
|
|
SP2=Pt2;
|
|
NbPointsTotal=2;
|
|
}
|
|
else if( (NbPoints==2)&&(NbPointsTotal==1) ) {//there is also Pt1 != Pt2
|
|
if(SP1.CheckSameSP(Pt1)) {
|
|
SP2=Pt2;
|
|
NbPointsTotal=2;
|
|
}
|
|
else if (SP1.CheckSameSP(Pt2)) {
|
|
SP2=Pt1;
|
|
NbPointsTotal=2;
|
|
}
|
|
else NbPointsTotal=3;///case SP1!=Pt1 && SP1!=Pt2!
|
|
}
|
|
else if( (NbPoints==2)&&(NbPointsTotal==2) ) {//there is also SP1!=SP2
|
|
if( (SP1.CheckSameSP(Pt1))||(SP1.CheckSameSP(Pt2)) ) {
|
|
if( (SP2.CheckSameSP(Pt1))||(SP2.CheckSameSP(Pt2)) )
|
|
NbPointsTotal=2;
|
|
else NbPointsTotal=3;
|
|
}
|
|
else NbPointsTotal=3;
|
|
}
|
|
}
|
|
}
|
|
//=======================================================================
|
|
//function : StartingPointsResearch
|
|
//purpose : From two triangles compute intersection points.
|
|
// If I found more than two intersection points
|
|
// it means that those triangle are coplanar
|
|
//=======================================================================
|
|
Standard_Integer IntPolyh_MaillageAffinage::StartingPointsResearch
|
|
(const Standard_Integer T1,
|
|
const Standard_Integer T2,
|
|
IntPolyh_StartPoint &SP1,
|
|
IntPolyh_StartPoint &SP2) const
|
|
{
|
|
const IntPolyh_Triangle &Tri1=TTriangles1[T1];
|
|
const IntPolyh_Triangle &Tri2=TTriangles2[T2];
|
|
|
|
const IntPolyh_Point &P1=TPoints1[Tri1.FirstPoint()];
|
|
const IntPolyh_Point &P2=TPoints1[Tri1.SecondPoint()];
|
|
const IntPolyh_Point &P3=TPoints1[Tri1.ThirdPoint()];
|
|
const IntPolyh_Point &Q1=TPoints2[Tri2.FirstPoint()];
|
|
const IntPolyh_Point &Q2=TPoints2[Tri2.SecondPoint()];
|
|
const IntPolyh_Point &Q3=TPoints2[Tri2.ThirdPoint()];
|
|
|
|
|
|
|
|
/* The first triangle is (p1,p2,p3). The other is (q1,q2,q3).
|
|
The sides are (e1,e2,e3) and (f1,f2,f3).
|
|
The normals are n1 and m1*/
|
|
|
|
const IntPolyh_Point e1=P2-P1;
|
|
const IntPolyh_Point e2=P3-P2;
|
|
const IntPolyh_Point e3=P1-P3;
|
|
|
|
const IntPolyh_Point f1=Q2-Q1;
|
|
const IntPolyh_Point f2=Q3-Q2;
|
|
const IntPolyh_Point f3=Q1-Q3;
|
|
|
|
|
|
IntPolyh_Point nn1,mm1;
|
|
nn1.Cross(e1, e2); //normal to the first triangle
|
|
mm1.Cross(f1, f2); //normal to the second triangle
|
|
|
|
Standard_Real nn1modulus, mm1modulus;
|
|
nn1modulus=sqrt(nn1.SquareModulus());
|
|
mm1modulus=sqrt(mm1.SquareModulus());
|
|
|
|
//-------------------------------------------------
|
|
///calculation of intersections points between triangles
|
|
//-------------------------------------------------
|
|
Standard_Integer NbPoints=0;
|
|
Standard_Integer NbPointsTotal=0;
|
|
|
|
|
|
///check T1 normal
|
|
if(Abs(nn1modulus)<MyConfusionPrecision) {//10.0e-20){
|
|
|
|
}
|
|
else {
|
|
const IntPolyh_Point n1=nn1.Divide(nn1modulus);
|
|
///T2 edges with T1
|
|
if(NbPointsTotal<3) {
|
|
IntPolyh_StartPoint Pt1,Pt2;
|
|
NbPoints=TriangleEdgeContact(1,1,Tri1,Tri2,P1,P2,P3,e1,e2,e3,Q1,Q2,f1,n1,Pt1,Pt2);
|
|
TestNbPoints(1,NbPoints,NbPointsTotal,Pt1,Pt2,SP1,SP2);
|
|
}
|
|
|
|
if(NbPointsTotal<3) {
|
|
IntPolyh_StartPoint Pt1,Pt2;
|
|
NbPoints=TriangleEdgeContact(1,2,Tri1,Tri2,P1,P2,P3,e1,e2,e3,Q2,Q3,f2,n1,Pt1,Pt2);
|
|
TestNbPoints(1,NbPoints,NbPointsTotal,Pt1,Pt2,SP1,SP2);
|
|
}
|
|
|
|
if(NbPointsTotal<3) {
|
|
IntPolyh_StartPoint Pt1,Pt2;
|
|
NbPoints=TriangleEdgeContact(1,3,Tri1,Tri2,P1,P2,P3,e1,e2,e3,Q3,Q1,f3,n1,Pt1,Pt2);
|
|
TestNbPoints(1,NbPoints,NbPointsTotal,Pt1,Pt2,SP1,SP2);
|
|
}
|
|
}
|
|
|
|
///check T2 normal
|
|
if(Abs(mm1modulus)<MyConfusionPrecision) {//10.0e-20){
|
|
|
|
}
|
|
else {
|
|
const IntPolyh_Point m1=mm1.Divide(mm1modulus);
|
|
///T1 edges with T2
|
|
if(NbPointsTotal<3) {
|
|
IntPolyh_StartPoint Pt1,Pt2;
|
|
NbPoints=TriangleEdgeContact(2,1,Tri1,Tri2,Q1,Q2,Q3,f1,f2,f3,P1,P2,e1,m1,Pt1,Pt2);
|
|
TestNbPoints(2,NbPoints,NbPointsTotal,Pt1,Pt2,SP1,SP2);
|
|
}
|
|
|
|
if(NbPointsTotal<3) {
|
|
IntPolyh_StartPoint Pt1,Pt2;
|
|
NbPoints=TriangleEdgeContact(2,2,Tri1,Tri2,Q1,Q2,Q3,f1,f2,f3,P2,P3,e2,m1,Pt1,Pt2);
|
|
TestNbPoints(2,NbPoints,NbPointsTotal,Pt1,Pt2,SP1,SP2);
|
|
}
|
|
|
|
if(NbPointsTotal<3) {
|
|
IntPolyh_StartPoint Pt1,Pt2;
|
|
NbPoints=TriangleEdgeContact(2,3,Tri1,Tri2,Q1,Q2,Q3,f1,f2,f3,P3,P1,e3,m1,Pt1,Pt2);
|
|
TestNbPoints(2,NbPoints,NbPointsTotal,Pt1,Pt2,SP1,SP2);
|
|
}
|
|
}
|
|
// no need already checked in TestNbPoints
|
|
// if( (NbPointsTotal==2)&&(SP1.CheckSameSP(SP2)) ) {
|
|
// NbPointsTotal=1;
|
|
//SP1.SetCoupleValue(T1,T2);
|
|
// }
|
|
// else
|
|
if(NbPointsTotal==2) {
|
|
SP1.SetCoupleValue(T1,T2);
|
|
SP2.SetCoupleValue(T1,T2);
|
|
}
|
|
else if(NbPointsTotal==1)
|
|
SP1.SetCoupleValue(T1,T2);
|
|
else if(NbPointsTotal==3)
|
|
SP1.SetCoupleValue(T1,T2);
|
|
|
|
return (NbPointsTotal);
|
|
}
|
|
//=======================================================================
|
|
//function : NextStartingPointsResearch
|
|
//purpose : from two triangles and an intersection point I
|
|
// seach the other point (if it exist).
|
|
// This function is used by StartPointChain
|
|
//=======================================================================
|
|
Standard_Integer IntPolyh_MaillageAffinage::NextStartingPointsResearch
|
|
(const Standard_Integer T1,
|
|
const Standard_Integer T2,
|
|
const IntPolyh_StartPoint &SPInit,
|
|
IntPolyh_StartPoint &SPNext) const
|
|
{
|
|
Standard_Integer NbPointsTotal=0;
|
|
Standard_Integer EdgeInit1=SPInit.E1();
|
|
Standard_Integer EdgeInit2=SPInit.E2();
|
|
if( (T1<0)||(T2<0) ) NbPointsTotal=0;
|
|
else {
|
|
|
|
const IntPolyh_Triangle &Tri1=TTriangles1[T1];
|
|
const IntPolyh_Triangle &Tri2=TTriangles2[T2];
|
|
|
|
const IntPolyh_Point &P1=TPoints1[Tri1.FirstPoint()];
|
|
const IntPolyh_Point &P2=TPoints1[Tri1.SecondPoint()];
|
|
const IntPolyh_Point &P3=TPoints1[Tri1.ThirdPoint()];
|
|
const IntPolyh_Point &Q1=TPoints2[Tri2.FirstPoint()];
|
|
const IntPolyh_Point &Q2=TPoints2[Tri2.SecondPoint()];
|
|
const IntPolyh_Point &Q3=TPoints2[Tri2.ThirdPoint()];
|
|
|
|
/* The first triangle is (p1,p2,p3). The other is (q1,q2,q3).
|
|
The edges are (e1,e2,e3) and (f1,f2,f3).
|
|
The normals are n1 and m1*/
|
|
|
|
const IntPolyh_Point e1=P2-P1;
|
|
const IntPolyh_Point e2=P3-P2;
|
|
const IntPolyh_Point e3=P1-P3;
|
|
|
|
const IntPolyh_Point f1=Q2-Q1;
|
|
const IntPolyh_Point f2=Q3-Q2;
|
|
const IntPolyh_Point f3=Q1-Q3;
|
|
|
|
IntPolyh_Point nn1,mm1;
|
|
nn1.Cross(e1, e2); //normal to the first triangle
|
|
mm1.Cross(f1, f2); //normal to the second triangle
|
|
|
|
Standard_Real nn1modulus, mm1modulus;
|
|
nn1modulus=sqrt(nn1.SquareModulus());
|
|
mm1modulus=sqrt(mm1.SquareModulus());
|
|
|
|
//-------------------------------------------------
|
|
///calculation of intersections points between triangles
|
|
//-------------------------------------------------
|
|
|
|
Standard_Integer NbPoints=0;
|
|
IntPolyh_StartPoint SP1,SP2;
|
|
|
|
///check T1 normal
|
|
if(Abs(nn1modulus)<MyConfusionPrecision) {//10.0e-20){
|
|
|
|
}
|
|
else {
|
|
const IntPolyh_Point n1=nn1.Divide(nn1modulus);
|
|
///T2 edges with T1
|
|
if( (NbPointsTotal<3)&&(EdgeInit2!=Tri2.FirstEdge()) ) {
|
|
IntPolyh_StartPoint Pt1,Pt2;
|
|
NbPoints=TriangleEdgeContact(1,1,Tri1,Tri2,P1,P2,P3,e1,e2,e3,Q1,Q2,f1,n1,Pt1,Pt2);
|
|
TestNbPoints(1,NbPoints,NbPointsTotal,Pt1,Pt2,SP1,SP2);
|
|
}
|
|
|
|
if( (NbPointsTotal<3)&&(EdgeInit2!=Tri2.SecondEdge()) ) {
|
|
IntPolyh_StartPoint Pt1,Pt2;
|
|
NbPoints=TriangleEdgeContact(1,2,Tri1,Tri2,P1,P2,P3,e1,e2,e3,Q2,Q3,f2,n1,Pt1,Pt2);
|
|
TestNbPoints(1,NbPoints,NbPointsTotal,Pt1,Pt2,SP1,SP2);
|
|
}
|
|
|
|
if( (NbPointsTotal<3)&&(EdgeInit2!=Tri2.ThirdEdge()) ) {
|
|
IntPolyh_StartPoint Pt1,Pt2;
|
|
NbPoints=TriangleEdgeContact(1,3,Tri1,Tri2,P1,P2,P3,e1,e2,e3,Q3,Q1,f3,n1,Pt1,Pt2);
|
|
TestNbPoints(1,NbPoints,NbPointsTotal,Pt1,Pt2,SP1,SP2);
|
|
}
|
|
}
|
|
///check T2 normal
|
|
if(Abs(mm1modulus)<MyConfusionPrecision) {//10.0e-20){
|
|
|
|
}
|
|
else {
|
|
const IntPolyh_Point m1=mm1.Divide(mm1modulus);
|
|
///T1 edges with T2
|
|
if( (NbPointsTotal<3)&&(EdgeInit1!=Tri1.FirstEdge()) ) {
|
|
IntPolyh_StartPoint Pt1,Pt2;
|
|
NbPoints=TriangleEdgeContact(2,1,Tri1,Tri2,Q1,Q2,Q3,f1,f2,f3,P1,P2,e1,m1,Pt1,Pt2);
|
|
TestNbPoints(2,NbPoints,NbPointsTotal,Pt1,Pt2,SP1,SP2);
|
|
}
|
|
|
|
if( (NbPointsTotal<3)&&(EdgeInit1!=Tri1.SecondEdge()) ) {
|
|
IntPolyh_StartPoint Pt1,Pt2;
|
|
NbPoints=TriangleEdgeContact(2,2,Tri1,Tri2,Q1,Q2,Q3,f1,f2,f3,P2,P3,e2,m1,Pt1,Pt2);
|
|
TestNbPoints(2,NbPoints,NbPointsTotal,Pt1,Pt2,SP1,SP2);
|
|
}
|
|
|
|
if( (NbPointsTotal<3)&&(EdgeInit1!=Tri1.ThirdEdge()) ) {
|
|
IntPolyh_StartPoint Pt1,Pt2;
|
|
NbPoints=TriangleEdgeContact(2,3,Tri1,Tri2,Q1,Q2,Q3,f1,f2,f3,P3,P1,e3,m1,Pt1,Pt2);
|
|
TestNbPoints(2,NbPoints,NbPointsTotal,Pt1,Pt2,SP1,SP2);
|
|
}
|
|
}
|
|
|
|
if (NbPointsTotal==1) {
|
|
if(SP1.CheckSameSP(SPInit))
|
|
NbPointsTotal=0;
|
|
else {
|
|
SPNext=SP1;
|
|
}
|
|
}
|
|
else if( (NbPointsTotal==2)&&(SP1.CheckSameSP(SPInit)) ) {
|
|
NbPointsTotal=1;//SP1 et SPInit sont identiques
|
|
SPNext=SP2;
|
|
}
|
|
else if( (NbPointsTotal==2)&&(SP2.CheckSameSP(SPInit)) ) {
|
|
NbPointsTotal=1;//SP2 et SPInit sont identiques
|
|
SPNext=SP1;
|
|
}
|
|
|
|
else if(NbPointsTotal>1) {
|
|
|
|
}
|
|
}
|
|
SPNext.SetCoupleValue(T1,T2);
|
|
return (NbPointsTotal);
|
|
}
|
|
//=======================================================================
|
|
//function : CalculPtsInterTriEdgeCoplanaires
|
|
//purpose :
|
|
//=======================================================================
|
|
void CalculPtsInterTriEdgeCoplanaires(const Standard_Integer TriSurfID,
|
|
const IntPolyh_Point &NormaleTri,
|
|
const IntPolyh_Triangle &Tri1,
|
|
const IntPolyh_Triangle &Tri2,
|
|
const IntPolyh_Point &PE1,
|
|
const IntPolyh_Point &PE2,
|
|
const IntPolyh_Point &Edge,
|
|
const Standard_Integer EdgeIndex,
|
|
const IntPolyh_Point &PT1,
|
|
const IntPolyh_Point &PT2,
|
|
const IntPolyh_Point &Cote,
|
|
const Standard_Integer CoteIndex,
|
|
IntPolyh_StartPoint &SP1,
|
|
IntPolyh_StartPoint &SP2,
|
|
Standard_Integer &NbPoints)
|
|
{
|
|
Standard_Real aDE, aDC;
|
|
//
|
|
gp_Vec aVE(Edge.X(), Edge.Y(), Edge.Z());
|
|
gp_Vec aVC(Cote.X(), Cote.Y(), Cote.Z());
|
|
//
|
|
aDE = aVE.SquareMagnitude();
|
|
aDC = aVC.SquareMagnitude();
|
|
//
|
|
if (aDE > SquareMyConfusionPrecision) {
|
|
aVE.Divide(aDE);
|
|
}
|
|
//
|
|
if (aDC > SquareMyConfusionPrecision) {
|
|
aVC.Divide(aDC);
|
|
}
|
|
//
|
|
if (!aVE.IsParallel(aVC, MyConfusionPrecision)) {
|
|
///Edge and side are not parallel
|
|
IntPolyh_Point Per;
|
|
Per.Cross(NormaleTri,Cote);
|
|
Standard_Real p1p = Per.Dot(PE1);
|
|
Standard_Real p2p = Per.Dot(PE2);
|
|
Standard_Real p0p = Per.Dot(PT1);
|
|
///The edge are PT1 are projected on the perpendicular of the side in the plane of the triangle
|
|
if ( ( ((p1p>=p0p)&&(p0p>=p2p) )||( (p1p<=p0p)&&(p0p<=p2p) )) && (Abs(p1p-p2p) > MyConfusionPrecision)) {
|
|
Standard_Real lambda=(p1p-p0p)/(p1p-p2p);
|
|
if (lambda<-MyConfusionPrecision) {
|
|
|
|
}
|
|
IntPolyh_Point PIE;
|
|
if (Abs(lambda)<MyConfusionPrecision)//lambda=0
|
|
PIE=PE1;
|
|
else if (Abs(lambda)>1.0-MyConfusionPrecision)//lambda=1
|
|
PIE=PE2;
|
|
else
|
|
PIE=PE1+Edge*lambda;
|
|
|
|
Standard_Real alpha=RealLast();
|
|
if(Cote.X()!=0) alpha=(PIE.X()-PT1.X())/Cote.X();
|
|
else if (Cote.Y()!=0) alpha=(PIE.Y()-PT1.Y())/Cote.Y();
|
|
else if (Cote.Z()!=0) alpha=(PIE.Z()-PT1.Z())/Cote.Z();
|
|
else {
|
|
|
|
}
|
|
|
|
if (alpha<-MyConfusionPrecision) {
|
|
|
|
}
|
|
else {
|
|
if (NbPoints==0) {
|
|
SP1.SetXYZ(PIE.X(),PIE.Y(),PIE.Z());
|
|
if (TriSurfID==1) {
|
|
if(Abs(alpha)<MyConfusionPrecision) {//alpha=0
|
|
SP1.SetUV1(PT1.U(),PT1.V());
|
|
SP1.SetUV1(PIE.U(),PIE.V());
|
|
SP1.SetEdge1(-1);
|
|
}
|
|
if(Abs(alpha)>1.0-MyConfusionPrecision) {//alpha=1
|
|
SP1.SetUV1(PT2.U(),PT2.V());
|
|
SP1.SetUV1(PIE.U(),PIE.V());
|
|
SP1.SetEdge1(-1);
|
|
}
|
|
else {
|
|
SP1.SetUV1(PT1.U()+Cote.U()*alpha,PT1.V()+Cote.V()*alpha);
|
|
SP1.SetUV2(PIE.U(),PIE.V());
|
|
SP1.SetEdge1(Tri1.GetEdgeNumber(CoteIndex));
|
|
if (Tri1.GetEdgeOrientation(CoteIndex)>0) SP1.SetLambda1(alpha);
|
|
else SP1.SetLambda1(1.0-alpha);
|
|
}
|
|
NbPoints++;
|
|
}
|
|
else if (TriSurfID==2) {
|
|
if(Abs(alpha)<MyConfusionPrecision) {//alpha=0
|
|
SP1.SetUV1(PT1.U(),PT1.V());
|
|
SP1.SetUV1(PIE.U(),PIE.V());
|
|
SP1.SetEdge2(-1);
|
|
}
|
|
if(Abs(alpha)>1.0-MyConfusionPrecision) {//alpha=1
|
|
SP1.SetUV1(PT2.U(),PT2.V());
|
|
SP1.SetUV1(PIE.U(),PIE.V());
|
|
SP1.SetEdge2(-1);
|
|
}
|
|
else {
|
|
SP1.SetUV1(PIE.U(),PIE.V());
|
|
SP1.SetUV2(PT1.U()+Cote.U()*alpha,PT1.V()+Cote.V()*alpha);
|
|
SP1.SetEdge2(Tri2.GetEdgeNumber(CoteIndex));
|
|
if (Tri2.GetEdgeOrientation(CoteIndex)>0) SP1.SetLambda2(alpha);
|
|
else SP1.SetLambda2(1.0-alpha);
|
|
}
|
|
NbPoints++;
|
|
}
|
|
else {
|
|
|
|
}
|
|
}
|
|
|
|
else if (NbPoints==1) {
|
|
SP2.SetXYZ(PIE.X(),PIE.Y(),PIE.Z());
|
|
if (TriSurfID==1) {
|
|
if(Abs(alpha)<MyConfusionPrecision) {//alpha=0
|
|
SP2.SetUV1(PT1.U(),PT1.V());
|
|
SP2.SetUV1(PIE.U(),PIE.V());
|
|
SP2.SetEdge1(-1);
|
|
}
|
|
if(Abs(alpha)>1.0-MyConfusionPrecision) {//alpha=1
|
|
SP2.SetUV1(PT2.U(),PT2.V());
|
|
SP2.SetUV1(PIE.U(),PIE.V());
|
|
SP2.SetEdge1(-1);
|
|
}
|
|
else {
|
|
SP2.SetUV1(PT1.U()+Cote.U()*alpha,PT1.V()+Cote.V()*alpha);
|
|
SP2.SetUV2(PIE.U(),PIE.V());
|
|
SP2.SetEdge1(Tri1.GetEdgeNumber(CoteIndex));
|
|
if (Tri1.GetEdgeOrientation(CoteIndex)>0) SP2.SetLambda1(alpha);
|
|
else SP2.SetLambda1(1.0-alpha);
|
|
}
|
|
NbPoints++;
|
|
}
|
|
else if (TriSurfID==2) {
|
|
if(Abs(alpha)<MyConfusionPrecision) {//alpha=0
|
|
SP2.SetUV1(PT1.U(),PT1.V());
|
|
SP2.SetUV1(PIE.U(),PIE.V());
|
|
SP2.SetEdge2(-1);
|
|
}
|
|
if(Abs(alpha)>1.0-MyConfusionPrecision) {//alpha=1
|
|
SP2.SetUV1(PT2.U(),PT2.V());
|
|
SP2.SetUV1(PIE.U(),PIE.V());
|
|
SP2.SetEdge2(-1);
|
|
}
|
|
else {
|
|
SP2.SetUV1(PIE.U(),PIE.V());
|
|
SP2.SetUV2(PT1.U()+Cote.U()*alpha,PT1.V()+Cote.V()*alpha);
|
|
SP2.SetEdge2(Tri2.GetEdgeNumber(CoteIndex));
|
|
if (Tri1.GetEdgeOrientation(CoteIndex)>0) SP2.SetLambda2(alpha);
|
|
else SP2.SetLambda2(1.0-alpha);
|
|
}
|
|
NbPoints++;
|
|
}
|
|
else {
|
|
|
|
}
|
|
}
|
|
|
|
else if( (NbPoints>2)||(NbPoints<0) ) {
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
//Side and Edge are parallel, with previous
|
|
//rejections they are at the same side
|
|
//The points are projected on that side
|
|
Standard_Real pe1p= Cote.Dot(PE1);
|
|
Standard_Real pe2p= Cote.Dot(PE2);
|
|
Standard_Real pt1p= Cote.Dot(PT1);
|
|
Standard_Real pt2p= Cote.Dot(PT2);
|
|
Standard_Real lambda1=0., lambda2=0., alpha1=0., alpha2=0.;
|
|
IntPolyh_Point PEP1,PTP1,PEP2,PTP2;
|
|
|
|
if (pe1p>pe2p) {
|
|
if ( (pt1p<pe1p)&&(pe1p<=pt2p) ) {
|
|
lambda1=0.0;
|
|
PEP1=PE1;
|
|
alpha1=((pe1p-pt1p)/(pt2p-pt1p));
|
|
PTP1=PT1+Cote*alpha1;
|
|
NbPoints=1;
|
|
if (pt1p<=pe2p) {
|
|
lambda2=1.0;
|
|
PEP2=PE2;
|
|
alpha2=((pe2p-pt1p)/(pt2p-pt1p));
|
|
PTP2=PT1+Cote*alpha2;
|
|
NbPoints=2;
|
|
}
|
|
else {
|
|
lambda2=((pt1p-pe1p)/(pe2p-pe1p));
|
|
PEP2=PE1+Edge*lambda2;
|
|
alpha2=0.0;
|
|
PTP2=PT1;
|
|
NbPoints=2;
|
|
}
|
|
}
|
|
else if( (pt2p<pe1p)&&(pe1p<=pt1p) ) {
|
|
lambda1=0.0;
|
|
PEP1=PE1;
|
|
alpha1=((pt1p-pe1p)/(pt1p-pt2p));
|
|
PTP1=PT1+Cote*alpha1;
|
|
NbPoints=1;
|
|
if (pt2p<=pe2p) {
|
|
lambda2=1.0;
|
|
PEP2=PE2;
|
|
alpha2=((pe2p-pt1p)/(pt2p-pt1p));
|
|
PTP2=PT1+Cote*alpha2;
|
|
NbPoints=2;
|
|
}
|
|
else {
|
|
lambda2=((pt2p-pe1p)/(pe2p-pe1p));
|
|
PEP2=PE1+Edge*lambda2;
|
|
alpha2=1.0;
|
|
PTP2=PT2;
|
|
NbPoints=2;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (pe1p<pe2p) {
|
|
if ( (pt1p<pe2p)&&(pe2p<=pt2p) ) {
|
|
lambda1=1.0;
|
|
PEP1=PE2;
|
|
alpha1=((pe2p-pt1p)/(pt2p-pt1p));
|
|
PTP1=PT1+Cote*alpha1;
|
|
NbPoints=1;
|
|
if (pt1p<=pe1p) {
|
|
lambda2=0.0;
|
|
PEP2=PE1;
|
|
alpha2=((pe1p-pt1p)/(pt2p-pt1p));
|
|
PTP2=PT1+Cote*alpha2;
|
|
NbPoints=2;
|
|
}
|
|
else {
|
|
lambda2=((pt1p-pe1p)/(pe2p-pe1p));
|
|
PEP2=PE2+Edge*lambda2;
|
|
alpha2=0.0;
|
|
PTP2=PT1;
|
|
NbPoints=2;
|
|
}
|
|
}
|
|
else if( (pt2p<pe2p)&&(pe2p<=pt1p) ) {
|
|
lambda1=1.0;
|
|
PEP1=PE2;
|
|
alpha1=((pt1p-pe2p)/(pt1p-pt2p));
|
|
PTP1=PT1+Cote*alpha1;
|
|
NbPoints=1;
|
|
if (pt2p<=pe1p) {
|
|
lambda2=0.0;
|
|
PEP2=PE1;
|
|
alpha2=((pe1p-pt1p)/(pt2p-pt1p));
|
|
PTP2=PT1+Cote*alpha2;
|
|
NbPoints=2;
|
|
}
|
|
else {
|
|
lambda2=((pt2p-pe1p)/(pe2p-pe1p));
|
|
PEP2=PE1+Edge*lambda2;
|
|
alpha2=1.0;
|
|
PTP2=PT2;
|
|
NbPoints=2;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (NbPoints!=0) {
|
|
SP1.SetXYZ(PEP1.X(),PEP1.Y(),PEP1.Z());
|
|
if (TriSurfID==1) {///cote appartient a Tri1
|
|
SP1.SetUV1(PTP1.U(),PTP1.V());
|
|
SP1.SetUV2(PEP1.U(),PEP1.V());
|
|
SP1.SetEdge1(Tri1.GetEdgeNumber(CoteIndex));
|
|
|
|
if(Tri1.GetEdgeOrientation(CoteIndex)>0) SP1.SetLambda1(alpha1);
|
|
else SP1.SetLambda1(1.0-alpha1);
|
|
|
|
if(Tri2.GetEdgeOrientation(EdgeIndex)>0) SP1.SetLambda2(lambda1);
|
|
else SP1.SetLambda2(1.0-lambda1);
|
|
}
|
|
if (TriSurfID==2) {///cote appartient a Tri2
|
|
SP1.SetUV1(PEP1.U(),PTP1.V());
|
|
SP1.SetUV2(PTP1.U(),PEP1.V());
|
|
SP1.SetEdge2(Tri2.GetEdgeNumber(CoteIndex));
|
|
|
|
if(Tri2.GetEdgeOrientation(CoteIndex)>0) SP1.SetLambda1(alpha1);
|
|
else SP1.SetLambda1(1.0-alpha1);
|
|
|
|
if(Tri1.GetEdgeOrientation(EdgeIndex)>0) SP1.SetLambda2(lambda1);
|
|
else SP1.SetLambda2(1.0-lambda1);
|
|
}
|
|
|
|
//It is checked if PEP1!=PEP2
|
|
if ( (NbPoints==2)&&(Abs(PEP1.U()-PEP2.U())<MyConfusionPrecision)
|
|
&&(Abs(PEP1.V()-PEP2.V())<MyConfusionPrecision) ) NbPoints=1;
|
|
if (NbPoints==2) {
|
|
SP2.SetXYZ(PEP2.X(),PEP2.Y(),PEP2.Z());
|
|
if (TriSurfID==1) {
|
|
SP2.SetUV1(PTP2.U(),PTP2.V());
|
|
SP2.SetUV2(PEP2.U(),PEP2.V());
|
|
SP2.SetEdge1(Tri1.GetEdgeNumber(CoteIndex));
|
|
|
|
if(Tri1.GetEdgeOrientation(CoteIndex)>0) SP2.SetLambda1(alpha1);
|
|
else SP2.SetLambda1(1.0-alpha1);
|
|
|
|
if(Tri2.GetEdgeOrientation(EdgeIndex)>0) SP2.SetLambda2(lambda1);
|
|
else SP2.SetLambda2(1.0-lambda1);
|
|
}
|
|
if (TriSurfID==2) {
|
|
SP2.SetUV1(PEP2.U(),PTP2.V());
|
|
SP2.SetUV2(PTP2.U(),PEP2.V());
|
|
SP2.SetEdge2(Tri2.GetEdgeNumber(CoteIndex));
|
|
|
|
if(Tri1.GetEdgeOrientation(CoteIndex)>0) SP2.SetLambda1(alpha1);
|
|
else SP2.SetLambda1(1.0-alpha1);
|
|
|
|
if(Tri2.GetEdgeOrientation(EdgeIndex)>0) SP2.SetLambda2(lambda1);
|
|
else SP2.SetLambda2(1.0-lambda1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//Filter if the point is placed on top, the edge is set to -1
|
|
if (NbPoints>0) {
|
|
if(Abs(SP1.Lambda1())<MyConfusionPrecision)
|
|
SP1.SetEdge1(-1);
|
|
if(Abs(SP1.Lambda1()-1)<MyConfusionPrecision)
|
|
SP1.SetEdge1(-1);
|
|
if(Abs(SP1.Lambda2())<MyConfusionPrecision)
|
|
SP1.SetEdge2(-1);
|
|
if(Abs(SP1.Lambda2()-1)<MyConfusionPrecision)
|
|
SP1.SetEdge2(-1);
|
|
}
|
|
if (NbPoints==2) {
|
|
if(Abs(SP2.Lambda1())<MyConfusionPrecision)
|
|
SP2.SetEdge1(-1);
|
|
if(Abs(SP2.Lambda1()-1)<MyConfusionPrecision)
|
|
SP2.SetEdge1(-1);
|
|
if(Abs(SP2.Lambda2())<MyConfusionPrecision)
|
|
SP2.SetEdge2(-1);
|
|
if(Abs(SP2.Lambda2()-1)<MyConfusionPrecision)
|
|
SP2.SetEdge2(-1);
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : TriangleEdgeContact
|
|
//purpose :
|
|
//=======================================================================
|
|
Standard_Integer IntPolyh_MaillageAffinage::TriangleEdgeContact
|
|
(const Standard_Integer TriSurfID,
|
|
const Standard_Integer EdgeIndex,
|
|
const IntPolyh_Triangle &Tri1,
|
|
const IntPolyh_Triangle &Tri2,
|
|
const IntPolyh_Point &PT1,
|
|
const IntPolyh_Point &PT2,
|
|
const IntPolyh_Point &PT3,
|
|
const IntPolyh_Point &Cote12,
|
|
const IntPolyh_Point &Cote23,
|
|
const IntPolyh_Point &Cote31,
|
|
const IntPolyh_Point &PE1,const IntPolyh_Point &PE2,
|
|
const IntPolyh_Point &Edge,
|
|
const IntPolyh_Point &NormaleT,
|
|
IntPolyh_StartPoint &SP1,IntPolyh_StartPoint &SP2) const
|
|
{
|
|
|
|
Standard_Real lambda =0., alpha =0., beta =0.;
|
|
|
|
//One of edges on which the point is located is known
|
|
if (TriSurfID==1) {
|
|
SP1.SetEdge2(Tri2.GetEdgeNumber(EdgeIndex));
|
|
SP2.SetEdge2(Tri2.GetEdgeNumber(EdgeIndex));
|
|
}
|
|
else if (TriSurfID==2) {
|
|
SP1.SetEdge1(Tri1.GetEdgeNumber(EdgeIndex));
|
|
SP2.SetEdge1(Tri1.GetEdgeNumber(EdgeIndex));
|
|
}
|
|
else {
|
|
|
|
}
|
|
|
|
/**The edge is projected on the normal in the triangle if yes
|
|
--> a free intersection (point I)--> Start point is found */
|
|
Standard_Integer NbPoints=0;
|
|
if(NormaleT.SquareModulus()==0) {
|
|
|
|
}
|
|
else if( (Cote12.SquareModulus()==0)
|
|
||(Cote23.SquareModulus()==0)
|
|
||(Cote31.SquareModulus()==0) ) {
|
|
|
|
}
|
|
else if(Edge.SquareModulus()==0) {
|
|
|
|
}
|
|
else {
|
|
Standard_Real pe1 = NormaleT.Dot(PE1);
|
|
Standard_Real pe2 = NormaleT.Dot(PE2);
|
|
Standard_Real pt1 = NormaleT.Dot(PT1);
|
|
|
|
// PE1I = lambda.Edge
|
|
|
|
if( (Abs(pe1-pt1)<MyConfusionPrecision)&&(Abs(pe2-pt1)<MyConfusionPrecision)) {
|
|
//edge and triangle are coplanar (two contact points at maximum)
|
|
|
|
|
|
//the tops of the triangle are projected on the perpendicular to the edge
|
|
IntPolyh_Point PerpEdge;
|
|
PerpEdge.Cross(NormaleT,Edge);
|
|
Standard_Real pp1 = PerpEdge.Dot(PT1);
|
|
Standard_Real pp2 = PerpEdge.Dot(PT2);
|
|
Standard_Real pp3 = PerpEdge.Dot(PT3);
|
|
Standard_Real ppe1 = PerpEdge.Dot(PE1);
|
|
|
|
|
|
if ( (Abs(pp1-pp2)<MyConfusionPrecision)&&(Abs(pp1-pp3)<MyConfusionPrecision) ) {
|
|
|
|
}
|
|
else {
|
|
if ( ( (pp1>=ppe1)&&(pp2<=ppe1)&&(pp3<=ppe1) ) || ( (pp1<=ppe1)&&(pp2>=ppe1)&&(pp3>=ppe1) ) ){
|
|
//there are two sides (common top PT1) that can cut the edge
|
|
|
|
//first side
|
|
CalculPtsInterTriEdgeCoplanaires(TriSurfID,NormaleT,Tri1,Tri2,PE1,PE2,Edge,EdgeIndex,
|
|
PT1,PT2,Cote12,1,SP1,SP2,NbPoints);
|
|
|
|
if ( (NbPoints>1)&&(Abs(SP2.U1()-SP1.U1())<MyConfusionPrecision)
|
|
&&(Abs(SP1.V1()-SP2.V1())<MyConfusionPrecision) ) NbPoints=1;
|
|
|
|
//second side
|
|
if (NbPoints<2) CalculPtsInterTriEdgeCoplanaires(TriSurfID,NormaleT,Tri1,Tri2,PE1,PE2,Edge,EdgeIndex,
|
|
PT3,PT1,Cote31,3,SP1,SP2,NbPoints);
|
|
}
|
|
|
|
if ( (NbPoints>1)&&(Abs(SP1.U1()-SP2.U1())<MyConfusionPrecision)
|
|
&&(Abs(SP1.V2()-SP2.V1())<MyConfusionPrecision) ) NbPoints=1;
|
|
if (NbPoints>=2) return(NbPoints);
|
|
|
|
else if ( ( ( (pp2>=ppe1)&&(pp1<=ppe1)&&(pp3<=ppe1) ) || ( (pp2<=ppe1)&&(pp1>=ppe1)&&(pp3>=ppe1) ) )
|
|
&& (NbPoints<2) ) {
|
|
//there are two sides (common top PT2) that can cut the edge
|
|
|
|
//first side
|
|
CalculPtsInterTriEdgeCoplanaires(TriSurfID,NormaleT,Tri1,Tri2,PE1,PE2,Edge,EdgeIndex,
|
|
PT1,PT2,Cote12,1,SP1,SP2,NbPoints);
|
|
|
|
if ( (NbPoints>1)&&(Abs(SP2.U1()-SP1.U1())<MyConfusionPrecision)
|
|
&&(Abs(SP1.V1()-SP2.V1())<MyConfusionPrecision) ) NbPoints=1;
|
|
|
|
//second side
|
|
if(NbPoints<2) CalculPtsInterTriEdgeCoplanaires(TriSurfID,NormaleT,Tri1,Tri2,PE1,PE2,Edge,EdgeIndex,
|
|
PT2,PT3,Cote23,2,SP1,SP2,NbPoints);
|
|
}
|
|
if ( (NbPoints>1)&&(Abs(SP2.U1()-SP1.U1())<MyConfusionPrecision)
|
|
&&(Abs(SP1.V1()-SP2.V1())<MyConfusionPrecision) ) NbPoints=1;
|
|
if (NbPoints>=2) return(NbPoints);
|
|
|
|
else if ( (( (pp3>=ppe1)&&(pp1<=ppe1)&&(pp2<=ppe1) ) || ( (pp3<=ppe1)&&(pp1>=ppe1)&&(pp2>=ppe1) ))
|
|
&& (NbPoints<2) ) {
|
|
//there are two sides (common top PT3) that can cut the edge
|
|
|
|
//first side
|
|
CalculPtsInterTriEdgeCoplanaires(TriSurfID,NormaleT,Tri1,Tri2,PE1,PE2,Edge,EdgeIndex,
|
|
PT3,PT1,Cote31,3,SP1,SP2,NbPoints);
|
|
|
|
if ( (NbPoints>1)&&(Abs(SP2.U1()-SP1.U1())<MyConfusionPrecision)
|
|
&&(Abs(SP1.V1()-SP2.V1())<MyConfusionPrecision) ) NbPoints=1;
|
|
|
|
//second side
|
|
if (NbPoints<2) CalculPtsInterTriEdgeCoplanaires(TriSurfID,NormaleT,Tri1,Tri2,PE1,PE2,Edge,EdgeIndex,
|
|
PT2,PT3,Cote23,2,SP1,SP2,NbPoints);
|
|
}
|
|
if ( (NbPoints>1)&&(Abs(SP2.U1()-SP1.U1())<MyConfusionPrecision)
|
|
&&(Abs(SP2.V1()-SP1.V1())<MyConfusionPrecision) ) NbPoints=1;
|
|
if (NbPoints>=2) return(NbPoints);
|
|
}
|
|
}
|
|
|
|
//------------------------------------------------------
|
|
// NON COPLANAR edge and triangle (a contact point)
|
|
//------------------------------------------------------
|
|
else if( ( (pe1>=pt1)&&(pt1>=pe2) ) || ( (pe1<=pt1)&&(pt1<=pe2) ) ) { //
|
|
lambda=(pe1-pt1)/(pe1-pe2);
|
|
IntPolyh_Point PI;
|
|
if (lambda<-MyConfusionPrecision) {
|
|
|
|
}
|
|
else if (Abs(lambda)<MyConfusionPrecision) {//lambda==0
|
|
PI=PE1;
|
|
if(TriSurfID==1) SP1.SetEdge2(-1);
|
|
else SP1.SetEdge1(-1);
|
|
}
|
|
else if (Abs(lambda-1.0)<MyConfusionPrecision) {//lambda==1
|
|
PI=PE2;
|
|
if(TriSurfID==1) SP1.SetEdge2(-1);
|
|
else SP1.SetEdge1(-1);
|
|
}
|
|
else {
|
|
PI=PE1+Edge*lambda;
|
|
if(TriSurfID==1) {
|
|
if(Tri2.GetEdgeOrientation(EdgeIndex)>0)
|
|
SP1.SetLambda2(lambda);
|
|
else SP1.SetLambda2(1.0-lambda);
|
|
}
|
|
if(TriSurfID==2) {
|
|
if(Tri1.GetEdgeOrientation(EdgeIndex)>0)
|
|
SP1.SetLambda1(lambda);
|
|
else SP1.SetLambda1(1.0-lambda);
|
|
}
|
|
}
|
|
|
|
Standard_Real Cote23X=Cote23.X();
|
|
Standard_Real D1=0.0;
|
|
Standard_Real D3,D4;
|
|
|
|
//Combination Eq1 Eq2
|
|
if(Abs(Cote23X)>MyConfusionPrecision) {
|
|
D1=Cote12.Y()-Cote12.X()*Cote23.Y()/Cote23X;
|
|
}
|
|
if(Abs(D1)>MyConfusionPrecision) {
|
|
alpha = ( PI.Y()-PT1.Y()-(PI.X()-PT1.X())*Cote23.Y()/Cote23X )/D1;
|
|
|
|
///It is checked if 1.0>=alpha>=0.0
|
|
if ((alpha<-MyConfusionPrecision)||(alpha>(1.0+MyConfusionPrecision))) return(0);
|
|
else beta = (PI.X()-PT1.X()-alpha*Cote12.X())/Cote23X;
|
|
}
|
|
//Combination Eq1 and Eq2 with Cote23.X()==0
|
|
else if ( (Abs(Cote12.X())>MyConfusionPrecision)
|
|
&&(Abs(Cote23X)<MyConfusionPrecision) ) { //There is Cote23.X()==0
|
|
alpha = (PI.X()-PT1.X())/Cote12.X();
|
|
|
|
if ((alpha<-MyConfusionPrecision)||(alpha>(1.0+MyConfusionPrecision))) return(0);
|
|
|
|
else if (Abs(Cote23.Y())>MyConfusionPrecision) beta = (PI.Y()-PT1.Y()-alpha*Cote12.Y())/Cote23.Y();
|
|
else if (Abs(Cote23.Z())>MyConfusionPrecision) beta = (PI.Z()-PT1.Z()-alpha*Cote12.Z())/Cote23.Z();
|
|
else {
|
|
|
|
}
|
|
}
|
|
//Combination Eq1 and Eq3
|
|
else if ( (Abs(Cote23.X())>MyConfusionPrecision)
|
|
&&(Abs( D3= (Cote12.Z()-Cote12.X()*Cote23.Z()/Cote23.X()) ) > MyConfusionPrecision) ) {
|
|
|
|
alpha = (PI.Z()-PT1.Z()-(PI.X()-PT1.X())*Cote23.Z()/Cote23.X())/D3;
|
|
|
|
if ( (alpha<-MyConfusionPrecision)||(alpha>(1.0+MyConfusionPrecision)) ) return(0);
|
|
else beta = (PI.X()-PT1.X()-alpha*Cote12.X())/Cote23.X();
|
|
}
|
|
//Combination Eq2 and Eq3
|
|
else if ( (Abs(Cote23.Y())>MyConfusionPrecision)
|
|
&&(Abs( D4= (Cote12.Z()-Cote12.Y()*Cote23.Z()/Cote23.Y()) ) > MyConfusionPrecision) ) {
|
|
|
|
alpha = (PI.Z()-PT1.Z()-(PI.Y()-PT1.Y())*Cote23.Z()/Cote23.Y())/D4;
|
|
|
|
if ( (alpha<-MyConfusionPrecision)||(alpha>(1.0+MyConfusionPrecision)) ) return(0);
|
|
else beta = (PI.Y()-PT1.Y()-alpha*Cote12.Y())/Cote23.Y();
|
|
}
|
|
//Combination Eq2 and Eq3 with Cote23.Y()==0
|
|
else if ( (Abs(Cote12.Y())>MyConfusionPrecision)
|
|
&& (Abs(Cote23.Y())<MyConfusionPrecision) ) {
|
|
alpha = (PI.Y()-PT1.Y())/Cote12.Y();
|
|
|
|
if ( (alpha<-MyConfusionPrecision)||(alpha>(1.0+MyConfusionPrecision)) ) return(0);
|
|
|
|
else if (Abs(Cote23.Z())>MyConfusionPrecision) beta = (PI.Z()-PT1.Z()-alpha*Cote12.Z())/Cote23.Z();
|
|
|
|
else {
|
|
printf("\nCote PT2PT3 nul1\n");
|
|
PT2.Dump(2004);
|
|
PT3.Dump(3004);
|
|
}
|
|
}
|
|
//Combination Eq1 and Eq3 with Cote23.Z()==0
|
|
else if ( (Abs(Cote12.Z())>MyConfusionPrecision)
|
|
&& (Abs(Cote23.Z())<MyConfusionPrecision) ) {
|
|
alpha = (PI.Z()-PT1.Z())/Cote12.Z();
|
|
|
|
if ( (alpha<-MyConfusionPrecision)||(alpha>(1.0+MyConfusionPrecision)) ) return(0);
|
|
|
|
else if (Abs(Cote23.X())>MyConfusionPrecision) beta = (PI.X()-PT1.X()-alpha*Cote12.X())/Cote23.X();
|
|
|
|
else {
|
|
|
|
}
|
|
}
|
|
|
|
else { //Particular case not processed ?
|
|
|
|
alpha=RealLast();
|
|
beta=RealLast();
|
|
}
|
|
|
|
if( (beta<-MyConfusionPrecision)||(beta>(alpha+MyConfusionPrecision)) ) return(0);
|
|
else {
|
|
SP1.SetXYZ(PI.X(),PI.Y(),PI.Z());
|
|
|
|
if (TriSurfID==1) {
|
|
SP1.SetUV2(PI.U(),PI.V());
|
|
SP1.SetUV1(PT1.U()+Cote12.U()*alpha+Cote23.U()*beta, PT1.V()+Cote12.V()*alpha+Cote23.V()*beta);
|
|
NbPoints++;
|
|
if (alpha<MyConfusionPrecision) {//alpha=0 --> beta==0
|
|
SP1.SetXYZ(PT1.X(),PT1.Y(),PT1.Z());
|
|
SP1.SetUV1(PT1.U(),PT1.V());
|
|
SP1.SetEdge1(-1);
|
|
}
|
|
else if ( (beta<MyConfusionPrecision)&&(Abs(1-alpha)<MyConfusionPrecision) ) {//beta==0 alpha==1
|
|
SP1.SetXYZ(PT2.X(),PT2.Y(),PT2.Z());
|
|
SP1.SetUV1(PT2.U(),PT2.V());
|
|
SP1.SetEdge1(-1);
|
|
}
|
|
else if ( (Abs(beta-1)<MyConfusionPrecision)&&(Abs(1-alpha)<MyConfusionPrecision) ) {//beta==1 alpha==1
|
|
SP1.SetXYZ(PT3.X(),PT3.Y(),PT3.Z());
|
|
SP1.SetUV1(PT3.U(),PT3.V());
|
|
SP1.SetEdge1(-1);
|
|
}
|
|
else if (beta<MyConfusionPrecision) {//beta==0
|
|
SP1.SetEdge1(Tri1.GetEdgeNumber(1));
|
|
if(Tri1.GetEdgeOrientation(1)>0)
|
|
SP1.SetLambda1(alpha);
|
|
else SP1.SetLambda1(1.0-alpha);
|
|
}
|
|
else if (Abs(beta-alpha)<MyConfusionPrecision) {//beta==alpha
|
|
SP1.SetEdge1(Tri1.GetEdgeNumber(3));
|
|
if(Tri1.GetEdgeOrientation(3)>0)
|
|
SP1.SetLambda1(1.0-alpha);
|
|
else SP1.SetLambda1(alpha);
|
|
}
|
|
else if (Abs(alpha-1)<MyConfusionPrecision) {//alpha==1
|
|
SP1.SetEdge1(Tri1.GetEdgeNumber(2));
|
|
if(Tri1.GetEdgeOrientation(2)>0)
|
|
SP1.SetLambda1(beta);
|
|
else SP1.SetLambda1(1.0-beta);
|
|
}
|
|
}
|
|
else if(TriSurfID==2) {
|
|
SP1.SetUV1(PI.U(),PI.V());
|
|
SP1.SetUV2(PT1.U()+Cote12.U()*alpha+Cote23.U()*beta, PT1.V()+Cote12.V()*alpha+Cote23.V()*beta);
|
|
NbPoints++;
|
|
if (alpha<MyConfusionPrecision) {//alpha=0 --> beta==0
|
|
SP1.SetXYZ(PT1.X(),PT1.Y(),PT1.Z());
|
|
SP1.SetUV2(PT1.U(),PT1.V());
|
|
SP1.SetEdge2(-1);
|
|
}
|
|
else if ( (beta<MyConfusionPrecision)&&(Abs(1-alpha)<MyConfusionPrecision) ) {//beta==0 alpha==1
|
|
SP1.SetXYZ(PT2.X(),PT2.Y(),PT2.Z());
|
|
SP1.SetUV2(PT2.U(),PT2.V());
|
|
SP1.SetEdge2(-1);
|
|
}
|
|
else if ( (Abs(beta-1)<MyConfusionPrecision)&&(Abs(1-alpha)<MyConfusionPrecision) ) {//beta==1 alpha==1
|
|
SP1.SetXYZ(PT3.X(),PT3.Y(),PT3.Z());
|
|
SP1.SetUV2(PT3.U(),PT3.V());
|
|
SP1.SetEdge2(-1);
|
|
}
|
|
else if (beta<MyConfusionPrecision) { //beta==0
|
|
SP1.SetEdge2(Tri2.GetEdgeNumber(1));
|
|
if(Tri2.GetEdgeOrientation(1)>0)
|
|
SP1.SetLambda2(alpha);
|
|
else SP1.SetLambda2(1.0-alpha);
|
|
}
|
|
else if (Abs(beta-alpha)<MyConfusionPrecision) {//beta==alpha
|
|
SP1.SetEdge2(Tri2.GetEdgeNumber(3));
|
|
if(Tri2.GetEdgeOrientation(3)>0)
|
|
SP1.SetLambda2(1.0-alpha);
|
|
else SP1.SetLambda2(alpha);
|
|
}
|
|
else if (Abs(alpha-1)<MyConfusionPrecision) {//alpha==1
|
|
SP1.SetEdge2(Tri2.GetEdgeNumber(2));
|
|
if(Tri2.GetEdgeOrientation(2)>0)
|
|
SP1.SetLambda2(alpha);
|
|
else SP1.SetLambda2(1.0-alpha);
|
|
}
|
|
}
|
|
else {
|
|
|
|
}
|
|
}
|
|
}
|
|
else return 0;
|
|
}
|
|
return (NbPoints);
|
|
}
|
|
//=======================================================================
|
|
//function : TriangleCompare
|
|
//purpose : Analyze each couple of triangles from the two --
|
|
// array of triangles, to see if they are in
|
|
// contact, and compute the incidence. Then put
|
|
// couples in contact in the array of couples
|
|
//=======================================================================
|
|
Standard_Integer IntPolyh_MaillageAffinage::TriangleCompare ()
|
|
{
|
|
// Find couples with interfering bounding boxes
|
|
IntPolyh_IndexedDataMapOfIntegerListOfInteger aDMILI;
|
|
GetInterferingTriangles(TTriangles1, TPoints1,
|
|
TTriangles2, TPoints2,
|
|
aDMILI);
|
|
if (aDMILI.IsEmpty()) {
|
|
return 0;
|
|
}
|
|
//
|
|
Standard_Real CoupleAngle = -2.0;
|
|
//
|
|
// Intersection of the triangles
|
|
Standard_Integer i, aNb = aDMILI.Extent();
|
|
for (i = 1; i <= aNb; ++i) {
|
|
const Standard_Integer i_S1 = aDMILI.FindKey(i);
|
|
IntPolyh_Triangle &Triangle1 = TTriangles1[i_S1];
|
|
const IntPolyh_Point& P1 = TPoints1[Triangle1.FirstPoint()];
|
|
const IntPolyh_Point& P2 = TPoints1[Triangle1.SecondPoint()];
|
|
const IntPolyh_Point& P3 = TPoints1[Triangle1.ThirdPoint()];
|
|
//
|
|
const TColStd_ListOfInteger& aLI2 = aDMILI(i);
|
|
TColStd_ListOfInteger::Iterator aItLI(aLI2);
|
|
for (; aItLI.More(); aItLI.Next()) {
|
|
const Standard_Integer i_S2 = aItLI.Value();
|
|
IntPolyh_Triangle &Triangle2 = TTriangles2[i_S2];
|
|
const IntPolyh_Point& Q1 = TPoints2[Triangle2.FirstPoint()];
|
|
const IntPolyh_Point& Q2 = TPoints2[Triangle2.SecondPoint()];
|
|
const IntPolyh_Point& Q3 = TPoints2[Triangle2.ThirdPoint()];
|
|
//
|
|
if (TriContact(P1, P2, P3, Q1, Q2, Q3, CoupleAngle)) {
|
|
IntPolyh_Couple aCouple(i_S1, i_S2, CoupleAngle);
|
|
TTrianglesContacts.Append(aCouple);
|
|
//
|
|
Triangle1.SetIntersection(Standard_True);
|
|
Triangle2.SetIntersection(Standard_True);
|
|
}
|
|
}
|
|
}
|
|
return TTrianglesContacts.Extent();
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : CheckCoupleAndGetAngle
|
|
//purpose :
|
|
//=======================================================================
|
|
Standard_Boolean CheckCoupleAndGetAngle(const Standard_Integer T1,
|
|
const Standard_Integer T2,
|
|
Standard_Real& Angle,
|
|
IntPolyh_ListOfCouples &TTrianglesContacts)
|
|
{
|
|
IntPolyh_ListIteratorOfListOfCouples aIt(TTrianglesContacts);
|
|
for (; aIt.More(); aIt.Next()) {
|
|
IntPolyh_Couple& TestCouple = aIt.ChangeValue();
|
|
if (!TestCouple.IsAnalyzed()) {
|
|
if (TestCouple.FirstValue() == T1 && TestCouple.SecondValue() == T2) {
|
|
TestCouple.SetAnalyzed(Standard_True);
|
|
Angle = TestCouple.Angle();
|
|
return Standard_True;
|
|
}
|
|
}
|
|
}
|
|
return Standard_False;
|
|
}
|
|
//=======================================================================
|
|
//function : CheckCoupleAndGetAngle2
|
|
//purpose :
|
|
//=======================================================================
|
|
Standard_Boolean CheckCoupleAndGetAngle2(const Standard_Integer T1,
|
|
const Standard_Integer T2,
|
|
const Standard_Integer T11,
|
|
const Standard_Integer T22,
|
|
IntPolyh_ListIteratorOfListOfCouples& theItCT11,
|
|
IntPolyh_ListIteratorOfListOfCouples& theItCT22,
|
|
Standard_Real & Angle,
|
|
IntPolyh_ListOfCouples &TTrianglesContacts)
|
|
{
|
|
///couple T1 T2 is found in the list
|
|
///T11 and T22 are two other triangles implied in the contact edge edge
|
|
/// CT11 couple( T1,T22) and CT22 couple (T2,T11)
|
|
/// these couples will be marked if there is a start point
|
|
Standard_Boolean Test1 , Test2, Test3;
|
|
Test1 = Test2 = Test3 = Standard_False;
|
|
//
|
|
IntPolyh_ListIteratorOfListOfCouples aIt(TTrianglesContacts);
|
|
for (; aIt.More(); aIt.Next()) {
|
|
IntPolyh_Couple& TestCouple = aIt.ChangeValue();
|
|
if (TestCouple.IsAnalyzed()) {
|
|
continue;
|
|
}
|
|
//
|
|
if (TestCouple.FirstValue() == T1) {
|
|
if (TestCouple.SecondValue() == T2) {
|
|
Test1 = Standard_True;
|
|
TestCouple.SetAnalyzed(Standard_True);
|
|
Angle = TestCouple.Angle();
|
|
}
|
|
else if (TestCouple.SecondValue() == T22) {
|
|
Test2 = Standard_True;
|
|
theItCT11 = aIt;
|
|
Angle = TestCouple.Angle();
|
|
}
|
|
}
|
|
else if (TestCouple.FirstValue() == T11) {
|
|
if (TestCouple.SecondValue() == T2) {
|
|
Test3 = Standard_True;
|
|
theItCT22 = aIt;
|
|
Angle = TestCouple.Angle();
|
|
}
|
|
}
|
|
//
|
|
if (Test1 && Test2 && Test3) {
|
|
break;
|
|
}
|
|
}
|
|
return Test1;
|
|
}
|
|
//=======================================================================
|
|
//function : CheckNextStartPoint
|
|
//purpose : it is checked if the point is not a top
|
|
// then it is stored in one or several valid arrays with
|
|
// the proper list number
|
|
//=======================================================================
|
|
Standard_Integer CheckNextStartPoint(IntPolyh_SectionLine & SectionLine,
|
|
IntPolyh_ArrayOfTangentZones & TTangentZones,
|
|
IntPolyh_StartPoint & SP,
|
|
const Standard_Boolean Prepend)//=Standard_False)
|
|
{
|
|
Standard_Integer Test=1;
|
|
if( (SP.E1()==-1)||(SP.E2()==-1) ) {
|
|
//The tops of triangle are analyzed
|
|
//It is checked if they are not in the array TTangentZones
|
|
Standard_Integer FinTTZ=TTangentZones.NbItems();
|
|
for(Standard_Integer uiui=0; uiui<FinTTZ; uiui++) {
|
|
IntPolyh_StartPoint TestSP=TTangentZones[uiui];
|
|
if ( (Abs(SP.U1()-TestSP.U1())<MyConfusionPrecision)
|
|
&&(Abs(SP.V1()-TestSP.V1())<MyConfusionPrecision) ) {
|
|
if ( (Abs(SP.U2()-TestSP.U2())<MyConfusionPrecision)
|
|
&&(Abs(SP.V2()-TestSP.V2())<MyConfusionPrecision) ) {
|
|
Test=0;//SP is already in the list of tops
|
|
uiui=FinTTZ;
|
|
}
|
|
}
|
|
}
|
|
if (Test) {//the top does not belong to the list of TangentZones
|
|
SP.SetChainList(-1);
|
|
TTangentZones[FinTTZ]=SP;
|
|
TTangentZones.IncrementNbItems();
|
|
Test=0;//the examined point is a top
|
|
}
|
|
}
|
|
else if (Test) {
|
|
if (Prepend)
|
|
SectionLine.Prepend(SP);
|
|
else {
|
|
SectionLine[SectionLine.NbStartPoints()]=SP;
|
|
SectionLine.IncrementNbStartPoints();
|
|
}
|
|
|
|
}
|
|
//if the point is not a top Test=1
|
|
//The chain is continued
|
|
return(Test);
|
|
}
|
|
//=======================================================================
|
|
//function : StartPointsChain
|
|
//purpose : Loop on the array of couples. Compute StartPoints.
|
|
// Try to chain the StartPoints into SectionLines or
|
|
// put the point in the ArrayOfTangentZones if
|
|
// chaining it, is not possible.
|
|
//=======================================================================
|
|
Standard_Integer IntPolyh_MaillageAffinage::StartPointsChain
|
|
(IntPolyh_ArrayOfSectionLines& TSectionLines,
|
|
IntPolyh_ArrayOfTangentZones& TTangentZones)
|
|
{
|
|
//Loop on the array of couples filled in the function COMPARE()
|
|
IntPolyh_ListIteratorOfListOfCouples aIt(TTrianglesContacts);
|
|
for (; aIt.More(); aIt.Next()) {
|
|
IntPolyh_Couple& aCouple = aIt.ChangeValue();
|
|
// Check if the couple of triangles has not been already examined.
|
|
if(!aCouple.IsAnalyzed()) {
|
|
|
|
Standard_Integer SectionLineIndex=TSectionLines.NbItems();
|
|
// fill last section line if still empty (eap)
|
|
if (SectionLineIndex > 0
|
|
&&
|
|
TSectionLines[SectionLineIndex-1].NbStartPoints() == 0)
|
|
SectionLineIndex -= 1;
|
|
else
|
|
TSectionLines.IncrementNbItems();
|
|
|
|
IntPolyh_SectionLine & MySectionLine=TSectionLines[SectionLineIndex];
|
|
if (MySectionLine.GetN() == 0) // eap
|
|
MySectionLine.Init(10000);//Initialisation of array of StartPoint
|
|
|
|
Standard_Integer NbPoints=-1;
|
|
Standard_Integer T1I, T2I;
|
|
T1I = aCouple.FirstValue();
|
|
T2I = aCouple.SecondValue();
|
|
|
|
// Start points for the current couple are found
|
|
IntPolyh_StartPoint SP1, SP2;
|
|
NbPoints=StartingPointsResearch(T1I,T2I,SP1, SP2);//first calculation
|
|
aCouple.SetAnalyzed(Standard_True);//the couple is marked
|
|
|
|
if(NbPoints==1) {// particular case top/triangle or edge/edge
|
|
//the start point is input in the array
|
|
SP1.SetChainList(SectionLineIndex);
|
|
SP1.SetAngle(aCouple.Angle());
|
|
//it is checked if the point is not atop of the triangle
|
|
if(CheckNextStartPoint(MySectionLine,TTangentZones,SP1)) {
|
|
IntPolyh_StartPoint SPNext1;
|
|
Standard_Integer TestSP1=0;
|
|
|
|
//chain of a side
|
|
IntPolyh_StartPoint SP11;//=SP1;
|
|
if(SP1.E1()>=0) { //&&(SP1.E2()!=-1) already tested if the point is not a top
|
|
Standard_Integer NextTriangle1=0;
|
|
if (TEdges1[SP1.E1()].FirstTriangle()!=T1I) NextTriangle1=TEdges1[SP1.E1()].FirstTriangle();
|
|
else NextTriangle1=TEdges1[SP1.E1()].SecondTriangle();
|
|
|
|
Standard_Real Angle=-2.0;
|
|
if (CheckCoupleAndGetAngle(NextTriangle1,T2I,Angle,TTrianglesContacts)) {
|
|
//it is checked if the couple exists and is marked
|
|
Standard_Integer NbPoints11=0;
|
|
NbPoints11=NextStartingPointsResearch(NextTriangle1,T2I,SP1,SP11);
|
|
if (NbPoints11==1) {
|
|
SP11.SetChainList(SectionLineIndex);
|
|
SP11.SetAngle(Angle);
|
|
|
|
if(CheckNextStartPoint(MySectionLine,TTangentZones,SP11)) {
|
|
Standard_Integer EndChainList=1;
|
|
while (EndChainList!=0) {
|
|
TestSP1=GetNextChainStartPoint(SP11,SPNext1,MySectionLine,TTangentZones);
|
|
if(TestSP1==1) {
|
|
SPNext1.SetChainList(SectionLineIndex);
|
|
if(CheckNextStartPoint(MySectionLine,TTangentZones,SPNext1))
|
|
SP11=SPNext1;
|
|
else EndChainList=0;
|
|
}
|
|
else EndChainList=0; //There is no next point
|
|
}
|
|
}
|
|
|
|
}
|
|
else {
|
|
if(NbPoints11>1) {//The point is input in the array TTangentZones
|
|
TTangentZones[TTangentZones.NbItems()]=SP11;//default list number = -1
|
|
TTangentZones.IncrementNbItems();
|
|
}
|
|
else {
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (SP1.E2()<0){
|
|
|
|
}
|
|
//chain of the other side
|
|
IntPolyh_StartPoint SP12;//=SP1;
|
|
if (SP1.E2()>=0) { //&&(SP1.E1()!=-1) already tested
|
|
Standard_Integer NextTriangle2;
|
|
if (TEdges2[SP1.E2()].FirstTriangle()!=T2I) NextTriangle2=TEdges2[SP1.E2()].FirstTriangle();
|
|
else NextTriangle2=TEdges2[SP1.E2()].SecondTriangle();
|
|
|
|
Standard_Real Angle=-2.0;
|
|
if(CheckCoupleAndGetAngle(T1I,NextTriangle2,Angle,TTrianglesContacts)) {
|
|
Standard_Integer NbPoints12=0;
|
|
NbPoints12=NextStartingPointsResearch(T1I,NextTriangle2,SP1, SP12);
|
|
if (NbPoints12==1) {
|
|
|
|
SP12.SetChainList(SectionLineIndex);
|
|
SP12.SetAngle(Angle);
|
|
Standard_Boolean Prepend = Standard_True; // eap
|
|
|
|
if(CheckNextStartPoint(MySectionLine,TTangentZones,SP12, Prepend)) {
|
|
Standard_Integer EndChainList=1;
|
|
while (EndChainList!=0) {
|
|
TestSP1=GetNextChainStartPoint(SP12,SPNext1,
|
|
MySectionLine,TTangentZones,
|
|
Prepend); // eap
|
|
if(TestSP1==1) {
|
|
SPNext1.SetChainList(SectionLineIndex);
|
|
if(CheckNextStartPoint(MySectionLine,TTangentZones,SPNext1,Prepend))
|
|
SP12=SPNext1;
|
|
else EndChainList=0;
|
|
}
|
|
else EndChainList=0; //there is no next point
|
|
}
|
|
}
|
|
|
|
else {
|
|
if(NbPoints12>1) {//The points are input in the array TTangentZones
|
|
TTangentZones[TTangentZones.NbItems()]=SP12;//default list number = -1
|
|
TTangentZones.IncrementNbItems();
|
|
}
|
|
else {
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if(SP1.E1()<0){
|
|
|
|
}
|
|
}
|
|
}
|
|
else if(NbPoints==2) {
|
|
//the start points are input in the array
|
|
IntPolyh_StartPoint SPNext2;
|
|
Standard_Integer TestSP2=0;
|
|
Standard_Integer EndChainList=1;
|
|
|
|
SP1.SetChainList(SectionLineIndex);
|
|
SP1.SetAngle(aCouple.Angle());
|
|
if(CheckNextStartPoint(MySectionLine,TTangentZones,SP1)) {
|
|
|
|
//chain of a side
|
|
while (EndChainList!=0) {
|
|
TestSP2=GetNextChainStartPoint(SP1,SPNext2,MySectionLine,TTangentZones);
|
|
if(TestSP2==1) {
|
|
SPNext2.SetChainList(SectionLineIndex);
|
|
if(CheckNextStartPoint(MySectionLine,TTangentZones,SPNext2))
|
|
SP1=SPNext2;
|
|
else EndChainList=0;
|
|
}
|
|
else EndChainList=0; //there is no next point
|
|
}
|
|
}
|
|
|
|
SP2.SetChainList(SectionLineIndex);
|
|
SP2.SetAngle(aCouple.Angle());
|
|
Standard_Boolean Prepend = Standard_True; // eap
|
|
|
|
if(CheckNextStartPoint(MySectionLine,TTangentZones,SP2,Prepend)) {
|
|
|
|
//chain of the other side
|
|
EndChainList=1;
|
|
while (EndChainList!=0) {
|
|
TestSP2=GetNextChainStartPoint(SP2,SPNext2,
|
|
MySectionLine,TTangentZones,
|
|
Prepend); // eap
|
|
if(TestSP2==1) {
|
|
SPNext2.SetChainList(SectionLineIndex);
|
|
if(CheckNextStartPoint(MySectionLine,TTangentZones,SPNext2,Prepend))
|
|
SP2=SPNext2;
|
|
else EndChainList=0;
|
|
}
|
|
else EndChainList=0; //there is no next point
|
|
}
|
|
}
|
|
}
|
|
|
|
else if( (NbPoints>2)&&(NbPoints<7) ) {
|
|
//More than two start points
|
|
//the start point is input in the table
|
|
SP1.SetChainList(SectionLineIndex);
|
|
CheckNextStartPoint(MySectionLine,TTangentZones,SP1);
|
|
}
|
|
|
|
else {
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
return(1);
|
|
}
|
|
//=======================================================================
|
|
//function : GetNextChainStartPoint
|
|
//purpose : Mainly used by StartPointsChain(), this function
|
|
// try to compute the next StartPoint.
|
|
// GetNextChainStartPoint is used only if it is known that there are 2 contact points
|
|
//=======================================================================
|
|
Standard_Integer IntPolyh_MaillageAffinage::GetNextChainStartPoint
|
|
(const IntPolyh_StartPoint & SP,
|
|
IntPolyh_StartPoint & SPNext,
|
|
IntPolyh_SectionLine & MySectionLine,
|
|
IntPolyh_ArrayOfTangentZones & TTangentZones,
|
|
const Standard_Boolean Prepend)
|
|
{
|
|
Standard_Integer NbPoints=0;
|
|
if( (SP.E1()>=0)&&(SP.E2()==-2) ) {
|
|
//case if the point is on edge of T1
|
|
Standard_Integer NextTriangle1;
|
|
if (TEdges1[SP.E1()].FirstTriangle()!=SP.T1()) NextTriangle1=TEdges1[SP.E1()].FirstTriangle();
|
|
else
|
|
NextTriangle1=TEdges1[SP.E1()].SecondTriangle();
|
|
//If is checked if two triangles intersect
|
|
Standard_Real Angle= -2.0;
|
|
if (CheckCoupleAndGetAngle(NextTriangle1,SP.T2(),Angle,TTrianglesContacts)) {
|
|
NbPoints=NextStartingPointsResearch(NextTriangle1,SP.T2(),SP,SPNext);
|
|
if( NbPoints!=1 ) {
|
|
if (NbPoints>1)
|
|
CheckNextStartPoint(MySectionLine,TTangentZones,SPNext,Prepend);
|
|
else {
|
|
|
|
NbPoints=0;
|
|
}
|
|
}
|
|
else
|
|
SPNext.SetAngle(Angle);
|
|
}
|
|
else NbPoints=0;//this couple does not intersect
|
|
}
|
|
else if( (SP.E1()==-2)&&(SP.E2()>=0) ) {
|
|
//case if the point is on edge of T2
|
|
Standard_Integer NextTriangle2;
|
|
if (TEdges2[SP.E2()].FirstTriangle()!=SP.T2()) NextTriangle2=TEdges2[SP.E2()].FirstTriangle();
|
|
else
|
|
NextTriangle2=TEdges2[SP.E2()].SecondTriangle();
|
|
Standard_Real Angle= -2.0;
|
|
if (CheckCoupleAndGetAngle(SP.T1(),NextTriangle2,Angle,TTrianglesContacts)) {
|
|
NbPoints=NextStartingPointsResearch(SP.T1(),NextTriangle2,SP,SPNext);
|
|
if( NbPoints!=1 ) {
|
|
if (NbPoints>1)
|
|
CheckNextStartPoint(MySectionLine,TTangentZones,SPNext,Prepend);
|
|
else {
|
|
|
|
NbPoints=0;
|
|
}
|
|
}
|
|
else
|
|
SPNext.SetAngle(Angle);
|
|
}
|
|
else NbPoints=0;
|
|
}
|
|
else if( (SP.E1()==-2)&&(SP.E2()==-2) ) {
|
|
///no edge is touched or cut
|
|
|
|
NbPoints=0;
|
|
}
|
|
else if( (SP.E1()>=0)&&(SP.E2()>=0) ) {
|
|
///the point is located on two edges
|
|
Standard_Integer NextTriangle1;
|
|
if (TEdges1[SP.E1()].FirstTriangle()!=SP.T1()) NextTriangle1=TEdges1[SP.E1()].FirstTriangle();
|
|
else
|
|
NextTriangle1=TEdges1[SP.E1()].SecondTriangle();
|
|
Standard_Integer NextTriangle2;
|
|
if (TEdges2[SP.E2()].FirstTriangle()!=SP.T2()) NextTriangle2=TEdges2[SP.E2()].FirstTriangle();
|
|
else
|
|
NextTriangle2=TEdges2[SP.E2()].SecondTriangle();
|
|
Standard_Real Angle= -2.0;
|
|
|
|
IntPolyh_ListIteratorOfListOfCouples aItCT11, aItCT22;
|
|
if (CheckCoupleAndGetAngle2(NextTriangle1,NextTriangle2,
|
|
SP.T1(),SP.T2(), aItCT11, aItCT22,
|
|
Angle,TTrianglesContacts)) {
|
|
NbPoints=NextStartingPointsResearch(NextTriangle1,NextTriangle2,SP,SPNext);
|
|
if( NbPoints!=1 ) {
|
|
if (NbPoints>1) {
|
|
///The new point is checked
|
|
if(CheckNextStartPoint(MySectionLine,TTangentZones,SPNext,Prepend)>0) {
|
|
}
|
|
else {
|
|
|
|
}
|
|
}
|
|
NbPoints=0;
|
|
}
|
|
else {//NbPoints==1
|
|
SPNext.SetAngle(Angle);
|
|
if (aItCT11.More()) aItCT11.ChangeValue().SetAnalyzed(Standard_True);
|
|
if (aItCT22.More()) aItCT22.ChangeValue().SetAnalyzed(Standard_True);
|
|
}
|
|
}
|
|
else NbPoints=0;
|
|
}
|
|
else if( (SP.E1()==-1)||(SP.E2()==-1) ) {
|
|
///the points are tops of triangle
|
|
///the point is atored in an intermediary array
|
|
}
|
|
return(NbPoints);
|
|
}
|
|
//=======================================================================
|
|
//function : GetArrayOfPoints
|
|
//purpose :
|
|
//=======================================================================
|
|
const IntPolyh_ArrayOfPoints& IntPolyh_MaillageAffinage::GetArrayOfPoints
|
|
(const Standard_Integer SurfID)const
|
|
{
|
|
if (SurfID==1)
|
|
return(TPoints1);
|
|
return(TPoints2);
|
|
}
|
|
//=======================================================================
|
|
//function : GetArrayOfEdges
|
|
//purpose :
|
|
//=======================================================================
|
|
const IntPolyh_ArrayOfEdges& IntPolyh_MaillageAffinage::GetArrayOfEdges
|
|
(const Standard_Integer SurfID)const
|
|
{
|
|
if (SurfID==1)
|
|
return(TEdges1);
|
|
return(TEdges2);
|
|
}
|
|
//=======================================================================
|
|
//function : GetArrayOfTriangles
|
|
//purpose :
|
|
//=======================================================================
|
|
const IntPolyh_ArrayOfTriangles&
|
|
IntPolyh_MaillageAffinage::GetArrayOfTriangles
|
|
(const Standard_Integer SurfID)const{
|
|
if (SurfID==1)
|
|
return(TTriangles1);
|
|
return(TTriangles2);
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : GetBox
|
|
//purpose :
|
|
//=======================================================================
|
|
Bnd_Box IntPolyh_MaillageAffinage::GetBox(const Standard_Integer SurfID) const
|
|
{
|
|
if (SurfID==1)
|
|
return(MyBox1);
|
|
return(MyBox2);
|
|
}
|
|
//=======================================================================
|
|
//function : GetArrayOfCouples
|
|
//purpose :
|
|
//=======================================================================
|
|
IntPolyh_ListOfCouples &IntPolyh_MaillageAffinage::GetCouples()
|
|
{
|
|
return TTrianglesContacts;
|
|
}
|
|
//=======================================================================
|
|
//function : SetEnlargeZone
|
|
//purpose :
|
|
//=======================================================================
|
|
void IntPolyh_MaillageAffinage::SetEnlargeZone(const Standard_Boolean EnlargeZone)
|
|
{
|
|
myEnlargeZone = EnlargeZone;
|
|
}
|
|
//=======================================================================
|
|
//function : GetEnlargeZone
|
|
//purpose :
|
|
//=======================================================================
|
|
Standard_Boolean IntPolyh_MaillageAffinage::GetEnlargeZone() const
|
|
{
|
|
return myEnlargeZone;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : GetMinDeflection
|
|
//purpose :
|
|
//=======================================================================
|
|
Standard_Real IntPolyh_MaillageAffinage::GetMinDeflection(const Standard_Integer SurfID) const
|
|
{
|
|
return (SurfID==1)? FlecheMin1:FlecheMin2;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : GetMaxDeflection
|
|
//purpose :
|
|
//=======================================================================
|
|
Standard_Real IntPolyh_MaillageAffinage::GetMaxDeflection(const Standard_Integer SurfID) const
|
|
{
|
|
return (SurfID==1)? FlecheMax1:FlecheMax2;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : DegeneratedIndex
|
|
//purpose :
|
|
//=======================================================================
|
|
void DegeneratedIndex(const TColStd_Array1OfReal& aXpars,
|
|
const Standard_Integer aNbX,
|
|
const Handle(Adaptor3d_HSurface)& aS,
|
|
const Standard_Integer aIsoDirection,
|
|
Standard_Integer& aI1,
|
|
Standard_Integer& aI2)
|
|
{
|
|
Standard_Integer i;
|
|
Standard_Boolean bDegX1, bDegX2;
|
|
Standard_Real aDegX1, aDegX2, aTol2, aX;
|
|
//
|
|
aI1=0;
|
|
aI2=0;
|
|
aTol2=MyTolerance*MyTolerance;
|
|
//
|
|
if (aIsoDirection==1){ // V=const
|
|
bDegX1=IsDegenerated(aS, 1, aTol2, aDegX1);
|
|
bDegX2=IsDegenerated(aS, 2, aTol2, aDegX2);
|
|
}
|
|
else if (aIsoDirection==2){ // U=const
|
|
bDegX1=IsDegenerated(aS, 3, aTol2, aDegX1);
|
|
bDegX2=IsDegenerated(aS, 4, aTol2, aDegX2);
|
|
}
|
|
else {
|
|
return;
|
|
}
|
|
//
|
|
if (!(bDegX1 || bDegX2)) {
|
|
return;
|
|
}
|
|
//
|
|
for(i=1; i<=aNbX; ++i) {
|
|
aX=aXpars(i);
|
|
if (bDegX1) {
|
|
if (fabs(aX-aDegX1) < MyTolerance) {
|
|
aI1=i;
|
|
}
|
|
}
|
|
if (bDegX2) {
|
|
if (fabs(aX-aDegX2) < MyTolerance) {
|
|
aI2=i;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//=======================================================================
|
|
//function : IsDegenerated
|
|
//purpose :
|
|
//=======================================================================
|
|
Standard_Boolean IsDegenerated(const Handle(Adaptor3d_HSurface)& aS,
|
|
const Standard_Integer aIndex,
|
|
const Standard_Real aTol2,
|
|
Standard_Real& aDegX)
|
|
{
|
|
Standard_Boolean bRet;
|
|
Standard_Integer i, aNbP;
|
|
Standard_Real aU, dU, aU1, aU2, aV, dV, aV1, aV2, aD2;
|
|
gp_Pnt aP1, aP2;
|
|
//
|
|
bRet=Standard_False;
|
|
aNbP=3;
|
|
aDegX=99;
|
|
//
|
|
aU1=aS->FirstUParameter();
|
|
aU2=aS->LastUParameter();
|
|
aV1=aS->FirstVParameter();
|
|
aV2=aS->LastVParameter();
|
|
//
|
|
if (aIndex<3) { // V=const
|
|
aV=aV1;
|
|
if (aIndex==2) {
|
|
aV=aV2;
|
|
}
|
|
dU=(aU2-aU1)/(aNbP-1);
|
|
aU=aU1;
|
|
aP1=aS->Value(aU, aV);
|
|
for (i=1; i<aNbP; ++i) {
|
|
aU=i*dU;
|
|
if (i==aNbP-1){
|
|
aU=aU2;
|
|
}
|
|
aP2=aS->Value(aU, aV);
|
|
aD2=aP1.SquareDistance(aP2);
|
|
if (aD2>aTol2) {
|
|
return bRet;
|
|
}
|
|
aP1=aP2;
|
|
}
|
|
aDegX=aV;
|
|
bRet=!bRet;
|
|
}
|
|
else {// U=const
|
|
aU=aU1;
|
|
if (aIndex==4) {
|
|
aU=aU2;
|
|
}
|
|
dV=(aV2-aV1)/(aNbP-1);
|
|
aV=aV1;
|
|
aP1=aS->Value(aU, aV);
|
|
for (i=1; i<aNbP; ++i) {
|
|
aV=i*dV;
|
|
if (i==aNbP-1){
|
|
aV=aV2;
|
|
}
|
|
aP2=aS->Value(aU, aV);
|
|
aD2=aP1.SquareDistance(aP2);
|
|
if (aD2>aTol2) {
|
|
return bRet;
|
|
}
|
|
aP1=aP2;
|
|
}
|
|
bRet=!bRet;
|
|
aDegX=aU;
|
|
}
|
|
//
|
|
return bRet;
|
|
}
|