Loading files
3d097a032This file is pinned to the selected release. Download the original to open it in your design tool.
// Created on: 1992-10-13
// Created by: Laurent BUCHARD
// Copyright (c) 1992-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 skv - Tue Mar 1 14:22:09 2005 OCC8169
#ifndef OCCT_DEBUG
#define No_Standard_RangeError
#define No_Standard_OutOfRange
#endif
#include <Standard_ConstructionError.hxx>
#include <IntRes2d_Domain.hxx>
#include <IntRes2d_Position.hxx>
#include <IntRes2d_Transition.hxx>
#include <IntRes2d_IntersectionPoint.hxx>
#include <IntRes2d_IntersectionSegment.hxx>
#include <IntImpParGen.hxx>
#include <Intf_SectionPoint.hxx>
#include <Intf_SectionLine.hxx>
#include <Intf_TangentZone.hxx>
#include <Intf_InterferencePolygon2d.hxx>
#include <gp_Vec2d.hxx>
#include <math_Vector.hxx>
#include <math_FunctionSetRoot.hxx>
#include <math_NewtonFunctionSetRoot.hxx>
#include <NCollection_Handle.hxx>
#include <Bnd_Box2d.hxx>
#include <Precision.hxx>
//======================================================================
#define NBITER_MAX_POLYGON 10
#define TOL_CONF_MINI 0.0000000001
#define TOL_MINI 0.0000000001
//=================================================================================================
void GetIntersection(const TheCurve& theC1,
const double theT1f,
const double theT1l,
const TheCurve& theC2,
const double theT2f,
const double theT2l,
const double theTolConf,
const int theMaxCount,
IntRes2d_IntersectionPoint& thePInt,
double& theDist,
int& theCount);
bool HeadOrEndPoint(const IntRes2d_Domain& D1,
const TheCurve& C1,
const double u,
const IntRes2d_Domain& D2,
const TheCurve& C2,
const double v,
const double TolConf,
IntRes2d_IntersectionPoint& IntPt,
bool& HeadOn1,
bool& HeadOn2,
bool& EndOn1,
bool& EndOn2,
int PosSegment);
//=================================================================================================
IntCurve_IntPolyPolyGen::IntCurve_IntPolyPolyGen()
{
const int aMinPntNb = 20; // Minimum number of samples.
myMinPntNb = aMinPntNb;
done = false;
}
//=================================================================================================
void IntCurve_IntPolyPolyGen::Perform(const TheCurve& C1,
const IntRes2d_Domain& D1,
const TheCurve& C2,
const IntRes2d_Domain& D2,
const double TheTolConf,
const double TheTol)
{
this->ResetFields();
DomainOnCurve1 = D1;
DomainOnCurve2 = D2;
double DU = D1.LastParameter() - D1.FirstParameter();
double DV = D2.LastParameter() - D2.FirstParameter();
double Tl = (TheTol < TOL_MINI) ? TOL_MINI : TheTol;
double TlConf = (TheTolConf < TOL_CONF_MINI) ? TOL_CONF_MINI : TheTolConf;
Perform(C1, D1, C2, D2, TlConf, Tl, 0, DU, DV);
//----------------------------------------------------------------------
//-- Processing of end points
//----------------------------------------------------------------------
bool HeadOn1 = false;
bool HeadOn2 = false;
bool EndOn1 = false;
bool EndOn2 = false;
int i;
int n = this->NbPoints();
//--------------------------------------------------------------------
//-- The points Head Head ... End End are not rejected if
//-- they are already present at the end of segment
//-- ( It is not possible to test the equities on the parameters)
//-- ( these points are not found at EpsX precision )
//-- PosSegment = 1 if Head Head
//-- 2 if Head End
//-- 4 if End Head
//-- 8 if End End
//--------------------------------------------------------------------
int PosSegment = 0;
for (i = 1; i <= n; i++)
{
IntRes2d_Position Pos1 = this->Point(i).TransitionOfFirst().PositionOnCurve();
if (Pos1 == IntRes2d_Head)
HeadOn1 = true;
else if (Pos1 == IntRes2d_End)
EndOn1 = true;
IntRes2d_Position Pos2 = this->Point(i).TransitionOfSecond().PositionOnCurve();
if (Pos2 == IntRes2d_Head)
HeadOn2 = true;
else if (Pos2 == IntRes2d_End)
EndOn2 = true;
if (Pos1 == IntRes2d_Head)
{
if (Pos2 == IntRes2d_Head)
PosSegment |= 1;
else if (Pos2 == IntRes2d_End)
PosSegment |= 2;
}
else if (Pos1 == IntRes2d_End)
{
if (Pos2 == IntRes2d_Head)
PosSegment |= 4;
else if (Pos2 == IntRes2d_End)
PosSegment |= 8;
}
}
n = this->NbSegments();
for (i = 1; i <= n; i++)
{
IntRes2d_Position Pos1 = this->Segment(i).FirstPoint().TransitionOfFirst().PositionOnCurve();
if (Pos1 == IntRes2d_Head)
HeadOn1 = true;
else if (Pos1 == IntRes2d_End)
EndOn1 = true;
IntRes2d_Position Pos2 = this->Segment(i).FirstPoint().TransitionOfSecond().PositionOnCurve();
if (Pos2 == IntRes2d_Head)
HeadOn2 = true;
else if (Pos2 == IntRes2d_End)
EndOn2 = true;
if (Pos1 == IntRes2d_Head)
{
if (Pos2 == IntRes2d_Head)
PosSegment |= 1;
else if (Pos2 == IntRes2d_End)
PosSegment |= 2;
}
else if (Pos1 == IntRes2d_End)
{
if (Pos2 == IntRes2d_Head)
PosSegment |= 4;
else if (Pos2 == IntRes2d_End)
PosSegment |= 8;
}
Pos1 = this->Segment(i).LastPoint().TransitionOfFirst().PositionOnCurve();
if (Pos1 == IntRes2d_Head)
HeadOn1 = true;
else if (Pos1 == IntRes2d_End)
EndOn1 = true;
Pos2 = this->Segment(i).LastPoint().TransitionOfSecond().PositionOnCurve();
if (Pos2 == IntRes2d_Head)
HeadOn2 = true;
else if (Pos2 == IntRes2d_End)
EndOn2 = true;
if (Pos1 == IntRes2d_Head)
{
if (Pos2 == IntRes2d_Head)
PosSegment |= 1;
else if (Pos2 == IntRes2d_End)
PosSegment |= 2;
}
else if (Pos1 == IntRes2d_End)
{
if (Pos2 == IntRes2d_Head)
PosSegment |= 4;
else if (Pos2 == IntRes2d_End)
PosSegment |= 8;
}
}
double U0 = D1.FirstParameter();
double U1 = D1.LastParameter();
double V0 = D2.FirstParameter();
double V1 = D2.LastParameter();
IntRes2d_IntersectionPoint IntPt;
if (D1.FirstTolerance() || D2.FirstTolerance())
{
if (HeadOrEndPoint(D1,
C1,
U0,
D2,
C2,
V0,
TheTolConf,
IntPt,
HeadOn1,
HeadOn2,
EndOn1,
EndOn2,
PosSegment))
this->Insert(IntPt);
}
if (D1.FirstTolerance() || D2.LastTolerance())
{
if (HeadOrEndPoint(D1,
C1,
U0,
D2,
C2,
V1,
TheTolConf,
IntPt,
HeadOn1,
HeadOn2,
EndOn1,
EndOn2,
PosSegment))
this->Insert(IntPt);
}
if (D1.LastTolerance() || D2.FirstTolerance())
{
if (HeadOrEndPoint(D1,
C1,
U1,
D2,
C2,
V0,
TheTolConf,
IntPt,
HeadOn1,
HeadOn2,
EndOn1,
EndOn2,
PosSegment))
this->Insert(IntPt);
}
if (D1.LastTolerance() || D2.LastTolerance())
{
if (HeadOrEndPoint(D1,
C1,
U1,
D2,
C2,
V1,
TheTolConf,
IntPt,
HeadOn1,
HeadOn2,
EndOn1,
EndOn2,
PosSegment))
this->Insert(IntPt);
}
}
//======================================================================
//== A u t o I n t e r s e c t i o n
//======================================================================
void IntCurve_IntPolyPolyGen::Perform(const TheCurve& C1,
const IntRes2d_Domain& D1,
const double TheTolConf,
const double TheTol)
{
this->ResetFields();
DomainOnCurve1 = D1;
DomainOnCurve2 = D1;
double DU = D1.LastParameter() - D1.FirstParameter();
double Tl = (TheTol < TOL_MINI) ? TOL_MINI : TheTol;
double TlConf = (TheTolConf < TOL_CONF_MINI) ? TOL_CONF_MINI : TheTolConf;
Perform(C1, D1, TlConf, Tl, 0, DU, DU);
int i;
int n = this->NbPoints();
//--------------------------------------------------------------------
//-- The points Head Head ... End End are not rejected if
//-- they are already present at the end of segment
//-- ( It is not possible to test the equities on the parameters)
//-- ( these points are not found at EpsX precision )
//-- PosSegment = 1 if Head Head
//-- 2 if Head End
//-- 4 if End Head
//-- 8 if End End
//--------------------------------------------------------------------
int PosSegment = 0;
for (i = 1; i <= n; i++)
{
IntRes2d_Position Pos1 = this->Point(i).TransitionOfFirst().PositionOnCurve();
IntRes2d_Position Pos2 = this->Point(i).TransitionOfSecond().PositionOnCurve();
if (Pos1 == IntRes2d_Head)
{
if (Pos2 == IntRes2d_Head)
PosSegment |= 1;
else if (Pos2 == IntRes2d_End)
PosSegment |= 2;
}
else if (Pos1 == IntRes2d_End)
{
if (Pos2 == IntRes2d_Head)
PosSegment |= 4;
else if (Pos2 == IntRes2d_End)
PosSegment |= 8;
}
}
n = this->NbSegments();
for (i = 1; i <= n; i++)
{
IntRes2d_Position Pos1 = this->Segment(i).FirstPoint().TransitionOfFirst().PositionOnCurve();
IntRes2d_Position Pos2 = this->Segment(i).FirstPoint().TransitionOfSecond().PositionOnCurve();
if (Pos1 == IntRes2d_Head)
{
if (Pos2 == IntRes2d_Head)
PosSegment |= 1;
else if (Pos2 == IntRes2d_End)
PosSegment |= 2;
}
else if (Pos1 == IntRes2d_End)
{
if (Pos2 == IntRes2d_Head)
PosSegment |= 4;
else if (Pos2 == IntRes2d_End)
PosSegment |= 8;
}
Pos1 = this->Segment(i).LastPoint().TransitionOfFirst().PositionOnCurve();
Pos2 = this->Segment(i).LastPoint().TransitionOfSecond().PositionOnCurve();
if (Pos1 == IntRes2d_Head)
{
if (Pos2 == IntRes2d_Head)
PosSegment |= 1;
else if (Pos2 == IntRes2d_End)
PosSegment |= 2;
}
else if (Pos1 == IntRes2d_End)
{
if (Pos2 == IntRes2d_Head)
PosSegment |= 4;
else if (Pos2 == IntRes2d_End)
PosSegment |= 8;
}
}
(void)PosSegment;
}
//======================================================================
void IntCurve_IntPolyPolyGen::Perform(const TheCurve& C1,
const IntRes2d_Domain& D1,
const double TolConf,
const double Tol,
const int NbIter,
const double /*DeltaU*/
,
const double)
{
gp_Vec2d Tan1, Tan2, Norm1, Norm2;
gp_Pnt2d P1, P2;
int nbsamples;
done = false;
nbsamples = TheCurveTool::NbSamples(C1, D1.FirstParameter(), D1.LastParameter());
if (NbIter > 3 || (NbIter > 2 && nbsamples > 100))
return;
nbsamples *= 2; //--- We take systematically two times more points
//-- than on a normal curve.
//-- Auto-intersecting curves often produce
//-- polygons rather far from the curve with parameter ct.
if (NbIter > 0)
{
nbsamples = (3 * (nbsamples * NbIter)) / 2;
}
IntCurve_ThePolygon2d Poly1(C1, nbsamples, D1, Tol);
if (!Poly1.AutoIntersectionIsPossible())
{
done = true;
return;
}
//-- Poly1.Dump();
//----------------------------------------------------------------------
//-- If the deflection is less than the Tolerance of Confusion
//-- then the deflection of the polygon is set in TolConf
//-- (Detection of Tangency Zones)
//----------------------------------------------------------------------
if (Poly1.DeflectionOverEstimation() < TolConf)
{
Poly1.SetDeflectionOverEstimation(TolConf);
}
Intf_InterferencePolygon2d InterPP(Poly1);
IntCurve_ExactIntersectionPoint EIP(C1, C1, TolConf);
double U, V;
//----------------------------------------------------------------------
//-- Processing of SectionPoint
//----------------------------------------------------------------------
int Nbsp = InterPP.NbSectionPoints();
if (Nbsp >= 1)
{
//-- ---------------------------------------------------------------------
//-- filtering, filtering, filtering ...
//--
int* TriIndex = new int[Nbsp + 1];
int* PtrSegIndex1 = new int[Nbsp + 1];
int* PtrSegIndex2 = new int[Nbsp + 1];
bool Triok;
int SegIndex1, SegIndex2, SegIndex_1, SegIndex_2;
// double ParamOn1,ParamOn2,ParamOn_1,ParamOn_2;
double ParamOn1, ParamOn2;
Intf_PIType Type;
int i;
for (i = 1; i <= Nbsp; i++)
{
TriIndex[i] = i;
const Intf_SectionPoint& SPnt1 = InterPP.PntValue(i);
SPnt1.InfoFirst(Type, PtrSegIndex1[i], ParamOn1);
SPnt1.InfoSecond(Type, PtrSegIndex2[i], ParamOn2);
}
do
{
Triok = true;
for (int tr = 1; tr < Nbsp; tr++)
{
SegIndex1 = PtrSegIndex1[TriIndex[tr]];
SegIndex_1 = PtrSegIndex1[TriIndex[tr + 1]];
SegIndex2 = PtrSegIndex2[TriIndex[tr]];
SegIndex_2 = PtrSegIndex2[TriIndex[tr + 1]];
if (SegIndex1 > SegIndex_1)
{
int q = TriIndex[tr];
TriIndex[tr] = TriIndex[tr + 1];
TriIndex[tr + 1] = q;
Triok = false;
}
else if (SegIndex1 == SegIndex_1)
{
if (SegIndex2 > SegIndex_2)
{
int q = TriIndex[tr];
TriIndex[tr] = TriIndex[tr + 1];
TriIndex[tr + 1] = q;
Triok = false;
}
}
}
} while (Triok == false);
//-- supression des doublons Si Si !
for (i = 1; i < Nbsp; i++)
{
if ((PtrSegIndex1[TriIndex[i]] == PtrSegIndex1[TriIndex[i + 1]])
&& (PtrSegIndex2[TriIndex[i]] == PtrSegIndex2[TriIndex[i + 1]]))
{
TriIndex[i] = -i;
}
}
for (int sp = 1; sp <= Nbsp; sp++)
{
if (TriIndex[sp] > 0)
{
const Intf_SectionPoint& SPnt = InterPP.PntValue(TriIndex[sp]);
SPnt.InfoFirst(Type, SegIndex1, ParamOn1);
SPnt.InfoSecond(Type, SegIndex2, ParamOn2);
if (std::abs(SegIndex1 - SegIndex2) > 1)
{
EIP.Perform(Poly1, Poly1, SegIndex1, SegIndex2, ParamOn1, ParamOn2);
if (EIP.NbRoots() >= 1)
{
//--------------------------------------------------------------------
//-- It is checked if the found point is a root
//--------------------------------------------------------------------
EIP.Roots(U, V);
TheCurveTool::D1(C1, U, P1, Tan1);
TheCurveTool::D1(C1, V, P2, Tan2);
double Dist = P1.Distance(P2);
double EpsX1 = 10.0 * TheCurveTool::EpsX(C1);
if (std::abs(U - V) <= EpsX1)
{
//-----------------------------------------
//-- Solution not valid
//-- The maths should have converged in a
//-- trivial solution ( point U = V )
//-----------------------------------------
Dist = TolConf + 1.0;
}
//-----------------------------------------------------------------
//-- It is checked if the point (u,v) already exists
//--
done = true;
int nbp = NbPoints();
for (int p = 1; p <= nbp; p++)
{
const IntRes2d_IntersectionPoint& P = Point(p);
if (std::abs(U - P.ParamOnFirst()) <= EpsX1)
{
if (std::abs(V - P.ParamOnSecond()) <= EpsX1)
{
Dist = TolConf + 1.0;
p += nbp;
}
}
}
if (Dist <= TolConf)
{ //-- Or the point is already present
IntRes2d_Position Pos1 = IntRes2d_Middle;
IntRes2d_Position Pos2 = IntRes2d_Middle;
IntRes2d_Transition Trans1, Trans2;
//-----------------------------------------------------------------
//-- Calculate Positions of Points on the curve
//--
if (P1.Distance(DomainOnCurve1.FirstPoint()) <= DomainOnCurve1.FirstTolerance())
Pos1 = IntRes2d_Head;
else if (P1.Distance(DomainOnCurve1.LastPoint()) <= DomainOnCurve1.LastTolerance())
Pos1 = IntRes2d_End;
if (P2.Distance(DomainOnCurve2.FirstPoint()) <= DomainOnCurve2.FirstTolerance())
Pos2 = IntRes2d_Head;
else if (P2.Distance(DomainOnCurve2.LastPoint()) <= DomainOnCurve2.LastTolerance())
Pos2 = IntRes2d_End;
//-----------------------------------------------------------------
if (IntImpParGen::DetermineTransition(Pos1, Tan1, Trans1, Pos2, Tan2, Trans2, TolConf)
== false)
{
TheCurveTool::D2(C1, U, P1, Tan1, Norm1);
TheCurveTool::D2(C1, V, P2, Tan2, Norm2);
IntImpParGen::DetermineTransition(Pos1,
Tan1,
Norm1,
Trans1,
Pos2,
Tan2,
Norm2,
Trans2,
TolConf);
}
IntRes2d_IntersectionPoint IP(P1, U, V, Trans1, Trans2, false);
Insert(IP);
}
}
}
}
}
delete[] TriIndex;
delete[] PtrSegIndex1;
delete[] PtrSegIndex2;
}
//----------------------------------------------------------------------
//-- Processing of TangentZone
//----------------------------------------------------------------------
int Nbtz = InterPP.NbTangentZones();
for (int tz = 1; tz <= Nbtz; tz++)
{
int NbPnts = InterPP.ZoneValue(tz).NumberOfPoints();
//====================================================================
//== Find the first and the last point in the tangency zone.
//====================================================================
double ParamSupOnCurve2, ParamInfOnCurve2;
double ParamSupOnCurve1, ParamInfOnCurve1;
// int SegIndex,SegIndex1onP1,SegIndex1onP2,SegIndex2onP1,SegIndex2onP2;
int SegIndex1onP1, SegIndex1onP2;
Intf_PIType Type;
double ParamOnLine;
double PolyUInf, PolyUSup, PolyVInf, PolyVSup;
ParamSupOnCurve2 = ParamSupOnCurve1 = PolyUSup = PolyVSup = -RealLast();
ParamInfOnCurve2 = ParamInfOnCurve1 = PolyUInf = PolyVInf = RealLast();
for (int qq = 1; qq <= NbPnts; qq++)
{
const Intf_SectionPoint& SPnt1 = InterPP.ZoneValue(tz).GetPoint(qq);
//====================================================================
//== The zones of tangency are discretized
//== Test of stop : Check if
//== (Deflection < Tolerance)
//== Or (Sample < EpsX) (normally the first condition is
//== more strict)
//====================================================================
// double _PolyUInf,_PolyUSup,_PolyVInf,_PolyVSup;
double _PolyUInf, _PolyVInf;
SPnt1.InfoFirst(Type, SegIndex1onP1, ParamOnLine);
if (SegIndex1onP1 > Poly1.NbSegments())
{
SegIndex1onP1--;
ParamOnLine = 1.0;
}
if (SegIndex1onP1 <= 0)
{
SegIndex1onP1 = 1;
ParamOnLine = 0.0;
}
_PolyUInf = Poly1.ApproxParamOnCurve(SegIndex1onP1, ParamOnLine);
SPnt1.InfoSecond(Type, SegIndex1onP2, ParamOnLine);
if (SegIndex1onP2 > Poly1.NbSegments())
{
SegIndex1onP2--;
ParamOnLine = 1.0;
}
if (SegIndex1onP2 <= 0)
{
SegIndex1onP2 = 1;
ParamOnLine = 0.0;
}
_PolyVInf = Poly1.ApproxParamOnCurve(SegIndex1onP2, ParamOnLine);
//----------------------------------------------------------------------
if (ParamInfOnCurve1 > _PolyUInf)
ParamInfOnCurve1 = _PolyUInf;
if (ParamInfOnCurve2 > _PolyVInf)
ParamInfOnCurve2 = _PolyVInf;
if (ParamSupOnCurve1 < _PolyUInf)
ParamSupOnCurve1 = _PolyUInf;
if (ParamSupOnCurve2 < _PolyVInf)
ParamSupOnCurve2 = _PolyVInf;
}
PolyUInf = ParamInfOnCurve1;
PolyUSup = ParamSupOnCurve1;
PolyVInf = ParamInfOnCurve2;
PolyVSup = ParamSupOnCurve2;
TheCurveTool::D0(C1, PolyUInf, P1);
TheCurveTool::D0(C1, PolyVInf, P2);
double distmemesens = P1.SquareDistance(P2);
TheCurveTool::D0(C1, PolyVSup, P2);
double distdiffsens = P1.SquareDistance(P2);
if (distmemesens > distdiffsens)
{
double qwerty = PolyVInf;
PolyVInf = PolyVSup;
PolyVSup = qwerty;
}
//-----------------------------------------------------------------
//-- Calculate Positions of Points on the curve and
//-- Transitions on each limit of the segment
IntRes2d_Position Pos1 = IntRes2d_Middle;
IntRes2d_Position Pos2 = IntRes2d_Middle;
IntRes2d_Transition Trans1, Trans2;
TheCurveTool::D1(C1, PolyUInf, P1, Tan1);
TheCurveTool::D1(C1, PolyVInf, P2, Tan2);
if (P1.Distance(DomainOnCurve1.FirstPoint()) <= DomainOnCurve1.FirstTolerance())
{
Pos1 = IntRes2d_Head;
}
else if (P1.Distance(DomainOnCurve1.LastPoint()) <= DomainOnCurve1.LastTolerance())
{
Pos1 = IntRes2d_End;
}
if (P2.Distance(DomainOnCurve2.FirstPoint()) <= DomainOnCurve2.FirstTolerance())
{
Pos2 = IntRes2d_Head;
}
else if (P2.Distance(DomainOnCurve2.LastPoint()) <= DomainOnCurve2.LastTolerance())
{
Pos2 = IntRes2d_End;
}
if (Pos1 == IntRes2d_Middle && Pos2 != IntRes2d_Middle)
{
PolyUInf = TheProjPCur::FindParameter(C1,
P2,
D1.FirstParameter(),
D1.LastParameter(),
TheCurveTool::EpsX(C1));
}
else if (Pos1 != IntRes2d_Middle && Pos2 == IntRes2d_Middle)
{
PolyVInf = TheProjPCur::FindParameter(C1,
P1,
D1.FirstParameter(),
D1.LastParameter(),
TheCurveTool::EpsX(C1));
}
else if (std::abs(ParamInfOnCurve1 - ParamSupOnCurve1)
> std::abs(ParamInfOnCurve2 - ParamSupOnCurve2))
{
PolyVInf = TheProjPCur::FindParameter(C1,
P1,
D1.FirstParameter(),
D1.LastParameter(),
TheCurveTool::EpsX(C1));
}
else
{
PolyUInf = TheProjPCur::FindParameter(C1,
P2,
D1.FirstParameter(),
D1.LastParameter(),
TheCurveTool::EpsX(C1));
}
if (IntImpParGen::DetermineTransition(Pos1, Tan1, Trans1, Pos2, Tan2, Trans2, TolConf) == false)
{
TheCurveTool::D2(C1, PolyUInf, P1, Tan1, Norm1);
TheCurveTool::D2(C1, PolyVInf, P2, Tan2, Norm2);
IntImpParGen::DetermineTransition(Pos1,
Tan1,
Norm1,
Trans1,
Pos2,
Tan2,
Norm2,
Trans2,
TolConf);
}
IntRes2d_IntersectionPoint PtSeg1(P1, PolyUInf, PolyVInf, Trans1, Trans2, false);
//----------------------------------------------------------------------
if ((std::abs(PolyUInf - PolyUSup) <= TheCurveTool::EpsX(C1))
|| (std::abs(PolyVInf - PolyVSup) <= TheCurveTool::EpsX(C1)))
{
// bad segment
}
else
{
TheCurveTool::D1(C1, PolyUSup, P1, Tan1);
TheCurveTool::D1(C1, PolyVSup, P2, Tan2);
Pos1 = IntRes2d_Middle;
Pos2 = IntRes2d_Middle;
if (P1.Distance(DomainOnCurve1.FirstPoint()) <= DomainOnCurve1.FirstTolerance())
{
Pos1 = IntRes2d_Head;
}
else if (P1.Distance(DomainOnCurve1.LastPoint()) <= DomainOnCurve1.LastTolerance())
{
Pos1 = IntRes2d_End;
}
if (P2.Distance(DomainOnCurve2.FirstPoint()) <= DomainOnCurve2.FirstTolerance())
{
Pos2 = IntRes2d_Head;
}
else if (P2.Distance(DomainOnCurve2.LastPoint()) <= DomainOnCurve2.LastTolerance())
{
Pos2 = IntRes2d_End;
}
if (Pos1 == IntRes2d_Middle && Pos2 != IntRes2d_Middle)
{
PolyUSup = TheProjPCur::FindParameter(C1,
P2,
D1.FirstParameter(),
D1.LastParameter(),
TheCurveTool::EpsX(C1));
}
else if (Pos1 != IntRes2d_Middle && Pos2 == IntRes2d_Middle)
{
PolyVSup = TheProjPCur::FindParameter(C1,
P1,
D1.FirstParameter(),
D1.LastParameter(),
TheCurveTool::EpsX(C1));
}
else if (std::abs(ParamInfOnCurve1 - ParamSupOnCurve1)
> std::abs(ParamInfOnCurve2 - ParamSupOnCurve2))
{
PolyVSup = TheProjPCur::FindParameter(C1,
P1,
D1.FirstParameter(),
D1.LastParameter(),
TheCurveTool::EpsX(C1));
}
else
{
PolyUSup = TheProjPCur::FindParameter(C1,
P2,
D1.FirstParameter(),
D1.LastParameter(),
TheCurveTool::EpsX(C1));
}
if (IntImpParGen::DetermineTransition(Pos1, Tan1, Trans1, Pos2, Tan2, Trans2, TolConf)
== false)
{
TheCurveTool::D2(C1, PolyUSup, P1, Tan1, Norm1);
TheCurveTool::D2(C1, PolyVSup, P2, Tan2, Norm2);
IntImpParGen::DetermineTransition(Pos1,
Tan1,
Norm1,
Trans1,
Pos2,
Tan2,
Norm2,
Trans2,
TolConf);
}
IntRes2d_IntersectionPoint PtSeg2(P1, PolyUSup, PolyVSup, Trans1, Trans2, false);
bool Oppos = (Tan1.Dot(Tan2) > 0.0) ? false : true;
if (ParamInfOnCurve1 > ParamSupOnCurve1)
{
IntRes2d_IntersectionSegment Seg(PtSeg2, PtSeg1, Oppos, false);
Append(Seg);
}
else
{
IntRes2d_IntersectionSegment Seg(PtSeg1, PtSeg2, Oppos, false);
Append(Seg);
}
}
} // end of processing of TangentZone
done = true;
}
bool HeadOrEndPoint(const IntRes2d_Domain& D1,
const TheCurve& C1,
const double tu,
const IntRes2d_Domain& D2,
const TheCurve& C2,
const double tv,
const double TolConf,
IntRes2d_IntersectionPoint& IntPt,
bool& HeadOn1,
bool& HeadOn2,
bool& EndOn1,
bool& EndOn2,
int PosSegment)
{
gp_Pnt2d P1, P2, SP1, SP2;
gp_Vec2d T1, T2, N1, N2;
double u = tu;
double v = tv;
double svu = u;
double svv = v;
TheCurveTool::D1(C1, u, P1, T1);
TheCurveTool::D1(C2, v, P2, T2);
IntRes2d_Position Pos1 = IntRes2d_Middle;
IntRes2d_Position Pos2 = IntRes2d_Middle;
IntRes2d_Transition Trans1, Trans2;
//----------------------------------------------------------------------
//-- Head On 1 : Head1 <-> P2
if (P2.Distance(D1.FirstPoint()) <= D1.FirstTolerance())
{
Pos1 = IntRes2d_Head;
HeadOn1 = true;
SP1 = D1.FirstPoint();
u = D1.FirstParameter();
}
//----------------------------------------------------------------------
//-- End On 1 : End1 <-> P2
else if (P2.Distance(D1.LastPoint()) <= D1.LastTolerance())
{
Pos1 = IntRes2d_End;
EndOn1 = true;
SP1 = D1.LastPoint();
u = D1.LastParameter();
}
//----------------------------------------------------------------------
//-- Head On 2 : Head2 <-> P1
else if (P1.Distance(D2.FirstPoint()) <= D2.FirstTolerance())
{
Pos2 = IntRes2d_Head;
HeadOn2 = true;
SP2 = D2.FirstPoint();
v = D2.FirstParameter();
}
//----------------------------------------------------------------------
//-- End On 2 : End2 <-> P1
else if (P1.Distance(D2.LastPoint()) <= D2.LastTolerance())
{
Pos2 = IntRes2d_End;
EndOn2 = true;
SP2 = D2.LastPoint();
v = D2.LastParameter();
}
double EpsX1 = TheCurveTool::EpsX(C1);
double EpsX2 = TheCurveTool::EpsX(C2);
if ((Pos1 != IntRes2d_Middle) || (Pos2 != IntRes2d_Middle))
{
if (Pos1 == IntRes2d_Middle)
{
if (std::abs(u - D1.FirstParameter()) <= EpsX1)
{
Pos1 = IntRes2d_Head;
P1 = D1.FirstPoint();
HeadOn1 = true;
}
else if (std::abs(u - D1.LastParameter()) <= EpsX1)
{
Pos1 = IntRes2d_End;
P1 = D1.LastPoint();
EndOn1 = true;
}
}
else if (u != tu)
{
P1 = SP1;
}
if (Pos2 == IntRes2d_Middle)
{
if (std::abs(v - D2.FirstParameter()) <= EpsX2)
{
Pos2 = IntRes2d_Head;
HeadOn2 = true;
P2 = D2.FirstPoint();
if (Pos1 != IntRes2d_Middle)
{
P1.SetCoord(0.5 * (P1.X() + P2.X()), 0.5 * (P1.Y() + P2.Y()));
}
else
{
P2 = P1;
}
}
else if (std::abs(v - D2.LastParameter()) <= EpsX2)
{
Pos2 = IntRes2d_End;
EndOn2 = true;
P2 = D2.LastPoint();
if (Pos1 != IntRes2d_Middle)
{
P1.SetCoord(0.5 * (P1.X() + P2.X()), 0.5 * (P1.Y() + P2.Y()));
}
else
{
P2 = P1;
}
}
}
//--------------------------------------------------------------------
//-- It is tested if a point at the end of segment already has its transitions
//-- If Yes, the new point is not created
//--
//-- PosSegment = 1 if Head Head
//-- 2 if Head End
//-- 4 if End Head
//-- 8 if End End
//--------------------------------------------------------------------
if (Pos1 == IntRes2d_Head)
{
if ((Pos2 == IntRes2d_Head) && (PosSegment & 1))
return (false);
if ((Pos2 == IntRes2d_End) && (PosSegment & 2))
return (false);
}
else if (Pos1 == IntRes2d_End)
{
if ((Pos2 == IntRes2d_Head) && (PosSegment & 4))
return (false);
if ((Pos2 == IntRes2d_End) && (PosSegment & 8))
return (false);
}
if (IntImpParGen::DetermineTransition(Pos1, T1, Trans1, Pos2, T2, Trans2, TolConf) == false)
{
TheCurveTool::D2(C1, svu, P1, T1, N1);
TheCurveTool::D2(C2, svv, P2, T2, N2);
IntImpParGen::DetermineTransition(Pos1, T1, N1, Trans1, Pos2, T2, N2, Trans2, TolConf);
}
IntPt.SetValues(P1, u, v, Trans1, Trans2, false);
return (true);
}
else
return (false);
}
//=======================================================================
// function : Perform
// purpose : Base method to perform polyline / polyline intersection for
// pair of curves.
//=======================================================================
void IntCurve_IntPolyPolyGen::Perform(const TheCurve& C1,
const IntRes2d_Domain& D1,
const TheCurve& C2,
const IntRes2d_Domain& D2,
const double TolConf,
const double Tol,
const int NbIter,
const double DeltaU,
const double DeltaV)
{
int nbsamplesOnC1, nbsamplesOnC2;
done = false;
if (NbIter > NBITER_MAX_POLYGON)
return;
// Number of samples running.
nbsamplesOnC1 = TheCurveTool::NbSamples(C1, D1.FirstParameter(), D1.LastParameter());
nbsamplesOnC2 = TheCurveTool::NbSamples(C2, D2.FirstParameter(), D2.LastParameter());
if (NbIter == 0)
{
// Minimal number of points.
nbsamplesOnC1 = std::max(nbsamplesOnC1, myMinPntNb);
nbsamplesOnC2 = std::max(nbsamplesOnC2, myMinPntNb);
}
else
{
// Increase number of samples in second and next iterations.
nbsamplesOnC1 = (5 * (nbsamplesOnC1 * NbIter)) / 4;
nbsamplesOnC2 = (5 * (nbsamplesOnC2 * NbIter)) / 4;
}
NCollection_Handle<IntCurve_ThePolygon2d> aPoly1 =
new IntCurve_ThePolygon2d(C1, nbsamplesOnC1, D1, Tol),
aPoly2 =
new IntCurve_ThePolygon2d(C2, nbsamplesOnC2, D2, Tol);
if ((aPoly1->DeflectionOverEstimation() > TolConf)
&& (aPoly2->DeflectionOverEstimation() > TolConf))
{
const double aDeflectionSum = std::max(aPoly1->DeflectionOverEstimation(), TolConf)
+ std::max(aPoly2->DeflectionOverEstimation(), TolConf);
if (nbsamplesOnC2 > nbsamplesOnC1)
{
aPoly2->ComputeWithBox(C2, aPoly1->Bounding());
aPoly1->SetDeflectionOverEstimation(aDeflectionSum);
aPoly1->ComputeWithBox(C1, aPoly2->Bounding());
}
else
{
aPoly1->ComputeWithBox(C1, aPoly2->Bounding());
aPoly2->SetDeflectionOverEstimation(aDeflectionSum);
aPoly2->ComputeWithBox(C2, aPoly1->Bounding());
}
}
//----------------------------------------------------------------------
//-- if the deflection less then the Tolerance of Confusion
//-- Then the deflection of the polygon is set in TolConf
//-- (Detection of Tangency Zones)
//----------------------------------------------------------------------
if (aPoly1->DeflectionOverEstimation() < TolConf)
{
aPoly1->SetDeflectionOverEstimation(TolConf);
}
if (aPoly2->DeflectionOverEstimation() < TolConf)
{
aPoly2->SetDeflectionOverEstimation(TolConf);
}
// for case when a few polygon points were replaced by line
// if exact solution was not found
// then search of precise solution will be repeated
// for polygon contains all initial points
// secondary search will be performed only for case when initial points
// were dropped
bool isFullRepresentation =
(aPoly1->NbSegments() == nbsamplesOnC1 && aPoly2->NbSegments() == nbsamplesOnC2);
if (!findIntersect(C1,
D1,
C2,
D2,
TolConf,
Tol,
NbIter,
DeltaU,
DeltaV,
*aPoly1,
*aPoly2,
isFullRepresentation)
&& !isFullRepresentation)
{
if (aPoly1->NbSegments() < nbsamplesOnC1)
{
aPoly1 = new IntCurve_ThePolygon2d(C1, nbsamplesOnC1, D1, Tol);
}
if (aPoly2->NbSegments() < nbsamplesOnC2)
{
aPoly2 = new IntCurve_ThePolygon2d(C2, nbsamplesOnC2, D2, Tol);
}
findIntersect(C1, D1, C2, D2, TolConf, Tol, NbIter, DeltaU, DeltaV, *aPoly1, *aPoly2, true);
}
done = true;
}
//======================================================================
// Purpose : findIntersect
//======================================================================
bool IntCurve_IntPolyPolyGen::findIntersect(const TheCurve& C1,
const IntRes2d_Domain& D1,
const TheCurve& C2,
const IntRes2d_Domain& D2,
const double TolConf,
const double Tol,
const int NbIter,
const double DeltaU,
const double DeltaV,
const IntCurve_ThePolygon2d& thePoly1,
const IntCurve_ThePolygon2d& thePoly2,
bool isFullPolygon)
{
gp_Vec2d Tan1, Tan2, Norm1, Norm2;
gp_Pnt2d P1, P2;
Intf_InterferencePolygon2d InterPP(thePoly1, thePoly2);
IntCurve_ExactIntersectionPoint EIP(C1, C2, TolConf);
double U = 0., V = 0.;
bool AnErrorOccurred = false;
done = true; // To prevent exception in nbp=NbPoints();
//----------------------------------------------------------------------
//-- Processing of SectionPoint
//----------------------------------------------------------------------
int Nbsp = InterPP.NbSectionPoints();
for (int sp = 1; sp <= Nbsp; sp++)
{
const Intf_SectionPoint& SPnt = InterPP.PntValue(sp);
int SegIndex1, SegIndex2;
double ParamOn1, ParamOn2;
Intf_PIType Type;
SPnt.InfoFirst(Type, SegIndex1, ParamOn1);
SPnt.InfoSecond(Type, SegIndex2, ParamOn2);
EIP.Perform(thePoly1, thePoly2, SegIndex1, SegIndex2, ParamOn1, ParamOn2);
AnErrorOccurred = EIP.AnErrorOccurred();
if (!EIP.NbRoots() && !isFullPolygon)
return false;
if (AnErrorOccurred)
{
continue;
}
//--------------------------------------------------------------------
//-- It is checked if the found point is really a root
//--------------------------------------------------------------------
EIP.Roots(U, V);
TheCurveTool::D1(C1, U, P1, Tan1);
TheCurveTool::D1(C2, V, P2, Tan2);
double Dist = P1.Distance(P2);
if (EIP.NbRoots() == 0 && Dist > TolConf)
{
IntRes2d_Transition aTrans;
IntRes2d_IntersectionPoint aPInt(P1, U, V, aTrans, aTrans, false);
double aT1f, aT1l, aT2f, aT2l;
aT1f = thePoly1.ApproxParamOnCurve(SegIndex1, 0.0);
aT1l = thePoly1.ApproxParamOnCurve(SegIndex1, 1.0);
aT2f = thePoly2.ApproxParamOnCurve(SegIndex2, 0.0);
aT2l = thePoly2.ApproxParamOnCurve(SegIndex2, 1.0);
//
int aMaxCount = 16, aCount = 0;
GetIntersection(C1, aT1f, aT1l, C2, aT2f, aT2l, TolConf, aMaxCount, aPInt, Dist, aCount);
U = aPInt.ParamOnFirst();
V = aPInt.ParamOnSecond();
TheCurveTool::D1(C1, U, P1, Tan1);
TheCurveTool::D1(C2, V, P2, Tan2);
Dist = P1.Distance(P2);
}
//-----------------------------------------------------------------
//-- It is checked if the point (u,v) does not exist already
//--
int nbp = NbPoints();
double EpsX1 = 10.0 * TheCurveTool::EpsX(C1);
double EpsX2 = 10.0 * TheCurveTool::EpsX(C2);
for (int p = 1; p <= nbp; p++)
{
const IntRes2d_IntersectionPoint& P = Point(p);
if (std::abs(U - P.ParamOnFirst()) <= EpsX1)
{
if (std::abs(V - P.ParamOnSecond()) <= EpsX2)
{
Dist = TolConf + 1.0;
p += nbp;
}
}
}
if (Dist <= TolConf)
{ //-- Or the point is already present
IntRes2d_Position Pos1 = IntRes2d_Middle;
IntRes2d_Position Pos2 = IntRes2d_Middle;
IntRes2d_Transition Trans1, Trans2;
//-----------------------------------------------------------------
//-- Calculate the Positions of Points on the curve
//--
if (P1.Distance(DomainOnCurve1.FirstPoint()) <= DomainOnCurve1.FirstTolerance())
Pos1 = IntRes2d_Head;
else if (P1.Distance(DomainOnCurve1.LastPoint()) <= DomainOnCurve1.LastTolerance())
Pos1 = IntRes2d_End;
if (P2.Distance(DomainOnCurve2.FirstPoint()) <= DomainOnCurve2.FirstTolerance())
Pos2 = IntRes2d_Head;
else if (P2.Distance(DomainOnCurve2.LastPoint()) <= DomainOnCurve2.LastTolerance())
Pos2 = IntRes2d_End;
//-----------------------------------------------------------------
//-- Calculate the Transitions (see IntImpParGen.cxx)
//--
if (IntImpParGen::DetermineTransition(Pos1, Tan1, Trans1, Pos2, Tan2, Trans2, TolConf)
== false)
{
TheCurveTool::D2(C1, U, P1, Tan1, Norm1);
TheCurveTool::D2(C2, V, P2, Tan2, Norm2);
IntImpParGen::DetermineTransition(Pos1,
Tan1,
Norm1,
Trans1,
Pos2,
Tan2,
Norm2,
Trans2,
TolConf);
}
IntRes2d_IntersectionPoint IP(P1, U, V, Trans1, Trans2, false);
Insert(IP);
}
}
//----------------------------------------------------------------------
//-- Processing of TangentZone
//----------------------------------------------------------------------
int Nbtz = InterPP.NbTangentZones();
for (int tz = 1; tz <= Nbtz; tz++)
{
int NbPnts = InterPP.ZoneValue(tz).NumberOfPoints();
//====================================================================
//== Find the first and the last point in the tangency zone.
//====================================================================
double ParamSupOnCurve2, ParamInfOnCurve2;
double ParamSupOnCurve1, ParamInfOnCurve1;
// int SegIndex,SegIndex1onP1,SegIndex1onP2,SegIndex2onP1,SegIndex2onP2;
int SegIndex1onP1, SegIndex1onP2;
Intf_PIType Type;
double ParamOnLine;
double PolyUInf, PolyUSup, PolyVInf, PolyVSup;
ParamSupOnCurve2 = ParamSupOnCurve1 = PolyUSup = PolyVSup = -RealLast();
ParamInfOnCurve2 = ParamInfOnCurve1 = PolyUInf = PolyVInf = RealLast();
for (int qq = 1; qq <= NbPnts; qq++)
{
const Intf_SectionPoint& SPnt1 = InterPP.ZoneValue(tz).GetPoint(qq);
//====================================================================
//== The zones of tangency are discretized
//== Test of stop : Check if
//== (Deflection < Tolerance)
//== Or (Sample < EpsX) (normally the first condition is
//== more strict)
//====================================================================
// double _PolyUInf,_PolyUSup,_PolyVInf,_PolyVSup;
double _PolyUInf, _PolyVInf;
SPnt1.InfoFirst(Type, SegIndex1onP1, ParamOnLine);
if (SegIndex1onP1 > thePoly1.NbSegments())
{
SegIndex1onP1--;
ParamOnLine = 1.0;
}
if (SegIndex1onP1 <= 0)
{
SegIndex1onP1 = 1;
ParamOnLine = 0.0;
}
_PolyUInf = thePoly1.ApproxParamOnCurve(SegIndex1onP1, ParamOnLine);
SPnt1.InfoSecond(Type, SegIndex1onP2, ParamOnLine);
if (SegIndex1onP2 > thePoly2.NbSegments())
{
SegIndex1onP2--;
ParamOnLine = 1.0;
}
if (SegIndex1onP2 <= 0)
{
SegIndex1onP2 = 1;
ParamOnLine = 0.0;
}
_PolyVInf = thePoly2.ApproxParamOnCurve(SegIndex1onP2, ParamOnLine);
//----------------------------------------------------------------------
if (ParamInfOnCurve1 > _PolyUInf)
ParamInfOnCurve1 = _PolyUInf;
if (ParamInfOnCurve2 > _PolyVInf)
ParamInfOnCurve2 = _PolyVInf;
if (ParamSupOnCurve1 < _PolyUInf)
ParamSupOnCurve1 = _PolyUInf;
if (ParamSupOnCurve2 < _PolyVInf)
ParamSupOnCurve2 = _PolyVInf;
}
PolyUInf = ParamInfOnCurve1;
PolyUSup = ParamSupOnCurve1;
PolyVInf = ParamInfOnCurve2;
PolyVSup = ParamSupOnCurve2;
TheCurveTool::D0(C1, PolyUInf, P1);
TheCurveTool::D0(C2, PolyVInf, P2);
double distmemesens = P1.SquareDistance(P2);
TheCurveTool::D0(C2, PolyVSup, P2);
double distdiffsens = P1.SquareDistance(P2);
if (distmemesens > distdiffsens)
{
double qwerty = PolyVInf;
PolyVInf = PolyVSup;
PolyVSup = qwerty;
}
if (((thePoly1.DeflectionOverEstimation() > TolConf)
|| (thePoly2.DeflectionOverEstimation() > TolConf))
&& (NbIter < NBITER_MAX_POLYGON))
{
IntRes2d_Domain RecursD1(TheCurveTool::Value(C1, ParamInfOnCurve1),
ParamInfOnCurve1,
TolConf,
TheCurveTool::Value(C1, ParamSupOnCurve1),
ParamSupOnCurve1,
TolConf);
IntRes2d_Domain RecursD2(TheCurveTool::Value(C2, ParamInfOnCurve2),
ParamInfOnCurve2,
TolConf,
TheCurveTool::Value(C2, ParamSupOnCurve2),
ParamSupOnCurve2,
TolConf);
//-- thePoly1(2) are not deleted,
//-- finally they are destroyed.
//-- !! No untimely return !!
Perform(C1, RecursD1, C2, RecursD2, Tol, TolConf, NbIter + 1, DeltaU, DeltaV);
}
else
{
//-----------------------------------------------------------------
//-- Calculate Positions of Points on the curve and
//-- Transitions on each limit of the segment
IntRes2d_Position Pos1 = IntRes2d_Middle;
IntRes2d_Position Pos2 = IntRes2d_Middle;
IntRes2d_Transition Trans1, Trans2;
TheCurveTool::D1(C1, PolyUInf, P1, Tan1);
TheCurveTool::D1(C2, PolyVInf, P2, Tan2);
if (P1.Distance(DomainOnCurve1.FirstPoint()) <= DomainOnCurve1.FirstTolerance())
{
Pos1 = IntRes2d_Head;
}
else if (P1.Distance(DomainOnCurve1.LastPoint()) <= DomainOnCurve1.LastTolerance())
{
Pos1 = IntRes2d_End;
}
if (P2.Distance(DomainOnCurve2.FirstPoint()) <= DomainOnCurve2.FirstTolerance())
{
Pos2 = IntRes2d_Head;
}
else if (P2.Distance(DomainOnCurve2.LastPoint()) <= DomainOnCurve2.LastTolerance())
{
Pos2 = IntRes2d_End;
}
if (Pos1 == IntRes2d_Middle && Pos2 != IntRes2d_Middle)
{
PolyUInf = TheProjPCur::FindParameter(C1,
P2,
D1.FirstParameter(),
D1.LastParameter(),
TheCurveTool::EpsX(C1));
}
else if (Pos1 != IntRes2d_Middle && Pos2 == IntRes2d_Middle)
{
PolyVInf = TheProjPCur::FindParameter(C2,
P1,
D2.FirstParameter(),
D2.LastParameter(),
TheCurveTool::EpsX(C2));
}
else if (std::abs(ParamInfOnCurve1 - ParamSupOnCurve1)
> std::abs(ParamInfOnCurve2 - ParamSupOnCurve2))
{
PolyVInf = TheProjPCur::FindParameter(C2,
P1,
D2.FirstParameter(),
D2.LastParameter(),
TheCurveTool::EpsX(C2));
}
else
{
PolyUInf = TheProjPCur::FindParameter(C1,
P2,
D1.FirstParameter(),
D1.LastParameter(),
TheCurveTool::EpsX(C1));
}
if (IntImpParGen::DetermineTransition(Pos1, Tan1, Trans1, Pos2, Tan2, Trans2, TolConf)
== false)
{
TheCurveTool::D2(C1, PolyUInf, P1, Tan1, Norm1);
TheCurveTool::D2(C2, PolyVInf, P2, Tan2, Norm2);
IntImpParGen::DetermineTransition(Pos1,
Tan1,
Norm1,
Trans1,
Pos2,
Tan2,
Norm2,
Trans2,
TolConf);
}
IntRes2d_IntersectionPoint PtSeg1(P1, PolyUInf, PolyVInf, Trans1, Trans2, false);
//----------------------------------------------------------------------
if ((std::abs(PolyUInf - PolyUSup) <= TheCurveTool::EpsX(C1))
|| (std::abs(PolyVInf - PolyVSup) <= TheCurveTool::EpsX(C2)))
{
Insert(PtSeg1);
}
else
{
TheCurveTool::D1(C1, PolyUSup, P1, Tan1);
TheCurveTool::D1(C2, PolyVSup, P2, Tan2);
Pos1 = IntRes2d_Middle;
Pos2 = IntRes2d_Middle;
if (P1.Distance(DomainOnCurve1.FirstPoint()) <= DomainOnCurve1.FirstTolerance())
{
Pos1 = IntRes2d_Head;
}
else if (P1.Distance(DomainOnCurve1.LastPoint()) <= DomainOnCurve1.LastTolerance())
{
Pos1 = IntRes2d_End;
}
if (P2.Distance(DomainOnCurve2.FirstPoint()) <= DomainOnCurve2.FirstTolerance())
{
Pos2 = IntRes2d_Head;
}
else if (P2.Distance(DomainOnCurve2.LastPoint()) <= DomainOnCurve2.LastTolerance())
{
Pos2 = IntRes2d_End;
}
if (Pos1 == IntRes2d_Middle && Pos2 != IntRes2d_Middle)
{
PolyUSup = TheProjPCur::FindParameter(C1,
P2,
D1.FirstParameter(),
D1.LastParameter(),
TheCurveTool::EpsX(C1));
}
else if (Pos1 != IntRes2d_Middle && Pos2 == IntRes2d_Middle)
{
PolyVSup = TheProjPCur::FindParameter(C2,
P1,
D2.FirstParameter(),
D2.LastParameter(),
TheCurveTool::EpsX(C2));
}
else if (std::abs(ParamInfOnCurve1 - ParamSupOnCurve1)
> std::abs(ParamInfOnCurve2 - ParamSupOnCurve2))
{
PolyVSup = TheProjPCur::FindParameter(C2,
P1,
D2.FirstParameter(),
D2.LastParameter(),
TheCurveTool::EpsX(C2));
}
else
{
PolyUSup = TheProjPCur::FindParameter(C1,
P2,
D1.FirstParameter(),
D1.LastParameter(),
TheCurveTool::EpsX(C1));
}
if (IntImpParGen::DetermineTransition(Pos1, Tan1, Trans1, Pos2, Tan2, Trans2, TolConf)
== false)
{
TheCurveTool::D2(C1, PolyUSup, P1, Tan1, Norm1);
TheCurveTool::D2(C2, PolyVSup, P2, Tan2, Norm2);
IntImpParGen::DetermineTransition(Pos1,
Tan1,
Norm1,
Trans1,
Pos2,
Tan2,
Norm2,
Trans2,
TolConf);
}
IntRes2d_IntersectionPoint PtSeg2(P1, PolyUSup, PolyVSup, Trans1, Trans2, false);
bool Oppos = (Tan1.Dot(Tan2) > 0.0) ? false : true;
if (ParamInfOnCurve1 > ParamSupOnCurve1)
{
IntRes2d_IntersectionSegment Seg(PtSeg2, PtSeg1, Oppos, false);
Append(Seg);
}
else
{
IntRes2d_IntersectionSegment Seg(PtSeg1, PtSeg2, Oppos, false);
Append(Seg);
}
}
}
}
return true;
}
//======================================================================
// GetIntersection
//======================================================================
void GetIntersection(const TheCurve& theC1,
const double theT1f,
const double theT1l,
const TheCurve& theC2,
const double theT2f,
const double theT2l,
const double theTolConf,
const int theMaxCount,
IntRes2d_IntersectionPoint& thePInt,
double& theDist,
int& theCount)
{
theCount++;
//
double aTol2 = theTolConf * theTolConf;
double aPTol1 =
std::max(100. * Epsilon(std::max(std::abs(theT1f), std::abs(theT1l))), Precision::PConfusion());
double aPTol2 =
std::max(100. * Epsilon(std::max(std::abs(theT2f), std::abs(theT2l))), Precision::PConfusion());
gp_Pnt2d aP1f, aP1l, aP2f, aP2l;
Bnd_Box2d aB1, aB2;
//
TheCurveTool::D0(theC1, theT1f, aP1f);
TheCurveTool::D0(theC1, theT1l, aP1l);
aB1.Add(aP1f);
aB1.Add(aP1l);
aB1.Enlarge(theTolConf);
//
TheCurveTool::D0(theC2, theT2f, aP2f);
TheCurveTool::D0(theC2, theT2l, aP2l);
aB2.Add(aP2f);
aB2.Add(aP2l);
aB2.Enlarge(theTolConf);
//
if (aB1.IsOut(aB2))
{
theCount--;
return;
}
//
bool isSmall1 = (theT1l - theT1f) <= aPTol1 || aP1f.SquareDistance(aP1l) / 4. <= aTol2;
bool isSmall2 = (theT2l - theT2f) <= aPTol2 || aP2f.SquareDistance(aP2l) / 4. <= aTol2;
if ((isSmall1 && isSmall2) || (theCount > theMaxCount))
{
// Seems to be intersection
// Simple treatment of segment intersection
gp_XY aPnts1[3] = {aP1f.XY(), (aP1f.XY() + aP1l.XY()) / 2., aP1l.XY()};
gp_XY aPnts2[3] = {aP2f.XY(), (aP2f.XY() + aP2l.XY()) / 2., aP2l.XY()};
int i, j, imin = -1, jmin = -1;
double dmin = RealLast(), d;
for (i = 0; i < 3; i++)
{
for (j = 0; j < 3; j++)
{
d = (aPnts1[i] - aPnts2[j]).SquareModulus();
if (d < dmin)
{
dmin = d;
imin = i;
jmin = j;
}
}
}
//
dmin = std::sqrt(dmin);
if (theDist > dmin)
{
theDist = dmin;
//
double t1;
if (imin == 0)
{
t1 = theT1f;
}
else if (imin == 1)
{
t1 = (theT1f + theT1l) / 2.;
}
else
{
t1 = theT1l;
}
//
double t2;
if (jmin == 0)
{
t2 = theT2f;
}
else if (jmin == 1)
{
t2 = (theT2f + theT2l) / 2.;
}
else
{
t2 = theT2l;
}
//
gp_Pnt2d aPint((aPnts1[imin] + aPnts2[jmin]) / 2.);
//
IntRes2d_Transition aTrans1, aTrans2;
thePInt.SetValues(aPint, t1, t2, aTrans1, aTrans2, false);
}
theCount--;
return;
}
if (isSmall1)
{
double aT2m = (theT2l + theT2f) / 2.;
GetIntersection(theC1,
theT1f,
theT1l,
theC2,
theT2f,
aT2m,
theTolConf,
theMaxCount,
thePInt,
theDist,
theCount);
GetIntersection(theC1,
theT1f,
theT1l,
theC2,
aT2m,
theT2l,
theTolConf,
theMaxCount,
thePInt,
theDist,
theCount);
}
else if (isSmall2)
{
double aT1m = (theT1l + theT1f) / 2.;
GetIntersection(theC1,
theT1f,
aT1m,
theC2,
theT2f,
theT2l,
theTolConf,
theMaxCount,
thePInt,
theDist,
theCount);
GetIntersection(theC1,
aT1m,
theT1l,
theC2,
theT2f,
theT2l,
theTolConf,
theMaxCount,
thePInt,
theDist,
theCount);
}
else
{
double aT1m = (theT1l + theT1f) / 2.;
double aT2m = (theT2l + theT2f) / 2.;
GetIntersection(theC1,
theT1f,
aT1m,
theC2,
theT2f,
aT2m,
theTolConf,
theMaxCount,
thePInt,
theDist,
theCount);
GetIntersection(theC1,
theT1f,
aT1m,
theC2,
aT2m,
theT2l,
theTolConf,
theMaxCount,
thePInt,
theDist,
theCount);
GetIntersection(theC1,
aT1m,
theT1l,
theC2,
theT2f,
aT2m,
theTolConf,
theMaxCount,
thePInt,
theDist,
theCount);
GetIntersection(theC1,
aT1m,
theT1l,
theC2,
aT2m,
theT2l,
theTolConf,
theMaxCount,
thePInt,
theDist,
theCount);
}
}
//=================================================================================================
int IntCurve_IntPolyPolyGen::GetMinNbSamples() const
{
return myMinPntNb;
}
//=================================================================================================
void IntCurve_IntPolyPolyGen::SetMinNbSamples(const int theMinNbSamples)
{
myMinPntNb = theMinNbSamples;
}