Warning, /include/opencascade/IntWalk_IWalking_6.gxx is written in an unsupported language. File is not indexed.
0001 // Copyright (c) 1995-1999 Matra Datavision
0002 // Copyright (c) 1999-2014 OPEN CASCADE SAS
0003 //
0004 // This file is part of Open CASCADE Technology software library.
0005 //
0006 // This library is free software; you can redistribute it and/or modify it under
0007 // the terms of the GNU Lesser General Public License version 2.1 as published
0008 // by the Free Software Foundation, with special exception defined in the file
0009 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
0010 // distribution for complete text of the license and disclaimer of any warranty.
0011 //
0012 // Alternatively, this file may be used under the terms of Open CASCADE
0013 // commercial license or contractual agreement.
0014
0015 #ifndef OCCT_DEBUG
0016 #define No_Standard_RangeError
0017 #define No_Standard_OutOfRange
0018 #endif
0019
0020
0021 void IntWalk_IWalking::AddPointInCurrentLine
0022 (const Standard_Integer N,
0023 const ThePointOfPath& PathPnt,
0024 const Handle(IntWalk_TheIWLine)& CurrentLine) const {
0025
0026
0027 IntSurf_PntOn2S Psol;
0028 Psol.SetValue(ThePointOfPathTool::Value3d(PathPnt),
0029 reversed,wd1[N].ustart,wd1[N].vstart);
0030 CurrentLine->AddPoint(Psol);
0031 }
0032
0033
0034 void IntWalk_IWalking::MakeWalkingPoint
0035 (const Standard_Integer Case,
0036 const Standard_Real U,
0037 const Standard_Real V,
0038 TheIWFunction& sp,
0039 IntSurf_PntOn2S& Psol )
0040
0041 {
0042
0043 // Case == 1 : make a WalkinkPoint.
0044 // Case == 2 : make a WalkinkPoint.
0045 // The computation of the tangency on is done
0046 // Case == 10 + i : make a WalkinkPoint according to i.
0047 // but F is updated according to U and V
0048 // Case == other : the exception Standard_Failure is raised.
0049
0050 if ((Case == 1) || (Case == 2))
0051 {
0052 Psol.SetValue(sp.Point(), reversed, U, V);
0053 }
0054 else if (Case == 11 || Case == 12)
0055 {
0056 Standard_Real aUV[2] = {}, aFF[1] = {}, aDD[1][2] = {};
0057 math_Vector UV(aUV, 1, 2);
0058 math_Vector FF(aFF, 1, 1);
0059 math_Matrix DD(aDD, 1, 1, 1, 2);
0060 UV(1) = U;
0061 UV(2) = V;
0062 sp.Values(UV, FF, DD);
0063 MakeWalkingPoint(Case - 10, U, V, sp, Psol);
0064 }
0065 else
0066 {
0067 throw Standard_ConstructionError();
0068 }
0069 }
0070
0071
0072
0073 void IntWalk_IWalking::OpenLine(const Standard_Integer N,
0074 const IntSurf_PntOn2S& Psol,
0075 const ThePOPIterator& Pnts1,
0076 TheIWFunction& sp,
0077 const Handle(IntWalk_TheIWLine)& Line )
0078 // **************** open the line and restart in the other direction********
0079
0080 {
0081 ThePointOfPath PathPnt;
0082
0083 Standard_Real aUV[2], aFF[1], aDD[1][2];
0084 math_Vector UV(aUV,1, 2);
0085 math_Vector FF(aFF,1, 1);
0086 math_Matrix DD(aDD,1, 1, 1, 2);
0087
0088 previousPoint = Line->Value(1);
0089 if (!reversed) {
0090 previousPoint.ParametersOnS2(UV(1),UV(2));
0091 }
0092 else {
0093 previousPoint.ParametersOnS1(UV(1),UV(2));
0094 }
0095 sp.Values(UV, FF, DD);
0096 previousd3d = sp.Direction3d();
0097 previousd2d = sp.Direction2d();
0098
0099 if (N>0) { //departure point given at input
0100 PathPnt = Pnts1.Value(N);
0101 //mark the line as open with a given stop point
0102 Line->AddStatusFirst(Standard_False,Standard_True,N,PathPnt);
0103
0104
0105 AddPointInCurrentLine(N,PathPnt,Line);
0106
0107 }
0108 else {
0109 if (N <0) Line->AddPoint(Psol);
0110 Line->AddStatusFirst(Standard_False,Standard_False);
0111 //mark the line as open without given stop point
0112 }
0113 Line->Reverse(); //inverser la ligne
0114 Line->SetTangentVector(previousd3d.Reversed(),Line->NbPoints());
0115 }
0116
0117 Standard_Boolean IntWalk_IWalking::IsValidEndPoint(const Standard_Integer IndOfPoint,
0118 const Standard_Integer IndOfLine)
0119 {
0120 if (PointLineLine.IsEmpty())
0121 return Standard_True;
0122
0123 TColStd_ListIteratorOfListOfInteger itl(PointLineLine(IndOfPoint));
0124 for (; itl.More(); itl.Next())
0125 if (itl.Value() == IndOfLine)
0126 {
0127 PointLineLine(IndOfPoint).Remove(itl);
0128 return Standard_True;
0129 }
0130 return Standard_False;
0131 }
0132
0133 void IntWalk_IWalking::RemoveTwoEndPoints(const Standard_Integer IndOfPoint)
0134 {
0135 if (PointLineLine.IsBound(IndOfPoint))
0136 {
0137 Standard_Integer Line1 = PointLineLine(IndOfPoint).First();
0138 Standard_Integer Line2 = PointLineLine(IndOfPoint).Last();
0139 for (Standard_Integer iseq = 1; iseq <= seqAlone.Length(); iseq++)
0140 {
0141 if (seqAlone(iseq) == Line1 ||
0142 seqAlone(iseq) == Line2)
0143 seqAlone.Remove(iseq--);
0144 }
0145 }
0146 }
0147
0148 Standard_Boolean IntWalk_IWalking::IsPointOnLine(const gp_Pnt2d& theP2d,
0149 const Standard_Integer Irang)
0150 {
0151 const Handle(IntWalk_TheIWLine)& aLine = lines.Value(Abs(Irang));
0152 for (Standard_Integer i = 1; i <= aLine->NbPoints(); i++)
0153 {
0154 gp_Pnt2d P2d1 = aLine->Value(i).ValueOnSurface(reversed);
0155 if (Abs(P2d1.X() - theP2d.X()) <= tolerance(1) &&
0156 Abs(P2d1.Y() - theP2d.Y()) <= tolerance(2))
0157 return Standard_True;
0158 if (i < aLine->NbPoints())
0159 {
0160 gp_Pnt2d P2d2 = aLine->Value(i+1).ValueOnSurface(reversed);
0161 gp_Vec2d PP1(theP2d, P2d1);
0162 gp_Vec2d PP2(theP2d, P2d2);
0163 if (PP1 * PP2 < 0)
0164 return Standard_True;
0165 }
0166 }
0167 return Standard_False;
0168 }
0169
0170 //==================================================================================
0171 //function : IsPointOnLine
0172 //purpose : Projects thePOn2S on the nearest segment of the already computed line.
0173 // The retrieved projection point (aPa) is refined using theSolver.
0174 // After the refinement, we will obtain a point aPb.
0175 // If thePOn2S is quite far from aPb then thePOn2S is not
0176 // in the line.
0177 // Every already computed line is checked.
0178 //==================================================================================
0179 Standard_Boolean IntWalk_IWalking::IsPointOnLine(const IntSurf_PntOn2S& thePOn2S,
0180 const math_Vector& theInfBounds,
0181 const math_Vector& theSupBounds,
0182 math_FunctionSetRoot& theSolver,
0183 TheIWFunction& theFunc)
0184 {
0185 const Standard_Real eps = Epsilon(1.);
0186 const gp_Pnt &aP3d = thePOn2S.Value();
0187
0188 for (Standard_Integer aLIdx = 1; aLIdx <= lines.Length(); aLIdx++)
0189 {
0190 const Handle(IntSurf_LineOn2S) &aL = lines(aLIdx)->Line();
0191
0192 if (aL->IsOutBox(aP3d))
0193 continue;
0194
0195 //Look for the nearest segment
0196 Standard_Real aUMin = 0.0, aVMin = 0.0;
0197 Standard_Real aMinSqDist = RealLast();
0198 for (Standard_Integer aPtIdx = 1; aPtIdx < aL->NbPoints(); aPtIdx++)
0199 {
0200 const gp_Pnt &aP1 = aL->Value(aPtIdx).Value();
0201 const gp_Pnt &aP2 = aL->Value(aPtIdx + 1).Value();
0202
0203 const gp_XYZ aP1P(aP3d.XYZ() - aP1.XYZ());
0204 const gp_XYZ aP1P2(aP2.XYZ() - aP1.XYZ());
0205
0206 const Standard_Real aSq12 = aP1P2.SquareModulus();
0207
0208 if (aSq12 < gp::Resolution())
0209 continue;
0210
0211 const Standard_Real aDP = aP1P.Dot(aP1P2);
0212
0213 Standard_Real aSqD = RealLast();
0214 if (aDP < 0.0)
0215 {
0216 continue;
0217 }
0218 else if (aDP > aSq12)
0219 {
0220 continue;
0221 }
0222 else
0223 {
0224 aSqD = aP1P.CrossSquareMagnitude(aP1P2) / aSq12;
0225 }
0226
0227 if (aSqD < aMinSqDist)
0228 {
0229 aMinSqDist = aSqD;
0230
0231 const Standard_Real aL1 = aDP / aSq12;
0232 const Standard_Real aL2 = 1.0 - aL1;
0233
0234 if (aL1 < eps || aL2 < eps)
0235 {
0236 return Standard_True;
0237 }
0238
0239 Standard_Real aU1, aV1, aU2, aV2;
0240 aL->Value(aPtIdx).ParametersOnSurface(reversed, aU1, aV1);
0241 aL->Value(aPtIdx + 1).ParametersOnSurface(reversed, aU2, aV2);
0242
0243 aUMin = aL1*aU2 + aL2*aU1;
0244 aVMin = aL1*aV2 + aL2*aV1;
0245 }
0246 }
0247
0248 if (aMinSqDist > Precision::Infinite())
0249 continue;
0250
0251 math_Vector aVecPrms(1, 2);
0252 aVecPrms(1) = aUMin;
0253 aVecPrms(2) = aVMin;
0254 theSolver.Perform(theFunc, aVecPrms, theInfBounds, theSupBounds);
0255 if (!theSolver.IsDone())
0256 continue;
0257
0258 theSolver.Root(aVecPrms);
0259
0260 const gp_Pnt aPa(theFunc.PSurface()->Value(aUMin, aVMin)),
0261 aPb(theFunc.PSurface()->Value(aVecPrms(1), aVecPrms(2)));
0262 const Standard_Real aSqD1 = aPb.SquareDistance(aP3d);
0263 const Standard_Real aSqD2 = aPa.SquareDistance(aPb);
0264
0265 if (aSqD1 < 4.0*aSqD2)
0266 {
0267 return Standard_True;
0268 }
0269 }
0270
0271 return Standard_False;
0272 }