Loading files
3d097a032This file is pinned to the selected release. Download the original to open it in your design tool.
// Created on: 1993-02-02
// Created by: Laurent BUCHARD
// Copyright (c) 1993-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 12:29:55 2002
// modified by Oleg FEDYAED (ofv) Fri Nov 29 16:08:02 2002
#include <Adaptor3d_Surface.hxx>
#include <Adaptor3d_TopolTool.hxx>
#include <gp_Dir.hxx>
#include <gp_Pnt.hxx>
#include <IntPatch_InterferencePolyhedron.hxx>
#include <IntPatch_Polyhedron.hxx>
#include <IntPatch_PrmPrmIntersection.hxx>
#include <IntPatch_PrmPrmIntersection_T3Bits.hxx>
#include <IntPatch_RstInt.hxx>
#include <IntPatch_WLine.hxx>
#include <IntPolyh_Intersection.hxx>
#include <IntSurf_LineOn2S.hxx>
#include <IntSurf_PntOn2S.hxx>
#include <NCollection_List.hxx>
#include <IntWalk_PWalking.hxx>
#include <Standard_OutOfRange.hxx>
#include <StdFail_NotDone.hxx>
#include <NCollection_Array1.hxx>
#include <Standard_Integer.hxx>
#include <NCollection_Sequence.hxx>
static void SectionPointToParameters(const Intf_SectionPoint& Sp,
const IntPatch_Polyhedron& Surf1,
const IntPatch_Polyhedron& Surf2,
double& u1,
double& v1,
double& u2,
double& v2);
static void AdjustOnPeriodic(const occ::handle<Adaptor3d_Surface>& Surf1,
const occ::handle<Adaptor3d_Surface>& Surf2,
NCollection_Sequence<occ::handle<IntPatch_Line>>& aSLin);
static IntSurf_PntOn2S MakeNewPoint(const IntSurf_PntOn2S& replacePnt,
const IntSurf_PntOn2S& oldPnt,
const double* Periods);
static bool IsPointOnLine(const IntSurf_PntOn2S& thePOn2S,
const occ::handle<IntPatch_WLine>& theWLine,
const double Deflection);
static void AddWLine(NCollection_Sequence<occ::handle<IntPatch_Line>>& theLines,
const occ::handle<IntPatch_WLine>& theWLine,
const double Deflection);
static void SeveralWlinesProcessing(const occ::handle<Adaptor3d_Surface>& theSurf1,
const occ::handle<Adaptor3d_Surface>& theSurf2,
const NCollection_Sequence<occ::handle<IntPatch_Line>>& theSLin,
const double* const thePeriodsArr,
const IntSurf_TypeTrans theTrans1,
const IntSurf_TypeTrans theTrans2,
const double theTol,
const double theMaxStepS1,
const double theMaxStepS2,
occ::handle<IntPatch_WLine>& theWLline)
{
if (theSLin.Length() == 0)
{
return;
}
double aU1 = 0.0, aV1 = 0.0, aU2 = 0.0, aV2 = 0.0;
int cnbV = theWLline->NbVertex();
int ciV;
for (ciV = 1; ciV <= cnbV; ciV++)
{
double pntDMin = 1.e+100;
int VDMin = 0;
int WLDMin = 0;
gp_Pnt cPV = theWLline->Vertex(ciV).Value();
theWLline->Vertex(ciV).Parameters(aU1, aV1, aU2, aV2);
const gp_Pnt2d aPCS1(aU1, aV1), aPCS2(aU2, aV2);
int iL;
for (iL = 1; iL <= theSLin.Length(); iL++)
{
const occ::handle<IntPatch_Line>& aSLine = theSLin.Value(iL);
IntPatch_IType aType = aSLine->ArcType();
if (aType != IntPatch_Walking)
{
continue;
}
const occ::handle<IntPatch_WLine> aWLine = occ::down_cast<IntPatch_WLine>(aSLine);
int tnbV = aWLine->NbVertex();
int tiV;
for (tiV = 1; tiV <= tnbV; tiV++)
{
gp_Pnt tPV = aWLine->Vertex(tiV).Value();
aWLine->Vertex(tiV).Parameters(aU1, aV1, aU2, aV2);
const gp_Pnt2d aPTS1(aU1, aV1), aPTS2(aU2, aV2);
double tDistance = cPV.Distance(tPV);
double uRs1 = theSurf1->UResolution(tDistance);
double vRs1 = theSurf1->VResolution(tDistance);
double uRs2 = theSurf2->UResolution(tDistance);
double vRs2 = theSurf2->VResolution(tDistance);
double RmaxS1 = std::max(uRs1, vRs1);
double RmaxS2 = std::max(uRs2, vRs2);
if (RmaxS1 < theMaxStepS1 && RmaxS2 < theMaxStepS2)
{
if (pntDMin > tDistance && tDistance > Precision::PConfusion())
{
const double aSqDist1 = aPCS1.SquareDistance(aPTS1),
aSqDist2 = aPCS2.SquareDistance(aPTS2);
if ((aSqDist1 < RmaxS1 * RmaxS1) && (aSqDist2 < RmaxS2 * RmaxS2))
{
pntDMin = tDistance;
VDMin = tiV;
WLDMin = iL;
}
}
}
}
}
if (VDMin != 0)
{
const occ::handle<IntPatch_Line>& aSLine = theSLin.Value(WLDMin);
const occ::handle<IntPatch_WLine> aWLine = occ::down_cast<IntPatch_WLine>(aSLine);
int tiVpar = (int)aWLine->Vertex(VDMin).ParameterOnLine();
int ciVpar = (int)theWLline->Vertex(ciV).ParameterOnLine();
double u11 = 0., u12 = 0., v11 = 0., v12 = 0.;
double u21 = 0., u22 = 0., v21 = 0., v22 = 0.;
theWLline->Point(ciVpar).Parameters(u11, v11, u12, v12);
aWLine->Point(tiVpar).Parameters(u21, v21, u22, v22);
occ::handle<IntSurf_LineOn2S> newL2s = new IntSurf_LineOn2S();
IntSurf_PntOn2S replacePnt = aWLine->Point(tiVpar);
int cNbP = theWLline->NbPnts();
NCollection_Sequence<int> VPold;
int iPo;
for (iPo = 1; iPo <= cnbV; iPo++)
{
double Po = theWLline->Vertex(iPo).ParameterOnLine();
int IPo = (int)Po;
VPold.Append(IPo);
}
bool removeNext = false;
bool removePrev = false;
if (ciV == 1)
{
int dPar = std::abs(VPold.Value(ciV) - VPold.Value(ciV + 1));
if (dPar > 10)
{
removeNext = true;
for (iPo = (ciV + 1); iPo <= cnbV; iPo++)
{
VPold.SetValue(iPo, VPold.Value(iPo) - 1);
}
}
}
else if (ciV == cnbV)
{
int dPar = std::abs(VPold.Value(ciV) - VPold.Value(ciV - 1));
if (dPar > 10)
{
removePrev = true;
VPold.SetValue(ciV, VPold.Value(ciV) - 1);
}
}
else
{
int dParMi = std::abs(VPold.Value(ciV) - VPold.Value(ciV - 1));
int dParMa = std::abs(VPold.Value(ciV) - VPold.Value(ciV + 1));
if (dParMi > 10)
{
removePrev = true;
VPold.SetValue(ciV, VPold.Value(ciV) - 1);
}
if (dParMa > 10)
{
removeNext = true;
for (iPo = (ciV + 1); iPo <= cnbV; iPo++)
{
if (dParMi > 10)
{
VPold.SetValue(iPo, VPold.Value(iPo) - 2);
}
else
{
VPold.SetValue(iPo, VPold.Value(iPo) - 1);
}
}
}
else
{
if (dParMi > 10)
{
for (iPo = (ciV + 1); iPo <= cnbV; iPo++)
{
VPold.SetValue(iPo, VPold.Value(iPo) - 1);
}
}
}
}
int pI = ciVpar;
int iP;
for (iP = 1; iP <= cNbP; iP++)
{
if (pI == iP)
{
IntSurf_PntOn2S newPnt = MakeNewPoint(replacePnt, theWLline->Point(iP), thePeriodsArr);
newL2s->Add(newPnt);
}
else if (removeNext && iP == (pI + 1))
{
continue;
}
else if (removePrev && iP == (pI - 1))
{
continue;
}
else
{
newL2s->Add(theWLline->Point(iP));
}
}
IntPatch_Point newVtx;
gp_Pnt Pnt3dV = aWLine->Vertex(VDMin).Value();
newVtx.SetValue(Pnt3dV, theTol, false);
newVtx.SetParameters(u21, v21, u22, v22);
newVtx.SetParameter(VPold.Value(ciV));
occ::handle<IntPatch_WLine> NWLine = new IntPatch_WLine(newL2s, false, theTrans1, theTrans2);
NWLine->SetCreatingWayInfo(IntPatch_WLine::IntPatch_WLPrmPrm);
int iV;
for (iV = 1; iV <= cnbV; iV++)
{
if (iV == ciV)
{
NWLine->AddVertex(newVtx);
}
else
{
IntPatch_Point theVtx = theWLline->Vertex(iV);
theVtx.SetParameter(VPold.Value(iV));
NWLine->AddVertex(theVtx);
}
}
theWLline = NWLine;
} // if( VDMin != 0 )
} // for( ciV = 1; ciV <= cnbV; ciV++ )
}
//=======================================================================
// function : DublicateOfLinesProcessing
// purpose : Decides, if rejecting current line is necessary
//=======================================================================
static void DublicateOfLinesProcessing(const IntWalk_PWalking& thePW,
const int theWLID,
NCollection_Sequence<occ::handle<IntPatch_Line>>& theLines,
bool& theIsRejectReq)
{
const occ::handle<IntPatch_WLine>& anExistWL =
*((occ::handle<IntPatch_WLine>*)&theLines.Value(theWLID));
const int aNbPrevPoints = anExistWL->NbPnts();
const int aNbCurrPoints = thePW.NbPoints();
if (aNbPrevPoints < aNbCurrPoints)
{ // Remove preview line
theLines.Remove(theWLID);
theIsRejectReq = false;
}
else if (aNbPrevPoints == aNbCurrPoints)
{
double aLPrev = 0.0, aLCurr = 0.0;
for (int aNbPP = 1; aNbPP < aNbPrevPoints; aNbPP++)
{
const gp_Pnt aP1prev(anExistWL->Point(aNbPP).Value()),
aP2prev(anExistWL->Point(aNbPP + 1).Value());
const gp_Pnt aP1curr(thePW.Value(aNbPP).Value()), aP2curr(thePW.Value(aNbPP + 1).Value());
aLPrev += aP1prev.Distance(aP2prev);
aLCurr += aP1curr.Distance(aP2curr);
}
if (aLPrev < aLCurr)
{ // Remove preview line
theLines.Remove(theWLID);
theIsRejectReq = false;
}
}
}
//=================================================================================================
IntPatch_PrmPrmIntersection::IntPatch_PrmPrmIntersection()
: done(false),
empt(true)
{
}
//=================================================================================================
void IntPatch_PrmPrmIntersection::Perform(const occ::handle<Adaptor3d_Surface>& Surf1,
const occ::handle<Adaptor3d_TopolTool>& D1,
const double TolTangency,
const double Epsilon,
const double Deflection,
const double Increment)
{
IntPatch_Polyhedron Poly1(Surf1, D1->NbSamplesU(), D1->NbSamplesV());
Perform(Surf1, Poly1, D1, TolTangency, Epsilon, Deflection, Increment);
}
//=================================================================================================
void IntPatch_PrmPrmIntersection::Perform(const occ::handle<Adaptor3d_Surface>& Surf1,
const IntPatch_Polyhedron& Poly1,
const occ::handle<Adaptor3d_TopolTool>& D1,
const occ::handle<Adaptor3d_Surface>& Surf2,
const occ::handle<Adaptor3d_TopolTool>& D2,
const double TolTangency,
const double Epsilon,
const double Deflection,
const double Increment)
{
IntPatch_Polyhedron Poly2(Surf2);
Perform(Surf1, Poly1, D1, Surf2, Poly2, D2, TolTangency, Epsilon, Deflection, Increment);
}
//=================================================================================================
void IntPatch_PrmPrmIntersection::Perform(const occ::handle<Adaptor3d_Surface>& Surf1,
const occ::handle<Adaptor3d_TopolTool>& D1,
const occ::handle<Adaptor3d_Surface>& Surf2,
const IntPatch_Polyhedron& Poly2,
const occ::handle<Adaptor3d_TopolTool>& D2,
const double TolTangency,
const double Epsilon,
const double Deflection,
const double Increment)
{
IntPatch_Polyhedron Poly1(Surf1);
Perform(Surf1, Poly1, D1, Surf2, Poly2, D2, TolTangency, Epsilon, Deflection, Increment);
}
//=================================================================================================
void IntPatch_PrmPrmIntersection::Perform(const occ::handle<Adaptor3d_Surface>& Surf1,
const IntPatch_Polyhedron& Poly1,
const occ::handle<Adaptor3d_TopolTool>& D1,
const occ::handle<Adaptor3d_Surface>& Surf2,
const IntPatch_Polyhedron& Poly2,
const occ::handle<Adaptor3d_TopolTool>& D2,
const double TolTangency,
const double Epsilon,
const double Deflection,
const double Increment)
{
IntPatch_InterferencePolyhedron Interference(Poly1, Poly2);
empt = true;
done = true;
SLin.Clear();
int nbLigSec = Interference.NbSectionLines();
int nbTanZon = Interference.NbTangentZones();
int NbLigCalculee = 0;
double U1, U2, V1, V2;
double pu1, pu2, pv1, pv2;
NCollection_Array1<double> StartParams(1, 4);
IntWalk_PWalking PW(Surf1, Surf2, TolTangency, Epsilon, Deflection, Increment);
double SeuildPointLigne = 15.0 * Increment * Increment; //-- 10 est insuffisant
double incidence;
double dminiPointLigne;
bool HasStartPoint, RejetLigne;
IntSurf_PntOn2S StartPOn2S;
int ver;
gp_Pnt Point3dDebut, Point3dFin;
if (nbLigSec >= 1)
{
int* TabL = new int[nbLigSec + 1];
int ls;
for (ls = 1; ls <= nbLigSec; ls++)
{
TabL[ls] = ls;
}
bool triok;
do
{
triok = true;
for (int b = 2; b <= nbLigSec; b++)
{
int nb_B = Interference.LineValue(TabL[b]).NumberOfPoints();
int nb_A = Interference.LineValue(TabL[b - 1]).NumberOfPoints();
if (nb_B > nb_A)
{
int tyu = TabL[b];
TabL[b] = TabL[b - 1];
TabL[b - 1] = tyu;
triok = false;
}
}
} while (!triok);
for (ls = 1; ls <= nbLigSec; ls++)
{
const Intf_SectionLine& LineSec = Interference.LineValue(TabL[ls]);
int nbp = LineSec.NumberOfPoints();
int* TabPtDep = new int[nbp + 1];
int ilig;
for (ilig = 1; ilig <= nbp; ilig++)
{
TabPtDep[ilig] = 0;
}
double UminLig1, VminLig1, UmaxLig1, VmaxLig1;
double UminLig2, VminLig2, UmaxLig2, VmaxLig2;
SectionPointToParameters(LineSec.GetPoint(1),
Poly1,
Poly2,
UminLig1,
VminLig1,
UminLig2,
VminLig2);
UmaxLig1 = UminLig1;
VmaxLig1 = VminLig1;
UmaxLig2 = UminLig2;
VmaxLig2 = VminLig2;
for (ilig = 2; ilig <= nbp; ilig++)
{
SectionPointToParameters(LineSec.GetPoint(ilig), Poly1, Poly2, U1, V1, U2, V2);
if (U1 > UmaxLig1)
{
UmaxLig1 = U1;
}
if (V1 > VmaxLig1)
{
VmaxLig1 = V1;
}
if (U2 > UmaxLig2)
{
UmaxLig2 = U2;
}
if (V2 > VmaxLig2)
{
VmaxLig2 = V2;
}
if (U1 < UminLig1)
{
UminLig1 = U1;
}
if (V1 < VminLig1)
{
VminLig1 = V1;
}
if (U2 < UminLig2)
{
UminLig2 = U2;
}
if (V2 < VminLig2)
{
VminLig2 = V2;
}
}
int nbps2 = (nbp > 3) ? (nbp / 2) : 1;
int NombreDePointsDeDepartDuCheminement = 0;
int IndicePointdeDepart1 = 0, IndicePointdeDepart2 = 0;
bool lignetrouvee = false;
do
{
NombreDePointsDeDepartDuCheminement++;
if (NombreDePointsDeDepartDuCheminement == 1)
{
incidence = 3.0;
int nbp1_4 = nbp / 4;
int nbp3_4 = nbp - nbp1_4;
int nsp;
for (nsp = nbp / 2; nsp < nbp3_4; nsp++)
{
double CurrentIncidence = LineSec.GetPoint(nsp).Incidence();
if (CurrentIncidence < incidence)
{
nbps2 = nsp;
incidence = 0.9 * CurrentIncidence;
}
}
for (nsp = nbp / 2; nsp > nbp1_4; nsp--)
{
double CurrentIncidence = LineSec.GetPoint(nsp).Incidence();
if (CurrentIncidence < incidence)
{
nbps2 = nsp;
incidence = 0.9 * CurrentIncidence;
}
}
if (nbp < 3)
{
NombreDePointsDeDepartDuCheminement = 3;
}
IndicePointdeDepart1 = nbps2;
}
else if (NombreDePointsDeDepartDuCheminement == 2)
{
if (IndicePointdeDepart1 == 1)
{
nbps2 = nbp / 2;
IndicePointdeDepart2 = nbps2;
}
else
{
nbps2 = 1;
IndicePointdeDepart2 = 1;
}
}
else if (NombreDePointsDeDepartDuCheminement == 3)
{
if (IndicePointdeDepart1 == nbp)
{
nbps2 = (IndicePointdeDepart1 + IndicePointdeDepart2) / 2;
}
else
{
nbps2 = nbp;
}
}
else
{
nbps2 = NombreDePointsDeDepartDuCheminement - 3;
NombreDePointsDeDepartDuCheminement++;
}
if (TabPtDep[nbps2] == 0)
{
TabPtDep[nbps2] = 1;
SectionPointToParameters(LineSec.GetPoint(nbps2), Poly1, Poly2, U1, V1, U2, V2);
StartParams(1) = U1;
StartParams(2) = V1;
StartParams(3) = U2;
StartParams(4) = V2;
HasStartPoint = PW.PerformFirstPoint(StartParams, StartPOn2S);
dminiPointLigne = SeuildPointLigne + SeuildPointLigne;
if (HasStartPoint)
{
StartPOn2S.Parameters(pu1, pv1, pu2, pv2);
NbLigCalculee = SLin.Length();
int l;
for (l = 1; (l <= NbLigCalculee) && (dminiPointLigne >= SeuildPointLigne); l++)
{
const occ::handle<IntPatch_WLine>& testwline =
*((occ::handle<IntPatch_WLine>*)&SLin.Value(l));
if (IsPointOnLine(StartPOn2S, testwline, Deflection))
{
dminiPointLigne = 0.0;
}
} // for ( l ...
if (dminiPointLigne > SeuildPointLigne)
{
PW.Perform(StartParams,
UminLig1,
VminLig1,
UminLig2,
VminLig2,
UmaxLig1,
VmaxLig1,
UmaxLig2,
VmaxLig2);
if (PW.IsDone())
{
if (PW.NbPoints() > 2)
{
RejetLigne = false;
Point3dDebut = PW.Value(1).Value();
const IntSurf_PntOn2S& PointFin = PW.Value(PW.NbPoints());
Point3dFin = PointFin.Value();
for (ver = 1; ver <= NbLigCalculee; ver++)
{
const occ::handle<IntPatch_WLine>& verwline =
*((occ::handle<IntPatch_WLine>*)&SLin.Value(ver));
// Check end point if it is on existing line.
// Start point is checked before.
if (IsPointOnLine(PointFin, verwline, Deflection))
{
RejetLigne = true;
break;
}
const IntSurf_PntOn2S& verPointDebut = verwline->Point(1);
const IntSurf_PntOn2S& verPointFin = verwline->Point(verwline->NbPnts());
if ((Point3dDebut.Distance(verPointDebut.Value()) <= TolTangency)
&& (Point3dFin.Distance(verPointFin.Value()) <= TolTangency))
{
RejetLigne = true;
break;
}
}
if (RejetLigne)
{
DublicateOfLinesProcessing(PW, ver, SLin, RejetLigne);
}
if (!RejetLigne)
{
// Calculation transition
IntSurf_TypeTrans trans1, trans2;
double locu, locv;
gp_Vec norm1, norm2, d1u, d1v;
gp_Pnt ptbid;
int indextg;
gp_Vec tgline(PW.TangentAtLine(indextg));
PW.Line()->Value(indextg).ParametersOnS1(locu, locv);
Surf1->D1(locu, locv, ptbid, d1u, d1v);
norm1 = d1u.Crossed(d1v);
PW.Line()->Value(indextg).ParametersOnS2(locu, locv);
Surf2->D1(locu, locv, ptbid, d1u, d1v);
norm2 = d1u.Crossed(d1v);
if (tgline.DotCross(norm2, norm1) > 0.)
{
trans1 = IntSurf_Out;
trans2 = IntSurf_In;
}
else
{
trans1 = IntSurf_In;
trans2 = IntSurf_Out;
}
double TolTang = TolTangency;
occ::handle<IntPatch_WLine> wline =
new IntPatch_WLine(PW.Line(), false, trans1, trans2);
wline->SetCreatingWayInfo(IntPatch_WLine::IntPatch_WLPrmPrm);
// the method PutVertexOnLine can reduce the number of points in <wline>
IntPatch_RstInt::PutVertexOnLine(wline, Surf1, D1, Surf2, true, TolTang);
if (wline->NbPnts() < 2)
{
continue;
}
IntPatch_RstInt::PutVertexOnLine(wline, Surf2, D2, Surf1, false, TolTang);
if (wline->NbPnts() < 2)
{
continue;
}
if (wline->NbVertex() == 0)
{
IntPatch_Point vtx;
IntSurf_PntOn2S POn2S = PW.Line()->Value(1);
POn2S.Parameters(pu1, pv1, pu2, pv2);
vtx.SetValue(Point3dDebut, TolTang, false);
vtx.SetParameters(pu1, pv1, pu2, pv2);
vtx.SetParameter(1);
wline->AddVertex(vtx);
POn2S = PW.Line()->Value(wline->NbPnts());
POn2S.Parameters(pu1, pv1, pu2, pv2);
vtx.SetValue(Point3dFin, TolTang, false);
vtx.SetParameters(pu1, pv1, pu2, pv2);
vtx.SetParameter(wline->NbPnts());
wline->AddVertex(vtx);
}
lignetrouvee = true;
AddWLine(SLin, wline, Deflection);
empt = false;
} // !RejetLigne
} // PW.NbPoints()>2
} // done is True
} // dminiPointLigne > SeuildPointLigne
} // HasStartPoint
} // TabPtDep[nbps2]==0
} while (nbp > 5
&& (((NombreDePointsDeDepartDuCheminement < 3) || !lignetrouvee)
&& ((NombreDePointsDeDepartDuCheminement - 3 < nbp) || lignetrouvee)));
delete[] TabPtDep;
} // for( ls ...
delete[] TabL;
} // nbLigSec >= 1
double UminLig1, VminLig1, UmaxLig1, VmaxLig1;
double UminLig2, VminLig2, UmaxLig2, VmaxLig2;
UminLig1 = VminLig1 = UminLig2 = VminLig2 = RealLast();
UmaxLig1 = VmaxLig1 = UmaxLig2 = VmaxLig2 = -UminLig1;
int z;
for (z = 1; z <= nbTanZon; z++)
{
const Intf_TangentZone& TangentZone = Interference.ZoneValue(z);
for (int pz = 1; pz <= TangentZone.NumberOfPoints(); pz++)
{
SectionPointToParameters(TangentZone.GetPoint(pz), Poly1, Poly2, U1, V1, U2, V2);
if (U1 > UmaxLig1)
{
UmaxLig1 = U1;
}
if (V1 > VmaxLig1)
{
VmaxLig1 = V1;
}
if (U2 > UmaxLig2)
{
UmaxLig2 = U2;
}
if (V2 > VmaxLig2)
{
VmaxLig2 = V2;
}
if (U1 < UminLig1)
{
UminLig1 = U1;
}
if (V1 < VminLig1)
{
VminLig1 = V1;
}
if (U2 < UminLig2)
{
UminLig2 = U2;
}
if (V2 < VminLig2)
{
VminLig2 = V2;
}
}
}
for (z = 1; z <= nbTanZon; z++)
{
const Intf_TangentZone& TangentZone = Interference.ZoneValue(z);
int pz;
for (pz = 1; pz <= TangentZone.NumberOfPoints(); pz++)
{
SectionPointToParameters(TangentZone.GetPoint(pz), Poly1, Poly2, U1, V1, U2, V2);
StartParams(1) = U1;
StartParams(2) = V1;
StartParams(3) = U2;
StartParams(4) = V2;
HasStartPoint = PW.PerformFirstPoint(StartParams, StartPOn2S);
if (HasStartPoint)
{
StartPOn2S.Parameters(pu1, pv1, pu2, pv2);
NbLigCalculee = SLin.Length();
dminiPointLigne = SeuildPointLigne + SeuildPointLigne;
int l;
for (l = 1; (l <= NbLigCalculee) && (dminiPointLigne >= SeuildPointLigne); l++)
{
const occ::handle<IntPatch_WLine>& testwline =
*((occ::handle<IntPatch_WLine>*)&SLin.Value(l));
if (IsPointOnLine(StartPOn2S, testwline, Deflection))
{
dminiPointLigne = 0.0;
}
} // for( l ...
if (dminiPointLigne > SeuildPointLigne)
{
PW.Perform(StartParams,
UminLig1,
VminLig1,
UminLig2,
VminLig2,
UmaxLig1,
VmaxLig1,
UmaxLig2,
VmaxLig2);
if (PW.IsDone())
{
if (PW.NbPoints() > 2)
{
RejetLigne = false;
Point3dDebut = PW.Value(1).Value();
const IntSurf_PntOn2S& PointFin = PW.Value(PW.NbPoints());
Point3dFin = PointFin.Value();
for (ver = 1; ver <= NbLigCalculee; ver++)
{
const occ::handle<IntPatch_WLine>& verwline =
*((occ::handle<IntPatch_WLine>*)&SLin.Value(ver));
// Check end point if it is on existing line.
// Start point is checked before.
if (IsPointOnLine(PointFin, verwline, Deflection))
{
RejetLigne = true;
break;
}
const IntSurf_PntOn2S& verPointDebut = verwline->Point(1);
const IntSurf_PntOn2S& verPointFin = verwline->Point(verwline->NbPnts());
if ((Point3dDebut.Distance(verPointDebut.Value()) < TolTangency)
|| (Point3dFin.Distance(verPointFin.Value()) < TolTangency))
{
RejetLigne = true;
break;
}
}
if (RejetLigne)
{
DublicateOfLinesProcessing(PW, ver, SLin, RejetLigne);
}
if (!RejetLigne)
{
IntSurf_TypeTrans trans1, trans2;
double locu, locv;
gp_Vec norm1, norm2, d1u, d1v;
gp_Pnt ptbid;
int indextg;
gp_Vec tgline(PW.TangentAtLine(indextg));
PW.Line()->Value(indextg).ParametersOnS1(locu, locv);
Surf1->D1(locu, locv, ptbid, d1u, d1v);
norm1 = d1u.Crossed(d1v);
PW.Line()->Value(indextg).ParametersOnS2(locu, locv);
Surf2->D1(locu, locv, ptbid, d1u, d1v);
norm2 = d1u.Crossed(d1v);
if (tgline.DotCross(norm2, norm1) > 0.)
{
trans1 = IntSurf_Out;
trans2 = IntSurf_In;
}
else
{
trans1 = IntSurf_In;
trans2 = IntSurf_Out;
}
double TolTang = TolTangency;
occ::handle<IntPatch_WLine> wline =
new IntPatch_WLine(PW.Line(), false, trans1, trans2);
wline->SetCreatingWayInfo(IntPatch_WLine::IntPatch_WLPrmPrm);
// the method PutVertexOnLine can reduce the number of points in <wline>
IntPatch_RstInt::PutVertexOnLine(wline, Surf1, D1, Surf2, true, TolTang);
if (wline->NbPnts() < 2)
{
continue;
}
IntPatch_RstInt::PutVertexOnLine(wline, Surf2, D2, Surf1, false, TolTang);
if (wline->NbPnts() < 2)
{
continue;
}
if (wline->NbVertex() == 0)
{
IntPatch_Point vtx;
IntSurf_PntOn2S POn2S = PW.Line()->Value(1);
POn2S.Parameters(pu1, pv1, pu2, pv2);
vtx.SetValue(Point3dDebut, TolTang, false);
vtx.SetParameters(pu1, pv1, pu2, pv2);
vtx.SetParameter(1);
wline->AddVertex(vtx);
POn2S = PW.Line()->Value(wline->NbPnts());
POn2S.Parameters(pu1, pv1, pu2, pv2);
vtx.SetValue(Point3dFin, TolTang, false);
vtx.SetParameters(pu1, pv1, pu2, pv2);
vtx.SetParameter(wline->NbPnts());
wline->AddVertex(vtx);
}
AddWLine(SLin, wline, Deflection);
empt = false;
} // if !RejetLigne
} // PW.NbPoints()>2
} // done is True
} // dminiPointLigne > SeuildPointLigne
} // HasStartPoint
} // for( pz ...
} // for( z ...
}
//=================================================================================================
void IntPatch_PrmPrmIntersection::Perform(const occ::handle<Adaptor3d_Surface>& Surf1,
const IntPatch_Polyhedron& Poly1,
const occ::handle<Adaptor3d_TopolTool>& D1,
const double TolTangency,
const double Epsilon,
const double Deflection,
const double Increment)
{
IntPatch_InterferencePolyhedron Interference(Poly1);
empt = true;
done = true;
SLin.Clear();
int nbLigSec = Interference.NbSectionLines();
int nbTanZon = Interference.NbTangentZones();
int NbPntOn2SOnLine;
int NbLigCalculee = 0;
double U1, U2, V1, V2;
double pu1, pu2, pv1, pv2;
NCollection_Array1<double> StartParams(1, 4);
IntWalk_PWalking PW(Surf1, Surf1, TolTangency, Epsilon, Deflection, Increment);
double SeuildPointLigne = 15.0 * Increment * Increment; //-- 10 est insuffisant
double incidence;
double dminiPointLigne;
bool HasStartPoint, RejetLigne;
IntSurf_PntOn2S StartPOn2S;
int ver;
gp_Pnt Point3dDebut, Point3dFin;
if (nbLigSec >= 1)
{
int ls;
for (ls = 1; ls <= nbLigSec; ls++)
{
const Intf_SectionLine& LineSec = Interference.LineValue(ls);
int nbp = LineSec.NumberOfPoints();
int nbps2 = (nbp > 3) ? (nbp / 2) : 1;
int NombreDePointsDeDepartDuCheminement = 0;
int IndicePointdeDepart1 = 0, IndicePointdeDepart2 = 0;
do
{
NombreDePointsDeDepartDuCheminement++;
if (NombreDePointsDeDepartDuCheminement == 1)
{
incidence = 0.0;
int nsp1;
for (nsp1 = nbp / 2; nsp1 >= 1; nsp1--)
{
SectionPointToParameters(LineSec.GetPoint(nsp1), Poly1, Poly1, U1, V1, U2, V2);
double CurrentIncidence = std::abs(U1 - U2) + std::abs(V1 - V2);
if (CurrentIncidence > incidence)
{
nbps2 = nsp1;
incidence = CurrentIncidence;
}
}
for (nsp1 = nbp / 2; nsp1 <= nbp; nsp1++)
{
SectionPointToParameters(LineSec.GetPoint(nsp1), Poly1, Poly1, U1, V1, U2, V2);
double CurrentIncidence = std::abs(U1 - U2) + std::abs(V1 - V2);
if (CurrentIncidence > incidence)
{
nbps2 = nsp1;
incidence = CurrentIncidence;
}
}
if (nbp < 3)
{
NombreDePointsDeDepartDuCheminement = 3;
}
IndicePointdeDepart1 = nbps2;
}
else if (NombreDePointsDeDepartDuCheminement == 2)
{
if (IndicePointdeDepart1 == 1)
{
nbps2 = nbp / 2;
IndicePointdeDepart2 = nbps2;
}
else
{
nbps2 = 1;
IndicePointdeDepart2 = 1;
}
}
else
{
if (IndicePointdeDepart1 == nbp)
{
nbps2 = (IndicePointdeDepart1 + IndicePointdeDepart2) / 2;
}
else
{
nbps2 = nbp;
}
}
SectionPointToParameters(LineSec.GetPoint(nbps2), Poly1, Poly1, U1, V1, U2, V2);
StartParams(1) = U1;
StartParams(2) = V1;
StartParams(3) = U2;
StartParams(4) = V2;
HasStartPoint = PW.PerformFirstPoint(StartParams, StartPOn2S);
dminiPointLigne = SeuildPointLigne + SeuildPointLigne;
if (HasStartPoint)
{
StartPOn2S.Parameters(pu1, pv1, pu2, pv2);
if (std::abs(pu1 - pu2) > 1e-7 || std::abs(pv1 - pv2) > 1e-7)
{
NbLigCalculee = SLin.Length();
int l;
for (l = 1; (l <= NbLigCalculee) && (dminiPointLigne >= SeuildPointLigne); l++)
{
const occ::handle<IntPatch_WLine>& testwline =
*((occ::handle<IntPatch_WLine>*)&SLin.Value(l));
if ((!testwline->IsOutSurf1Box(gp_Pnt2d(pu1, pv1)))
&& (!testwline->IsOutSurf2Box(gp_Pnt2d(pu2, pv2)))
&& (!testwline->IsOutBox(StartPOn2S.Value())))
{
NbPntOn2SOnLine = testwline->NbPnts();
int ll;
for (ll = 1; (ll < NbPntOn2SOnLine) && (dminiPointLigne >= SeuildPointLigne); ll++)
{
double t, Au1, Av1, Au2, Av2, Bu1, Bv1, Bu2, Bv2;
testwline->Point(ll).Parameters(Au1, Av1, Au2, Av2);
testwline->Point(ll + 1).Parameters(Bu1, Bv1, Bu2, Bv2);
if (Au1 > Bu1)
{
t = Au1;
Au1 = Bu1;
Bu1 = t;
}
if (Av1 > Bv1)
{
t = Av1;
Av1 = Bv1;
Bv1 = t;
}
Au1 -= 1.0e-7;
Av1 -= 1.0e-7;
Bu1 += 1.0e-7;
Bv1 += 1.0e-7;
if ((pu1 >= Au1) && (pu1 <= Bu1) && (pv1 >= Av1) && (pv1 <= Bv1))
{
dminiPointLigne = 0.0;
}
else
{
if ((pu2 >= Au1) && (pu2 <= Bu1) && (pv2 >= Av1) && (pv2 <= Bv1))
{
dminiPointLigne = 0.0;
}
}
} // for( ll ...
} // if ...
} // for( l ...
if (dminiPointLigne > SeuildPointLigne)
{
PW.Perform(StartParams);
if (PW.IsDone())
{
if (PW.NbPoints() > 2)
{
RejetLigne = false;
Point3dDebut = PW.Value(1).Value();
Point3dFin = PW.Value(PW.NbPoints()).Value();
for (ver = 1; ver <= NbLigCalculee; ver++)
{
const occ::handle<IntPatch_WLine>& verwline =
*((occ::handle<IntPatch_WLine>*)&SLin.Value(ver));
const IntSurf_PntOn2S& verPointDebut = verwline->Point(1);
const IntSurf_PntOn2S& verPointFin = verwline->Point(verwline->NbPnts());
if ((Point3dDebut.Distance(verPointDebut.Value()) < TolTangency)
|| (Point3dFin.Distance(verPointFin.Value()) < TolTangency))
{
RejetLigne = true;
break;
}
}
if (RejetLigne)
{
DublicateOfLinesProcessing(PW, ver, SLin, RejetLigne);
}
if (!RejetLigne)
{
IntSurf_TypeTrans trans1, trans2;
double locu, locv;
gp_Vec norm1, norm2, d1u, d1v;
gp_Pnt ptbid;
int indextg;
gp_Vec tgline(PW.TangentAtLine(indextg));
PW.Line()->Value(indextg).ParametersOnS1(locu, locv);
Surf1->D1(locu, locv, ptbid, d1u, d1v);
norm1 = d1u.Crossed(d1v);
PW.Line()->Value(indextg).ParametersOnS2(locu, locv);
Surf1->D1(locu, locv, ptbid, d1u, d1v);
norm2 = d1u.Crossed(d1v);
if (tgline.DotCross(norm2, norm1) > 0.)
{
trans1 = IntSurf_Out;
trans2 = IntSurf_In;
}
else
{
trans1 = IntSurf_In;
trans2 = IntSurf_Out;
}
IntSurf_LineOn2S LineOn2S;
int nbpw, imin, imax, i;
nbpw = PW.Line()->NbPoints();
double u1, v1, u2, v2;
i = 0;
do
{
i++;
imin = i;
const IntSurf_PntOn2S& Pi = PW.Line()->Value(i);
Pi.Parameters(u1, v1, u2, v2);
} while ((i < nbpw)
&& (std::abs(u1 - u2) <= 1e-6 && std::abs(v1 - v2) <= 1e-6));
if (imin > 2)
{
imin--;
}
i = nbpw + 1;
do
{
i--;
imax = i;
const IntSurf_PntOn2S& Pi = PW.Line()->Value(i);
Pi.Parameters(u1, v1, u2, v2);
} while ((i > 2) && (std::abs(u1 - u2) <= 1e-6 && std::abs(v1 - v2) <= 1e-6));
if (imax < nbpw)
{
imax++;
}
if (imin < imax)
{
occ::handle<IntSurf_LineOn2S> PWLine = new IntSurf_LineOn2S();
for (i = imin; i <= imax; i++)
{
PWLine->Add(PW.Line()->Value(i));
}
double TolTang = TolTangency;
occ::handle<IntPatch_WLine> wline =
new IntPatch_WLine(PWLine, false, trans1, trans2);
wline->SetCreatingWayInfo(IntPatch_WLine::IntPatch_WLPrmPrm);
const IntSurf_PntOn2S& POn2SDeb = wline->Point(1);
const IntSurf_PntOn2S& POn2SFin = wline->Point(wline->NbPnts());
if ((POn2SDeb.Value()).Distance(POn2SFin.Value()) <= TolTangency)
{
double u1t, v1t, u2t, v2t;
POn2SDeb.Parameters(u1t, v1t, u2t, v2t);
IntPatch_Point vtx;
vtx.SetValue(POn2SDeb.Value(), TolTang, false);
vtx.SetParameters(u2t, v2t, u1t, v1t);
vtx.SetParameter(wline->NbPnts());
wline->SetPoint(wline->NbPnts(), vtx);
}
// the method PutVertexOnLine can reduce the number of points in <wline>
IntPatch_RstInt::PutVertexOnLine(wline, Surf1, D1, Surf1, true, TolTang);
if (wline->NbPnts() < 2)
{
continue;
}
if (wline->NbVertex() == 0)
{
IntPatch_Point vtx;
IntSurf_PntOn2S POn2S = PW.Line()->Value(1);
POn2S.Parameters(pu1, pv1, pu2, pv2);
vtx.SetValue(Point3dDebut, TolTang, false);
vtx.SetParameters(pu1, pv1, pu2, pv2);
vtx.SetParameter(1);
wline->AddVertex(vtx);
POn2S = PW.Line()->Value(wline->NbPnts());
POn2S.Parameters(pu1, pv1, pu2, pv2);
vtx.SetValue(Point3dFin, TolTang, false);
vtx.SetParameters(pu1, pv1, pu2, pv2);
vtx.SetParameter(wline->NbPnts());
wline->AddVertex(vtx);
}
SLin.Append(wline);
empt = false;
} // imin<imax
} // !RejetLigne
} // PW.NbPoints()>2
} // done is True
} // dminiPointLigne > SeuildPointLigne
} // Abs || Abs
} // HasStartPoint
} while (nbp > 5 && NombreDePointsDeDepartDuCheminement < 3);
} // for( ls ...
} // nbLigSec>=1
int z;
for (z = 1; z <= nbTanZon; z++)
{
const Intf_TangentZone& TangentZone = Interference.ZoneValue(z);
for (int pz = 1; pz <= TangentZone.NumberOfPoints(); pz++)
{
SectionPointToParameters(TangentZone.GetPoint(pz), Poly1, Poly1, U1, V1, U2, V2);
StartParams(1) = U1;
StartParams(2) = V1;
StartParams(3) = U2;
StartParams(4) = V2;
HasStartPoint = PW.PerformFirstPoint(StartParams, StartPOn2S);
if (HasStartPoint)
{
StartPOn2S.Parameters(pu1, pv1, pu2, pv2);
if (std::abs(pu1 - pu2) > 1e-7 || std::abs(pv1 - pv2) > 1e-7)
{
NbLigCalculee = SLin.Length();
dminiPointLigne = SeuildPointLigne + SeuildPointLigne;
int l;
for (l = 1; (l <= NbLigCalculee) && (dminiPointLigne >= SeuildPointLigne); l++)
{
const occ::handle<IntPatch_WLine>& testwline =
*((occ::handle<IntPatch_WLine>*)&SLin.Value(l));
if ((!testwline->IsOutSurf1Box(gp_Pnt2d(pu1, pv1)))
&& (!testwline->IsOutSurf2Box(gp_Pnt2d(pu2, pv2)))
&& (!testwline->IsOutBox(StartPOn2S.Value())))
{
NbPntOn2SOnLine = testwline->NbPnts();
int ll;
for (ll = 1; (ll < NbPntOn2SOnLine) && (dminiPointLigne >= SeuildPointLigne); ll++)
{
double t, Au1, Av1, Au2, Av2, Bu1, Bv1, Bu2, Bv2;
testwline->Point(ll).Parameters(Au1, Av1, Au2, Av2);
testwline->Point(ll + 1).Parameters(Bu1, Bv1, Bu2, Bv2);
if (Au1 > Bu1)
{
t = Au1;
Au1 = Bu1;
Bu1 = t;
}
if (Av1 > Bv1)
{
t = Av1;
Av1 = Bv1;
Bv1 = t;
}
Au1 -= 1.0e-7;
Av1 -= 1.0e-7;
Bu1 += 1.0e-7;
Bv1 += 1.0e-7;
if ((pu1 >= Au1) && (pu1 <= Bu1) && (pv1 >= Av1) && (pv1 <= Bv1))
{
dminiPointLigne = 0.0;
}
else
{
if ((pu2 >= Au1) && (pu2 <= Bu1) && (pv2 >= Av1) && (pv2 <= Bv1))
{
dminiPointLigne = 0.0;
}
}
} // for( ll ...
} // if ...
} // for( l ...
if (dminiPointLigne > SeuildPointLigne)
{
PW.Perform(StartParams);
if (PW.IsDone())
{
if (PW.NbPoints() > 2)
{
RejetLigne = false;
Point3dDebut = PW.Value(1).Value();
Point3dFin = PW.Value(PW.NbPoints()).Value();
for (ver = 1; ver <= NbLigCalculee; ver++)
{
const occ::handle<IntPatch_WLine>& verwline =
*((occ::handle<IntPatch_WLine>*)&SLin.Value(ver));
const IntSurf_PntOn2S& verPointDebut = verwline->Point(1);
const IntSurf_PntOn2S& verPointFin = verwline->Point(verwline->NbPnts());
if ((Point3dDebut.Distance(verPointDebut.Value()) < TolTangency)
|| (Point3dFin.Distance(verPointFin.Value()) < TolTangency))
{
RejetLigne = true;
break;
}
}
if (RejetLigne)
{
DublicateOfLinesProcessing(PW, ver, SLin, RejetLigne);
}
if (!RejetLigne)
{
IntSurf_TypeTrans trans1, trans2;
double locu, locv;
gp_Vec norm1, norm2, d1u, d1v;
gp_Pnt ptbid;
int indextg;
gp_Vec tgline(PW.TangentAtLine(indextg));
PW.Line()->Value(indextg).ParametersOnS1(locu, locv);
Surf1->D1(locu, locv, ptbid, d1u, d1v);
norm1 = d1u.Crossed(d1v);
PW.Line()->Value(indextg).ParametersOnS2(locu, locv);
Surf1->D1(locu, locv, ptbid, d1u, d1v);
norm2 = d1u.Crossed(d1v);
if (tgline.DotCross(norm2, norm1) > 0.)
{
trans1 = IntSurf_Out;
trans2 = IntSurf_In;
}
else
{
trans1 = IntSurf_In;
trans2 = IntSurf_Out;
}
IntSurf_LineOn2S LineOn2S;
int nbp, imin, imax, i;
nbp = PW.Line()->NbPoints();
double u1, v1, u2, v2;
i = 0;
do
{
i++;
imin = i;
const IntSurf_PntOn2S& Pi = PW.Line()->Value(i);
Pi.Parameters(u1, v1, u2, v2);
} while ((i < nbp) && (std::abs(u1 - u2) <= 1e-6 && std::abs(v1 - v2) <= 1e-6));
if (imin > 2)
{
imin--;
}
i = nbp + 1;
do
{
i--;
imax = i;
const IntSurf_PntOn2S& Pi = PW.Line()->Value(i);
Pi.Parameters(u1, v1, u2, v2);
} while ((i > 2) && (std::abs(u1 - u2) <= 1e-6 && std::abs(v1 - v2) <= 1e-6));
if (imax < nbp)
{
imax++;
}
if (imin < imax)
{
occ::handle<IntSurf_LineOn2S> PWLine = new IntSurf_LineOn2S();
for (i = imin; i <= imax; i++)
{
PWLine->Add(PW.Line()->Value(i));
}
double TolTang = TolTangency;
occ::handle<IntPatch_WLine> wline =
new IntPatch_WLine(PWLine, false, trans1, trans2);
wline->SetCreatingWayInfo(IntPatch_WLine::IntPatch_WLPrmPrm);
const IntSurf_PntOn2S& POn2SDeb = wline->Point(1);
const IntSurf_PntOn2S& POn2SFin = wline->Point(wline->NbPnts());
if ((POn2SDeb.Value()).Distance(POn2SFin.Value()) <= TolTangency)
{
double u1t, v1t, u2t, v2t;
POn2SDeb.Parameters(u1t, v1t, u2t, v2t);
IntPatch_Point vtx;
vtx.SetValue(POn2SDeb.Value(), TolTang, false);
vtx.SetParameters(u2t, v2t, u1t, v1t);
vtx.SetParameter(wline->NbPnts());
wline->SetPoint(wline->NbPnts(), vtx);
}
// the method PutVertexOnLine can reduce the number of points in <wline>
IntPatch_RstInt::PutVertexOnLine(wline, Surf1, D1, Surf1, true, TolTang);
if (wline->NbPnts() < 2)
{
continue;
}
if (wline->NbVertex() == 0)
{
IntPatch_Point vtx;
IntSurf_PntOn2S POn2S = PW.Line()->Value(1);
POn2S.Parameters(pu1, pv1, pu2, pv2);
vtx.SetValue(Point3dDebut, TolTang, false);
vtx.SetParameters(pu1, pv1, pu2, pv2);
vtx.SetParameter(1);
wline->AddVertex(vtx);
POn2S = PW.Line()->Value(wline->NbPnts());
POn2S.Parameters(pu1, pv1, pu2, pv2);
vtx.SetValue(Point3dFin, TolTang, false);
vtx.SetParameters(pu1, pv1, pu2, pv2);
vtx.SetParameter(wline->NbPnts());
wline->AddVertex(vtx);
}
SLin.Append(wline);
empt = false;
} // imin<imax
} // !RejetLigne
} // PW.NbPoints()>2
} // done a True
} // dminiPointLigne > SeuildPointLigne
} // Abs || Abs
} // HasStartPoint
} // for ( pz ...
} // for( z ...
}
//=================================================================================================
occ::handle<IntPatch_Line> IntPatch_PrmPrmIntersection::NewLine(
const occ::handle<Adaptor3d_Surface>& Surf1,
const occ::handle<Adaptor3d_Surface>& Surf2,
const int NumLine,
const int Low,
const int High,
const int NbPntsToInsert) const
{
int NbPnts = NbPntsToInsert + High - Low;
if (NumLine > NbLines() || NumLine < 1 || Low >= High)
{
throw Standard_OutOfRange(" IntPatch_PrmPrmIntersection NewLine ");
}
//------------------------------------------------------------------
//-- Indice : Low Low+1 I I+1 High --
//-- --
//-- Abs.Curv. : S(Low) S(I) S(I+1) S(High) --
//-- --
//-- On echantillonne a abcisse curviligne --
//-- constante. --
//-- L abcisse est calculee sur les params U1,V1 --
//------------------------------------------------------------------
NCollection_Array1<double> U1(Low, High);
NCollection_Array1<double> V1(Low, High);
NCollection_Array1<double> U2(Low, High);
NCollection_Array1<double> V2(Low, High);
NCollection_Array1<double> AC(Low, High);
double s, ds;
occ::handle<IntPatch_WLine> TheLine = occ::down_cast<IntPatch_WLine>(Line(NumLine));
const IntSurf_PntOn2S& Point = TheLine->Point(Low);
double u1, v1, u2, v2;
Point.Parameters(u1, v1, u2, v2);
U1(Low) = u1;
V1(Low) = v1;
U2(Low) = u2;
V2(Low) = v2;
AC(Low) = 0.0;
IntWalk_PWalking PW(Surf1, Surf2, 0.000001, 0.000001, 0.001, 0.001);
int i;
for (i = Low + 1; i <= High; i++)
{
const IntSurf_PntOn2S& Pointi = TheLine->Point(i);
Pointi.Parameters(u1, v1, u2, v2);
U1(i) = u1;
V1(i) = v1;
U2(i) = u2;
V2(i) = v2;
double du1 = u1 - U1(i - 1);
double dv1 = v1 - V1(i - 1);
AC(i) = AC(i - 1) + std::sqrt((du1 * du1) + (dv1 * dv1));
}
occ::handle<IntSurf_LineOn2S> ResultPntOn2SLine = new IntSurf_LineOn2S();
IntSurf_PntOn2S StartPOn2S;
NCollection_Array1<double> StartParams(1, 4);
ResultPntOn2SLine->Add(TheLine->Point(Low));
ds = AC(High) / (NbPnts - 1);
int Indice = Low;
double dsmin = ds * 0.3;
double smax = AC(High);
for (i = 2, s = ds; (i < NbPnts) && (s < smax); i++, s += ds)
{
while (AC(Indice + 1) <= s)
{
ResultPntOn2SLine->Add(TheLine->Point(Indice));
Indice++;
}
double a = s - AC(Indice);
double b = AC(Indice + 1) - s;
double nab = 1.0 / (a + b);
//----------------------------------------------------------
//-- Verification : Si Dist au prochain point < dsmin --
//-- Si Dist au precedent point < dsmin --
//-- --
//----------------------------------------------------------
if ((nab > ds) && (a > dsmin) && (b > dsmin))
{
StartParams(1) = (U1(Indice) * b + U1(Indice + 1) * a) * nab;
StartParams(2) = (V1(Indice) * b + V1(Indice + 1) * a) * nab;
StartParams(3) = (U2(Indice) * b + U2(Indice + 1) * a) * nab;
StartParams(4) = (V2(Indice) * b + V2(Indice + 1) * a) * nab;
bool HasStartPoint = PW.PerformFirstPoint(StartParams, StartPOn2S);
if (HasStartPoint)
{
ResultPntOn2SLine->Add(StartPOn2S);
}
}
else
{
s += dsmin;
}
}
ResultPntOn2SLine->Add(TheLine->Point(High));
occ::handle<IntPatch_WLine> aRWL = new IntPatch_WLine(ResultPntOn2SLine, false);
aRWL->SetCreatingWayInfo(IntPatch_WLine::IntPatch_WLPrmPrm);
return (aRWL);
}
//=================================================================================================
void SectionPointToParameters(const Intf_SectionPoint& Sp,
const IntPatch_Polyhedron& Poly1,
const IntPatch_Polyhedron& Poly2,
double& u1,
double& v1,
double& u2,
double& v2)
{
Intf_PIType typ;
int Adr1, Adr2;
double Param, u, v;
gp_Pnt P(Sp.Pnt());
int Pt1, Pt2, Pt3;
Sp.InfoFirst(typ, Adr1, Adr2, Param);
switch (typ)
{
case Intf_VERTEX: //-- Adr1 est le numero du vertex
{
Poly1.Parameters(Adr1, u1, v1);
break;
}
case Intf_EDGE: {
Poly1.Parameters(Adr1, u1, v1);
Poly1.Parameters(Adr2, u, v);
u1 += Param * (u - u1);
v1 += Param * (v - v1);
break;
}
case Intf_FACE: {
double ua, va, ub, vb, uc, vc, ca, cb, cc, cabc;
Poly1.Triangle(Adr1, Pt1, Pt2, Pt3);
gp_Pnt PA(Poly1.Point(Pt1));
gp_Pnt PB(Poly1.Point(Pt2));
gp_Pnt PC(Poly1.Point(Pt3));
Poly1.Parameters(Pt1, ua, va);
Poly1.Parameters(Pt2, ub, vb);
Poly1.Parameters(Pt3, uc, vc);
gp_Vec Normale(gp_Vec(PA, PB).Crossed(gp_Vec(PA, PC)));
cc = (gp_Vec(PA, PB).Crossed(gp_Vec(PA, P))).Dot(Normale);
ca = (gp_Vec(PB, PC).Crossed(gp_Vec(PB, P))).Dot(Normale);
cb = (gp_Vec(PC, PA).Crossed(gp_Vec(PC, P))).Dot(Normale);
cabc = ca + cb + cc;
ca /= cabc;
cb /= cabc;
cc /= cabc;
u1 = ca * ua + cb * ub + cc * uc;
v1 = ca * va + cb * vb + cc * vc;
break;
}
default: {
//-- std::cout<<" Default dans SectionPointToParameters "<<std::endl;
break;
}
}
Sp.InfoSecond(typ, Adr1, Adr2, Param);
switch (typ)
{
case Intf_VERTEX: //-- Adr1 est le numero du vertex
{
Poly2.Parameters(Adr1, u2, v2);
break;
}
case Intf_EDGE: {
Poly2.Parameters(Adr1, u2, v2);
Poly2.Parameters(Adr2, u, v);
u2 += Param * (u - u2);
v2 += Param * (v - v2);
break;
}
case Intf_FACE: {
double ua, va, ub, vb, uc, vc, ca, cb, cc, cabc;
Poly2.Triangle(Adr1, Pt1, Pt2, Pt3);
gp_Pnt PA(Poly2.Point(Pt1));
gp_Pnt PB(Poly2.Point(Pt2));
gp_Pnt PC(Poly2.Point(Pt3));
Poly2.Parameters(Pt1, ua, va);
Poly2.Parameters(Pt2, ub, vb);
Poly2.Parameters(Pt3, uc, vc);
gp_Vec Normale(gp_Vec(PA, PB).Crossed(gp_Vec(PA, PC)));
cc = (gp_Vec(PA, PB).Crossed(gp_Vec(PA, P))).Dot(Normale);
ca = (gp_Vec(PB, PC).Crossed(gp_Vec(PB, P))).Dot(Normale);
cb = (gp_Vec(PC, PA).Crossed(gp_Vec(PC, P))).Dot(Normale);
cabc = ca + cb + cc;
ca /= cabc;
cb /= cabc;
cc /= cabc;
u2 = ca * ua + cb * ub + cc * uc;
v2 = ca * va + cb * vb + cc * vc;
break;
}
default: {
//-- std::cout<<" Default dans SectionPointToParameters "<<std::endl;
break;
}
}
}
//=================================================================================================
void IntPatch_PrmPrmIntersection::RemplitLin(const int x1,
const int y1,
const int z1,
const int x2,
const int y2,
const int z2,
IntPatch_PrmPrmIntersection_T3Bits& Map) const
{
int xg, yg, zg;
xg = x1 - x2;
if (xg < 0)
{
xg = -xg;
}
yg = y1 - y2;
if (yg < 0)
{
yg = -yg;
}
zg = z1 - z2;
if (zg < 0)
{
zg = -zg;
}
if (DansGrille(x1) && DansGrille(y1) && DansGrille(z1))
{
int t = GrilleInteger(x1, y1, z1);
Map.Add(t);
}
if (xg <= 1 && yg <= 1 && zg <= 1)
{
return;
}
xg = (x1 + x2) >> 1;
yg = (y1 + y2) >> 1;
zg = (z1 + z2) >> 1;
RemplitLin(x1, y1, z1, xg, yg, zg, Map);
RemplitLin(x2, y2, z2, xg, yg, zg, Map);
}
//=================================================================================================
void IntPatch_PrmPrmIntersection::RemplitTri(const int x1,
const int y1,
const int z1,
const int x2,
const int y2,
const int z2,
const int x3,
const int y3,
const int z3,
IntPatch_PrmPrmIntersection_T3Bits& Map) const
{
if (x1 == x2 && x1 == x3 && y1 == y2 && y1 == y3 && z1 == z2 && z1 == z3)
{
if (DansGrille(x1) && DansGrille(y1) && DansGrille(z1))
{
int t = GrilleInteger(x1, y1, z1);
Map.Add(t);
}
return;
}
else
{
int xg = (x1 + x2 + x3) / 3;
int yg = (y1 + y2 + y3) / 3;
int zg = (z1 + z2 + z3) / 3;
if (xg == x1 && yg == y1 && zg == z1)
{
RemplitLin(x1, y1, z1, x2, y2, z2, Map);
RemplitLin(x1, y1, z1, x3, y3, z3, Map);
return;
}
if (xg == x2 && yg == y2 && zg == z2)
{
RemplitLin(x2, y2, z2, x1, y1, z1, Map);
RemplitLin(x2, y2, z2, x3, y3, z3, Map);
return;
}
if (xg == x3 && yg == y3 && zg == z3)
{
RemplitLin(x3, y3, z3, x2, y2, z2, Map);
RemplitLin(x3, y3, z3, x1, y1, z1, Map);
return;
}
if (DansGrille(xg) && DansGrille(yg) && DansGrille(zg))
{
int t = GrilleInteger(xg, yg, zg);
Map.Add(t);
}
if (xg != x3 || yg != y3 || zg != z3)
{
RemplitTri(x1, y1, z1, x2, y2, z2, xg, yg, zg, Map);
}
if (xg != x1 || yg != y1 || zg != z1)
{
RemplitTri(xg, yg, zg, x2, y2, z2, x3, y3, z3, Map);
}
if (xg != x2 || yg != y2 || zg != z2)
{
RemplitTri(x1, y1, z1, xg, yg, zg, x3, y3, z3, Map);
}
}
}
//=================================================================================================
void IntPatch_PrmPrmIntersection::Remplit(const int a,
const int b,
const int c,
IntPatch_PrmPrmIntersection_T3Bits& Map) const
{
int iax, iay, iaz, ibx, iby, ibz, icx, icy, icz;
if (a != -1)
{
Map.Add(a);
}
if (b != -1)
{
Map.Add(b);
}
if (c != -1)
{
Map.Add(c);
}
if (a != -1 && b != -1 && c != -1)
{
IntegerGrille(a, iax, iay, iaz);
IntegerGrille(b, ibx, iby, ibz);
IntegerGrille(c, icx, icy, icz);
RemplitTri(iax, iay, iaz, ibx, iby, ibz, icx, icy, icz, Map);
}
}
//=================================================================================================
void IntPatch_PrmPrmIntersection::Perform(const occ::handle<Adaptor3d_Surface>& Surf1,
const occ::handle<Adaptor3d_TopolTool>& D1,
const occ::handle<Adaptor3d_Surface>& Surf2,
const occ::handle<Adaptor3d_TopolTool>& D2,
const double TolTangency,
const double Epsilon,
const double Deflection,
const double Increment,
NCollection_List<IntSurf_PntOn2S>& LOfPnts)
{
if (LOfPnts.IsEmpty())
{
done = true;
return;
}
empt = true;
SLin.Clear();
double UminLig1, VminLig1, UmaxLig1, VmaxLig1;
double UminLig2, VminLig2, UmaxLig2, VmaxLig2;
double U1, U2, V1, V2;
UminLig1 = Surf1->FirstUParameter();
VminLig1 = Surf1->FirstVParameter();
UmaxLig1 = Surf1->LastUParameter();
VmaxLig1 = Surf1->LastVParameter();
UminLig2 = Surf2->FirstUParameter();
VminLig2 = Surf2->FirstVParameter();
UmaxLig2 = Surf2->LastUParameter();
VmaxLig2 = Surf2->LastVParameter();
double Periods[4];
Periods[0] = (Surf1->IsUPeriodic()) ? Surf1->UPeriod() : 0.;
Periods[1] = (Surf1->IsVPeriodic()) ? Surf1->VPeriod() : 0.;
Periods[2] = (Surf2->IsUPeriodic()) ? Surf2->UPeriod() : 0.;
Periods[3] = (Surf2->IsVPeriodic()) ? Surf2->VPeriod() : 0.;
NCollection_List<IntSurf_PntOn2S>::Iterator IterLOP1(LOfPnts);
if (Surf1->IsUClosed() || Surf1->IsVClosed() || Surf2->IsUClosed() || Surf2->IsVClosed())
{
constexpr double TolPar = Precision::PConfusion();
NCollection_List<IntSurf_PntOn2S> AdditionalPnts;
double NewU1, NewV1, NewU2, NewV2;
for (; IterLOP1.More(); IterLOP1.Next())
{
IntSurf_PntOn2S Pnt = IterLOP1.Value();
Pnt.Parameters(U1, V1, U2, V2);
IntSurf_PntOn2S NewPnt;
if (Surf1->IsUClosed())
{
if (std::abs(U1 - Surf1->FirstUParameter()) <= TolPar)
{
NewU1 = Surf1->LastUParameter();
NewPnt.SetValue(NewU1, V1, U2, V2);
AdditionalPnts.Append(NewPnt);
}
else if (std::abs(U1 - Surf1->LastUParameter()) <= TolPar)
{
NewU1 = Surf1->FirstUParameter();
NewPnt.SetValue(NewU1, V1, U2, V2);
AdditionalPnts.Append(NewPnt);
}
}
if (Surf1->IsVClosed())
{
if (std::abs(V1 - Surf1->FirstVParameter()) <= TolPar)
{
NewV1 = Surf1->LastVParameter();
NewPnt.SetValue(U1, NewV1, U2, V2);
AdditionalPnts.Append(NewPnt);
}
else if (std::abs(V1 - Surf1->LastVParameter()) <= TolPar)
{
NewV1 = Surf1->FirstVParameter();
NewPnt.SetValue(U1, NewV1, U2, V2);
AdditionalPnts.Append(NewPnt);
}
}
if (Surf2->IsUClosed())
{
if (std::abs(U2 - Surf2->FirstUParameter()) <= TolPar)
{
NewU2 = Surf2->LastUParameter();
NewPnt.SetValue(U1, V1, NewU2, V2);
AdditionalPnts.Append(NewPnt);
}
else if (std::abs(U2 - Surf2->LastUParameter()) <= TolPar)
{
NewU2 = Surf2->FirstUParameter();
NewPnt.SetValue(U1, V1, NewU2, V2);
AdditionalPnts.Append(NewPnt);
}
}
if (Surf2->IsVClosed())
{
if (std::abs(V2 - Surf2->FirstVParameter()) <= TolPar)
{
NewV2 = Surf2->LastVParameter();
NewPnt.SetValue(U1, V1, U2, NewV2);
AdditionalPnts.Append(NewPnt);
}
else if (std::abs(V2 - Surf2->LastVParameter()) <= TolPar)
{
NewV2 = Surf2->FirstVParameter();
NewPnt.SetValue(U1, V1, U2, NewV2);
AdditionalPnts.Append(NewPnt);
}
}
}
// Cut repeated points
for (IterLOP1.Initialize(LOfPnts); IterLOP1.More(); IterLOP1.Next())
{
IntSurf_PntOn2S aPnt = IterLOP1.Value();
aPnt.Parameters(U1, V1, U2, V2);
NCollection_List<IntSurf_PntOn2S>::Iterator iter2(AdditionalPnts);
while (iter2.More())
{
IntSurf_PntOn2S aNewPnt = iter2.Value();
aNewPnt.Parameters(NewU1, NewV1, NewU2, NewV2);
if (std::abs(U1 - NewU1) <= TolPar && std::abs(V1 - NewV1) <= TolPar
&& std::abs(U2 - NewU2) <= TolPar && std::abs(V2 - NewV2) <= TolPar)
{
AdditionalPnts.Remove(iter2);
}
else
{
iter2.Next();
}
}
}
LOfPnts.Append(AdditionalPnts);
}
for (IterLOP1.Initialize(LOfPnts); IterLOP1.More(); IterLOP1.Next())
{
IntSurf_PntOn2S Pnt = IterLOP1.Value();
Pnt.Parameters(U1, V1, U2, V2);
if (U1 > UmaxLig1)
{
UmaxLig1 = U1;
}
if (V1 > VmaxLig1)
{
VmaxLig1 = V1;
}
if (U2 > UmaxLig2)
{
UmaxLig2 = U2;
}
if (V2 > VmaxLig2)
{
VmaxLig2 = V2;
}
if (U1 < UminLig1)
{
UminLig1 = U1;
}
if (V1 < VminLig1)
{
VminLig1 = V1;
}
if (U2 < UminLig2)
{
UminLig2 = U2;
}
if (V2 < VminLig2)
{
VminLig2 = V2;
}
}
double SeuildPointLigne = 15.0 * Increment * Increment;
int NbLigCalculee = 0, ver;
double pu1, pu2, pv1, pv2, dminiPointLigne;
bool HasStartPoint, RejetLigne;
IntSurf_PntOn2S StartPOn2S;
gp_Pnt Point3dDebut, Point3dFin;
NCollection_Array1<double> StartParams(1, 4);
IntWalk_PWalking PW(Surf1, Surf2, TolTangency, Epsilon, Deflection, Increment);
NCollection_List<IntSurf_PntOn2S>::Iterator IterLOP2(LOfPnts);
for (; IterLOP2.More(); IterLOP2.Next())
{
IntSurf_PntOn2S cPnt = IterLOP2.Value();
cPnt.Parameters(U1, V1, U2, V2);
StartParams(1) = U1;
StartParams(2) = V1;
StartParams(3) = U2;
StartParams(4) = V2;
HasStartPoint = PW.PerformFirstPoint(StartParams, StartPOn2S);
dminiPointLigne = SeuildPointLigne + SeuildPointLigne;
if (HasStartPoint)
{
StartPOn2S.Parameters(pu1, pv1, pu2, pv2);
NbLigCalculee = SLin.Length();
int l;
for (l = 1; (l <= NbLigCalculee) && (dminiPointLigne >= SeuildPointLigne); l++)
{
const occ::handle<IntPatch_WLine>& testwline =
*((occ::handle<IntPatch_WLine>*)&SLin.Value(l));
if (IsPointOnLine(StartPOn2S, testwline, Deflection))
{
dminiPointLigne = 0.0;
}
} // for( l ...
if (dminiPointLigne > SeuildPointLigne)
{
PW.Perform(StartParams,
UminLig1,
VminLig1,
UminLig2,
VminLig2,
UmaxLig1,
VmaxLig1,
UmaxLig2,
VmaxLig2);
if (PW.IsDone())
{
if (PW.NbPoints() > 2)
{
// Try to extend the intersection line to boundary, if it is possible.
PW.PutToBoundary(Surf1, Surf2);
RejetLigne = false;
Point3dDebut = PW.Value(1).Value();
const IntSurf_PntOn2S& PointFin = PW.Value(PW.NbPoints());
Point3dFin = PointFin.Value();
for (ver = 1; ver <= NbLigCalculee; ver++)
{
const occ::handle<IntPatch_WLine>& verwline =
*((occ::handle<IntPatch_WLine>*)&SLin.Value(ver));
// Check end point if it is on existing line.
// Start point is checked before.
if (IsPointOnLine(PointFin, verwline, Deflection))
{
RejetLigne = true;
break;
}
const IntSurf_PntOn2S& verPointDebut = verwline->Point(1);
const IntSurf_PntOn2S& verPointFin = verwline->Point(verwline->NbPnts());
if ((Point3dDebut.Distance(verPointDebut.Value()) <= TolTangency)
&& (Point3dFin.Distance(verPointFin.Value()) <= TolTangency))
{
RejetLigne = true;
break;
}
}
if (RejetLigne)
{
DublicateOfLinesProcessing(PW, ver, SLin, RejetLigne);
}
if (!RejetLigne)
{
IntSurf_TypeTrans trans1, trans2;
double locu, locv;
gp_Vec norm1, norm2, d1u, d1v;
gp_Pnt ptbid;
int indextg;
gp_Vec tgline(PW.TangentAtLine(indextg));
PW.Line()->Value(indextg).ParametersOnS1(locu, locv);
Surf1->D1(locu, locv, ptbid, d1u, d1v);
norm1 = d1u.Crossed(d1v);
PW.Line()->Value(indextg).ParametersOnS2(locu, locv);
Surf2->D1(locu, locv, ptbid, d1u, d1v);
norm2 = d1u.Crossed(d1v);
if (tgline.DotCross(norm2, norm1) >= 0.)
{
trans1 = IntSurf_Out;
trans2 = IntSurf_In;
}
else
{
trans1 = IntSurf_In;
trans2 = IntSurf_Out;
}
double TolTang = TolTangency;
occ::handle<IntPatch_WLine> wline =
new IntPatch_WLine(PW.Line(), false, trans1, trans2);
wline->SetCreatingWayInfo(IntPatch_WLine::IntPatch_WLPrmPrm);
// the method PutVertexOnLine can reduce the number of points in <wline>
IntPatch_RstInt::PutVertexOnLine(wline, Surf1, D1, Surf2, true, TolTang);
if (wline->NbPnts() < 2)
{
continue;
}
IntPatch_RstInt::PutVertexOnLine(wline, Surf2, D2, Surf1, false, TolTang);
if (wline->NbPnts() < 2)
{
continue;
}
if (wline->NbVertex() == 0)
{
IntPatch_Point vtx;
IntSurf_PntOn2S POn2S = PW.Line()->Value(1);
POn2S.Parameters(pu1, pv1, pu2, pv2);
vtx.SetValue(Point3dDebut, TolTang, false);
vtx.SetParameters(pu1, pv1, pu2, pv2);
vtx.SetParameter(1);
wline->AddVertex(vtx);
POn2S = PW.Line()->Value(wline->NbPnts());
POn2S.Parameters(pu1, pv1, pu2, pv2);
vtx.SetValue(Point3dFin, TolTang, false);
vtx.SetParameters(pu1, pv1, pu2, pv2);
vtx.SetParameter(wline->NbPnts());
wline->AddVertex(vtx);
}
SeveralWlinesProcessing(Surf1,
Surf2,
SLin,
Periods,
trans1,
trans2,
TolTang,
std::max(PW.MaxStep(0), PW.MaxStep(1)),
std::max(PW.MaxStep(2), PW.MaxStep(3)),
wline);
AddWLine(SLin, wline, Deflection);
empt = false;
} // !RejetLigne
} // PW points > 2
} // done is True
} // dminiPointLigne > SeuildPointLigne
} // HasStartPoint
} // for( IterLOP ...
done = true;
}
//=================================================================================================
void IntPatch_PrmPrmIntersection::Perform(const occ::handle<Adaptor3d_Surface>& Surf1,
const occ::handle<Adaptor3d_TopolTool>& D1,
const occ::handle<Adaptor3d_Surface>& Surf2,
const occ::handle<Adaptor3d_TopolTool>& D2,
const double U1Depart,
const double V1Depart,
const double U2Depart,
const double V2Depart,
const double TolTangency,
const double Epsilon,
const double Deflection,
const double Increment)
{
// int NbU1 = D1->NbSamplesU();
// int NbV1 = D1->NbSamplesV();
// int NbU2 = D2->NbSamplesU();
// int NbV2 = D2->NbSamplesV();
//-- Traitement des Lignes de sections
empt = true;
done = true;
SLin.Clear();
//------------------------------------------------------------
double pu1, pu2, pv1, pv2;
NCollection_Array1<double> StartParams(1, 4);
// int MaxOscill = NbU1;
// if(MaxOscill < NbU2) MaxOscill=NbU2;
// if(MaxOscill < NbV1) MaxOscill=NbV1;
// if(MaxOscill < NbV2) MaxOscill=NbV2;
// double nIncrement=Increment;
// if(MaxOscill>10) {
// #ifdef OCCT_DEBUG
// std::cout<<"\n IntPatch_PrmPrmIntersection.gxx : Increment:"<<Increment<<" ->
// "<<Increment/(0.5*MaxOscill)<<std::endl;
// #endif
// nIncrement/=0.5*MaxOscill;
// }
IntWalk_PWalking PW(Surf1, Surf2, TolTangency, Epsilon, Deflection,
Increment); // nIncrement);
// double SeuildPointLigne = 15.0 * Increment * Increment; //-- 10 est insuffisant
// double incidence;
// double dminiPointLigne;
bool HasStartPoint; //,RejetLigne;
IntSurf_PntOn2S StartPOn2S;
// int ver;
gp_Pnt Point3dDebut, Point3dFin;
//------------------------------------------------------------
StartParams(1) = U1Depart;
StartParams(2) = V1Depart;
StartParams(3) = U2Depart;
StartParams(4) = V2Depart;
//-----------------------------------------------------------------------
//-- Calcul du premier point de cheminement a partir du point approche --
//-----------------------------------------------------------------------
HasStartPoint = PW.PerformFirstPoint(StartParams, StartPOn2S);
if (HasStartPoint)
{
//-------------------------------------------------
//-- Un point a ete trouve --
//-- On verifie qu il n appartient pas --
//-- a une ligne de cheminement deja calculee. --
//-------------------------------------------------
PW.Perform(StartParams);
if (PW.IsDone())
{
if (PW.NbPoints() > 2)
{
Point3dDebut = PW.Value(1).Value();
Point3dFin = PW.Value(PW.NbPoints()).Value();
IntSurf_TypeTrans trans1, trans2;
double locu, locv;
gp_Vec norm1, norm2, d1u, d1v;
gp_Pnt ptbid;
int indextg;
gp_Vec tgline(PW.TangentAtLine(indextg));
PW.Line()->Value(indextg).ParametersOnS1(locu, locv);
Surf1->D1(locu, locv, ptbid, d1u, d1v);
norm1 = d1u.Crossed(d1v);
PW.Line()->Value(indextg).ParametersOnS2(locu, locv);
Surf2->D1(locu, locv, ptbid, d1u, d1v);
norm2 = d1u.Crossed(d1v);
if (tgline.DotCross(norm2, norm1) > 0.)
{
trans1 = IntSurf_Out;
trans2 = IntSurf_In;
}
else
{
trans1 = IntSurf_In;
trans2 = IntSurf_Out;
}
double TolTang = TolTangency;
occ::handle<IntPatch_WLine> wline = new IntPatch_WLine(PW.Line(), false, trans1, trans2);
wline->SetCreatingWayInfo(IntPatch_WLine::IntPatch_WLPrmPrm);
// the method PutVertexOnLine can reduce the number of points in <wline>
IntPatch_RstInt::PutVertexOnLine(wline, Surf1, D1, Surf2, true, TolTang);
if (wline->NbPnts() < 2)
{
return;
}
IntPatch_RstInt::PutVertexOnLine(wline, Surf2, D2, Surf1, false, TolTang);
if (wline->NbPnts() < 2)
{
return;
}
//---------------
if (wline->NbVertex() == 0)
{
IntPatch_Point vtx;
IntSurf_PntOn2S POn2S = PW.Line()->Value(1);
POn2S.Parameters(pu1, pv1, pu2, pv2);
vtx.SetValue(Point3dDebut, TolTang, false);
vtx.SetParameters(pu1, pv1, pu2, pv2);
vtx.SetParameter(1);
wline->AddVertex(vtx);
POn2S = PW.Line()->Value(wline->NbPnts());
POn2S.Parameters(pu1, pv1, pu2, pv2);
vtx.SetValue(Point3dFin, TolTang, false);
vtx.SetParameters(pu1, pv1, pu2, pv2);
vtx.SetParameter(wline->NbPnts());
wline->AddVertex(vtx);
}
//---------------
SLin.Append(wline);
empt = false;
} // if(PW.NbPoints()>2)
} // if(PW.IsDone())
} // if(HasStartPoint)
}
//=================================================================================================
void AdjustOnPeriodic(const occ::handle<Adaptor3d_Surface>& Surf1,
const occ::handle<Adaptor3d_Surface>& Surf2,
NCollection_Sequence<occ::handle<IntPatch_Line>>& aSLin)
{
bool bIsPeriodic[4], bModified, bIsNull, bIsPeriod;
int i, j, k, aNbLines, aNbPx, aIndx, aIndq;
double aPeriod[4], dPeriod[4], ux[4], uq[4], aEps, du;
//
aEps = Precision::Confusion();
//
for (k = 0; k < 4; ++k)
{
aPeriod[k] = 0.;
}
//
bIsPeriodic[0] = Surf1->IsUPeriodic();
bIsPeriodic[1] = Surf1->IsVPeriodic();
bIsPeriodic[2] = Surf2->IsUPeriodic();
bIsPeriodic[3] = Surf2->IsVPeriodic();
//
if (bIsPeriodic[0])
{
aPeriod[0] = Surf1->UPeriod();
}
if (bIsPeriodic[1])
{
aPeriod[1] = Surf1->VPeriod();
}
if (bIsPeriodic[2])
{
aPeriod[2] = Surf2->UPeriod();
}
if (bIsPeriodic[3])
{
aPeriod[3] = Surf2->VPeriod();
}
//
for (k = 0; k < 4; ++k)
{
dPeriod[k] = 0.25 * aPeriod[k];
}
//
aNbLines = aSLin.Length();
for (i = 1; i <= aNbLines; ++i)
{
occ::handle<IntPatch_WLine> aIL = occ::down_cast<IntPatch_WLine>(aSLin.Value(i));
occ::handle<IntSurf_LineOn2S> aL = aIL->Curve();
aNbPx = aL->NbPoints();
if (aNbPx < 10)
{
continue;
}
//
for (j = 0; j < 2; ++j)
{
bModified = false;
aIndx = 1;
aIndq = 2;
if (j)
{
aIndx = aNbPx;
aIndq = aNbPx - 1;
}
//
const IntSurf_PntOn2S& aPSx = aL->Value(aIndx);
const IntSurf_PntOn2S& aPSq = aL->Value(aIndq);
//
aPSx.Parameters(ux[0], ux[1], ux[2], ux[3]);
aPSq.Parameters(uq[0], uq[1], uq[2], uq[3]);
//
for (k = 0; k < 4; ++k)
{
bIsNull = false;
bIsPeriod = false;
//
if (!bIsPeriodic[k])
{
continue;
}
//
if (fabs(ux[k]) < aEps)
{
bModified = true;
bIsNull = true;
}
//
else if (fabs(ux[k] - aPeriod[k]) < aEps)
{
bModified = true;
bIsPeriod = true;
}
//
if (bModified)
{
du = fabs(ux[k] - uq[k]);
if (du > dPeriod[k])
{
if (bIsNull)
{
ux[k] = aPeriod[k];
}
if (bIsPeriod)
{
ux[k] = 0.;
}
}
}
} // for (k=0; k<4; ++k)
if (bModified)
{
IntSurf_PntOn2S aPntOn2S;
//
aPntOn2S = aPSx;
aPntOn2S.SetValue(ux[0], ux[1], ux[2], ux[3]);
aL->Value(aIndx, aPntOn2S);
}
} // for (j=0; j<1; ++j) {
} // for (i=1; i<=aNbLines; ++i)
}
//=================================================================================================
IntSurf_PntOn2S MakeNewPoint(const IntSurf_PntOn2S& replacePnt,
const IntSurf_PntOn2S& oldPnt,
const double* Periods)
{
IntSurf_PntOn2S NewPoint;
NewPoint.SetValue(replacePnt.Value());
double OldParams[4], NewParams[4];
oldPnt.Parameters(OldParams[0], OldParams[1], OldParams[2], OldParams[3]);
replacePnt.Parameters(NewParams[0], NewParams[1], NewParams[2], NewParams[3]);
int i;
for (i = 0; i < 4; i++)
{
if (Periods[i] != 0.)
{
if (std::abs(NewParams[i] - OldParams[i]) >= 0.5 * Periods[i])
{
if (NewParams[i] < OldParams[i])
{
NewParams[i] += Periods[i];
}
else
{
NewParams[i] -= Periods[i];
}
}
}
}
NewPoint.SetValue(NewParams[0], NewParams[1], NewParams[2], NewParams[3]);
return NewPoint;
}
//=================================================================================================
void IntPatch_PrmPrmIntersection::Perform(const occ::handle<Adaptor3d_Surface>& Surf1,
const occ::handle<Adaptor3d_TopolTool>& D1,
const occ::handle<Adaptor3d_Surface>& Surf2,
const occ::handle<Adaptor3d_TopolTool>& D2,
const double TolTangency,
const double Epsilon,
const double Deflection,
const double Increment,
const bool ClearFlag)
{
int Limit = 2500;
int NbU1 = 10, NbV1 = 10, NbU2 = 10, NbV2 = 10;
//
D1->SamplePnts(Deflection, NbU1, NbV1);
D2->SamplePnts(Deflection, NbU2, NbV2);
//
NbU1 = D1->NbSamplesU();
NbV1 = D1->NbSamplesV();
NbU2 = D2->NbSamplesU();
NbV2 = D2->NbSamplesV();
NCollection_Array1<double> anUpars1(1, NbU1), aVpars1(1, NbV1);
NCollection_Array1<double> anUpars2(1, NbU2), aVpars2(1, NbV2);
//
D1->UParameters(anUpars1);
D1->VParameters(aVpars1);
D2->UParameters(anUpars2);
D2->VParameters(aVpars2);
double Periods[4];
Periods[0] = (Surf1->IsUPeriodic()) ? Surf1->UPeriod() : 0.;
Periods[1] = (Surf1->IsVPeriodic()) ? Surf1->VPeriod() : 0.;
Periods[2] = (Surf2->IsUPeriodic()) ? Surf2->UPeriod() : 0.;
Periods[3] = (Surf2->IsVPeriodic()) ? Surf2->VPeriod() : 0.;
//---------------------------------------------
if ((NbU1 * NbV1 <= Limit && NbV2 * NbU2 <= Limit))
{
empt = true;
if (ClearFlag)
{
SLin.Clear();
}
//
IntPolyh_Intersection* pInterference = nullptr;
if (D1->IsUniformSampling() || D2->IsUniformSampling())
{
pInterference = new IntPolyh_Intersection(Surf1, NbU1, NbV1, Surf2, NbU2, NbV2);
}
else
{
pInterference = new IntPolyh_Intersection(Surf1, anUpars1, aVpars1, Surf2, anUpars2, aVpars2);
}
if (!pInterference)
{
done = false;
return;
}
//
IntPolyh_Intersection& Interference = *pInterference;
//
done = Interference.IsDone();
if (!done)
{
delete pInterference;
pInterference = nullptr;
return;
}
int nbLigSec = Interference.NbSectionLines();
int nbTanZon = Interference.NbTangentZones();
double SeuildPointLigne = 15.0 * Increment * Increment;
int NbLigCalculee = 0, ver;
double pu1, pu2, pv1, pv2, incidence, dminiPointLigne;
bool HasStartPoint = false, RejectLine = false;
IntSurf_PntOn2S StartPOn2S;
gp_Pnt Point3dDebut, Point3dFin;
NCollection_Array1<double> StartParams(1, 4);
IntWalk_PWalking PW(Surf1, Surf2, TolTangency, Epsilon, Deflection, Increment);
if (nbLigSec >= 1)
{
int* TabL = new int[nbLigSec + 1];
for (int ls = 1; ls <= nbLigSec; ++ls)
{
TabL[ls] = ls;
}
//----------------------------------------1.1
{
bool triok;
int nb_A, nb_B, tyu;
do
{
triok = true;
for (int b = 2; b <= nbLigSec; ++b)
{
nb_B = Interference.NbPointsInLine(TabL[b]);
nb_A = Interference.NbPointsInLine(TabL[b - 1]);
if (nb_B > nb_A)
{
tyu = TabL[b];
TabL[b] = TabL[b - 1];
TabL[b - 1] = tyu;
triok = false;
}
}
} while (!triok);
}
//----------------------------------------
// 1.2 For the line "ls" get 2D-bounds U,V for surfaces 1,2
//
for (int ls = 1; ls <= nbLigSec; ++ls)
{
int nbp = Interference.NbPointsInLine(TabL[ls]);
if (!nbp)
{
continue;
}
//
int* TabPtDep = new int[nbp + 1];
for (int ilig = 1; ilig <= nbp; ++ilig)
{
TabPtDep[ilig] = 0;
}
//
double UminLig1, VminLig1, UmaxLig1, VmaxLig1;
double UminLig2, VminLig2, UmaxLig2, VmaxLig2;
double _x, _y, _z;
//
Interference
.GetLinePoint(TabL[ls], 1, _x, _y, _z, UminLig1, VminLig1, UminLig2, VminLig2, incidence);
UmaxLig1 = UminLig1;
VmaxLig1 = VminLig1;
UmaxLig2 = UminLig2;
VmaxLig2 = VminLig2;
//
for (int ilig = 2; ilig <= nbp; ilig++)
{
double U1, U2, V1, V2;
Interference.GetLinePoint(TabL[ls], ilig, _x, _y, _z, U1, V1, U2, V2, incidence);
//
if (U1 > UmaxLig1)
{
UmaxLig1 = U1;
}
if (V1 > VmaxLig1)
{
VmaxLig1 = V1;
}
if (U2 > UmaxLig2)
{
UmaxLig2 = U2;
}
if (V2 > VmaxLig2)
{
VmaxLig2 = V2;
}
//
if (U1 < UminLig1)
{
UminLig1 = U1;
}
if (V1 < VminLig1)
{
VminLig1 = V1;
}
if (U2 < UminLig2)
{
UminLig2 = U2;
}
if (V2 < VminLig2)
{
VminLig2 = V2;
}
} // for( ilig = 2; ilig <= nbp; ilig++ ) {
//
//----------------------------------------
// 1.3
int nbps2 = (nbp > 3) ? (nbp / 2) : 1;
int NombreDePointsDeDepartDuCheminement = 0;
bool lignetrouvee = false;
const int NbDePointsDeDepartDuChmLimit = 5;
//
do
{
NombreDePointsDeDepartDuCheminement++;
switch (NombreDePointsDeDepartDuCheminement)
{
case 1:
nbps2 = (nbp > 1) ? nbp / 2 : 1;
if (nbp < 3)
{
NombreDePointsDeDepartDuCheminement = NbDePointsDeDepartDuChmLimit;
}
break;
case 2:
nbps2 = 1;
break;
case 3:
nbps2 = nbp - 1;
break;
case 4:
nbps2 = 3 * nbp / 4;
break;
case 5:
nbps2 = nbp / 4;
break;
default:
nbps2 = NombreDePointsDeDepartDuCheminement - 3;
NombreDePointsDeDepartDuCheminement++;
}
//
if (TabPtDep[nbps2] == 0)
{
double U1, U2, V1, V2;
TabPtDep[nbps2] = 1;
Interference.GetLinePoint(TabL[ls], nbps2, _x, _y, _z, U1, V1, U2, V2, incidence);
StartParams(1) = U1;
StartParams(2) = V1;
StartParams(3) = U2;
StartParams(4) = V2;
HasStartPoint = PW.PerformFirstPoint(StartParams, StartPOn2S);
dminiPointLigne = SeuildPointLigne + SeuildPointLigne;
if (HasStartPoint)
{
StartPOn2S.Parameters(pu1, pv1, pu2, pv2);
NbLigCalculee = SLin.Length();
int l;
for (l = 1; (l <= NbLigCalculee) && (dminiPointLigne >= SeuildPointLigne); l++)
{
const occ::handle<IntPatch_WLine>& testwline =
*((occ::handle<IntPatch_WLine>*)&SLin.Value(l));
if (IsPointOnLine(StartPOn2S, testwline, Deflection))
{
dminiPointLigne = 0.0;
}
} // for( l ...
if (dminiPointLigne > SeuildPointLigne)
{
PW.Perform(StartParams,
UminLig1,
VminLig1,
UminLig2,
VminLig2,
UmaxLig1,
VmaxLig1,
UmaxLig2,
VmaxLig2);
//
bool bPWIsDone;
double aD11, aD12, aD21, aD22, aDx;
//
bPWIsDone = PW.IsDone();
if (bPWIsDone)
{
bool hasBeenAdded = false;
if (PW.NbPoints() > 2)
{
// Try to extend the intersection line to the boundary,
// if it is possibly
PW.PutToBoundary(Surf1, Surf2);
//
if (PW.NbPoints() < 3)
{
continue;
}
const int aMinNbPoints = 40;
if (PW.NbPoints() < aMinNbPoints)
{
hasBeenAdded = PW.SeekAdditionalPoints(Surf1, Surf2, aMinNbPoints);
}
int iPWNbPoints = PW.NbPoints(), aNbPointsVer = 0;
RejectLine = false;
Point3dDebut = PW.Value(1).Value();
Point3dFin = PW.Value(iPWNbPoints).Value();
for (ver = 1; (!RejectLine) && (ver <= NbLigCalculee); ++ver)
{
const occ::handle<IntPatch_WLine>& verwline =
*((occ::handle<IntPatch_WLine>*)&SLin.Value(ver));
//
aNbPointsVer = verwline->NbPnts();
if (aNbPointsVer < 3)
{
continue;
}
//
const IntSurf_PntOn2S& verPointDebut = verwline->Point(1);
const IntSurf_PntOn2S& verPointFin = verwline->Point(verwline->NbPnts());
// xf
const gp_Pnt& aP21 = verPointDebut.Value();
const gp_Pnt& aP22 = verPointFin.Value();
//
aD11 = Point3dDebut.Distance(aP21);
aD12 = Point3dDebut.Distance(aP22);
aD21 = Point3dFin.Distance(aP21);
aD22 = Point3dFin.Distance(aP22);
//
if ((aD11 <= TolTangency && aD22 <= TolTangency)
|| (aD12 <= TolTangency && aD21 <= TolTangency))
{
int m, mx;
//
mx = aNbPointsVer / 2;
if (aNbPointsVer % 2)
{
++mx;
}
//
const gp_Pnt& aPx = verwline->Point(mx).Value();
for (m = 1; m < iPWNbPoints; ++m)
{
const gp_Pnt& aP1 = PW.Value(m).Value();
const gp_Pnt& aP2 = PW.Value(m + 1).Value();
gp_Vec aVec12(aP1, aP2);
if (aVec12.SquareMagnitude() < 1.e-20)
{
continue;
}
//
gp_Dir aDir12(aVec12);
gp_Lin aLin12(aP1, aDir12);
aDx = aLin12.Distance(aPx);
// modified by NIZNHY-PKV Tue May 10 11:08:07 2011f
if (aDx <= 2. * Epsilon)
{
// if (aDx<=TolTangency) {
// modified by NIZNHY-PKV Tue May 10 11:08:13 2011t
RejectLine = true;
ver--;
break;
}
} // for(m=1; m<iPWNbPoints; ++m){
} // if((aD11<=TolTangency && aD22<=TolTangency) ||...
} // for( ver = 1 ; (!RejetLigne) && (ver<= NbLigCalculee) ; ver++) {
//
if (RejectLine)
{
DublicateOfLinesProcessing(PW, ver, SLin, RejectLine);
}
if (!RejectLine)
{
IntSurf_TypeTrans trans1, trans2;
double locu, locv;
gp_Vec norm1, norm2, d1u, d1v;
gp_Pnt ptbid;
int indextg;
gp_Vec tgline(PW.TangentAtLine(indextg));
PW.Line()->Value(indextg).ParametersOnS1(locu, locv);
Surf1->D1(locu, locv, ptbid, d1u, d1v);
norm1 = d1u.Crossed(d1v);
PW.Line()->Value(indextg).ParametersOnS2(locu, locv);
Surf2->D1(locu, locv, ptbid, d1u, d1v);
norm2 = d1u.Crossed(d1v);
if (tgline.DotCross(norm2, norm1) >= 0.)
{
trans1 = IntSurf_Out;
trans2 = IntSurf_In;
}
else
{
trans1 = IntSurf_In;
trans2 = IntSurf_Out;
}
double TolTang = TolTangency;
occ::handle<IntPatch_WLine> wline =
new IntPatch_WLine(PW.Line(), false, trans1, trans2);
wline->SetCreatingWayInfo(IntPatch_WLine::IntPatch_WLPrmPrm);
wline->EnablePurging(!hasBeenAdded);
// the method PutVertexOnLine can reduce the number of points in <wline>
IntPatch_RstInt::PutVertexOnLine(wline, Surf1, D1, Surf2, true, TolTang);
if (wline->NbPnts() < 2)
{
continue;
}
IntPatch_RstInt::PutVertexOnLine(wline, Surf2, D2, Surf1, false, TolTang);
if (wline->NbPnts() < 2)
{
continue;
}
if (wline->NbVertex() == 0)
{
IntPatch_Point vtx;
IntSurf_PntOn2S POn2S = PW.Line()->Value(1);
POn2S.Parameters(pu1, pv1, pu2, pv2);
vtx.SetValue(Point3dDebut, TolTang, false);
vtx.SetParameters(pu1, pv1, pu2, pv2);
vtx.SetParameter(1);
wline->AddVertex(vtx);
POn2S = PW.Line()->Value(wline->NbPnts());
POn2S.Parameters(pu1, pv1, pu2, pv2);
vtx.SetValue(Point3dFin, TolTang, false);
vtx.SetParameters(pu1, pv1, pu2, pv2);
vtx.SetParameter(wline->NbPnts());
wline->AddVertex(vtx);
}
lignetrouvee = true;
SeveralWlinesProcessing(Surf1,
Surf2,
SLin,
Periods,
trans1,
trans2,
TolTang,
std::max(PW.MaxStep(0), PW.MaxStep(1)),
std::max(PW.MaxStep(2), PW.MaxStep(3)),
wline);
AddWLine(SLin, wline, Deflection);
empt = false;
} // !RejetLigne
} // PW points > 2
} // done is True
} // dminiPointLigne > SeuildPointLigne
} // HasStartPoint
} // if TabPtDep[nbps2] == 0
} while (
nbp > 5
&& (NombreDePointsDeDepartDuCheminement < NbDePointsDeDepartDuChmLimit || !lignetrouvee)
&& (NombreDePointsDeDepartDuCheminement - 3 < nbp || !(!lignetrouvee)));
delete[] TabPtDep;
} // for( ls ...
delete[] TabL;
} // if nbLigSec >= 1
//
AdjustOnPeriodic(Surf1, Surf2, SLin);
//
//--------------------------------------------------------------------
//-- Calcul des parametres approches a partir des Zones De Tangence --
//--------------------------------------------------------------------
double UminLig1, VminLig1, UmaxLig1, VmaxLig1;
double UminLig2, VminLig2, UmaxLig2, VmaxLig2;
UminLig1 = VminLig1 = UminLig2 = VminLig2 = RealLast();
UmaxLig1 = VmaxLig1 = UmaxLig2 = VmaxLig2 = -UminLig1;
// NbPointsInTangentZone always == 1 (eap)
int z;
for (z = 1; z <= nbTanZon; z++)
{
// int NbPointsInTangentZone=Interference.NbPointsInTangentZone(z);
// for(int pz=1; pz<=NbPointsInTangentZone; pz++) {
int pz = 1;
double _x, _y, _z;
double U1, U2, V1, V2;
Interference.GetTangentZonePoint(z, pz, _x, _y, _z, U1, V1, U2, V2);
if (U1 > UmaxLig1)
{
UmaxLig1 = U1;
}
if (V1 > VmaxLig1)
{
VmaxLig1 = V1;
}
if (U2 > UmaxLig2)
{
UmaxLig2 = U2;
}
if (V2 > VmaxLig2)
{
VmaxLig2 = V2;
}
if (U1 < UminLig1)
{
UminLig1 = U1;
}
if (V1 < VminLig1)
{
VminLig1 = V1;
}
if (U2 < UminLig2)
{
UminLig2 = U2;
}
if (V2 < VminLig2)
{
VminLig2 = V2;
}
//}
}
for (z = 1; z <= nbTanZon; z++)
{
// int NbPointsInTangentZone=Interference.NbPointsInTangentZone(z);
// for(int pz=1; pz<=NbPointsInTangentZone; pz++) {
int pz = 1;
double _x, _y, _z;
double U1, U2, V1, V2;
Interference.GetTangentZonePoint(z, pz, _x, _y, _z, U1, V1, U2, V2);
StartParams(1) = U1;
StartParams(2) = V1;
StartParams(3) = U2;
StartParams(4) = V2;
//-----------------------------------------------------------------------
//-- Calcul du premier point de cheminement a partir du point approche --
//-----------------------------------------------------------------------
HasStartPoint = PW.PerformFirstPoint(StartParams, StartPOn2S);
if (HasStartPoint)
{
//-------------------------------------------------
//-- Un point a ete trouve --
//-- On verifie qu il n appartient pas --
//-- a une ligne de cheminement deja calculee. --
//-------------------------------------------------
StartPOn2S.Parameters(pu1, pv1, pu2, pv2);
NbLigCalculee = SLin.Length();
dminiPointLigne = SeuildPointLigne + SeuildPointLigne;
for (int l = 1; (l <= NbLigCalculee) && (dminiPointLigne >= SeuildPointLigne); l++)
{
const occ::handle<IntPatch_WLine>& testwline =
*((occ::handle<IntPatch_WLine>*)&SLin.Value(l));
if (IsPointOnLine(StartPOn2S, testwline, Deflection))
{
dminiPointLigne = 0.0;
}
}
//-- Fin d exploration des lignes
if (dminiPointLigne > SeuildPointLigne)
{
//---------------------------------------------------
//-- Le point de depart du nouveau cheminement --
//-- n est present dans aucune ligne deja calculee.--
//---------------------------------------------------
PW.Perform(StartParams,
UminLig1,
VminLig1,
UminLig2,
VminLig2,
UmaxLig1,
VmaxLig1,
UmaxLig2,
VmaxLig2);
if (PW.IsDone())
{
bool hasBeenAdded = false;
if (PW.NbPoints() > 2)
{
const int aMinNbPoints = 40;
if (PW.NbPoints() < aMinNbPoints)
{
hasBeenAdded = PW.SeekAdditionalPoints(Surf1, Surf2, aMinNbPoints);
}
//-----------------------------------------------
//-- Verification a posteriori :
//-- On teste si le point de depart et de fin de
//-- la ligne de cheminement est present dans une
//-- autre ligne .
//-----------------------------------------------
RejectLine = false;
Point3dDebut = PW.Value(1).Value();
const IntSurf_PntOn2S& PointFin = PW.Value(PW.NbPoints());
Point3dFin = PointFin.Value();
for (ver = 1; (!RejectLine) && (ver <= NbLigCalculee); ver++)
{
const occ::handle<IntPatch_WLine>& verwline =
*((occ::handle<IntPatch_WLine>*)&SLin.Value(ver));
//-- occ::handle<IntPatch_WLine>
// verwline=occ::down_cast<IntPatch_WLine>(SLin.Value(ver));
// Check end point if it is on existing line.
// Start point is checked before.
if (IsPointOnLine(PointFin, verwline, Deflection))
{
RejectLine = true;
break;
}
const IntSurf_PntOn2S& verPointDebut = verwline->Point(1);
const IntSurf_PntOn2S& verPointFin = verwline->Point(verwline->NbPnts());
if (Point3dDebut.Distance(verPointDebut.Value()) < TolTangency)
{
RejectLine = true;
}
else
{
if (Point3dFin.Distance(verPointFin.Value()) < TolTangency)
{
RejectLine = true;
}
}
}
if (!RejectLine)
{
IntSurf_TypeTrans trans1, trans2;
double locu, locv;
gp_Vec norm1, norm2, d1u, d1v;
gp_Pnt ptbid;
int indextg;
gp_Vec tgline(PW.TangentAtLine(indextg));
PW.Line()->Value(indextg).ParametersOnS1(locu, locv);
Surf1->D1(locu, locv, ptbid, d1u, d1v);
norm1 = d1u.Crossed(d1v);
PW.Line()->Value(indextg).ParametersOnS2(locu, locv);
Surf2->D1(locu, locv, ptbid, d1u, d1v);
norm2 = d1u.Crossed(d1v);
if (tgline.DotCross(norm2, norm1) > 0.)
{
trans1 = IntSurf_Out;
trans2 = IntSurf_In;
}
else
{
trans1 = IntSurf_In;
trans2 = IntSurf_Out;
}
double TolTang = TolTangency;
occ::handle<IntPatch_WLine> wline =
new IntPatch_WLine(PW.Line(), false, trans1, trans2);
wline->SetCreatingWayInfo(IntPatch_WLine::IntPatch_WLPrmPrm);
wline->EnablePurging(!hasBeenAdded);
// the method PutVertexOnLine can reduce the number of points in <wline>
IntPatch_RstInt::PutVertexOnLine(wline, Surf1, D1, Surf2, true, TolTang);
if (wline->NbPnts() < 2)
{
continue;
}
IntPatch_RstInt::PutVertexOnLine(wline, Surf2, D2, Surf1, false, TolTang);
if (wline->NbPnts() < 2)
{
continue;
}
//---------------
if (wline->NbVertex() == 0)
{
IntPatch_Point vtx;
IntSurf_PntOn2S POn2S = PW.Line()->Value(1);
POn2S.Parameters(pu1, pv1, pu2, pv2);
vtx.SetValue(Point3dDebut, TolTang, false);
vtx.SetParameters(pu1, pv1, pu2, pv2);
vtx.SetParameter(1);
wline->AddVertex(vtx);
POn2S = PW.Line()->Value(wline->NbPnts());
POn2S.Parameters(pu1, pv1, pu2, pv2);
vtx.SetValue(Point3dFin, TolTang, false);
vtx.SetParameters(pu1, pv1, pu2, pv2);
vtx.SetParameter(wline->NbPnts());
wline->AddVertex(vtx);
}
//---------------
AddWLine(SLin, wline, Deflection);
empt = false;
}
else
{
//-- std::cout<<" ----- REJET DE LIGNE (POINT DE DEPART) ----- "<<std::endl;
}
//------------------------------------------------------------
}
} //-- le cheminement a reussi (done a True)
} //-- le point approche ne renvoie pas sur une ligne existante
} //-- Si HasStartPoint
//} //-- Boucle Sur les Points de la Tangent Zone
} //-- Boucle sur Les Tangent Zones
if (pInterference)
{
delete pInterference;
pInterference = nullptr;
}
return;
} // if((NbU1*NbV1<=Limit && NbV2*NbU2<=Limit)) {
occ::handle<IntSurf_LineOn2S> LOn2S = new IntSurf_LineOn2S();
PointDepart(LOn2S, Surf1, NbU1, NbV1, Surf2, NbU2, NbV2);
empt = true;
done = true;
int NbLigCalculee = 0;
double U1, U2, V1, V2;
double pu1, pu2, pv1, pv2;
NCollection_Array1<double> StartParams(1, 4);
int MaxOscill = NbU1;
if (MaxOscill < NbU2)
{
MaxOscill = NbU2;
}
if (MaxOscill < NbV1)
{
MaxOscill = NbV1;
}
if (MaxOscill < NbV2)
{
MaxOscill = NbV2;
}
double nIncrement = Increment;
// if(MaxOscill>10)
// nIncrement/=0.5*MaxOscill;
IntWalk_PWalking PW(Surf1, Surf2, TolTangency, Epsilon, Deflection, nIncrement);
double SeuildPointLigne = 15.0 * Increment * Increment; //-- 10 est insuffisant
double dminiPointLigne;
bool HasStartPoint, RejetLigne;
IntSurf_PntOn2S StartPOn2S;
int ver;
gp_Pnt Point3dDebut, Point3dFin;
//------------------------------------------------------------
//-- Calcul des parametres approches a partir des Zones De Tangence --
//--------------------------------------------------------------------
int nbTanZon = LOn2S->NbPoints();
for (int z = 1; z <= nbTanZon; z++)
{
const IntSurf_PntOn2S& POn2S = LOn2S->Value(z);
POn2S.Parameters(U1, V1, U2, V2);
StartParams(1) = U1;
StartParams(2) = V1;
StartParams(3) = U2;
StartParams(4) = V2;
//-----------------------------------------------------------------------
//-- Calcul du premier point de cheminement a partir du point approche --
//-----------------------------------------------------------------------
HasStartPoint = PW.PerformFirstPoint(StartParams, StartPOn2S);
if (HasStartPoint)
{
//-------------------------------------------------
//-- Un point a ete trouve --
//-- On verifie qu il n appartient pas --
//-- a une ligne de cheminement deja calculee. --
//-------------------------------------------------
StartPOn2S.Parameters(pu1, pv1, pu2, pv2);
NbLigCalculee = SLin.Length();
dminiPointLigne = SeuildPointLigne + SeuildPointLigne;
for (int l = 1; (l <= NbLigCalculee) && (dminiPointLigne >= SeuildPointLigne); l++)
{
const occ::handle<IntPatch_WLine>& testwline =
*((occ::handle<IntPatch_WLine>*)&SLin.Value(l));
if (IsPointOnLine(StartPOn2S, testwline, Deflection))
{
dminiPointLigne = 0.0;
}
}
//-- Fin d exploration des lignes
if (dminiPointLigne > SeuildPointLigne)
{
//---------------------------------------------------
//-- Le point de depart du nouveau cheminement --
//-- n est present dans aucune ligne deja calculee.--
//---------------------------------------------------
PW.Perform(StartParams);
if (PW.IsDone())
{
if (PW.NbPoints() > 2)
{
//-----------------------------------------------
//-- Verification a posteriori :
//-- On teste si le point de depart et de fin de
//-- la ligne de cheminement est present dans une
//-- autre ligne .
//-----------------------------------------------
RejetLigne = false;
Point3dDebut = PW.Value(1).Value();
const IntSurf_PntOn2S& PointFin = PW.Value(PW.NbPoints());
Point3dFin = PointFin.Value();
for (ver = 1; ver <= NbLigCalculee; ver++)
{
const occ::handle<IntPatch_WLine>& verwline =
*((occ::handle<IntPatch_WLine>*)&SLin.Value(ver));
//-- occ::handle<IntPatch_WLine>
// verwline=occ::down_cast<IntPatch_WLine>(SLin.Value(ver));
// Check end point if it is on existing line.
// Start point is checked before.
if (IsPointOnLine(PointFin, verwline, Deflection))
{
RejetLigne = true;
break;
}
const IntSurf_PntOn2S& verPointDebut = verwline->Point(1);
const IntSurf_PntOn2S& verPointFin = verwline->Point(verwline->NbPnts());
if ((Point3dDebut.Distance(verPointDebut.Value()) < TolTangency)
|| (Point3dFin.Distance(verPointFin.Value()) < TolTangency))
{
RejetLigne = true;
break;
}
}
if (RejetLigne)
{
DublicateOfLinesProcessing(PW, ver, SLin, RejetLigne);
}
if (!RejetLigne)
{
IntSurf_TypeTrans trans1, trans2;
double locu, locv;
gp_Vec norm1, norm2, d1u, d1v;
gp_Pnt ptbid;
int indextg;
gp_Vec tgline(PW.TangentAtLine(indextg));
PW.Line()->Value(indextg).ParametersOnS1(locu, locv);
Surf1->D1(locu, locv, ptbid, d1u, d1v);
norm1 = d1u.Crossed(d1v);
PW.Line()->Value(indextg).ParametersOnS2(locu, locv);
Surf2->D1(locu, locv, ptbid, d1u, d1v);
norm2 = d1u.Crossed(d1v);
if (tgline.DotCross(norm2, norm1) > 0.)
{
trans1 = IntSurf_Out;
trans2 = IntSurf_In;
}
else
{
trans1 = IntSurf_In;
trans2 = IntSurf_Out;
}
double TolTang = TolTangency;
occ::handle<IntPatch_WLine> wline =
new IntPatch_WLine(PW.Line(), false, trans1, trans2);
wline->SetCreatingWayInfo(IntPatch_WLine::IntPatch_WLPrmPrm);
// the method PutVertexOnLine can reduce the number of points in <wline>
IntPatch_RstInt::PutVertexOnLine(wline, Surf1, D1, Surf2, true, TolTang);
if (wline->NbPnts() < 2)
{
continue;
}
IntPatch_RstInt::PutVertexOnLine(wline, Surf2, D2, Surf1, false, TolTang);
if (wline->NbPnts() < 2)
{
continue;
}
//---------------
if (wline->NbVertex() == 0)
{
IntPatch_Point vtx;
const IntSurf_PntOn2S& POn2Sf = PW.Line()->Value(1);
POn2Sf.Parameters(pu1, pv1, pu2, pv2);
vtx.SetValue(Point3dDebut, TolTang, false);
vtx.SetParameters(pu1, pv1, pu2, pv2);
vtx.SetParameter(1);
wline->AddVertex(vtx);
const IntSurf_PntOn2S& POn2Sl = PW.Line()->Value(wline->NbPnts());
POn2Sl.Parameters(pu1, pv1, pu2, pv2);
vtx.SetValue(Point3dFin, TolTang, false);
vtx.SetParameters(pu1, pv1, pu2, pv2);
vtx.SetParameter(wline->NbPnts());
wline->AddVertex(vtx);
}
//---------------
AddWLine(SLin, wline, Deflection);
empt = false;
}
else
{
//-- std::cout<<" ----- REJET DE LIGNE (POINT DE DEPART) ----- "<<std::endl;
}
//------------------------------------------------------------
}
} //-- le cheminement a reussi (done a True)
} //-- le point approche ne renvoie pas sur une ligne existante
} //-- Si HasStartPoint
} //-- Boucle sur Les Tangent Zones
}
// modified by NIZNHY-PKV Wed May 25 09:39:07 2011f
//=================================================================================================
class IntPatch_InfoPD
{
public:
//----------------------------------------C-tor
IntPatch_InfoPD(const int aNBI)
{
int aNBI2, i, j;
myNBI = aNBI;
//
aNBI2 = aNBI * aNBI;
myP1DS2 = new char[aNBI2];
myP2DS1 = new char[aNBI2];
myIP1 = new int[aNBI2];
myIP2 = new int[aNBI2];
myP1 = new gp_Pnt[aNBI2];
myP2 = new gp_Pnt[aNBI2];
//
for (i = 0; i < myNBI; ++i)
{
for (j = 0; j < myNBI; ++j)
{
xP1DS2(i, j) = 0;
xP2DS1(i, j) = 0;
xIP1(i, j) = 0;
xIP2(i, j) = 0;
xP1(i, j).SetCoord(0., 0., 0.);
xP2(i, j).SetCoord(0., 0., 0.);
}
}
};
//---------------------------------------- D-tor
~IntPatch_InfoPD()
{
delete[] (char*)myP1DS2;
delete[] (char*)myP2DS1;
delete[] (int*)myIP1;
delete[] (int*)myIP2;
delete[] (gp_Pnt*)myP1;
delete[] (gp_Pnt*)myP2;
};
//---------------------------------------- Index
int Index(const int i, const int j) const { return i * myNBI + j; };
//---------------------------------------- NBI
int NBI() const { return myNBI; };
//----------------------------------------xP1DS2
char& xP1DS2(const int i, const int j) { return myP1DS2[Index(i, j)]; };
//----------------------------------------xP2DS1
char& xP2DS1(const int i, const int j) { return myP2DS1[Index(i, j)]; };
//----------------------------------------xIP1
int& xIP1(const int i, const int j) { return myIP1[Index(i, j)]; };
//----------------------------------------xIP2
int& xIP2(const int i, const int j) { return myIP2[Index(i, j)]; };
//----------------------------------------xP1
gp_Pnt& xP1(const int i, const int j) { return myP1[Index(i, j)]; };
//----------------------------------------xP1
gp_Pnt& xP2(const int i, const int j) { return myP2[Index(i, j)]; };
private:
IntPatch_InfoPD(const IntPatch_InfoPD&) = delete;
IntPatch_InfoPD& operator=(const IntPatch_InfoPD&) = delete;
private:
int myNBI;
char* myP1DS2;
char* myP2DS1;
int* myIP1;
int* myIP2;
gp_Pnt* myP1;
gp_Pnt* myP2;
};
// modified by NIZNHY-PKV Tue May 24 11:38:55 2011t
//=================================================================================================
void IntPatch_PrmPrmIntersection::PointDepart(occ::handle<IntSurf_LineOn2S>& LineOn2S,
const occ::handle<Adaptor3d_Surface>& S1,
const int SU_1,
const int SV_1,
const occ::handle<Adaptor3d_Surface>& S2,
const int SU_2,
const int SV_2) const
{
int i, j, xNBI;
// modified by NIZNHY-PKV Tue May 24 11:37:38 2011f
xNBI = 200;
IntPatch_InfoPD aIPD(xNBI);
// modified by NIZNHY-PKV Wed May 25 06:47:12 2011t
int iC15, SU1, SV1, SU2, SV2;
double U0, U1, V0, V1, U, V;
double resu0, resv0;
double du1, du2, dv1, dv2, dmaxOn1, dmaxOn2;
double x0, y0, z0, x1, y1, z1, d;
Bnd_Box Box1, Box2;
//
iC15 = 15;
SU1 = iC15 * SU_1;
SV1 = iC15 * SV_1;
SU2 = iC15 * SU_2;
SV2 = iC15 * SV_2;
//
if (xNBI < SU1)
{
SU1 = xNBI;
}
if (xNBI < SV1)
{
SV1 = xNBI;
}
if (xNBI < SU2)
{
SU2 = xNBI;
}
if (xNBI < SV2)
{
SV2 = xNBI;
}
//
U0 = S1->FirstUParameter();
U1 = S1->LastUParameter();
V0 = S1->FirstVParameter();
V1 = S1->LastVParameter();
//
resu0 = U0;
resv0 = V0;
//
dmaxOn1 = 0.0;
dmaxOn2 = 0.0;
//-----
du1 = (U1 - U0) / (SU1 - 1);
dv1 = (V1 - V0) / (SV1 - 1);
for (U = U0, i = 0; i < SU1; i++, U += du1)
{
for (V = V0, j = 0; j < SV1; V += dv1, j++)
{
aIPD.xP1(i, j) = S1->Value(U, V);
Box1.Add(aIPD.xP1(i, j));
if (i > 0 && j > 0)
{
aIPD.xP1(i, j).Coord(x0, y0, z0);
aIPD.xP1(i - 1, j - 1).Coord(x1, y1, z1);
//
d = std::abs(x1 - x0) + std::abs(y1 - y0) + std::abs(z1 - z0);
if (d > dmaxOn1)
{
dmaxOn1 = d;
}
}
}
}
Box1.Enlarge(1.e-8);
//
U0 = S2->FirstUParameter();
U1 = S2->LastUParameter();
V0 = S2->FirstVParameter();
V1 = S2->LastVParameter();
//
du2 = (U1 - U0) / (SU2 - 1);
dv2 = (V1 - V0) / (SV2 - 1);
for (U = U0, i = 0; i < SU2; i++, U += du2)
{
for (V = V0, j = 0; j < SV2; V += dv2, j++)
{
aIPD.xP2(i, j) = S2->Value(U, V);
Box2.Add(aIPD.xP2(i, j));
if (i > 0 && j > 0)
{
aIPD.xP2(i, j).Coord(x0, y0, z0);
aIPD.xP2(i - 1, j - 1).Coord(x1, y1, z1);
d = std::abs(x1 - x0) + std::abs(y1 - y0) + std::abs(z1 - z0);
if (d > dmaxOn2)
{
dmaxOn2 = d;
}
}
}
}
Box2.Enlarge(1.e-8);
//--------
//
if (Box1.IsOut(Box2))
{
return;
}
//
int aNbPG;
double x10, y10, z10, x11, y11, z11;
double x20, y20, z20, x21, y21, z21;
double dx, dy, dz, dmax;
double dx2, dy2, dz2;
//
Box1.Get(x10, y10, z10, x11, y11, z11);
Box2.Get(x20, y20, z20, x21, y21, z21);
//
x0 = (x10 > x20) ? x10 : x20;
y0 = (y10 > y20) ? y10 : y20;
z0 = (z10 > z20) ? z10 : z20;
//
x1 = (x11 < x21) ? x11 : x21;
y1 = (y11 < y21) ? y11 : y21;
z1 = (z11 < z21) ? z11 : z21;
//
if (dmaxOn2 > dmaxOn1)
{
dmaxOn1 = dmaxOn2;
}
//
dmaxOn1 += dmaxOn1;
x0 -= dmaxOn1;
y0 -= dmaxOn1;
z0 -= dmaxOn1;
x1 += dmaxOn1;
y1 += dmaxOn1;
z1 += dmaxOn1;
//
x10 -= dmaxOn1;
y10 -= dmaxOn1;
z10 -= dmaxOn1;
x11 += dmaxOn1;
y11 += dmaxOn1;
z11 += dmaxOn1;
x20 -= dmaxOn1;
y20 -= dmaxOn1;
z20 -= dmaxOn1;
x21 += dmaxOn1;
y21 += dmaxOn1;
z21 += dmaxOn1;
aNbPG = NbPointsGrille();
dx = (x1 - x0) / aNbPG;
dy = (y1 - y0) / aNbPG;
dz = (z1 - z0) / aNbPG;
//
dmax = dx;
if (dy > dmax)
{
dmax = dy;
}
if (dz > dmax)
{
dmax = dz;
}
//
if (dx < dmax * 0.01)
{
dx = dmax * 0.01;
}
if (dy < dmax * 0.01)
{
dy = dmax * 0.01;
}
if (dz < dmax * 0.01)
{
dz = dmax * 0.01;
}
//
dx2 = dx * 0.5;
dy2 = dy * 0.5;
dz2 = dz * 0.5;
//
IntPatch_PrmPrmIntersection_T3Bits M1(_BASE);
IntPatch_PrmPrmIntersection_T3Bits M2(_BASE);
//
for (i = 0; i < SU1; i++)
{
for (j = 0; j < SV1; j++)
{
aIPD.xIP1(i, j) = -1;
const gp_Pnt& P = aIPD.xP1(i, j);
aIPD.xP1DS2(i, j) = (char)CodeReject(x20, y20, z20, x21, y21, z21, P.X(), P.Y(), P.Z());
int ix = (int)((P.X() - x0 + dx2) / dx);
if (DansGrille(ix))
{
int iy = (int)((P.Y() - y0 + dy2) / dy);
if (DansGrille(iy))
{
int iz = (int)((P.Z() - z0 + dz2) / dz);
if (DansGrille(iz))
{
aIPD.xIP1(i, j) = GrilleInteger(ix, iy, iz);
}
}
}
}
}
//-- std::cout<<" Grille du 1 fini "<<std::endl;
for (i = 0; i < SU2; i++)
{
for (j = 0; j < SV2; j++)
{
aIPD.xIP2(i, j) = -1;
const gp_Pnt& P = aIPD.xP2(i, j);
aIPD.xP2DS1(i, j) = (char)CodeReject(x10, y10, z10, x11, y11, z11, P.X(), P.Y(), P.Z());
int ix = (int)((P.X() - x0 + dx2) / dx);
if (DansGrille(ix))
{
int iy = (int)((P.Y() - y0 + dy2) / dy);
if (DansGrille(iy))
{
int iz = (int)((P.Z() - z0 + dz2) / dz);
if (DansGrille(iz))
{
aIPD.xIP2(i, j) = GrilleInteger(ix, iy, iz);
}
}
}
}
}
//
for (i = 0; i < SU1 - 1; i += 1)
{
for (j = 0; j < SV1 - 1; j += 1)
{
if (!((aIPD.xP1DS2(i, j) & aIPD.xP1DS2(i + 1, j))
|| (aIPD.xP1DS2(i, j) & aIPD.xP1DS2(i + 1, j + 1))))
{
Remplit(aIPD.xIP1(i, j), aIPD.xIP1(i + 1, j), aIPD.xIP1(i + 1, j + 1), M1);
}
if (!((aIPD.xP1DS2(i, j) & aIPD.xP1DS2(i, j + 1))
|| (aIPD.xP1DS2(i, j) & aIPD.xP1DS2(i + 1, j + 1))))
{
Remplit(aIPD.xIP1(i, j), aIPD.xIP1(i, j + 1), aIPD.xIP1(i + 1, j + 1), M1);
}
}
}
//
for (i = 0; i < SU2 - 1; i += 1)
{
for (j = 0; j < SV2 - 1; j += 1)
{
if (!((aIPD.xP2DS1(i, j) & aIPD.xP2DS1(i + 1, j))
|| (aIPD.xP2DS1(i, j) & aIPD.xP2DS1(i + 1, j + 1))))
{
Remplit(aIPD.xIP2(i, j), aIPD.xIP2(i + 1, j), aIPD.xIP2(i + 1, j + 1), M2);
}
if (!((aIPD.xP2DS1(i, j) & aIPD.xP2DS1(i, j + 1))
|| (aIPD.xP2DS1(i, j) & aIPD.xP2DS1(i + 1, j + 1))))
{
Remplit(aIPD.xIP2(i, j), aIPD.xIP2(i, j + 1), aIPD.xIP2(i + 1, j + 1), M2);
}
}
}
//
M1.ResetAnd();
M2.ResetAnd();
//
int newind = 0;
int ok = 0;
int indicepointtraite = 0;
int k, nu, nv;
//
do
{
indicepointtraite--;
ok = M1.And(M2, newind);
if (ok)
{
IntegerGrille(newind, i, j, k);
int nb = 0;
int LIM = 3;
if (DansGrille(i - 1) && DansGrille(j - 1) && DansGrille(k - 1) && DansGrille(i + 1)
&& DansGrille(j + 1) && DansGrille(k + 1))
{
int si, sj, sk;
for (si = -1; si <= 1 && nb < LIM; si++)
{
for (sj = -1; sj <= 1 && nb < LIM; sj++)
{
for (sk = -1; sk <= 1 && nb < LIM; sk++)
{
int lu = GrilleInteger(i + si, j + sj, k + sk);
if (M1.Val(lu) && M2.Val(lu))
{
nb++;
}
}
}
}
if (nb >= LIM)
{
for (si = -1; si <= 1; si++)
{
for (sj = -1; sj <= 1; sj++)
{
for (sk = -1; sk <= 1; sk++)
{
if (si || sj || sk)
{
int lu = GrilleInteger(i + si, j + sj, k + sk);
M1.Raz(lu);
}
}
}
}
}
}
//
gp_Pnt P(dx * i + x0, dy * j + y0, dz * k + z0);
//
int nu1 = -1, nu2 = -1;
int nv1 = 0, nv2 = 0;
for (nu = 0; nu1 < 0 && nu < SU1; nu++)
{
for (nv = 0; nu1 < 0 && nv < SV1; nv++)
{
if (aIPD.xIP1(nu, nv) == (int)newind)
{
aIPD.xIP1(nu, nv) = indicepointtraite;
nu1 = nu;
nv1 = nv;
}
}
}
if (nu1 >= 0)
{
for (nu = 0; nu2 < 0 && nu < SU2; nu++)
{
for (nv = 0; nu2 < 0 && nv < SV2; nv++)
{
if (aIPD.xIP2(nu, nv) == (int)newind)
{
aIPD.xIP2(nu, nv) = indicepointtraite;
nu2 = nu;
nv2 = nv;
}
}
}
}
if (nu1 >= 0 && nu2 >= 0)
{
IntSurf_PntOn2S POn2S;
POn2S.SetValue(P,
S1->FirstUParameter() + nu1 * du1,
S1->FirstVParameter() + nv1 * dv1,
S2->FirstUParameter() + nu2 * du2,
S2->FirstVParameter() + nv2 * dv2);
LineOn2S->Add(POn2S);
}
else
{
//-- aucun point du triangle n a ete trouve assez proche
//-- on recherche les 3 points les plus proches de P
//-- dans chacun des tableaux
double Dist3[3], u3[3] = {0.0, 0.0, 0.0}, v3[3] = {0.0, 0.0, 0.0};
Dist3[0] = Dist3[1] = Dist3[2] = RealLast();
for (U = resu0, i = 0; i < SU1; i++, U += du1)
{
for (V = resv0, j = 0; j < SV1; V += dv1, j++)
{
//-- On place les 3 meilleures valeurs dans Dist1,Dist2,Dist3
double t = aIPD.xP1(i, j).SquareDistance(P);
//-- On remplace la plus grande valeur ds Dist[.] par la val courante
if (Dist3[0] < Dist3[1])
{
double z;
z = Dist3[0];
Dist3[0] = Dist3[1];
Dist3[1] = z;
z = u3[0];
u3[0] = u3[1];
u3[1] = z;
z = v3[0];
v3[0] = v3[1];
v3[1] = z;
}
if (Dist3[1] < Dist3[2])
{
double z;
z = Dist3[1];
Dist3[1] = Dist3[2];
Dist3[2] = z;
z = u3[1];
u3[1] = u3[2];
u3[2] = z;
z = v3[1];
v3[1] = v3[2];
v3[2] = z;
}
if (Dist3[0] < Dist3[1])
{
double z;
z = Dist3[0];
Dist3[0] = Dist3[1];
Dist3[1] = z;
z = u3[0];
u3[0] = u3[1];
u3[1] = z;
z = v3[0];
v3[0] = v3[1];
v3[1] = z;
}
//-- la plus grande valeur est dans Dist3[0]
if (t < Dist3[0])
{
Dist3[0] = t;
u3[0] = U;
v3[0] = V;
}
}
}
//
double U1_3 = (u3[0] + u3[1] + u3[2]) / 3.0;
double V1_3 = (v3[0] + v3[1] + v3[2]) / 3.0;
Dist3[0] = Dist3[1] = Dist3[2] = RealLast();
for (U = U0, i = 0; i < SU2; i++, U += du2)
{
for (V = V0, j = 0; j < SV2; V += dv2, j++)
{
//-- On place les 3 meilleures valeurs dans Dist1,Dist2,Dist3
double t = aIPD.xP2(i, j).SquareDistance(P);
//-- On remplace la plus grande valeur ds Dist3[.] par la val courante
if (Dist3[0] < Dist3[1])
{
double z;
z = Dist3[0];
Dist3[0] = Dist3[1];
Dist3[1] = z;
z = u3[0];
u3[0] = u3[1];
u3[1] = z;
z = v3[0];
v3[0] = v3[1];
v3[1] = z;
}
if (Dist3[1] < Dist3[2])
{
double z;
z = Dist3[1];
Dist3[1] = Dist3[2];
Dist3[2] = z;
z = u3[1];
u3[1] = u3[2];
u3[2] = z;
z = v3[1];
v3[1] = v3[2];
v3[2] = z;
}
if (Dist3[0] < Dist3[1])
{
double z;
z = Dist3[0];
Dist3[0] = Dist3[1];
Dist3[1] = z;
z = u3[0];
u3[0] = u3[1];
u3[1] = z;
z = v3[0];
v3[0] = v3[1];
v3[1] = z;
}
//-- la plus grande valeur est dans Dist3[0]
if (t < Dist3[0])
{
Dist3[0] = t;
u3[0] = U;
v3[0] = V;
}
}
}
//
double U2_3 = (u3[0] + u3[1] + u3[2]) / 3.0;
double V2_3 = (v3[0] + v3[1] + v3[2]) / 3.0;
//
IntSurf_PntOn2S POn2S;
POn2S.SetValue(P, U1_3, V1_3, U2_3, V2_3);
LineOn2S->Add(POn2S);
}
}
} while (ok);
}
//=================================================================================================
bool IsPointOnLine(const IntSurf_PntOn2S& thePOn2S,
const occ::handle<IntPatch_WLine>& theWLine,
const double Deflection)
{
bool isOnLine = false;
double Deflection2 = Deflection * Deflection;
double pu1, pu2, pv1, pv2;
thePOn2S.Parameters(pu1, pv1, pu2, pv2);
if ((!theWLine->IsOutSurf1Box(gp_Pnt2d(pu1, pv1)))
&& (!theWLine->IsOutSurf2Box(gp_Pnt2d(pu2, pv2))) && (!theWLine->IsOutBox(thePOn2S.Value())))
{
const int NbPntOn2SOnLine = theWLine->NbPnts();
int ll;
for (ll = 1; ll < NbPntOn2SOnLine && !isOnLine; ll++)
{
const gp_Pnt& Pa = theWLine->Point(ll).Value();
const gp_Pnt& Pb = theWLine->Point(ll + 1).Value();
const gp_Pnt& PStart = thePOn2S.Value();
const gp_Vec AM(Pa, PStart);
const gp_Vec MB(PStart, Pb);
const double AMMB = AM.Dot(MB);
if (AMMB > 0.0)
{
gp_Dir ABN(Pb.X() - Pa.X(), Pb.Y() - Pa.Y(), Pb.Z() - Pa.Z());
double lan = ABN.X() * AM.X() + ABN.Y() * AM.Y() + ABN.Z() * AM.Z();
gp_Vec AH(lan * ABN.X(), lan * ABN.Y(), lan * ABN.Z());
gp_Vec HM(AM.X() - AH.X(), AM.Y() - AH.Y(), AM.Z() - AH.Z());
double d = 0.0;
if (HM.X() < Deflection)
{
d += HM.X() * HM.X();
if (HM.Y() < Deflection)
{
d += HM.Y() * HM.Y();
if (HM.Z() < Deflection)
{
d += HM.Z() * HM.Z();
}
else
{
d = Deflection2;
}
}
else
{
d = Deflection2;
}
}
else
{
d = Deflection2;
}
if (d < Deflection2)
{
isOnLine = true;
}
}
else
{
double dab = Pa.SquareDistance(Pb);
double dap = Pa.SquareDistance(PStart);
if (dap < dab)
{
isOnLine = true;
}
else
{
double dbp = Pb.SquareDistance(PStart);
if (dbp < dab)
{
isOnLine = true;
}
}
}
}
}
return isOnLine;
}
//=================================================================================================
void AddWLine(NCollection_Sequence<occ::handle<IntPatch_Line>>& theLines,
const occ::handle<IntPatch_WLine>& theWLine,
const double Deflection)
{
int i = 1;
int aNbLines = theLines.Length();
bool isToRemove;
// Check each line of theLines if it is on theWLine.
while (i <= aNbLines)
{
occ::handle<IntPatch_WLine> aWLine = occ::down_cast<IntPatch_WLine>(theLines.Value(i));
isToRemove = false;
if (!aWLine.IsNull())
{
// Check the middle point.
int aMidIndex = (aWLine->NbPnts() + 1) / 2;
if (aMidIndex > 0)
{
const IntSurf_PntOn2S& aPnt = aWLine->Point(aMidIndex);
if (IsPointOnLine(aPnt, theWLine, Deflection))
{
// Middle point is on theWLine. Check vertices.
isToRemove = true;
int j;
const int aNbVtx = aWLine->NbVertex();
for (j = 1; j <= aNbVtx; j++)
{
const IntPatch_Point& aPoint = aWLine->Vertex(j);
if (!IsPointOnLine(aPoint.PntOn2S(), theWLine, Deflection))
{
isToRemove = false;
break;
}
}
}
}
}
if (isToRemove)
{
theLines.Remove(i);
aNbLines--;
}
else
{
i++;
}
}
// Add theWLine to the sequence of lines.
theLines.Append(theWLine);
}