1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
4 // This file is part of Open CASCADE Technology software library.
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
15 #include <gce_MakePln.hxx>
16 #include <Extrema_ExtPS.hxx>
17 #include <Extrema_ExtPC.hxx>
20 #include <DrawTrSurf.hxx>
24 static const Standard_Real CosRef3D = 0.88;
26 static void RecadreIfPeriodic(Standard_Real& NewU,
28 const Standard_Real OldU,
29 const Standard_Real OldV,
30 const Standard_Real UPeriod,
31 const Standard_Real VPeriod)
35 Standard_Real sign = (NewU < OldU)? 1 : -1;
36 while (Abs(NewU - OldU) > UPeriod/2)
37 NewU += sign * UPeriod;
41 Standard_Real sign = (NewV < OldV)? 1 : -1;
42 while (Abs(NewV - OldV) > VPeriod/2)
43 NewV += sign * VPeriod;
47 static void evalpinit(math_Vector& parinit,
48 const Blend_Point& previousP,
49 const Standard_Real parprec,
50 const Standard_Real param,
51 const math_Vector& infbound,
52 const math_Vector& supbound,
53 const Standard_Boolean classonS1,
54 const Standard_Boolean classonS2)
56 if(previousP.IsTangencyPoint()){
57 previousP.ParametersOnS1(parinit(1),parinit(2));
58 previousP.ParametersOnS2(parinit(3),parinit(4));
61 Standard_Real u1,v1,u2,v2;
62 Standard_Real du1,dv1,du2,dv2;
63 Standard_Boolean Inside=Standard_True;
64 previousP.ParametersOnS1(u1,v1);
65 previousP.ParametersOnS2(u2,v2);
66 previousP.Tangent2dOnS1().Coord(du1,dv1);
67 previousP.Tangent2dOnS2().Coord(du2,dv2);
68 Standard_Real step = param - parprec;
72 if ((u1<infbound(1)) || (u1>supbound(1))) Inside=Standard_False;
73 if ((v1<infbound(2)) || (v1>supbound(2))) Inside=Standard_False;
78 if ((u2<infbound(3)) || (u2>supbound(3))) Inside=Standard_False;
79 if ((v2<infbound(4)) || (v2>supbound(4))) Inside=Standard_False;
88 else { // on ne joue pas au plus malin
89 previousP.ParametersOnS1(parinit(1),parinit(2));
90 previousP.ParametersOnS2(parinit(3),parinit(4));
98 void Blend_Walking::InternalPerform(Blend_Function& Func,
99 Blend_FuncInv& FuncInv,
100 const Standard_Real Bound)
102 Standard_Real Cosi = 0., Cosi2 = 0.;
104 Standard_Real stepw = pasmax;
105 Standard_Integer nbp = line->NbPoints();
106 if(nbp >= 2){ //On reprend le dernier step s'il n est pas trop petit.
108 stepw = (line->Point(2).Parameter() - line->Point(1).Parameter());
111 stepw = (line->Point(nbp).Parameter() - line->Point(nbp - 1).Parameter());
113 stepw = Max(stepw,100.*tolgui);
115 Standard_Real parprec = param;
116 gp_Vec TgOnGuide, PrevTgOnGuide;
118 hguide->D1(parprec, PtOnGuide, TgOnGuide);
119 PrevTgOnGuide = TgOnGuide;
121 if (sens*(parprec - Bound) >= -tolgui) {
124 Blend_Status State = Blend_OnRst12;
125 TopAbs_State situ1 =TopAbs_IN,situ2=TopAbs_IN;
127 Standard_Integer Index1 = 0, Index2 = 0, nbarc;
128 Standard_Boolean Arrive,recad1,recad2, control;
129 Standard_Boolean Isvtx1 = Standard_False, Isvtx2 = Standard_False, echecrecad;
131 math_Vector tolerance(1,4),infbound(1,4),supbound(1,4),parinit(1,4);
132 math_Vector solrst1(1,4),solrst2(1,4);
134 TheExtremity Ext1,Ext2;
136 //IntSurf_Transition Tline,Tarc;
138 Func.GetTolerance(tolerance,tolesp);
139 Func.GetBounds(infbound,supbound);
141 math_FunctionSetRoot rsnld(Func,tolerance,30);
144 Arrive = Standard_False;
145 param = parprec + sens*stepw;
146 if(sens *(param - Bound) > 0.) {
147 stepw = sens*(Bound - parprec)*0.5;
148 param = parprec + sens*stepw;
151 evalpinit(parinit,previousP,parprec,param,
152 infbound,supbound, clasonS1, clasonS2);
161 hguide->D1(param, PtOnGuide, TgOnGuide);
162 //Check deflection on guide
163 Cosi = PrevTgOnGuide * TgOnGuide;
164 if (Cosi < gp::Resolution()) //angle>=pi/2 or null magnitude
167 Cosi2 = Cosi * Cosi / PrevTgOnGuide.SquareMagnitude() / TgOnGuide.SquareMagnitude();
168 if (Cosi2 < CosRef3D) //angle 3d too great
170 State = Blend_StepTooLarge;
172 param = parprec + sens*stepw; // on ne risque pas de depasser Bound.
173 if (Abs(stepw) < tolgui) {
174 Ext1.SetValue(previousP.PointOnS1(),
176 previousP.Parameter(),tolesp);
177 Ext2.SetValue(previousP.PointOnS2(),
179 previousP.Parameter(),tolesp);
180 if (!previousP.IsTangencyPoint()) {
181 Ext1.SetTangent(previousP.TangentOnS1());
182 Ext2.SetTangent(previousP.TangentOnS2());
184 Arrive = Standard_True;
188 PrevTgOnGuide = TgOnGuide;
189 //////////////////////////
191 Standard_Boolean bonpoint = 1;
193 rsnld.Perform(Func,parinit,infbound,supbound);
195 if (!rsnld.IsDone()) {
196 State = Blend_StepTooLarge;
202 if(clasonS1) situ1 = domain1->Classify(gp_Pnt2d(sol(1),sol(2)),
203 Min(tolerance(1),tolerance(2)),0);
204 else situ1 = TopAbs_IN;
205 if(clasonS2) situ2 = domain2->Classify(gp_Pnt2d(sol(3),sol(4)),
206 Min(tolerance(3),tolerance(4)),0);
207 else situ2 = TopAbs_IN;
209 if(bonpoint && line->NbPoints() == 1 && (situ1 != TopAbs_IN || situ2 != TopAbs_IN)){
210 State = Blend_StepTooLarge;
215 recad1 = Standard_False;
216 recad2 = Standard_False;
217 echecrecad = Standard_False;
218 control = Standard_False;
220 if (situ1 == TopAbs_OUT || situ1 == TopAbs_ON) {
221 // pb inverse sur surf1
222 //Si le recadrage s'effectue dans le sens de la progression a une tolerance pres,
223 //on a pris la mauvaise solution.
224 recad1 = Recadre(FuncInv,Standard_True,
225 sol,solrst1,Index1,Isvtx1,Vtx1);
230 if ((param - wtemp)/sens>= -10*tolesp){
232 control = Standard_True;
235 echecrecad = Standard_True;
236 recad1 = Standard_False;
237 State = Blend_StepTooLarge;
243 echecrecad = Standard_True;
246 if (situ2 == TopAbs_OUT || situ2 == TopAbs_ON) {
247 // pb inverse sur surf2
248 //Si le recadrage s'effectue dans le sens de la progression a une tolerance pres,
249 //on a pris la mauvaise solution.
250 recad2 = Recadre(FuncInv,Standard_False,
251 sol,solrst2,Index2,Isvtx2,Vtx2);
256 if ((param - wtemp)/sens>= -10*tolesp){
258 control = Standard_True;
261 echecrecad = Standard_True;
262 recad2 = Standard_False;
263 State = Blend_StepTooLarge;
269 echecrecad = Standard_True;
273 // Que faut il controler
274 if (recad1 && recad2) {
275 if (Abs(w1-w2) <= 10*tolgui) {
276 // pas besoin de controler les recadrage
277 // Le control pouvant se planter (cf model blend10)
278 // La tolerance est choisie grossse afin, de permetre au
279 // cheminement suivant, de poser quelques sections ...
280 control = Standard_False;
282 else if (sens*(w1-w2) < 0.) {
284 recad2 = Standard_False;
288 recad1 = Standard_False;
292 // Controle effectif des recadrage
295 if (recad1 && clasonS2) {
296 situ = recdomain2->Classify(gp_Pnt2d(solrst1(3),solrst1(4)),
297 Min(tolerance(3),tolerance(4)));
298 if (situ == TopAbs_OUT) {
299 recad1 = Standard_False;
300 echecrecad = Standard_True;
303 else if (recad2 && clasonS1) {
304 situ = recdomain1->Classify(gp_Pnt2d(solrst2(3),solrst2(4)),
305 Min(tolerance(1),tolerance(1)));
306 if (situ == TopAbs_OUT) {
307 recad2 = Standard_False;
308 echecrecad = Standard_True;
313 if(recad1 || recad2) echecrecad = Standard_False;
316 if (recad1 && recad2) {
317 //sol sur 1 et 2 a la fois
318 // On passe par les arcs , pour ne pas avoir de probleme
319 // avec les surfaces periodiques.
320 State = Blend_OnRst12;
323 p2d = TheArcTool::Value(recdomain1->Value(),solrst1(1));
326 Pnt1 = TheSurfaceTool::Value(surf1,sol(1),sol(2));
327 p2d = TheArcTool::Value(recdomain2->Value(),solrst2(1));
330 Pnt2 = TheSurfaceTool::Value(surf2,sol(3),sol(4));
331 const Standard_Real TolProd = 1.e-5;
332 Standard_Real SavedParams [2];
333 Standard_Boolean SameDirs [2] = {Standard_False, Standard_False};
334 ChFiDS_ElSpine& theElSpine = *hguide;
335 SavedParams[0] = theElSpine.GetSavedFirstParameter();
336 SavedParams[1] = theElSpine.GetSavedLastParameter();
337 for (Standard_Integer ind = 0; ind < 2; ind++)
339 if (!Precision::IsInfinite(SavedParams[ind]))
341 //Check the original first and last parameters of guide curve
342 //for equality to found parameter <param>:
343 //check equality of tangent to guide curve and
344 //normal to plane built on 3 points:
345 //point on guide curve and points on restrictions of adjacent
349 hguide->D1(SavedParams[ind], Pnt0, Dir0);
350 Standard_Real Length = Dir0.Magnitude();
351 if (Length <= gp::Resolution())
354 gce_MakePln PlaneBuilder(Pnt0, Pnt1, Pnt2);
355 if (!PlaneBuilder.IsDone())
357 gp_Pln thePlane = PlaneBuilder.Value();
358 gp_Dir DirPlane = thePlane.Axis().Direction();
359 gp_Vec theProd = Dir0 ^ DirPlane;
360 Standard_Real ProdMod = theProd.Magnitude();
361 if (ProdMod <= TolProd)
362 SameDirs[ind] = Standard_True;
365 Standard_Real theParam = Precision::Infinite();
366 //Choose the closest parameter
367 if (SameDirs[0] && SameDirs[1])
368 theParam = (Abs(param - SavedParams[0]) < Abs(param - SavedParams[1]))?
369 SavedParams[0] : SavedParams[1];
370 else if (SameDirs[0])
371 theParam = SavedParams[0];
372 else if (SameDirs[1])
373 theParam = SavedParams[1];
375 Standard_Real NewU, NewV, NewParam;
377 Standard_Boolean Corrected = CorrectExtremityOnOneRst(1, sol(3), sol(4), param, Pnt1,
378 NewU, NewV, NewPnt, NewParam);
381 if (Abs(param - NewParam) < Abs(param - theParam))
385 if (!Precision::IsInfinite(theParam))
390 State = Blend_OnRst1;
394 while (nbarc < Index1) {
398 p2d = TheArcTool::Value(recdomain1->Value(),solrst1(1));
403 gp_Pnt thePntOnRst = TheSurfaceTool::Value(surf1,sol(1),sol(2));
404 Standard_Real NewU, NewV, NewParam;
406 Standard_Boolean Corrected = CorrectExtremityOnOneRst(1, sol(3), sol(4), param, thePntOnRst,
407 NewU, NewV, NewPnt, NewParam);
417 State = Blend_OnRst2;
422 while (nbarc < Index2) {
426 p2d = TheArcTool::Value(recdomain2->Value(),solrst2(1));
431 gp_Pnt thePntOnRst = TheSurfaceTool::Value(surf2,sol(3),sol(4));
432 Standard_Real NewU, NewV, NewParam;
434 Standard_Boolean Corrected = CorrectExtremityOnOneRst(2, sol(1), sol(2), param, thePntOnRst,
435 NewU, NewV, NewPnt, NewParam);
447 Standard_Boolean testdefl = 1;
449 testdefl = !Blend_GetcontextNOTESTDEFL();
451 if (recad1 || recad2) {
453 // Il vaut mieux un pas non orthodoxe que pas de recadrage!! PMN
454 State = TestArret(Func, State,
455 (testdefl && (Abs(stepw) > 3*tolgui)),
456 Standard_False, Standard_True);
459 State = TestArret(Func, State, testdefl);
463 // Ou bien le pas max est mal regle. On divise.
464 // if(line->NbPoints() == 1) State = Blend_StepTooLarge;
465 if (stepw > 2*tolgui) State = Blend_StepTooLarge;
466 // Sinon echec recadrage. On sort avec PointsConfondus
469 std::cout << "Echec recadrage" << std::endl;
471 State = Blend_SamePoints;
477 if (Blend_GettraceDRAWSECT()){
478 Drawsect(surf1,surf2,sol,param,Func, State);
484 // Mettre a jour la ligne.
486 line->Append(previousP);
489 line->Prepend(previousP);
492 Standard_Integer nbpts = line->NbPoints();
494 sprintf(name, "pg%d", nbpts);
495 DrawTrSurf::Set(name, PtOnGuide);
496 sprintf(name, "p1_%d", nbpts);
497 DrawTrSurf::Set(name, previousP.PointOnS1());
498 sprintf(name, "p2_%d", nbpts);
499 DrawTrSurf::Set(name, previousP.PointOnS2());
504 if (param == Bound) {
505 Arrive = Standard_True;
506 Ext1.SetValue(previousP.PointOnS1(),
508 previousP.Parameter(), tolesp);
509 Ext2.SetValue(previousP.PointOnS2(),
511 previousP.Parameter(), tolesp);
512 if (!previousP.IsTangencyPoint()) {
513 Ext1.SetTangent(previousP.TangentOnS1());
514 Ext2.SetTangent(previousP.TangentOnS2());
517 // Indiquer que fin sur Bound.
520 param = param + sens*stepw;
521 if (sens*(param - Bound) > - tolgui) {
525 evalpinit(parinit,previousP,parprec,param,
526 infbound,supbound, clasonS1, clasonS2);
530 case Blend_StepTooLarge :
533 if (Abs(stepw) < tolgui) {
534 Ext1.SetValue(previousP.PointOnS1(),
536 previousP.Parameter(),tolesp);
537 Ext2.SetValue(previousP.PointOnS2(),
539 previousP.Parameter(),tolesp);
540 if (!previousP.IsTangencyPoint()) {
541 Ext1.SetTangent(previousP.TangentOnS1());
542 Ext2.SetTangent(previousP.TangentOnS2());
544 Arrive = Standard_True;
545 if (line->NbPoints()>=2) {
546 // Indiquer qu on s arrete en cours de cheminement
553 param = parprec + sens*stepw; // on ne risque pas de depasser Bound.
554 evalpinit(parinit,previousP,parprec,param,
555 infbound,supbound, clasonS1, clasonS2);
560 case Blend_StepTooSmall :
562 // Mettre a jour la ligne.
564 line->Append(previousP);
567 line->Prepend(previousP);
570 Standard_Integer nbpts = line->NbPoints();
572 sprintf(name, "pg%d", nbpts);
573 DrawTrSurf::Set(name, PtOnGuide);
574 sprintf(name, "p1_%d", nbpts);
575 DrawTrSurf::Set(name, previousP.PointOnS1());
576 sprintf(name, "p2_%d", nbpts);
577 DrawTrSurf::Set(name, previousP.PointOnS2());
582 stepw = Min(1.5*stepw,pasmax);
583 if (param == Bound) {
584 Arrive = Standard_True;
585 Ext1.SetValue(previousP.PointOnS1(),
587 previousP.Parameter(),tolesp);
588 Ext2.SetValue(previousP.PointOnS2(),
590 previousP.Parameter(),tolesp);
591 if (!previousP.IsTangencyPoint()) {
592 Ext1.SetTangent(previousP.TangentOnS1());
593 Ext2.SetTangent(previousP.TangentOnS2());
595 // Indiquer que fin sur Bound.
598 param = param + sens*stepw;
599 if (sens*(param - Bound) > - tolgui) {
603 evalpinit(parinit,previousP,parprec,param,
604 infbound,supbound, clasonS1, clasonS2);
611 line->Append(previousP);
614 line->Prepend(previousP);
617 Standard_Integer nbpts = line->NbPoints();
619 sprintf(name, "pg%d", nbpts);
620 DrawTrSurf::Set(name, PtOnGuide);
621 sprintf(name, "p1_%d", nbpts);
622 DrawTrSurf::Set(name, previousP.PointOnS1());
623 sprintf(name, "p2_%d", nbpts);
624 DrawTrSurf::Set(name, previousP.PointOnS2());
627 MakeExtremity(Ext1,Standard_True,Index1,
628 solrst1(1),Isvtx1,Vtx1);
629 // On blinde le cas singulier ou un des recadrage a planter
630 if (previousP.PointOnS1().IsEqual(previousP.PointOnS2(), 2*tolesp)) {
631 Ext2.SetValue(previousP.PointOnS1(),
632 sol(3),sol(4),tolesp);
633 if (Isvtx1) MakeSingularExtremity(Ext2, Standard_False, Vtx1);
636 Ext2.SetValue(previousP.PointOnS2(),
638 previousP.Parameter(),tolesp);
640 Arrive = Standard_True;
647 line->Append(previousP);
650 line->Prepend(previousP);
653 Standard_Integer nbpts = line->NbPoints();
655 sprintf(name, "pg%d", nbpts);
656 DrawTrSurf::Set(name, PtOnGuide);
657 sprintf(name, "p1_%d", nbpts);
658 DrawTrSurf::Set(name, previousP.PointOnS1());
659 sprintf(name, "p2_%d", nbpts);
660 DrawTrSurf::Set(name, previousP.PointOnS2());
663 // On blinde le cas singulier ou un des recadrage a plante
664 if (previousP.PointOnS1().IsEqual(previousP.PointOnS2(), 2*tolesp)) {
665 Ext1.SetValue(previousP.PointOnS2(),
666 sol(1),sol(2),tolesp);
667 if (Isvtx2) MakeSingularExtremity(Ext1, Standard_True, Vtx2);
670 Ext1.SetValue(previousP.PointOnS1(),
672 previousP.Parameter(),tolesp);
674 MakeExtremity(Ext2,Standard_False,Index2,
675 solrst2(1),Isvtx2,Vtx2);
676 Arrive = Standard_True;
684 line->Append(previousP);
687 line->Prepend(previousP);
690 Standard_Integer nbpts = line->NbPoints();
692 sprintf(name, "pg%d", nbpts);
693 DrawTrSurf::Set(name, PtOnGuide);
694 sprintf(name, "p1_%d", nbpts);
695 DrawTrSurf::Set(name, previousP.PointOnS1());
696 sprintf(name, "p2_%d", nbpts);
697 DrawTrSurf::Set(name, previousP.PointOnS2());
700 if ( (Isvtx1 != Isvtx2) &&
701 (previousP.PointOnS1().IsEqual(previousP.PointOnS2(), 2*tolesp)) ) {
702 // On blinde le cas singulier ou un seul recadrage
703 // est reconnu comme vertex.
705 Isvtx2 = Standard_True;
709 Isvtx1 = Standard_True;
714 MakeExtremity(Ext1,Standard_True,Index1,
715 solrst1(1),Isvtx1,Vtx1);
716 MakeExtremity(Ext2,Standard_False,Index2,
717 solrst2(1),Isvtx2,Vtx2);
718 Arrive = Standard_True;
722 case Blend_SamePoints :
726 std::cout << " Points confondus dans le cheminement" << std::endl;
728 Ext1.SetValue(previousP.PointOnS1(),
730 previousP.Parameter(),tolesp);
731 Ext2.SetValue(previousP.PointOnS2(),
733 previousP.Parameter(),tolesp);
734 if (!previousP.IsTangencyPoint()) {
735 Ext1.SetTangent(previousP.TangentOnS1());
736 Ext2.SetTangent(previousP.TangentOnS2());
738 Arrive = Standard_True;
746 line->SetEndPoints(Ext1,Ext2);
749 line->SetStartPoints(Ext1,Ext2);
758 Standard_Boolean Blend_Walking::CorrectExtremityOnOneRst(const Standard_Integer IndexOfRst,
759 const Standard_Real theU,
760 const Standard_Real theV,
761 const Standard_Real theParam,
762 const gp_Pnt& thePntOnRst,
766 Standard_Real& NewParam) const
768 const Standard_Real TolAng = 0.001; //bug OCC25701
770 ChFiDS_ElSpine& theElSpine = *hguide;
771 if (theElSpine.NbVertices() == 0)
772 return Standard_False;
774 Handle(TheTopolTool) DomainOfRst = (IndexOfRst == 1)? recdomain1 : recdomain2;
775 TheSurface SurfOfRst = (IndexOfRst == 1)? surf1 : surf2;
776 TheSurface AnotherSurf = (IndexOfRst == 1)? surf2 : surf1;
778 //Correct point on surface 2
779 //First we find right <param>
780 Standard_Real Ends [2];
781 Ends[0] = TheArcTool::FirstParameter(DomainOfRst->Value());
782 Ends[1] = TheArcTool::LastParameter(DomainOfRst->Value());
783 Standard_Real GlobalMinSqDist = Precision::Infinite();
784 Standard_Real ParamOnGuide = 0;
786 for (Standard_Integer k = 0; k < 2; k++)
788 gp_Pnt2d P2dOnEnd = TheArcTool::Value(DomainOfRst->Value(), Ends[k]);
789 gp_Pnt PntOnEnd = TheSurfaceTool::Value(SurfOfRst, P2dOnEnd.X(), P2dOnEnd.Y());
790 Extrema_ExtPC projoncurv(PntOnEnd, theElSpine);
791 if (!projoncurv.IsDone())
793 Standard_Real MinSqDist = Precision::Infinite();
794 Standard_Integer imin = 0;
795 for (Standard_Integer ind = 1; ind <= projoncurv.NbExt(); ind++)
797 Standard_Real aSqDist = projoncurv.SquareDistance(ind);
798 if (aSqDist < MinSqDist)
804 if (MinSqDist < GlobalMinSqDist)
806 GlobalMinSqDist = MinSqDist;
807 ParamOnGuide = projoncurv.Point(imin).Parameter();
808 PointOnGuide = projoncurv.Point(imin).Value();
811 NewParam = ParamOnGuide;
812 if (hguide->IsPeriodic())
814 Standard_Real Period = hguide->Period();
815 Standard_Real sign = (NewParam < theParam)? 1 : -1;
816 while (Abs(NewParam - theParam) > Period/2)
817 NewParam += sign *Period;
820 //Second we find right point and tangent on guide
821 GlobalMinSqDist = Precision::Infinite();
823 for (Standard_Integer ind = 1; ind <= theElSpine.NbVertices(); ind++)
825 const gp_Ax1& anAx1 = theElSpine.VertexWithTangent(ind);
826 gp_Pnt aPnt = anAx1.Location();
827 Standard_Real aSqDist = PointOnGuide.SquareDistance(aPnt);
828 if (aSqDist < GlobalMinSqDist)
830 GlobalMinSqDist = aSqDist;
834 const gp_Pnt& Pnt0 = theAx1.Location();
835 const gp_Dir& Dir0 = theAx1.Direction();
836 //Check new point: is it real solution?
837 gp_Pnt OldPonGuide = hguide->Value(theParam);
838 gp_Pnt PntOnSurf2 = TheSurfaceTool::Value(AnotherSurf,theU,theV); //old point
839 gce_MakePln PlaneBuilder(thePntOnRst, OldPonGuide, PntOnSurf2);
840 if (!PlaneBuilder.IsDone())
841 return Standard_False;
842 gp_Pln OldPlane = PlaneBuilder.Value();
843 gp_Dir OldDir = OldPlane.Axis().Direction();
844 Standard_Real Angle = OldDir.Angle(Dir0);
846 Angle = M_PI - Angle;
848 return Standard_False;
849 ///////////////////////////////////////
850 //Project the point(theU,theV) on the plane(Pnt0,Dir0)
851 gp_Vec aVec(Pnt0, PntOnSurf2);
852 gp_Vec aTranslation( (aVec.XYZ() * Dir0.XYZ()) * Dir0.XYZ() );
853 gp_Pnt PntOnPlane = PntOnSurf2.Translated(-aTranslation);
855 //Check new point again: does point on restriction belong to the plane?
856 PlaneBuilder = gce_MakePln(thePntOnRst, Pnt0, PntOnPlane);
857 if (!PlaneBuilder.IsDone())
858 return Standard_False;
859 gp_Pln NewPlane = PlaneBuilder.Value();
860 const gp_Dir& DirOfNewPlane = NewPlane.Axis().Direction();
861 Angle = Dir0.Angle(DirOfNewPlane);
863 Angle = M_PI - Angle;
865 return Standard_False;
866 ////////////////////////////////////////////////////////////////////////
868 //Project the point <PntOnPlane> on the surface 2
869 Extrema_ExtPS projonsurf(PntOnPlane, *AnotherSurf,
870 Precision::PConfusion(), Precision::PConfusion(),
871 Extrema_ExtFlag_MIN);
872 if (projonsurf.IsDone())
874 Standard_Real MinSqDist = Precision::Infinite();
875 Standard_Integer imin = 0;
876 for (Standard_Integer ind = 1; ind <= projonsurf.NbExt(); ind++)
878 Standard_Real aSqDist = projonsurf.SquareDistance(ind);
879 if (aSqDist < MinSqDist)
887 Extrema_POnSurf NewPOnSurf2 = projonsurf.Point(imin);
888 NewPoint = NewPOnSurf2.Value();
889 NewPOnSurf2.Parameter(NewU, NewV);
890 Standard_Real uperiod = (AnotherSurf->IsUPeriodic())? AnotherSurf->UPeriod() : 0.;
891 Standard_Real vperiod = (AnotherSurf->IsVPeriodic())? AnotherSurf->VPeriod() : 0.;
892 RecadreIfPeriodic(NewU, NewV, theU, theV,
894 return Standard_True;
898 return Standard_False;