Warning, /include/opencascade/IntPatch_ImpImpIntersection_0.gxx is written in an unsupported language. File is not indexed.
0001 // Created on: 1992-05-07
0002 // Created by: Jacques GOUSSARD
0003 // Copyright (c) 1992-1999 Matra Datavision
0004 // Copyright (c) 1999-2014 OPEN CASCADE SAS
0005 //
0006 // This file is part of Open CASCADE Technology software library.
0007 //
0008 // This library is free software; you can redistribute it and/or modify it under
0009 // the terms of the GNU Lesser General Public License version 2.1 as published
0010 // by the Free Software Foundation, with special exception defined in the file
0011 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
0012 // distribution for complete text of the license and disclaimer of any warranty.
0013 //
0014 // Alternatively, this file may be used under the terms of Open CASCADE
0015 // commercial license or contractual agreement.
0016
0017 // Modified by skv - Thu Jan 15 15:57:15 2004 OCC4455
0018
0019 #include <IntPatch_ThePathPointOfTheSOnBounds.hxx>
0020 #include <IntPatch_TheSegmentOfTheSOnBounds.hxx>
0021 #include <IntPatch_RLine.hxx>
0022 #include <IntSurf.hxx>
0023 #include <TColStd_Array1OfInteger.hxx>
0024 #include <TColStd_SequenceOfReal.hxx>
0025 #include <IntPatch_GLine.hxx>
0026 #include <Extrema_ExtPC.hxx>
0027 #include <GeomAdaptor_Curve.hxx>
0028 #include <Geom_Ellipse.hxx>
0029 #include <Geom_Parabola.hxx>
0030 #include <Geom_Hyperbola.hxx>
0031 #include <IntPatch_ALine.hxx>
0032
0033
0034 static void PutPointsOnLine(const Handle(Adaptor3d_Surface)& S1,
0035 const Handle(Adaptor3d_Surface)& S2,
0036 const IntPatch_SequenceOfPathPointOfTheSOnBounds&,
0037 const IntPatch_SequenceOfLine&,
0038 const Standard_Boolean,
0039 const Handle(Adaptor3d_TopolTool)&,
0040 const IntSurf_Quadric&,
0041 const IntSurf_Quadric&,
0042 const Standard_Boolean,
0043 const Standard_Real);
0044
0045 static Standard_Boolean MultiplePoint(const IntPatch_SequenceOfPathPointOfTheSOnBounds& listpnt,
0046 const Handle(Adaptor3d_TopolTool)& Domain,
0047 const IntSurf_Quadric& QuadSurf,
0048 const gp_Vec& Normale,
0049 const IntPatch_SequenceOfLine& slin,
0050 TColStd_Array1OfInteger& Done,
0051 TColStd_Array1OfInteger& UsedLine,
0052 const Standard_Integer Index,
0053 const Standard_Boolean OnFirst,
0054 const Standard_Real theToler);
0055
0056 static Standard_Boolean PointOnSecondDom(const IntPatch_SequenceOfPathPointOfTheSOnBounds& listpnt,
0057 const Handle(Adaptor3d_TopolTool)& Domain,
0058 const IntSurf_Quadric& QuadSurf,
0059 const gp_Vec& Normale,
0060 const gp_Vec& Vtgint,
0061 const Handle(IntPatch_Line)& lin,
0062 TColStd_Array1OfInteger& Done,
0063 const Standard_Integer Index,
0064 const Standard_Real theToler);
0065
0066 static Standard_Boolean SingleLine (const gp_Pnt&,
0067 const Handle(IntPatch_Line)&,
0068 const Standard_Real,
0069 Standard_Real&,
0070 gp_Vec&);
0071
0072
0073 static Standard_Boolean FindLine(gp_Pnt& Psurf,
0074 const IntPatch_SequenceOfLine& slin,
0075 const Standard_Real Tol,
0076 TColStd_ListOfReal& theLParams,
0077 gp_Vec& Vtgtint,
0078 Standard_Integer& theLineIdx,
0079 Standard_Integer OnlyThisLine,
0080 const Handle(Adaptor2d_Curve2d)& thearc,
0081 Standard_Real& theparameteronarc,
0082 gp_Pnt& thepointonarc,
0083 const IntSurf_Quadric& QuadSurf1,
0084 const IntSurf_Quadric& QuadSurf2,
0085 Standard_Real& theOutputToler);
0086
0087 static void ProcessSegments (const IntPatch_SequenceOfSegmentOfTheSOnBounds&,
0088 IntPatch_SequenceOfLine&,
0089 const IntSurf_Quadric&,
0090 const IntSurf_Quadric&,
0091 const Standard_Boolean,
0092 const Standard_Real);
0093
0094 static void ProcessRLine (IntPatch_SequenceOfLine&,
0095 const IntSurf_Quadric&,
0096 const IntSurf_Quadric&,
0097 const Standard_Real,
0098 const Standard_Boolean theIsReqToKeepRLine);
0099
0100 //-- le calcul de dist est completement faux ds la routine ci dessous a revoir (lbr le 18 nov 97)
0101 Standard_Boolean IntersectionWithAnArc(gp_Pnt& PSurf,
0102 const Handle(IntPatch_ALine)& alin,
0103 Standard_Real& para,
0104 const Handle(Adaptor2d_Curve2d)& thearc,
0105 Standard_Real& _theparameteronarc,
0106 gp_Pnt& thepointonarc,
0107 const IntSurf_Quadric& QuadSurf,
0108 const Standard_Real u0alin,
0109 const Standard_Real u1alin) {
0110 Standard_Real dtheta,theta;
0111 #ifdef OCCT_DEBUG
0112 //Standard_Real u,v,A,B,C,cost,sint,sign;
0113 #endif
0114 //-- recherche bete du point le plus proche de thearc->Value(...)
0115 dtheta = (u1alin-u0alin)*0.01;
0116 Standard_Real du=0.000000001;
0117 if (du >= dtheta)
0118 du = dtheta/2;
0119 Standard_Real distmin = RealLast();
0120
0121 Standard_Real thetamin = 0.;
0122
0123 Standard_Real theparameteronarc = _theparameteronarc;
0124 for(Standard_Real _theta=u0alin+dtheta; _theta<=u1alin-dtheta; _theta+=dtheta) {
0125 gp_Pnt P=alin->Value(_theta);
0126 Standard_Real d=P.Distance(PSurf);
0127 if(d<distmin) {
0128 thetamin=_theta;
0129 distmin=d;
0130 }
0131 }
0132
0133 Standard_Real bestpara =0., besttheta =0., bestdist =0., distinit =0. ;
0134
0135 //-- Distance initiale
0136 {
0137 gp_Pnt pp0 = alin->Value(thetamin);
0138 Standard_Real ua0,va0;
0139 QuadSurf.Parameters(pp0,ua0,va0);
0140 gp_Pnt2d p2d;
0141 gp_Vec2d d2d;
0142 thearc->D1(theparameteronarc,p2d,d2d);
0143 gp_Vec2d PaPr(gp_Pnt2d(ua0,va0),p2d);
0144 distinit=PaPr.Magnitude();
0145 }
0146 theta = thetamin;
0147 //-- recherche a partir de theta et theparameteronarc
0148 Standard_Boolean cpasok=Standard_True;
0149 Standard_Integer nbiter=0;
0150 Standard_Real drmax = (thearc->LastParameter() - thearc->FirstParameter())*0.05;
0151 Standard_Real damax = (u1alin-u0alin)*0.05;
0152
0153
0154
0155 bestdist = RealLast();
0156
0157 do {
0158 Standard_Real ua0,va0,ua1,va1;
0159 //-- alin->Curve().InternalUVValue(theta,ua0,va0,A,B,C,cost,sint,sign);
0160 //-- alin->Curve().InternalUVValue(theta+du,ua1,va1,A,B,C,cost,sint,sign);
0161 gp_Pnt pp0 = alin->Value(theta);
0162 gp_Pnt pp1 = alin->Value(theta+du);
0163 QuadSurf.Parameters(pp0,ua0,va0);
0164 QuadSurf.Parameters(pp1,ua1,va1);
0165
0166
0167 gp_Vec2d D1a((ua1-ua0)/du,(va1-va0)/du);
0168 gp_Pnt2d p2d;
0169 gp_Vec2d d2d;
0170 thearc->D1(theparameteronarc,p2d,d2d);
0171 gp_Vec2d PaPr(gp_Pnt2d(ua0,va0),p2d);
0172
0173 Standard_Real pbd=PaPr.Magnitude();
0174 if(bestdist>pbd) {
0175 bestdist = pbd;
0176 bestpara = theparameteronarc;
0177 besttheta = theta;
0178 }
0179
0180 D1a.SetCoord(-D1a.X(),-D1a.Y());
0181
0182 Standard_Real d = D1a.X() * d2d.Y() - D1a.Y() * d2d.X();
0183
0184 Standard_Real da = (-PaPr.X())* d2d.Y() - (-PaPr.Y()) * d2d.X();
0185 Standard_Real dr = D1a.X() * (-PaPr.Y()) - D1a.Y() * (-PaPr.X());
0186 if(Abs(d)>1e-15) {
0187 da/=d;
0188 dr/=d;
0189 }
0190 else {
0191 if(Abs(PaPr.X())>Abs(PaPr.Y())) {
0192 Standard_Real xx=PaPr.X();
0193 xx*=0.5;
0194 if(D1a.X()) {
0195 da = -xx/D1a.X();
0196 }
0197 if(d2d.X()) {
0198 dr = -xx/d2d.X();
0199 }
0200 }
0201 else {
0202 Standard_Real yy=PaPr.Y();
0203 yy*=0.5;
0204 if(D1a.Y()) {
0205 da = -yy/D1a.Y();
0206 }
0207 if(d2d.Y()) {
0208 dr = -yy/d2d.Y();
0209 }
0210 }
0211 }
0212 //-- Standard_Real da = -PaPr.Dot(D1a);
0213 //-- Standard_Real dr = -PaPr.Dot(d2d);
0214
0215 if(da<-damax) da=-damax;
0216 else if(da>damax) da=damax;
0217 if(dr<-drmax) dr=-drmax;
0218 else if(dr>drmax) dr=drmax;
0219
0220 if(Abs(da)<1e-10 && Abs(dr)<1e-10) {
0221 para = theta;
0222 PSurf = alin->Value(para);
0223 _theparameteronarc=theparameteronarc;
0224 thepointonarc = alin->Value(para);
0225 cpasok=Standard_False;
0226 //-- printf("\nt:%d",nbiter);
0227 return(Standard_True);
0228 }
0229 else {
0230 theta+=da;
0231 theparameteronarc+=dr;
0232 if( theparameteronarc>thearc->LastParameter() ) {
0233 theparameteronarc = thearc->LastParameter();
0234 }
0235 if( theparameteronarc<thearc->FirstParameter() ) {
0236 theparameteronarc = thearc->FirstParameter();
0237 }
0238 if( theta < u0alin) {
0239 theta = u0alin;
0240 }
0241 if( theta > u1alin-du) {
0242 theta = u1alin-du-du;
0243 }
0244 }
0245 nbiter++;
0246 }
0247 while(cpasok && nbiter<20);
0248 if(bestdist < distinit) {
0249 para = besttheta;
0250 PSurf = alin->Value(para);
0251 _theparameteronarc=bestpara;
0252 thepointonarc = alin->Value(para);
0253 //-- printf("\nT:%d",nbiter);
0254 return(Standard_True);
0255 }
0256 //-- printf("\nF:%d",nbiter);
0257 return(Standard_False);
0258 }
0259
0260
0261
0262
0263
0264 //-- ======================================================================
0265 static void Recadre(const Handle(Adaptor3d_Surface)& myHS1,
0266 const Handle(Adaptor3d_Surface)& myHS2,
0267 Standard_Real& u1,
0268 Standard_Real& v1,
0269 Standard_Real& u2,
0270 Standard_Real& v2) {
0271 Standard_Real f,l,lmf,fpls2;
0272 GeomAbs_SurfaceType typs1 = myHS1->GetType();
0273 GeomAbs_SurfaceType typs2 = myHS2->GetType();
0274
0275 Standard_Boolean myHS1IsUPeriodic,myHS1IsVPeriodic;
0276 switch (typs1) {
0277 case GeomAbs_Cylinder:
0278 case GeomAbs_Cone:
0279 case GeomAbs_Sphere:
0280 {
0281 myHS1IsUPeriodic = Standard_True;
0282 myHS1IsVPeriodic = Standard_False;
0283 break;
0284 }
0285 case GeomAbs_Torus:
0286 {
0287 myHS1IsUPeriodic = myHS1IsVPeriodic = Standard_True;
0288 break;
0289 }
0290 default:
0291 {
0292 //-- Le cas de biparametrees periodiques est gere en amont
0293 myHS1IsUPeriodic = myHS1IsVPeriodic = Standard_False;
0294 break;
0295 }
0296 }
0297
0298 Standard_Boolean myHS2IsUPeriodic,myHS2IsVPeriodic;
0299 switch (typs2) {
0300 case GeomAbs_Cylinder:
0301 case GeomAbs_Cone:
0302 case GeomAbs_Sphere:
0303 {
0304 myHS2IsUPeriodic = Standard_True;
0305 myHS2IsVPeriodic = Standard_False;
0306 break;
0307 }
0308 case GeomAbs_Torus:
0309 {
0310 myHS2IsUPeriodic = myHS2IsVPeriodic = Standard_True;
0311 break;
0312 }
0313 default:
0314 {
0315 //-- Le cas de biparametrees periodiques est gere en amont
0316 myHS2IsUPeriodic = myHS2IsVPeriodic = Standard_False;
0317 break;
0318 }
0319 }
0320 if(myHS1IsUPeriodic) {
0321 lmf = M_PI+M_PI; //-- myHS1->UPeriod();
0322 f = myHS1->FirstUParameter();
0323 l = myHS1->LastUParameter();
0324 fpls2=0.5*(f+l);
0325 while((u1 < f)&&((fpls2-u1) > (u1+lmf-fpls2) )) { u1+=lmf; }
0326 while((u1 > l)&&((u1-fpls2) > (fpls2-(u1-lmf)) )) { u1-=lmf; }
0327
0328 }
0329 if(myHS1IsVPeriodic) {
0330 lmf = M_PI+M_PI; //-- myHS1->VPeriod();
0331 f = myHS1->FirstVParameter();
0332 l = myHS1->LastVParameter();
0333 fpls2=0.5*(f+l);
0334 while((v1 < f)&&((fpls2-v1) > (v1+lmf-fpls2) )) { v1+=lmf; }
0335 while((v1 > l)&&((v1-fpls2) > (fpls2-(v1-lmf)) )) { v1-=lmf; }
0336 //-- while(v1 < f) { v1+=lmf; }
0337 //-- while(v1 > l) { v1-=lmf; }
0338 }
0339 if(myHS2IsUPeriodic) {
0340 lmf = M_PI+M_PI; //-- myHS2->UPeriod();
0341 f = myHS2->FirstUParameter();
0342 l = myHS2->LastUParameter();
0343 fpls2=0.5*(f+l);
0344 while((u2 < f)&&((fpls2-u2) > (u2+lmf-fpls2) )) { u2+=lmf; }
0345 while((u2 > l)&&((u2-fpls2) > (fpls2-(u2-lmf)) )) { u2-=lmf; }
0346 //-- while(u2 < f) { u2+=lmf; }
0347 //-- while(u2 > l) { u2-=lmf; }
0348 }
0349 if(myHS2IsVPeriodic) {
0350 lmf = M_PI+M_PI; //-- myHS2->VPeriod();
0351 f = myHS2->FirstVParameter();
0352 l = myHS2->LastVParameter();
0353 fpls2=0.5*(f+l);
0354 while((v2 < f)&&((fpls2-v2) > (v2+lmf-fpls2) )) { v2+=lmf; }
0355 while((v2 > l)&&((v2-fpls2) > (fpls2-(v2-lmf)) )) { v2-=lmf; }
0356 //-- while(v2 < f) { v2+=lmf; }
0357 //-- while(v2 > l) { v2-=lmf; }
0358 }
0359 }
0360 //=======================================================================
0361 //function : PutPointsOnLine
0362 //purpose :
0363 //=======================================================================
0364 void PutPointsOnLine(const Handle(Adaptor3d_Surface)& S1,
0365 const Handle(Adaptor3d_Surface)& S2,
0366 const IntPatch_SequenceOfPathPointOfTheSOnBounds& listpnt,
0367 const IntPatch_SequenceOfLine& slin,
0368 const Standard_Boolean OnFirst,
0369 const Handle(Adaptor3d_TopolTool)& Domain,
0370 const IntSurf_Quadric& QuadSurf,
0371 const IntSurf_Quadric& OtherQuad,
0372 const Standard_Boolean multpoint,
0373 const Standard_Real Tolarc) {
0374
0375 // Traitement des point (de listpnt) de depart. On les replace sur
0376 // la ligne d intersection, en leur affectant la transition correcte sur
0377 // cette ligne.
0378 Standard_Integer nbpnt = listpnt.Length();
0379 Standard_Integer nblin=slin.Length();
0380
0381 if (!slin.Length() || !nbpnt) {
0382 return;
0383 }
0384 //
0385 Standard_Integer i,k;
0386 Standard_Integer linenumber;
0387 Standard_Real currentparameter,tolerance;
0388 Standard_Real U1,V1,U2,V2;
0389 Standard_Boolean goon;
0390
0391
0392 gp_Pnt Psurf, ptbid;
0393 gp_Vec Normale, Vtgint, Vtgrst;
0394
0395 gp_Vec d1u,d1v;
0396 gp_Pnt2d p2d;
0397 gp_Vec2d d2d;
0398
0399 IntSurf_Transition Transline,Transarc;
0400
0401 Handle(Adaptor2d_Curve2d) currentarc;
0402 Handle(Adaptor3d_HVertex) vtx,vtxbis;
0403
0404 IntPatch_Point solpnt;
0405 IntPatch_ThePathPointOfTheSOnBounds currentpointonrst;
0406 IntPatch_IType TheType;
0407
0408 TColStd_Array1OfInteger UsedLine(1,nblin);
0409 TColStd_Array1OfInteger Done(1,nbpnt);
0410 for(i=1;i<=nbpnt;i++) Done(i) = 0; //-- Initialisation a la main
0411
0412 for (i=1; i<=nbpnt; i++) {
0413
0414 if (Done(i) != 1) {
0415 currentpointonrst = listpnt.Value(i);
0416 Psurf = currentpointonrst.Value(); // Point dans l espace
0417 tolerance = currentpointonrst.Tolerance();
0418
0419 // On recherche d abord si on a correspondance avec un "point multiple"
0420 UsedLine.Init(0);
0421
0422 goon = Standard_True;
0423 if (multpoint) {
0424 #if 1
0425 Normale = QuadSurf.Normale(Psurf); // Normale a la surface au point
0426 currentarc = currentpointonrst.Arc();
0427 currentparameter = currentpointonrst.Parameter();
0428 currentarc->D1(currentparameter,p2d,d2d);
0429 QuadSurf.D1(p2d.X(),p2d.Y(),ptbid,d1u,d1v);
0430 Vtgrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
0431 #endif
0432 goon = MultiplePoint(listpnt,Domain,QuadSurf,Normale,slin,Done, UsedLine,
0433 i, OnFirst, Tolarc);
0434 }
0435 if (goon) {
0436 Standard_Boolean linefound = Standard_False;
0437
0438 for(Standard_Integer indiceline = 1; indiceline <=slin.Length(); indiceline++) {
0439 if( UsedLine(indiceline) != 0 )
0440 continue;
0441 linenumber = indiceline;
0442
0443 //-- Attention , les points peuvent etre deplaces
0444 //-- il faut reprendre le point original
0445 currentpointonrst = listpnt.Value(i);
0446 currentarc = currentpointonrst.Arc();
0447 currentparameter = currentpointonrst.Parameter();
0448 Psurf = currentpointonrst.Value(); // Point dans l espace
0449 tolerance = currentpointonrst.Tolerance();
0450 //--
0451
0452
0453 // Modified by skv - Thu Jan 15 15:57:15 2004 OCC4455 Begin
0454 if (! currentpointonrst.IsNew()) {
0455 Handle(Adaptor3d_HVertex) aVtx = currentpointonrst.Vertex();
0456 Standard_Real aVtxTol = aVtx->Resolution(currentarc);
0457 Standard_Real aTolAng = 0.01*tolerance;
0458
0459 tolerance = Max(tolerance, aVtxTol);
0460
0461 gp_Vec aNorm1 = QuadSurf.Normale(Psurf);
0462 gp_Vec aNorm2 = OtherQuad.Normale(Psurf);
0463 //
0464 if (aNorm1.Magnitude()>gp::Resolution() &&
0465 aNorm2.Magnitude()>gp::Resolution()) {
0466
0467 if (aNorm1.IsParallel(aNorm2, aTolAng))
0468 tolerance = Sqrt(tolerance);
0469 }//
0470 }
0471 // Modified by skv - Thu Jan 15 15:57:15 2004 OCC4455 End
0472 gp_Pnt pointonarc;
0473 Vtgint.SetCoord(0,0,0);
0474 Standard_Real aVertTol = Tolarc;
0475 TColStd_ListOfReal aLParams;
0476 linefound = FindLine(Psurf, slin, tolerance, aLParams, Vtgint, linenumber,
0477 indiceline, currentarc, currentparameter,
0478 pointonarc, QuadSurf, OtherQuad, aVertTol);
0479 if (linefound) {
0480
0481 #if 1
0482 Normale = QuadSurf.Normale(Psurf); // Normale a la surface au point
0483 currentarc = currentpointonrst.Arc();
0484 //-- currentparameter = currentpointonrst.Parameter();
0485 currentarc->D1(currentparameter,p2d,d2d);
0486 QuadSurf.D1(p2d.X(),p2d.Y(),ptbid,d1u,d1v);
0487 Vtgrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
0488 #endif
0489
0490
0491
0492 const Handle(IntPatch_Line)& lin = slin.Value(linenumber);
0493 TheType = lin->ArcType();
0494
0495 if (!OnFirst) { // on cherche la correspondance entre point sur domaine
0496 // de la premiere surface et point sur domaine de la
0497 // deuxieme surface
0498
0499 goon = PointOnSecondDom (listpnt, Domain, QuadSurf, Normale,
0500 Vtgint, lin, Done, i, aVertTol);
0501 }
0502
0503 if (goon) {
0504 //-- Modification du 4 avril 97 tolerance->Tolarc
0505 //-- on replace sur le vertex la tolerance d entree et
0506 //-- non la tolerance qui a servi au FindLine
0507 solpnt.SetValue(Psurf, aVertTol, Standard_False);
0508
0509 U1 = p2d.X(); V1 = p2d.Y();
0510 OtherQuad.Parameters(Psurf,U2,V2);
0511
0512 if (OnFirst) {
0513 Recadre(S1,S2,U1,V1,U2,V2);
0514 solpnt.SetParameters(U1,V1,U2,V2);
0515 }
0516 else {
0517 Recadre(S1,S2,U2,V2,U1,V1);
0518 solpnt.SetParameters(U2,V2,U1,V1);
0519 }
0520
0521 if (! currentpointonrst.IsNew()) {
0522 vtx = currentpointonrst.Vertex();
0523 solpnt.SetVertex(OnFirst,vtx);
0524 }
0525 else {
0526 //-- goon = Standard_False; ????
0527 }
0528
0529 if(Normale.SquareMagnitude()<1e-16) {
0530 Transline.SetValue(Standard_True,IntSurf_Undecided);
0531 Transarc.SetValue(Standard_True,IntSurf_Undecided);
0532 }
0533 else {
0534 IntSurf::MakeTransition(Vtgint,Vtgrst,Normale,Transline,Transarc);
0535 }
0536 solpnt.SetArc(OnFirst,currentarc, currentparameter,
0537 Transline,Transarc);
0538
0539 for (TColStd_ListIteratorOfListOfReal anItr(aLParams);
0540 anItr.More(); anItr.Next())
0541 {
0542 solpnt.SetParameter(anItr.Value());
0543 if (TheType == IntPatch_Analytic)
0544 {
0545 Handle(IntPatch_ALine)::DownCast(lin)->AddVertex(solpnt);
0546 }
0547 else
0548 {
0549 Handle(IntPatch_GLine)::DownCast(lin)->AddVertex(solpnt);
0550 }
0551 }
0552
0553 Done(i) = 1;
0554
0555 if (goon) {
0556 for (k=i+1; k<= nbpnt; k++) {
0557 if (Done(k) != 1) {
0558 currentpointonrst = listpnt.Value(k);
0559 if (!currentpointonrst.IsNew()) {
0560 vtxbis = currentpointonrst.Vertex();
0561 if(vtx.IsNull()) {
0562 }
0563 else if (Domain->Identical(vtx, vtxbis)) {
0564 solpnt.SetVertex(OnFirst,vtxbis);
0565 solpnt.SetTolerance(Tolarc);
0566 currentarc = currentpointonrst.Arc();
0567 currentparameter = currentpointonrst.Parameter();
0568
0569 // currentarc->D1(currentparameter,ptbid,Vtgrst);
0570 currentarc->D1(currentparameter,p2d,d2d);
0571 Vtgrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
0572 if(Normale.SquareMagnitude()<1e-16) {
0573 Transline.SetValue(Standard_True,IntSurf_Undecided);
0574 Transarc.SetValue(Standard_True,IntSurf_Undecided);
0575 }
0576 else {
0577 IntSurf::MakeTransition(Vtgint,Vtgrst,Normale,
0578 Transline,Transarc);
0579 }
0580 solpnt.SetArc(OnFirst,currentarc,currentparameter,
0581 Transline,Transarc);
0582 if (TheType == IntPatch_Analytic) {
0583 Handle(IntPatch_ALine)::DownCast (lin)->AddVertex(solpnt);
0584 }
0585 else {
0586 Handle(IntPatch_GLine)::DownCast (lin)->AddVertex(solpnt);
0587 }
0588 Done(k) = 1;
0589 }
0590 }
0591 }
0592 }
0593 }
0594 }
0595 }
0596 else {
0597 Done(i) = 1; // il faudra tester si IsNew ou pas
0598 // et traiter en consequence
0599 }
0600 }
0601 }
0602 }
0603 }
0604 }
0605
0606
0607 Standard_Boolean MultiplePoint (const IntPatch_SequenceOfPathPointOfTheSOnBounds& listpnt,
0608 const Handle(Adaptor3d_TopolTool)& Domain,
0609 const IntSurf_Quadric& QuadSurf,
0610 const gp_Vec& Normale,
0611 const IntPatch_SequenceOfLine& slin,
0612 TColStd_Array1OfInteger& Done,
0613 TColStd_Array1OfInteger& UsedLine,
0614 const Standard_Integer Index,
0615 const Standard_Boolean OnFirst,
0616 const Standard_Real theToler) {
0617
0618 // Traitement des points "multiples".
0619
0620
0621 Standard_Integer k,ii,jj,nbvtx;
0622 Standard_Integer nblin = slin.Length();
0623 IntPatch_IType TheType;
0624
0625
0626 IntSurf_Transition Transline,Transarc;
0627
0628
0629 IntPatch_Point intpt;
0630 Handle(Adaptor2d_Curve2d) currentarc;
0631 Handle(Adaptor3d_HVertex) vtx,vtxbis;
0632
0633 Standard_Integer nbpnt = listpnt.Length();
0634 IntPatch_ThePathPointOfTheSOnBounds currentpointonrst = listpnt.Value(Index);
0635 IntPatch_ThePathPointOfTheSOnBounds otherpt;
0636 gp_Pnt Point = currentpointonrst.Value();
0637 TColStd_Array1OfInteger localdone(1,nbpnt); localdone.Init(0);
0638 for (ii=1; ii<=nbpnt; ii++) {
0639 localdone(ii)=Done(ii);
0640 }
0641
0642 Standard_Real currentparameter;
0643 Standard_Real Paraint;
0644 gp_Vec Vtgint,Vtgrst;
0645 gp_Pnt ptbid;
0646
0647 gp_Vec d1u,d1v;
0648 gp_Pnt2d p2d;
0649 gp_Vec2d d2d;
0650
0651 Standard_Boolean goon;
0652
0653 Standard_Boolean Retvalue = Standard_True;
0654
0655 for (ii = 1; ii <= nblin; ii++) {
0656 const Handle(IntPatch_Line)& slinValueii = slin.Value(ii);
0657 TheType = slinValueii->ArcType();
0658 if (TheType == IntPatch_Analytic) {
0659 nbvtx = Handle(IntPatch_ALine)::DownCast (slinValueii)->NbVertex();
0660 }
0661 else {
0662 nbvtx = Handle(IntPatch_GLine)::DownCast (slinValueii)->NbVertex();
0663 }
0664 jj = 1;
0665 while (jj <= nbvtx) {
0666 if (TheType == IntPatch_Analytic) {
0667 intpt = Handle(IntPatch_ALine)::DownCast (slinValueii)->Vertex(jj);
0668 }
0669 else {
0670 intpt = Handle(IntPatch_GLine)::DownCast (slinValueii)->Vertex(jj);
0671 }
0672 if (intpt.IsMultiple() &&
0673 (( OnFirst && !intpt.IsOnDomS1()) ||
0674 (!OnFirst && !intpt.IsOnDomS2()))) {
0675 if (Point.Distance(intpt.Value()) <= intpt.Tolerance()) {
0676 Retvalue = Standard_False;
0677 Standard_Boolean foo = SingleLine(Point,slinValueii,
0678 intpt.Tolerance(),Paraint,Vtgint);
0679 if (!foo) {
0680 return Standard_False; // ne doit pas se produire
0681 }
0682
0683 if (!currentpointonrst.IsNew()) {
0684 goon = Standard_True;
0685 vtx = currentpointonrst.Vertex();
0686 intpt.SetVertex(OnFirst,vtx);
0687 }
0688 else {
0689 goon = Standard_False;
0690 }
0691 currentarc = currentpointonrst.Arc();
0692 currentparameter = currentpointonrst.Parameter();
0693 currentarc->D1(currentparameter,p2d,d2d);
0694 QuadSurf.D1(p2d.X(),p2d.Y(),ptbid,d1u,d1v);
0695 Vtgrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
0696
0697 //-- Si la normale est nulle (apex d un cone) On simule une transition UNKNOWN
0698 if(Normale.SquareMagnitude()<1e-16) {
0699 Transline.SetValue(Standard_True,IntSurf_Undecided);
0700 Transarc.SetValue(Standard_True,IntSurf_Undecided);
0701 }
0702 else {
0703 IntSurf::MakeTransition(Vtgint,Vtgrst,Normale,Transline,Transarc);
0704 }
0705
0706 //-- Avant, on ne mettait pas ce point (17 nov 97)
0707 //--printf("\n ImpImp_0 : Point(%g,%g,%g) intpt(%g,%g,%g) \n",
0708 //-- Point.X(),Point.Y(),Point.Z(),intpt.Value().X(),intpt.Value().Y(),intpt.Value().Z());
0709 intpt.SetValue(Point);
0710
0711 intpt.SetArc(OnFirst,currentarc,currentparameter,
0712 Transline,Transarc);
0713 intpt.SetTolerance(theToler);
0714
0715 if (TheType == IntPatch_Analytic) {
0716 Handle(IntPatch_ALine)::DownCast (slinValueii)->Replace(jj,intpt);
0717 }
0718 else {
0719 Handle(IntPatch_GLine)::DownCast (slinValueii)->Replace(jj,intpt);
0720 }
0721 localdone(Index) = 1;
0722 if (goon) {
0723 for (k=Index+1; k<= nbpnt; k++) {
0724 if (Done(k) != 1) {
0725 otherpt= listpnt.Value(k);
0726 if (!otherpt.IsNew()) {
0727 vtxbis = otherpt.Vertex();
0728 if (Domain->Identical(vtx, vtxbis)) {
0729 intpt.SetVertex(OnFirst,vtxbis);
0730 currentarc = otherpt.Arc();
0731 currentparameter = otherpt.Parameter();
0732
0733 currentarc->D1(currentparameter,p2d,d2d);
0734 Vtgrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
0735 if(Normale.SquareMagnitude()<1e-16) {
0736 Transline.SetValue(Standard_True,IntSurf_Undecided);
0737 Transarc.SetValue(Standard_True,IntSurf_Undecided);
0738 }
0739 else {
0740 IntSurf::MakeTransition(Vtgint,Vtgrst,Normale,
0741 Transline,Transarc);
0742 }
0743 intpt.SetArc(OnFirst,currentarc,currentparameter,
0744 Transline,Transarc);
0745 intpt.SetTolerance(theToler);
0746 if (TheType == IntPatch_Analytic) {
0747 Handle(IntPatch_ALine)::DownCast (slinValueii)->AddVertex(intpt);
0748 }
0749 else {
0750 Handle(IntPatch_GLine)::DownCast (slinValueii)->AddVertex(intpt);
0751 }
0752 UsedLine(ii) = 1;
0753 Retvalue = Standard_True;
0754 localdone(k) = 1;
0755 }
0756 }
0757 }
0758 }
0759 }
0760 //-- jj = nbvtx +1;
0761 }
0762 //-- else {
0763 jj = jj+1;
0764 //-- }
0765 }
0766 else {
0767 jj = jj+1;
0768 }
0769 }
0770 }
0771
0772 for (ii=1; ii<=nbpnt;ii++) {
0773 Done(ii) = localdone(ii);
0774 }
0775
0776 return Retvalue;
0777 }
0778
0779
0780
0781 Standard_Boolean PointOnSecondDom (const IntPatch_SequenceOfPathPointOfTheSOnBounds& listpnt,
0782 const Handle(Adaptor3d_TopolTool)& Domain,
0783 const IntSurf_Quadric& QuadSurf,
0784 const gp_Vec& Normale,
0785 const gp_Vec& Vtgint,
0786 const Handle(IntPatch_Line)& lin,
0787 TColStd_Array1OfInteger& Done,
0788 const Standard_Integer Index,
0789 const Standard_Real theToler)
0790
0791
0792 // Duplication des points sur domaine de l autre surface.
0793 // On sait que le vertex sous-jacent est PntRef
0794
0795
0796 {
0797
0798 Standard_Integer k,jj,nbvtx;
0799 IntPatch_IType TheType;
0800
0801 IntSurf_Transition Transline,Transarc;
0802 IntPatch_Point intpt;
0803 Handle(Adaptor2d_Curve2d) currentarc;
0804 Handle(Adaptor3d_HVertex) vtx,vtxbis;
0805 gp_Pnt ptbid;
0806 gp_Vec Vtgrst;
0807
0808 gp_Vec d1u,d1v;
0809 gp_Pnt2d p2d;
0810 gp_Vec2d d2d;
0811
0812 Standard_Integer nbpnt = listpnt.Length();
0813 IntPatch_ThePathPointOfTheSOnBounds currentpointonrst = listpnt.Value(Index);
0814 Standard_Real currentparameter;
0815
0816 Standard_Boolean goon;
0817 Standard_Boolean Retvalue = Standard_True;
0818
0819 TheType = lin->ArcType();
0820 if (TheType == IntPatch_Analytic) {
0821 nbvtx = Handle(IntPatch_ALine)::DownCast (lin)->NbVertex();
0822 }
0823 else {
0824 nbvtx = Handle(IntPatch_GLine)::DownCast (lin)->NbVertex();
0825 }
0826 jj = 1;
0827 while (jj <= nbvtx) {
0828 if (TheType == IntPatch_Analytic) {
0829 intpt = Handle(IntPatch_ALine)::DownCast (lin)->Vertex(jj);
0830 }
0831 else {
0832 intpt = Handle(IntPatch_GLine)::DownCast (lin)->Vertex(jj);
0833 }
0834 if (!intpt.IsOnDomS2()) {
0835 if (currentpointonrst.Value().Distance(intpt.Value()) <=
0836 intpt.Tolerance()) {
0837 Retvalue = Standard_False;
0838 if (!currentpointonrst.IsNew()) {
0839 goon = Standard_True;
0840 vtx = currentpointonrst.Vertex();
0841 intpt.SetVertex(Standard_False,vtx);
0842 }
0843 else {
0844 goon = Standard_False;
0845 }
0846 currentarc = currentpointonrst.Arc();
0847 currentparameter = currentpointonrst.Parameter();
0848 currentarc->D1(currentparameter,p2d,d2d);
0849 QuadSurf.D1(p2d.X(),p2d.Y(),ptbid,d1u,d1v);
0850 Vtgrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
0851 if(Normale.SquareMagnitude()<1e-16) {
0852 Transline.SetValue(Standard_True,IntSurf_Undecided);
0853 Transarc.SetValue(Standard_True,IntSurf_Undecided);
0854 }
0855 else {
0856 IntSurf::MakeTransition(Vtgint,Vtgrst,Normale,Transline,Transarc);
0857 }
0858 intpt.SetArc(Standard_False,currentarc,currentparameter,
0859 Transline,Transarc);
0860 intpt.SetTolerance(theToler);
0861
0862 if (TheType == IntPatch_Analytic) {
0863 Handle(IntPatch_ALine)::DownCast (lin)->Replace(jj,intpt);
0864 }
0865 else {
0866 Handle(IntPatch_GLine)::DownCast (lin)->Replace(jj,intpt);
0867 }
0868 Done(Index) = 1;
0869
0870 if (goon) {
0871 for (k=Index+1; k<= nbpnt; k++) {
0872 if (Done(k) != 1) {
0873 currentpointonrst = listpnt.Value(k);
0874 if (!currentpointonrst.IsNew()) {
0875 vtxbis = currentpointonrst.Vertex();
0876 if (Domain->Identical(vtx, vtxbis)) {
0877 intpt.SetVertex(Standard_False,vtxbis);
0878 currentarc = currentpointonrst.Arc();
0879 currentparameter = currentpointonrst.Parameter();
0880 currentarc->D1(currentparameter,p2d,d2d);
0881 Vtgrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
0882 if(Normale.SquareMagnitude()<1e-16) {
0883 Transline.SetValue(Standard_True,IntSurf_Undecided);
0884 Transarc.SetValue(Standard_True,IntSurf_Undecided);
0885 }
0886 else {
0887 IntSurf::MakeTransition(Vtgint,Vtgrst,Normale,
0888 Transline,Transarc);
0889 }
0890 intpt.SetArc(Standard_False,currentarc,currentparameter,
0891 Transline,Transarc);
0892 intpt.SetTolerance(theToler);
0893 if (TheType == IntPatch_Analytic) {
0894 Handle(IntPatch_ALine)::DownCast (lin)->AddVertex(intpt);
0895 }
0896 else {
0897 Handle(IntPatch_GLine)::DownCast (lin)->AddVertex(intpt);
0898 }
0899 Done(k) = 1;
0900 }
0901 }
0902 }
0903 }
0904 }
0905 //-- jj = nbvtx + 1;
0906 jj++;
0907 }
0908 else {
0909 jj = jj+1;
0910 }
0911 }
0912 else {
0913 jj = jj+1;
0914 }
0915 if (TheType == IntPatch_Analytic) {
0916 nbvtx = Handle(IntPatch_ALine)::DownCast (lin)->NbVertex();
0917 }
0918 else {
0919 nbvtx = Handle(IntPatch_GLine)::DownCast (lin)->NbVertex();
0920 }
0921 }
0922 return Retvalue;
0923 }
0924
0925
0926
0927 Standard_Boolean FindLine(gp_Pnt& Psurf,
0928 const IntPatch_SequenceOfLine& slin,
0929 const Standard_Real Tol,
0930 TColStd_ListOfReal& theLParams,
0931 gp_Vec& Vtgtint,
0932 Standard_Integer& theLineIdx,
0933 Standard_Integer OnlyThisLine,
0934 const Handle(Adaptor2d_Curve2d)& thearc,
0935 Standard_Real& theparameteronarc,
0936 gp_Pnt& thepointonarc,
0937 const IntSurf_Quadric& QuadSurf1,
0938 const IntSurf_Quadric& QuadSurf2,
0939 Standard_Real& theOutputToler)
0940 {
0941 if ((QuadSurf1.Distance(Psurf) > Tol) || (QuadSurf2.Distance(Psurf) > Tol))
0942 return Standard_False;
0943
0944 // Traitement du point de depart ayant pour representation Psurf
0945 // dans l espace. On recherche la ligne d intersection contenant ce point.
0946 // On a en sortie la ligne, et le parametre et sa tangente du point sur
0947 // la ligne d intersection.
0948 const Standard_Real aSqTol = Tol*Tol;
0949 Standard_Real aSqDistMin = RealLast();
0950 Standard_Real aSqDist, para;
0951 Standard_Real lower,upper;
0952 gp_Pnt pt;
0953 Standard_Integer i;
0954 IntPatch_IType typarc;
0955
0956 Standard_Real aParaInt = RealLast();
0957 Standard_Integer nblin = slin.Length();
0958 for (i=1; i<=nblin; i++) {
0959 if(OnlyThisLine) { i=OnlyThisLine; nblin=0; }
0960 const Handle(IntPatch_Line)& lin = slin.Value(i);
0961 typarc = lin->ArcType();
0962 if (typarc == IntPatch_Analytic) {
0963 Standard_Boolean foo;
0964 lower = Handle(IntPatch_ALine)::DownCast (lin)->FirstParameter(foo);
0965 upper = Handle(IntPatch_ALine)::DownCast (lin)->LastParameter(foo);
0966 }
0967 else {
0968 if (Handle(IntPatch_GLine)::DownCast (lin)->HasFirstPoint()) {
0969 lower = Handle(IntPatch_GLine)::DownCast (lin)->FirstPoint().ParameterOnLine();
0970 }
0971 else {
0972 lower = RealFirst();
0973 }
0974 if (Handle(IntPatch_GLine)::DownCast (lin)->HasLastPoint()) {
0975 upper = Handle(IntPatch_GLine)::DownCast (lin)->LastPoint().ParameterOnLine();
0976 }
0977 else {
0978 upper = RealLast();
0979 }
0980 }
0981
0982 switch (typarc) {
0983 case IntPatch_Lin :
0984 {
0985 para = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast (lin)->Line(),Psurf);
0986 if (para <= upper && para >= lower) {
0987 pt = ElCLib::Value(para,Handle(IntPatch_GLine)::DownCast (lin)->Line());
0988 aSqDist = Psurf.SquareDistance(pt);
0989 if ((aSqDist < aSqTol) && (aSqDist < aSqDistMin))
0990 {
0991 aSqDistMin = aSqDist;
0992 aParaInt = para;
0993 theLineIdx = i;
0994 }
0995 }
0996 }
0997 break;
0998 case IntPatch_Circle :
0999 {
1000 para = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast (lin)->Circle(),Psurf);
1001 if ((para <= upper && para >= lower) ||
1002 (para + 2.*M_PI <=upper && para + 2.*M_PI >= lower) ||
1003 (para - 2.*M_PI <=upper && para - 2.*M_PI >= lower)) {
1004 pt = ElCLib::Value(para,Handle(IntPatch_GLine)::DownCast (lin)->Circle());
1005 aSqDist = Psurf.SquareDistance(pt);
1006 if ((aSqDist < aSqTol) && (aSqDist < aSqDistMin))
1007 {
1008 aSqDistMin = aSqDist;
1009 aParaInt = para;
1010 theLineIdx = i;
1011 }
1012 }
1013 }
1014 break;
1015 case IntPatch_Ellipse :
1016 {
1017 para = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast (lin)->Ellipse(),Psurf);
1018 if ((para <= upper && para >= lower) ||
1019 (para + 2.*M_PI <=upper && para + 2.*M_PI >= lower) ||
1020 (para - 2.*M_PI <=upper && para - 2.*M_PI >= lower)) {
1021 pt = ElCLib::Value(para,Handle(IntPatch_GLine)::DownCast (lin)->Ellipse());
1022 aSqDist = Psurf.SquareDistance(pt);
1023 if ((aSqDist < aSqTol) && (aSqDist < aSqDistMin))
1024 {
1025 aSqDistMin = aSqDist;
1026 aParaInt = para;
1027 theLineIdx = i;
1028 }
1029 }
1030 }
1031 break;
1032 case IntPatch_Parabola :
1033 {
1034
1035 #if 0
1036 para = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast (lin)->Parabola(),Psurf);
1037 if (para <= upper && para >= lower) {
1038 pt = ElCLib::Value(para,Handle(IntPatch_GLine)::DownCast (lin)->Parabola());
1039 dist = Psurf.Distance(pt);
1040 if (dist< distmin) {
1041 distmin = dist;
1042 Paraint = para;
1043 Range = i;
1044 }
1045 }
1046 #else
1047 //-- Le calcul du parametre sur une parabole est mal fait ds ElCLib. Il ne tient pas compte
1048 //-- de la meilleure facon de calculer (axe X ou axe Y). Bilan : Si la parabole est tres
1049 //-- pointue (focal de l'ordre de 1e-2 et si le point est a un parametre grand, ca foire. )
1050 //-- On ne peut pas modifier faciolement ds ElCLib car on ne passe pas la focale. ...
1051 const gp_Parab& Parab=Handle(IntPatch_GLine)::DownCast (lin)->Parabola();
1052 para = ElCLib::Parameter(Parab,Psurf);
1053 if (para <= upper && para >= lower) {
1054 Standard_Integer amelioration=0;
1055 //-- cout<<"\n ****** \n";
1056 do {
1057 Standard_Real parabis = para+0.0000001;
1058
1059 pt = ElCLib::Value(para,Parab);
1060 aSqDist = Psurf.SquareDistance(pt);
1061
1062 const gp_Pnt ptbis = ElCLib::Value(parabis,Parab);
1063 const Standard_Real distbis = Psurf.Distance(ptbis);
1064 const Standard_Real aDist = Sqrt(aSqDist);
1065 const Standard_Real ddist = distbis - aDist;
1066
1067 //--cout<<" para: "<<para<<" dist:"<<dist<<" ddist:"<<ddist<<endl;
1068
1069 if ((aSqDist < aSqTol) && (aSqDist < aSqDistMin))
1070 {
1071 aSqDistMin = aSqDist;
1072 aParaInt = para;
1073 theLineIdx = i;
1074 }
1075 if (aSqDist < Precision::SquarePConfusion())
1076 {
1077 amelioration = 100;
1078 }
1079
1080 if(ddist>1.0e-9 || ddist<-1.0e-9 ) {
1081 para = para - aDist*(parabis - para) / ddist;
1082 }
1083 else {
1084 amelioration=100;
1085 }
1086 }
1087 while(++amelioration < 5);
1088 }
1089
1090
1091 #endif
1092 }
1093 break;
1094 case IntPatch_Hyperbola :
1095 {
1096 para = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast (lin)->Hyperbola(),Psurf);
1097 if (para <= upper && para >= lower) {
1098 pt = ElCLib::Value(para,Handle(IntPatch_GLine)::DownCast (lin)->Hyperbola());
1099 aSqDist = Psurf.SquareDistance(pt);
1100 if ((aSqDist < aSqTol) && (aSqDist < aSqDistMin))
1101 {
1102 aSqDistMin = aSqDist;
1103 aParaInt = para;
1104 theLineIdx = i;
1105 }
1106 }
1107 }
1108 break;
1109
1110 case IntPatch_Analytic :
1111 {
1112 Handle(IntPatch_ALine) alin(Handle(IntPatch_ALine)::DownCast(lin));
1113 TColStd_ListOfReal aLParams;
1114 alin->FindParameter(Psurf, aLParams);
1115 if (!aLParams.IsEmpty())
1116 {
1117 // All found distances are already in some internal tolerance
1118 // set in alin->FindParameter(...) method.
1119
1120 aSqDist = RealLast();
1121 for (TColStd_ListIteratorOfListOfReal anItr(aLParams);
1122 anItr.More(); anItr.Next())
1123 {
1124 pt = alin->Value(anItr.Value());
1125 const Standard_Real aSqD = Psurf.SquareDistance(pt);
1126 if (aSqD < aSqDist)
1127 {
1128 aSqDist = aSqD;
1129 }
1130 }
1131
1132 if (aSqDist < aSqDistMin)
1133 {
1134 aSqDistMin = aSqDist;
1135 theLParams = aLParams;
1136 theLineIdx = i;
1137 }
1138 }
1139 else {
1140 //-- le point n a pas ete trouve par bete projection.
1141 //-- on essaie l intersection avec la restriction en 2d
1142 Standard_Real theparamonarc = theparameteronarc;
1143 //#ifdef OCCT_DEBUG
1144 // Standard_Real anpara=para;
1145 //#endif
1146 gp_Pnt CopiePsurf=Psurf;
1147 Standard_Boolean IntersectIsOk = IntersectionWithAnArc(CopiePsurf, alin, para,
1148 thearc, theparamonarc,
1149 thepointonarc,
1150 QuadSurf1,
1151 lower, upper);
1152 aSqDist = CopiePsurf.SquareDistance(Psurf);
1153 if(IntersectIsOk) {
1154 if (aSqDist < aSqTol)
1155 {
1156 theparameteronarc = theparamonarc;
1157 Psurf = thepointonarc;
1158 aSqDistMin = aSqDist;
1159 theLParams.Append(para);
1160 theLineIdx = i;
1161 }
1162 }
1163 }
1164 }
1165 break;
1166
1167 case IntPatch_Walking: // impossible . c est pour eviter les warnings
1168 {
1169 }
1170 case IntPatch_Restriction: // impossible . c est pour eviter les warnings
1171 {
1172 }
1173 }
1174 }
1175
1176 if (aSqDistMin == RealLast())
1177 return Standard_False;
1178
1179 theOutputToler = Max(theOutputToler, Sqrt(aSqDistMin));
1180
1181 typarc = slin.Value(theLineIdx)->ArcType();
1182
1183 // Computation of tangent vector
1184 switch (typarc) {
1185 case IntPatch_Lin :
1186 theLParams.Append(aParaInt);
1187 Vtgtint = (*((Handle(IntPatch_GLine)*)&slin(theLineIdx)))->Line().Direction();
1188 break;
1189 case IntPatch_Circle :
1190 theLParams.Append(aParaInt);
1191 Vtgtint = ElCLib::DN(aParaInt, (*((Handle(IntPatch_GLine)*)&slin(theLineIdx)))->Circle(), 1);
1192 break;
1193 case IntPatch_Ellipse :
1194 theLParams.Append(aParaInt);
1195 Vtgtint = ElCLib::DN(aParaInt, (*((Handle(IntPatch_GLine)*)&slin(theLineIdx)))->Ellipse(), 1);
1196 break;
1197 case IntPatch_Parabola :
1198 theLParams.Append(aParaInt);
1199 Vtgtint = ElCLib::DN(aParaInt, (*((Handle(IntPatch_GLine)*)&slin(theLineIdx)))->Parabola(), 1);
1200 break;
1201 case IntPatch_Hyperbola :
1202 theLParams.Append(aParaInt);
1203 Vtgtint = ElCLib::DN(aParaInt, (*((Handle(IntPatch_GLine)*)&slin(theLineIdx)))->Hyperbola(), 1);
1204 break;
1205
1206 case IntPatch_Analytic:
1207 {
1208 if (!Handle(IntPatch_ALine)::DownCast(slin(theLineIdx))->D1(theLParams.Last(), pt, Vtgtint))
1209 {
1210 //Previously (before the fix #29807) this code tried to process case
1211 //when Handle(IntPatch_ALine)::D1(...) method returns FALSE and
1212 //computed Vtgtint input argument value. Currently, any singularities
1213 //must be processed by high-level algorithms (IntPatch_SpecialPoints class).
1214 //Therefore this code has been deleted as deprecated.
1215
1216 Vtgtint.SetCoord(0.0, 0.0, 0.0);
1217 }
1218 }
1219 break;
1220 case IntPatch_Walking: // impossible . c est pour eviter les warnings
1221 {
1222 }
1223 case IntPatch_Restriction: // impossible . c est pour eviter les warnings
1224 {
1225 }
1226
1227 }
1228 return Standard_True;
1229 }
1230
1231 //=======================================================================
1232 //function : SingleLine
1233 //purpose : Traitement du point de depart ayant pour representation Psurf
1234 // dans l espace. On le replace sur la ligne d intersection; On a en sortie
1235 // son parametre et sa tangente sur la ligne d intersection.
1236 // La fonction renvoie False si le point projete est a une distance
1237 // superieure a Tol du point a projeter.
1238 //=======================================================================
1239 Standard_Boolean SingleLine(const gp_Pnt& Psurf,
1240 const Handle(IntPatch_Line)& lin,
1241 const Standard_Real Tol,
1242 Standard_Real& Paraint,
1243 gp_Vec& Vtgtint)
1244 {
1245 IntPatch_IType typarc = lin->ArcType();
1246
1247 Standard_Real parproj = 0.;
1248 gp_Vec tgint;
1249 gp_Pnt ptproj;
1250 Standard_Boolean retvalue;
1251
1252 switch (typarc) {
1253 case IntPatch_Lin :
1254 parproj = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast (lin)->Line(),Psurf);
1255 ElCLib::D1(parproj,Handle(IntPatch_GLine)::DownCast (lin)->Line(),ptproj,tgint);
1256 break;
1257 case IntPatch_Circle :
1258 parproj = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast (lin)->Circle(),Psurf);
1259 ElCLib::D1(parproj,Handle(IntPatch_GLine)::DownCast (lin)->Circle(),ptproj,tgint);
1260 break;
1261 case IntPatch_Ellipse :
1262 parproj = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast (lin)->Ellipse(),Psurf);
1263 ElCLib::D1(parproj,Handle(IntPatch_GLine)::DownCast (lin)->Ellipse(),ptproj,tgint);
1264 break;
1265 case IntPatch_Parabola :
1266 parproj = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast (lin)->Parabola(),Psurf);
1267 ElCLib::D1(parproj,Handle(IntPatch_GLine)::DownCast (lin)->Parabola(),ptproj,tgint);
1268 break;
1269 case IntPatch_Hyperbola :
1270 parproj = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast (lin)->Hyperbola(),Psurf);
1271 ElCLib::D1(parproj,Handle(IntPatch_GLine)::DownCast (lin)->Hyperbola(),ptproj,tgint);
1272 break;
1273 case IntPatch_Analytic :
1274 {
1275 Handle(IntPatch_ALine) alin(Handle(IntPatch_ALine)::DownCast(lin));
1276 TColStd_ListOfReal aLParams;
1277 alin->FindParameter(Psurf, aLParams);
1278 if (!aLParams.IsEmpty())
1279 {
1280 ptproj = Psurf;
1281 parproj = aLParams.Last();
1282 gp_Pnt aPtemp;
1283 if (!alin->D1(parproj, aPtemp, tgint))
1284 {
1285 //Previously (before the fix #29807) this code tried to process case
1286 //when Handle(IntPatch_ALine)::D1(...) method returns FALSE and
1287 //computed Vtgtint input argument value. Currently, any singularities
1288 //must be processed by high-level algorithms (IntPatch_SpecialPoints class).
1289 //Therefore this code has been deleted as deprecated.
1290
1291 tgint.SetCoord(0.0, 0.0, 0.0);
1292 }
1293 }
1294 else
1295 {
1296 //-- cout << "---- Pb sur ligne analytique dans SingleLine" << endl;
1297 //-- cout << " Find Parameter"<<endl;
1298 return Standard_False;
1299 }
1300 }
1301 break;
1302 case IntPatch_Walking: // impossible . c est pour eviter les warnings
1303 {
1304 }
1305 case IntPatch_Restriction: // impossible . c est pour eviter les warnings
1306 {
1307 }
1308 }
1309
1310 if (Psurf.Distance(ptproj) <= Tol) {
1311 Paraint = parproj;
1312 Vtgtint = tgint;
1313 retvalue = Standard_True;
1314 }
1315 else {
1316 retvalue = Standard_False;
1317 }
1318 return retvalue;
1319 }
1320
1321
1322 void ProcessSegments (const IntPatch_SequenceOfSegmentOfTheSOnBounds& listedg,
1323 IntPatch_SequenceOfLine& slin,
1324 const IntSurf_Quadric& Quad1,
1325 const IntSurf_Quadric& Quad2,
1326 const Standard_Boolean OnFirst,
1327 const Standard_Real TolArc) {
1328
1329 Standard_Integer i,j,k;
1330 Standard_Integer nbedg = listedg.Length();
1331 Standard_Integer Nblines,Nbpts;
1332
1333 Handle(Adaptor2d_Curve2d) arcRef;
1334 IntPatch_Point ptvtx, newptvtx;
1335
1336 Handle(IntPatch_RLine) rline; //-- On fait rline = new ... par la suite
1337
1338 IntPatch_TheSegmentOfTheSOnBounds thesegsol;
1339 IntPatch_ThePathPointOfTheSOnBounds PStartf,PStartl;
1340 Standard_Boolean dofirst,dolast,procf,procl;
1341
1342 Standard_Real paramf =0.,paraml =0.,U1 =0.,V1 =0.,U2 =0.,V2 =0.;
1343
1344 IntPatch_IType typ;
1345 IntSurf_TypeTrans trans1,trans2;
1346 IntSurf_Transition TRest,TArc;
1347 gp_Vec tgline,norm1,norm2,tgarc;
1348 gp_Pnt valpt;
1349
1350 gp_Vec d1u,d1v;
1351 gp_Pnt2d p2d;
1352 gp_Vec2d d2d;
1353
1354
1355 for (i = 1; i <= nbedg; i++) {
1356 Standard_Boolean EdgeDegenere=Standard_False;
1357 thesegsol = listedg.Value(i);
1358 arcRef = thesegsol.Curve();
1359
1360
1361 rline = new IntPatch_RLine(Standard_False);
1362 if(OnFirst) {
1363 rline->SetArcOnS1(arcRef);
1364 }
1365 else {
1366 rline->SetArcOnS2(arcRef);
1367 }
1368
1369 // Traitement des points debut/fin du segment solution.
1370
1371 dofirst = Standard_False;
1372 dolast = Standard_False;
1373 procf = Standard_False;
1374 procl = Standard_False;
1375
1376 if (thesegsol.HasFirstPoint()) {
1377 dofirst = Standard_True;
1378 PStartf = thesegsol.FirstPoint();
1379 paramf = PStartf.Parameter();
1380 }
1381 if (thesegsol.HasLastPoint()) {
1382 dolast = Standard_True;
1383 PStartl = thesegsol.LastPoint();
1384 paraml = PStartl.Parameter();
1385 }
1386
1387 if (dofirst && dolast) { // determination de la transition de la ligne
1388 arcRef->D1(0.5*(paramf+paraml),p2d,d2d);
1389 if (OnFirst) {
1390 Quad1.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
1391 }
1392 else {
1393 Quad2.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
1394 }
1395 tgline.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
1396
1397 if(d1u.Magnitude()<1e-7) { //-- edge degenere ?
1398 EdgeDegenere=Standard_True;
1399 for(Standard_Integer edg=0;edg<=10;edg++) {
1400 arcRef->D1(paramf+(paraml-paramf)*edg*0.1,p2d,d2d);
1401 if (OnFirst) {
1402 Quad1.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
1403 }
1404 else {
1405 Quad2.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
1406 }
1407
1408 if(d1u.Magnitude()>1e-7) {
1409 EdgeDegenere=Standard_False;
1410 }
1411 }
1412 rline = new IntPatch_RLine(Standard_False);
1413 if(OnFirst) {
1414 rline->SetArcOnS1(arcRef);
1415 }
1416 else {
1417 rline->SetArcOnS2(arcRef);
1418 }
1419 }
1420 else {
1421 norm2 = Quad2.Normale(valpt);
1422 norm1 = Quad1.Normale(valpt);
1423
1424 if (tgline.DotCross(norm2,norm1) > 0.000000001) {
1425 trans1 = IntSurf_Out;
1426 trans2 = IntSurf_In;
1427 }
1428 else if (tgline.DotCross(norm2,norm1) < -0.000000001){
1429 trans1 = IntSurf_In;
1430 trans2 = IntSurf_Out;
1431 }
1432 else {
1433 trans1 = trans2 = IntSurf_Undecided;
1434 }
1435 rline = new IntPatch_RLine(Standard_False,trans1,trans2);
1436 if(OnFirst) {
1437 rline->SetArcOnS1(arcRef);
1438 }
1439 else {
1440 rline->SetArcOnS2(arcRef);
1441 }
1442 }
1443 }
1444 else {
1445 rline = new IntPatch_RLine(Standard_False);
1446 if(OnFirst) {
1447 rline->SetArcOnS1(arcRef);
1448 }
1449 else {
1450 rline->SetArcOnS2(arcRef);
1451 }
1452 }
1453
1454 if (dofirst || dolast) {
1455 Nblines = slin.Length();
1456 for (j=1; j<=Nblines; j++) {
1457 const Handle(IntPatch_Line)& slinj = slin(j);
1458 typ = slinj->ArcType();
1459 if (typ == IntPatch_Analytic) {
1460 Nbpts = Handle(IntPatch_ALine)::DownCast (slinj)->NbVertex();
1461 }
1462 else if (typ == IntPatch_Restriction) {
1463 Nbpts = Handle(IntPatch_RLine)::DownCast (slinj)->NbVertex();
1464 }
1465 else {
1466 Nbpts = Handle(IntPatch_GLine)::DownCast (slinj)->NbVertex();
1467 }
1468 for (k=1; k<=Nbpts;k++) {
1469 if (typ == IntPatch_Analytic) {
1470 ptvtx = Handle(IntPatch_ALine)::DownCast (slinj)->Vertex(k);
1471 }
1472 else if (typ == IntPatch_Restriction) {
1473 ptvtx = Handle(IntPatch_RLine)::DownCast (slinj)->Vertex(k);
1474 }
1475 else {
1476 ptvtx = Handle(IntPatch_GLine)::DownCast (slinj)->Vertex(k);
1477 }
1478
1479 if (EdgeDegenere==Standard_False && dofirst) {
1480 if (ptvtx.Value().Distance(PStartf.Value()) <=TolArc) {
1481 ptvtx.SetMultiple(Standard_True);
1482 ptvtx.SetTolerance(TolArc);
1483 if (typ == IntPatch_Analytic) {
1484 Handle(IntPatch_ALine)::DownCast (slinj)->Replace(k,ptvtx);
1485 }
1486 else if (typ == IntPatch_Restriction) {
1487 Handle(IntPatch_RLine)::DownCast (slinj)->Replace(k,ptvtx);
1488 }
1489 else {
1490 Handle(IntPatch_GLine)::DownCast (slinj)->Replace(k,ptvtx);
1491 }
1492 newptvtx = ptvtx;
1493 newptvtx.SetParameter(paramf);
1494 //Recalcul des transitions si point sur restriction
1495
1496 arcRef->D1(paramf,p2d,d2d);
1497 if (OnFirst) {
1498 Quad1.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
1499 }
1500 else {
1501 Quad2.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
1502 }
1503 tgline.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
1504 if (ptvtx.IsOnDomS1()) {
1505 const Handle(Adaptor2d_Curve2d)& thearc = ptvtx.ArcOnS1();
1506 thearc->D1(ptvtx.ParameterOnArc1(),p2d,d2d);
1507 Quad1.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
1508 tgarc.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
1509 norm1 = d1u.Crossed(d1v);
1510 if(norm1.SquareMagnitude()<1e-16) {
1511 TRest.SetValue(Standard_True,IntSurf_Undecided);
1512 TArc.SetValue(Standard_True,IntSurf_Undecided);
1513 }
1514 else {
1515 IntSurf::MakeTransition(tgline,tgarc,norm1,TRest,TArc);
1516 }
1517 newptvtx.SetArc(Standard_True,thearc,ptvtx.ParameterOnArc1(),
1518 TRest,TArc);
1519 }
1520 if (ptvtx.IsOnDomS2()) {
1521 const Handle(Adaptor2d_Curve2d)& thearc = ptvtx.ArcOnS2();
1522 thearc->D1(ptvtx.ParameterOnArc2(),p2d,d2d);
1523 Quad2.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
1524 tgarc.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
1525 norm2 = d1u.Crossed(d1v);
1526 if(norm2.SquareMagnitude()<1e-16) {
1527 TRest.SetValue(Standard_True,IntSurf_Undecided);
1528 TArc.SetValue(Standard_True,IntSurf_Undecided);
1529 }
1530 else {
1531 IntSurf::MakeTransition(tgline,tgarc,norm2,TRest,TArc);
1532 }
1533 newptvtx.SetArc(Standard_False,thearc,ptvtx.ParameterOnArc2(),
1534 TRest,TArc);
1535 }
1536
1537 rline->AddVertex(newptvtx);
1538 if (!procf){
1539 procf=Standard_True;
1540 rline->SetFirstPoint(rline->NbVertex());
1541 }
1542 }
1543 }
1544 if (EdgeDegenere==Standard_False && dolast) {
1545 if (ptvtx.Value().Distance(PStartl.Value()) <=TolArc) {
1546 ptvtx.SetMultiple(Standard_True);
1547 ptvtx.SetTolerance(TolArc);
1548 if (typ == IntPatch_Analytic) {
1549 Handle(IntPatch_ALine)::DownCast (slinj)->Replace(k,ptvtx);
1550 }
1551 else if (typ == IntPatch_Restriction) {
1552 Handle(IntPatch_RLine)::DownCast (slinj)->Replace(k,ptvtx);
1553 }
1554 else {
1555 Handle(IntPatch_GLine)::DownCast (slinj)->Replace(k,ptvtx);
1556 }
1557
1558 newptvtx = ptvtx;
1559 newptvtx.SetParameter(paraml);
1560 //Recalcul des transitions si point sur restriction
1561
1562 arcRef->D1(paraml,p2d,d2d);
1563 if (OnFirst) {
1564 Quad1.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
1565 }
1566 else {
1567 Quad2.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
1568 }
1569 tgline.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
1570 if (ptvtx.IsOnDomS1()) {
1571 const Handle(Adaptor2d_Curve2d)& thearc = ptvtx.ArcOnS1();
1572 thearc->D1(ptvtx.ParameterOnArc1(),p2d,d2d);
1573 Quad1.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
1574 tgarc.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
1575 norm1 = d1u.Crossed(d1v);
1576 if(norm1.SquareMagnitude()<1e-16) {
1577 TRest.SetValue(Standard_True,IntSurf_Undecided);
1578 TArc.SetValue(Standard_True,IntSurf_Undecided);
1579 }
1580 else {
1581 IntSurf::MakeTransition(tgline,tgarc,norm1,TRest,TArc);
1582 }
1583 newptvtx.SetArc(Standard_True,thearc,ptvtx.ParameterOnArc1(),
1584 TRest,TArc);
1585 }
1586 if (ptvtx.IsOnDomS2()) {
1587 const Handle(Adaptor2d_Curve2d)& thearc = ptvtx.ArcOnS2();
1588 thearc->D1(ptvtx.ParameterOnArc2(),p2d,d2d);
1589 Quad2.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
1590 tgarc.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
1591 norm2 = d1u.Crossed(d1v);
1592 if(norm2.SquareMagnitude()<1e-16) {
1593 TRest.SetValue(Standard_True,IntSurf_Undecided);
1594 TArc.SetValue(Standard_True,IntSurf_Undecided);
1595 }
1596 else {
1597 IntSurf::MakeTransition(tgline,tgarc,norm2,TRest,TArc);
1598 }
1599 newptvtx.SetArc(Standard_False,thearc,ptvtx.ParameterOnArc2(),
1600 TRest,TArc);
1601 }
1602
1603 rline->AddVertex(newptvtx);
1604 if (!procl){
1605 procl=Standard_True;
1606 rline->SetLastPoint(rline->NbVertex());
1607 }
1608 }
1609 }
1610 }
1611 // Si on a traite le pt debut et/ou fin, on ne doit pas recommencer si
1612 // il (ils) correspond(ent) a un point multiple.
1613
1614 if (procf) {
1615 dofirst = Standard_False;
1616 }
1617 if (procl) {
1618 dolast = Standard_False;
1619 }
1620 }
1621 }
1622 // Si on n a pas trouve le point debut et./ou fin sur une des lignes
1623 // d intersection, il faut quand-meme le placer sur la restriction solution
1624
1625 if (dofirst) {
1626 ptvtx.SetValue(PStartf.Value(),PStartf.Tolerance(),Standard_False);
1627 Quad1.Parameters(PStartf.Value(),U1,V1);
1628 Quad2.Parameters(PStartf.Value(),U2,V2);
1629 ptvtx.SetParameters(U1,V1,U2,V2);
1630 ptvtx.SetParameter(paramf);
1631 if (! PStartf.IsNew()) {
1632 IntSurf_Transition Transline;
1633 IntSurf_Transition Transarc;
1634 ptvtx.SetVertex(OnFirst,PStartf.Vertex());
1635 ptvtx.SetArc(OnFirst,PStartf.Arc(),PStartf.Parameter(),
1636 Transline,Transarc);
1637 }
1638
1639 rline->AddVertex(ptvtx);
1640 rline->SetFirstPoint(rline->NbVertex());
1641 }
1642 if (dolast) {
1643 ptvtx.SetValue(PStartl.Value(),PStartl.Tolerance(),Standard_False);
1644 Quad1.Parameters(PStartl.Value(),U1,V1);
1645 Quad2.Parameters(PStartl.Value(),U2,V2);
1646 ptvtx.SetParameters(U1,V1,U2,V2);
1647 ptvtx.SetParameter(paraml);
1648 if (! PStartl.IsNew()) {
1649 IntSurf_Transition Transline;
1650 IntSurf_Transition Transarc;
1651
1652 ptvtx.SetVertex(OnFirst,PStartl.Vertex());
1653 ptvtx.SetArc(OnFirst,PStartl.Arc(),PStartl.Parameter(),
1654 Transline,Transarc);
1655 }
1656
1657 rline->AddVertex(ptvtx);
1658 rline->SetLastPoint(rline->NbVertex());
1659 }
1660 slin.Append(rline);
1661 }
1662 }
1663
1664 inline const gp_Pnt& PointValue(const Handle(IntPatch_RLine) theRLine,
1665 const Standard_Integer theIndex)
1666 {
1667 return theRLine->Point(theIndex).Value();
1668 }
1669
1670 inline const gp_Pnt& VertexValue( const Handle(IntPatch_RLine) theRLine,
1671 const Standard_Integer theIndex)
1672 {
1673 return theRLine->Vertex(theIndex).Value();
1674 }
1675
1676 static Standard_Real SquareDistance(const Handle(IntPatch_GLine)& theGLine,
1677 const gp_Pnt& theP,
1678 Extrema_ExtPC& theExtr)
1679 {
1680 Standard_Real aSQDist = RealLast();
1681 switch(theGLine->ArcType())
1682 {
1683 case IntPatch_Lin:
1684 aSQDist = theGLine->Line().SquareDistance(theP);
1685 break;
1686 case IntPatch_Circle:
1687 aSQDist = theGLine->Circle().SquareDistance(theP);
1688 break;
1689 default:
1690 theExtr.Perform(theP);
1691 if(!theExtr.IsDone() || !theExtr.NbExt())
1692 {
1693 //Lines are not overlapped
1694 return aSQDist;
1695 }
1696
1697 aSQDist = theExtr.SquareDistance(1);
1698 const Standard_Integer aNbExtr = theExtr.NbExt();
1699 for ( Standard_Integer i = 2; i <= aNbExtr; i++)
1700 {
1701 const Standard_Real aSQD = theExtr.SquareDistance(i);
1702 if (aSQD < aSQDist)
1703 {
1704 aSQDist = aSQD;
1705 }
1706 }
1707 }
1708
1709 return aSQDist;
1710 }
1711
1712 static Standard_Boolean IsRLineGood(const IntSurf_Quadric& Quad1,
1713 const IntSurf_Quadric& Quad2,
1714 const Handle(IntPatch_GLine) theGLine,
1715 const Handle(IntPatch_RLine) theRLine,
1716 const Standard_Real theTol)
1717 {
1718 const Standard_Real aSQTol = theTol*theTol;
1719 const IntPatch_IType aGType = theGLine->ArcType();
1720 Standard_Integer aNbPntsM1 = 0;
1721
1722 const gp_Pnt& (*Value) (const Handle(IntPatch_RLine), const Standard_Integer);
1723
1724 if(theRLine->HasPolygon())
1725 {
1726 aNbPntsM1 = theRLine->NbPnts()-1;
1727 Value = PointValue;
1728 }
1729 else
1730 {
1731 aNbPntsM1 = theRLine->NbVertex()-1;
1732 Value = VertexValue;
1733 }
1734
1735 if(aNbPntsM1 < 1)
1736 return Standard_False;
1737
1738 Extrema_ExtPC anExtr;
1739 GeomAdaptor_Curve anAC;
1740 Handle(Geom_Curve) aCurv;
1741
1742 if(aGType == IntPatch_Ellipse)
1743 aCurv = new Geom_Ellipse(theGLine->Ellipse());
1744 else if(aGType == IntPatch_Parabola)
1745 aCurv = new Geom_Parabola(theGLine->Parabola());
1746 else if(aGType == IntPatch_Hyperbola)
1747 aCurv = new Geom_Hyperbola(theGLine->Hyperbola());
1748
1749 if(!aCurv.IsNull())
1750 {
1751 const Standard_Real anUinf = aCurv->FirstParameter(),
1752 anUsup = aCurv->LastParameter();
1753 anAC.Load(aCurv, anUinf, anUsup);
1754 anExtr.Initialize(anAC, anUinf, anUsup);
1755 }
1756
1757 if(aNbPntsM1 == 1)
1758 {
1759 gp_Pnt aP1(Value(theRLine, 1)), aP2(Value(theRLine, 2));
1760
1761 if(aP1.SquareDistance(aP2) < aSQTol)
1762 {
1763 //RLine is degenerated
1764 return Standard_False;
1765 }
1766
1767 gp_Pnt aPMid;
1768 if(theRLine->IsArcOnS1())
1769 {
1770 const Handle(Adaptor2d_Curve2d)& anAC2d = theRLine->ArcOnS1();
1771 const Standard_Real aParF = anAC2d->FirstParameter(),
1772 aParL = anAC2d->LastParameter();
1773 gp_Pnt2d aP2d(anAC2d->Value(0.5*(aParF+aParL)));
1774 aPMid = Quad1.Value(aP2d.X(), aP2d.Y());
1775 }
1776 else
1777 {
1778 const Handle(Adaptor2d_Curve2d)& anAC2d = theRLine->ArcOnS2();
1779 const Standard_Real aParF = anAC2d->FirstParameter(),
1780 aParL = anAC2d->LastParameter();
1781 gp_Pnt2d aP2d(anAC2d->Value(0.5*(aParF+aParL)));
1782 aPMid = Quad2.Value(aP2d.X(), aP2d.Y());
1783 }
1784
1785 const Standard_Real aSQDist = SquareDistance(theGLine, aPMid, anExtr);
1786 return (aSQDist > aSQTol);
1787 }
1788
1789 for(Standard_Integer i = 2; i <= aNbPntsM1; i++)
1790 {
1791 const gp_Pnt aP(Value(theRLine, i));
1792 const Standard_Real aSQDist = SquareDistance(theGLine, aP, anExtr);
1793
1794 if(aSQDist > aSQTol)
1795 return Standard_True;
1796 }
1797
1798 return Standard_False;
1799 }
1800
1801
1802 void ProcessRLine (IntPatch_SequenceOfLine& slin,
1803 // const Handle(Adaptor3d_Surface)& Surf1,
1804 // const Handle(Adaptor3d_Surface)& Surf2,
1805 const IntSurf_Quadric& Quad1,
1806 const IntSurf_Quadric& Quad2,
1807 const Standard_Real _TolArc,
1808 const Standard_Boolean theIsReqToKeepRLine) {
1809
1810 // On cherche a placer sur les restrictions solutions les points "multiples"
1811 // des autres lignes d intersection
1812 // Pas forcemment le plus efficace : on rique de projeter plusieurs fois
1813 // le meme point sur la meme restriction...
1814
1815 Standard_Real TolArc=100.0*_TolArc;
1816 if(TolArc>0.1) TolArc=0.1;
1817
1818 Standard_Integer i,j,k;
1819 Standard_Integer Nblin,Nbvtx, Nbpt;
1820
1821 Standard_Boolean OnFirst = Standard_False,project = Standard_False,keeppoint = Standard_False;
1822
1823 Handle(Adaptor2d_Curve2d) arcref;
1824 Standard_Real paramproj,paramf,paraml;
1825
1826 TColgp_SequenceOfPnt seq_Pnt3d;
1827 TColStd_SequenceOfReal seq_Real;
1828
1829 gp_Pnt ptproj,toproj,valpt;
1830
1831 gp_Pnt2d p2d;
1832 gp_Vec2d d2d;
1833 gp_Vec d1u,d1v,tgrest,tgarc,norm;
1834 IntSurf_Transition TRest,TArc;
1835 #ifndef OCCT_DEBUG
1836 Standard_Real U =0.,V =0.;
1837 #else
1838 Standard_Real U,V;
1839 #endif
1840 IntPatch_Point Ptvtx,newptvtx;
1841
1842 IntPatch_IType typ1,typ2;
1843
1844
1845 Nblin = slin.Length();
1846 for (i=1; i<=Nblin; i++) {
1847 const Handle(IntPatch_Line)& slini = slin(i);
1848 typ1 = slini->ArcType();
1849
1850 Standard_Boolean HasToDeleteRLine = Standard_False;
1851 if (typ1 == IntPatch_Restriction) {
1852 seq_Pnt3d.Clear();
1853 seq_Real.Clear();
1854
1855 for (j=1; j<=Nblin; j++) {
1856 const Handle(IntPatch_Line)& slinj = slin(j);
1857 Nbpt = seq_Pnt3d.Length(); // important que ce soit ici
1858 typ2 = slinj->ArcType();
1859 if (typ2 != IntPatch_Restriction) {
1860 //-- arcref = Handle(IntPatch_RLine)::DownCast (slini)->Arc();
1861 //-- OnFirst = Handle(IntPatch_RLine)::DownCast (slini)->IsOnFirstSurface();
1862
1863 //-- DES CHOSES A FAIRE ICI
1864 if(Handle(IntPatch_RLine)::DownCast (slini)->IsArcOnS1()) {
1865 OnFirst=Standard_True;
1866 arcref= Handle(IntPatch_RLine)::DownCast (slini)->ArcOnS1();
1867 }
1868 else if(Handle(IntPatch_RLine)::DownCast (slini)->IsArcOnS2()) {
1869 arcref= Handle(IntPatch_RLine)::DownCast (slini)->ArcOnS2();
1870 OnFirst=Standard_False;
1871 }
1872 if (Handle(IntPatch_RLine)::DownCast (slini)->HasFirstPoint()) {
1873 paramf = Handle(IntPatch_RLine)::DownCast (slini)->FirstPoint().ParameterOnLine();
1874 }
1875 else {
1876 // cout << "Pas de param debut sur rst solution" << endl;
1877 paramf = RealFirst();
1878 }
1879 if (Handle(IntPatch_RLine)::DownCast (slini)->HasLastPoint()) {
1880 paraml = Handle(IntPatch_RLine)::DownCast (slini)->LastPoint().ParameterOnLine();
1881 }
1882 else {
1883 // cout << "Pas de param debut sur rst solution" << endl;
1884 paraml = RealLast();
1885 }
1886
1887 if (typ2 == IntPatch_Analytic) {
1888 Nbvtx = Handle(IntPatch_ALine)::DownCast (slinj)->NbVertex();
1889 }
1890 else {
1891 Nbvtx = Handle(IntPatch_GLine)::DownCast (slinj)->NbVertex();
1892 }
1893
1894
1895 Standard_Boolean EdgeDegenere=Standard_True;
1896 for(Standard_Integer edg=0;EdgeDegenere && edg<=10;edg++) {
1897 arcref->D1(paramf+(paraml-paramf)*edg*0.1,p2d,d2d);
1898 if (OnFirst) {
1899 Quad1.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
1900 }
1901 else {
1902 Quad2.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
1903 }
1904 if(d1u.Magnitude()>1e-7) {
1905 EdgeDegenere=Standard_False;
1906 }
1907 }
1908
1909 for (k=1; EdgeDegenere==Standard_False && k<=Nbvtx; k++) {
1910 if (typ2 == IntPatch_Analytic) {
1911 Ptvtx = Handle(IntPatch_ALine)::DownCast (slinj)->Vertex(k);
1912 }
1913 else {
1914 Ptvtx = Handle(IntPatch_GLine)::DownCast (slinj)->Vertex(k);
1915 }
1916 if ((OnFirst && !Ptvtx.IsOnDomS1()) ||
1917 (!OnFirst && !Ptvtx.IsOnDomS2())) {
1918 // Si OnFirst && OnDomS1, c est qu on est a une extremite
1919 // ca doit etre traite par Process Segment...
1920 project = Standard_True;
1921 keeppoint = Standard_False;
1922 toproj = Ptvtx.Value();
1923
1924 Standard_Integer jj;
1925 for (jj = 1; jj <= Nbpt; jj++) {
1926 //for (Standard_Integer jj = 1; jj <= Nbpt; jj++) {
1927 if (toproj.Distance(seq_Pnt3d(jj)) < _TolArc) {
1928 project = Standard_False;
1929 break;
1930 }
1931 }
1932 if (project) { //-- il faut projeter pour trouver le point sur la rline.
1933 if (OnFirst) {
1934 Ptvtx.ParametersOnS1(U,V);
1935 }
1936 else {
1937 Ptvtx.ParametersOnS2(U,V);
1938 }
1939
1940 project = IntPatch_HInterTool::Project(arcref,gp_Pnt2d(U,V),
1941 paramproj,p2d);
1942
1943 if (project) {
1944 if (OnFirst) {
1945 ptproj = Quad1.Value(p2d.X(),p2d.Y());
1946 }
1947 else {
1948 ptproj = Quad2.Value(p2d.X(),p2d.Y());
1949 }
1950 if ((toproj.Distance(ptproj) <=100*TolArc) &&
1951 (paramproj >= paramf) && (paramproj <= paraml)){
1952 newptvtx = Ptvtx;
1953 newptvtx.SetParameter(paramproj);
1954 keeppoint = Standard_True;
1955 seq_Pnt3d.Append(toproj);
1956 seq_Real.Append(paramproj);
1957
1958 //-- verifier que si la restriction arcref est trouvee, elle porte ce vertex
1959 for (int ri=1; ri<=Nblin; ri++) {
1960 const Handle(IntPatch_Line)& slinri = slin(ri);
1961 if (slinri->ArcType() == IntPatch_Restriction) {
1962 if(OnFirst && Handle(IntPatch_RLine)::DownCast (slinri)->IsArcOnS1()) {
1963 if(arcref == Handle(IntPatch_RLine)::DownCast (slinri)->ArcOnS1()) {
1964 Handle(IntPatch_RLine)::DownCast (slinri)->AddVertex(newptvtx);
1965 //printf("\n ImpImpIntersection_0.gxx CAS1 \n");
1966 }
1967 }
1968 else if(OnFirst==Standard_False && Handle(IntPatch_RLine)::DownCast (slinri)->IsArcOnS2()) {
1969 if(arcref == Handle(IntPatch_RLine)::DownCast (slinri)->ArcOnS2()) {
1970 Handle(IntPatch_RLine)::DownCast (slinri)->AddVertex(newptvtx);
1971 //printf("\n ImpImpIntersection_0.gxx CAS2 \n");
1972 }
1973 }
1974 }
1975 }
1976 // -- --------------------------------------------------
1977 }
1978 }
1979 }
1980 else {
1981 keeppoint = Standard_True;
1982 newptvtx = Ptvtx;
1983 newptvtx.SetParameter(seq_Real(jj));
1984 }
1985 if (keeppoint) {
1986 Ptvtx.SetMultiple(Standard_True);
1987 Ptvtx.SetTolerance(_TolArc);
1988 newptvtx.SetMultiple(Standard_True);
1989
1990 if (typ2 == IntPatch_Analytic) {
1991 Handle(IntPatch_ALine)::DownCast (slinj)->Replace(k,Ptvtx);
1992 }
1993 else {
1994 Handle(IntPatch_GLine)::DownCast (slinj)->Replace(k,Ptvtx);
1995 }
1996
1997 if (Ptvtx.IsOnDomS1() || Ptvtx.IsOnDomS2()) {
1998
1999 arcref->D1(newptvtx.ParameterOnLine(),p2d,d2d);
2000
2001 if (OnFirst) { // donc OnDomS2
2002 Quad1.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
2003 tgrest.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
2004
2005 const Handle(Adaptor2d_Curve2d)& thearc = Ptvtx.ArcOnS2();
2006 thearc->D1(Ptvtx.ParameterOnArc2(),p2d,d2d);
2007 Quad2.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
2008 tgarc.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
2009 norm = d1u.Crossed(d1v); //Quad2.Normale(valpt);
2010 if(norm.SquareMagnitude()<1e-16) {
2011 TRest.SetValue(Standard_True,IntSurf_Undecided);
2012 TArc.SetValue(Standard_True,IntSurf_Undecided);
2013 }
2014 else {
2015 IntSurf::MakeTransition(tgrest,tgarc,norm,TRest,TArc);
2016 }
2017 newptvtx.SetArc(Standard_False,thearc,
2018 Ptvtx.ParameterOnArc2(),TRest,TArc);
2019
2020 }
2021 else { // donc OnDomS1
2022 Quad2.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
2023 tgrest.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
2024
2025 const Handle(Adaptor2d_Curve2d)& thearc = Ptvtx.ArcOnS1();
2026 thearc->D1(Ptvtx.ParameterOnArc1(),p2d,d2d);
2027 Quad1.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
2028 tgarc.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
2029 norm = d1u.Crossed(d1v); //Quad1.Normale(valpt);
2030 if(norm.SquareMagnitude()<1e-16) {
2031 TRest.SetValue(Standard_True,IntSurf_Undecided);
2032 TArc.SetValue(Standard_True,IntSurf_Undecided);
2033 }
2034 else {
2035 IntSurf::MakeTransition(tgrest,tgarc,norm,TRest,TArc);
2036 }
2037 newptvtx.SetArc(Standard_True,thearc,
2038 Ptvtx.ParameterOnArc1(),TRest,TArc);
2039 }
2040 } //-- if (Ptvtx.IsOnDomS1() || Ptvtx.IsOnDomS2())
2041
2042 Handle(IntPatch_RLine)::DownCast (slini)->AddVertex(newptvtx);
2043
2044 } //-- if (keeppoint)
2045 } //-- if ((OnFirst && !Ptvtx.IsOnDomS1())||(!OnFirst && !Ptvtx.IsOnDomS2()))
2046 } //-- boucle sur les vertex
2047
2048 if(!theIsReqToKeepRLine)
2049 {
2050 Handle(IntPatch_GLine) aGL = Handle(IntPatch_GLine)::DownCast(slinj);
2051
2052 if(!aGL.IsNull())
2053 {
2054 HasToDeleteRLine = !IsRLineGood(Quad1, Quad2, aGL,
2055 Handle(IntPatch_RLine)::DownCast(slini), TolArc);
2056 }
2057
2058 if(HasToDeleteRLine)
2059 {
2060 break;
2061 }
2062 }
2063 } //-- if (typ2 != IntPatch_Restriction)
2064 } //-- for (j=1; j<=Nblin; j++)
2065 } //-- if (typ1 == IntPatch_Restriction)
2066
2067 if(HasToDeleteRLine)
2068 {
2069 slin.Remove(i);
2070 i--;
2071 Nblin = slin.Length();
2072 continue;
2073 }
2074 } //-- for (i=1; i<=Nblin; i++)
2075 }