1 // Created on: 1993-02-05
2 // Created by: Jacques GOUSSARD
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
18 #include <Adaptor3d_HSurface.hxx>
19 #include <Adaptor3d_HSurfaceTool.hxx>
20 #include <Adaptor3d_TopolTool.hxx>
21 #include <Bnd_Box.hxx>
22 #include <BndLib_AddSurface.hxx>
23 #include <Contap_ContAna.hxx>
24 #include <Contap_Contour.hxx>
25 #include <Contap_HContTool.hxx>
26 #include <Contap_HCurve2dTool.hxx>
27 #include <Contap_Line.hxx>
28 #include <Contap_SurfFunction.hxx>
29 #include <Contap_SurfProps.hxx>
30 #include <Contap_TheIWalking.hxx>
31 #include <Contap_ThePathPointOfTheSearch.hxx>
32 #include <Contap_TheSegmentOfTheSearch.hxx>
37 #include <IntSurf.hxx>
38 #include <IntSurf_InteriorPoint.hxx>
39 #include <IntSurf_SequenceOfPathPoint.hxx>
40 #include <math_FunctionSetRoot.hxx>
41 #include <Standard_ConstructionError.hxx>
42 #include <Standard_OutOfRange.hxx>
43 #include <StdFail_NotDone.hxx>
44 #include <TColStd_Array1OfInteger.hxx>
45 #include <TopTrans_CurveTransition.hxx>
47 static const Standard_Real Tolpetit = 1.e-10; // pour dist au carre
49 static const Standard_Real tole = 5.e-6;
51 Contap_Contour::Contap_Contour () :
52 done(Standard_False),modeset(Standard_False)
55 Contap_Contour::Contap_Contour (const gp_Vec& Direction) :
57 done(Standard_False),modeset(Standard_True)
59 mySFunc.Set(Direction);
60 myAFunc.Set(Direction);
64 Contap_Contour::Contap_Contour (const gp_Vec& Direction,
65 const Standard_Real Angle) :
67 done(Standard_False),modeset(Standard_True)
69 mySFunc.Set(Direction,Angle);
70 myAFunc.Set(Direction,Angle);
73 Contap_Contour::Contap_Contour (const gp_Pnt& Eye) :
75 done(Standard_False),modeset(Standard_True)
82 Contap_Contour::Contap_Contour (const Handle(Adaptor3d_HSurface)& Surf,
83 const Handle(Adaptor3d_TopolTool)& Domain,
84 const gp_Vec& Direction) :
86 done(Standard_False),modeset(Standard_True)
88 Perform(Surf,Domain,Direction);
92 Contap_Contour::Contap_Contour (const Handle(Adaptor3d_HSurface)& Surf,
93 const Handle(Adaptor3d_TopolTool)& Domain,
94 const gp_Vec& Direction,
95 const Standard_Real Angle) :
97 done(Standard_False),modeset(Standard_True)
99 Perform(Surf,Domain,Direction,Angle);
103 Contap_Contour::Contap_Contour (const Handle(Adaptor3d_HSurface)& Surf,
104 const Handle(Adaptor3d_TopolTool)& Domain,
107 done(Standard_False),modeset(Standard_True)
109 Perform(Surf,Domain,Eye);
113 void Contap_Contour::Init (const gp_Vec& Direction)
116 done = Standard_False;
117 modeset = Standard_True;
118 mySFunc.Set(Direction);
119 myAFunc.Set(Direction);
123 void Contap_Contour::Init(const gp_Vec& Direction,
124 const Standard_Real Angle)
126 done = Standard_False;
127 modeset = Standard_True;
128 mySFunc.Set(Direction,Angle);
129 myAFunc.Set(Direction,Angle);
132 void Contap_Contour::Init (const gp_Pnt& Eye)
134 done = Standard_False;
135 modeset = Standard_True;
141 void Contap_Contour::Perform (const Handle(Adaptor3d_HSurface)& Surf,
142 const Handle(Adaptor3d_TopolTool)& Domain)
144 if (!modeset) {throw Standard_ConstructionError();}
148 GeomAbs_SurfaceType typS = Adaptor3d_HSurfaceTool::GetType(Surf);
152 case GeomAbs_Cylinder:
155 PerformAna(Domain); //Surf,Domain,Direction,0.,gp_Pnt(0.,0.,0.),1);
161 Perform(Domain); //Surf,Domain,Direction,0.,gp_Pnt(0.,0.,0.),1);
169 void Contap_Contour::Perform (const Handle(Adaptor3d_HSurface)& Surf,
170 const Handle(Adaptor3d_TopolTool)& Domain,
171 const gp_Vec& Direction)
175 Perform(Surf,Domain);
178 void Contap_Contour::Perform (const Handle(Adaptor3d_HSurface)& Surf,
179 const Handle(Adaptor3d_TopolTool)& Domain,
180 const gp_Vec& Direction,
181 const Standard_Real Angle)
184 Init(Direction,Angle);
185 Perform(Surf,Domain);
189 void Contap_Contour::Perform (const Handle(Adaptor3d_HSurface)& Surf,
190 const Handle(Adaptor3d_TopolTool)& Domain,
195 Perform(Surf,Domain);
198 static IntSurf_TypeTrans ComputeTransitionOnLine
199 (Contap_SurfFunction&,
205 static IntSurf_TypeTrans ComputeTransitionOngpCircle
206 (Contap_SurfFunction&,
210 static IntSurf_TypeTrans ComputeTransitionOngpLine
211 (Contap_SurfFunction&,
215 static void ComputeInternalPoints
217 Contap_SurfFunction&,
218 const Standard_Real ureso,
219 const Standard_Real vreso);
222 static void ComputeInternalPointsOnRstr
226 Contap_SurfFunction&);
228 static void ProcessSegments (const Contap_TheSearch&,
229 Contap_TheSequenceOfLine&,
231 Contap_SurfFunction&,
232 const Handle(Adaptor3d_TopolTool)&);
234 //-- --------------------------------------------------------------------------------
235 //-- Recherche des portions utiles sur les lignes
238 static void Recadre(const Handle(Adaptor3d_HSurface)& myHS1,
241 Standard_Real f,l,lmf;
242 GeomAbs_SurfaceType typs1 = myHS1->GetType();
244 Standard_Boolean myHS1IsUPeriodic,myHS1IsVPeriodic;
246 case GeomAbs_Cylinder:
250 myHS1IsUPeriodic = Standard_True;
251 myHS1IsVPeriodic = Standard_False;
256 myHS1IsUPeriodic = myHS1IsVPeriodic = Standard_True;
261 myHS1IsUPeriodic = myHS1IsVPeriodic = Standard_False;
265 if(myHS1IsUPeriodic) {
266 lmf = M_PI+M_PI; //-- myHS1->UPeriod();
267 f = myHS1->FirstUParameter();
268 l = myHS1->LastUParameter();
269 while(u1 < f) { u1+=lmf; }
270 while(u1 > l) { u1-=lmf; }
272 if(myHS1IsVPeriodic) {
273 lmf = M_PI+M_PI; //-- myHS1->VPeriod();
274 f = myHS1->FirstVParameter();
275 l = myHS1->LastVParameter();
276 while(v1 < f) { v1+=lmf; }
277 while(v1 > l) { v1-=lmf; }
282 static void LineConstructor(Contap_TheSequenceOfLine& slin,
283 const Handle(Adaptor3d_TopolTool)& Domain,
285 const Handle(Adaptor3d_HSurface)& Surf) {
287 //-- ------------------------------------------------------------
288 //-- on decoupe la ligne en portions entre 2 vertex
289 Standard_Real Tol = Precision::PConfusion();
290 Contap_IType typl = L.TypeContour();
291 //-- cout<<"\n ----------- Ligne Constructor "<<endl;
292 if(typl == Contap_Walking) {
293 Standard_Real u1,v1,u2,v2;
294 Standard_Integer nbvtx = L.NbVertex();
295 //-- cout<<" WLine -> "<<nbvtx<<" vtx"<<endl;
296 for(Standard_Integer i=1;i<nbvtx;i++) {
297 Standard_Integer firstp = (Standard_Integer) L.Vertex(i).ParameterOnLine();
298 Standard_Integer lastp = (Standard_Integer) L.Vertex(i+1).ParameterOnLine();
300 Standard_Integer pmid = (firstp+lastp)/2; //-- entiers
301 const IntSurf_PntOn2S& Pmid = L.Point(pmid);
302 Pmid.Parameters(u1,v1,u2,v2);
304 TopAbs_State in2 = Domain->Classify(gp_Pnt2d(u2,v2),Tol);
305 if(in2 == TopAbs_OUT) {
308 //-- cout<<"ContapWLine : firtsp="<<firstp<<" lastp="<<lastp<<" Vtx:"<<i<<","<<i+1<<endl;
309 Handle(IntSurf_LineOn2S) LineOn2S = new IntSurf_LineOn2S();
310 LineOn2S->Add(L.Point(firstp));
311 for (Standard_Integer j = firstp + 1; j <= lastp; j++) {
312 Standard_Real aSqDist = L.Point(j).Value().
313 SquareDistance(L.Point(j - 1).Value());
314 if (aSqDist > gp::Resolution())
315 LineOn2S->Add(L.Point(j));
317 if (LineOn2S->NbPoints() < 2)
320 Line.SetLineOn2S(LineOn2S);
321 Contap_Point pvtx = L.Vertex(i);
322 pvtx.SetParameter(1);
325 pvtx = L.Vertex(i+1);
326 pvtx.SetParameter(LineOn2S->NbPoints());
328 Line.SetTransitionOnS(L.TransitionOnS());
334 else if(typl==Contap_Lin) {
335 Standard_Real u2,v2;// u1,v1;
336 Standard_Integer nbvtx = L.NbVertex();
337 //-- cout<<" Lin -> "<<nbvtx<<" vtx"<<endl;
338 for(Standard_Integer i=1;i<nbvtx;i++) {
339 Standard_Real firstp = L.Vertex(i).ParameterOnLine();
340 Standard_Real lastp = L.Vertex(i+1).ParameterOnLine();
342 Standard_Real pmid = (firstp+lastp)*0.5;
343 gp_Pnt Pmid = ElCLib::Value(pmid,L.Line());
344 if(Adaptor3d_HSurfaceTool::GetType(Surf)==GeomAbs_Cylinder) {
345 ElSLib::Parameters(Adaptor3d_HSurfaceTool::Cylinder(Surf),Pmid,u2,v2);
347 else if(Adaptor3d_HSurfaceTool::GetType(Surf)==GeomAbs_Cone) {
348 ElSLib::Parameters(Adaptor3d_HSurfaceTool::Cone(Surf),Pmid,u2,v2);
351 //-- cout<<" Pb ds Contap_ContourGen_2.gxx (type)"<<endl;
355 TopAbs_State in2 = Domain->Classify(gp_Pnt2d(u2,v2),Tol);
356 if(in2 == TopAbs_OUT) {
359 //-- cout<<"Contap Lin : firtsp="<<firstp<<" lastp="<<lastp<<" Vtx:"<<i<<","<<i+1<<endl;
361 Line.SetValue(L.Line());
362 Contap_Point pvtx = L.Vertex(i);
365 pvtx = L.Vertex(i+1);
367 Line.SetTransitionOnS(L.TransitionOnS());
373 else if(typl==Contap_Circle) {
374 Standard_Real u2,v2; //u1,v1,
375 Standard_Integer nbvtx = L.NbVertex();
376 //-- cout<<" Circ -> "<<nbvtx<<" vtx"<<endl;
377 Standard_Boolean novtx = Standard_True;
378 if(nbvtx) novtx=Standard_False;
379 for(Standard_Integer i=1;i<nbvtx || novtx;i++) {
380 Standard_Real firstp=0,lastp=M_PI+M_PI;
381 if(novtx == Standard_False) {
382 firstp = L.Vertex(i).ParameterOnLine();
383 lastp = L.Vertex(i+1).ParameterOnLine();
385 if(Abs(firstp-lastp)>0.000000001) {
386 Standard_Real pmid = (firstp+lastp)*0.5;
387 gp_Pnt Pmid = ElCLib::Value(pmid,L.Circle());
388 if(Adaptor3d_HSurfaceTool::GetType(Surf)==GeomAbs_Cylinder) {
389 ElSLib::Parameters(Adaptor3d_HSurfaceTool::Cylinder(Surf),Pmid,u2,v2);
391 else if(Adaptor3d_HSurfaceTool::GetType(Surf)==GeomAbs_Cone) {
392 ElSLib::Parameters(Adaptor3d_HSurfaceTool::Cone(Surf),Pmid,u2,v2);
394 else if(Adaptor3d_HSurfaceTool::GetType(Surf)==GeomAbs_Sphere) {
395 ElSLib::Parameters(Adaptor3d_HSurfaceTool::Sphere(Surf),Pmid,u2,v2);
398 //-- cout<<" Pb ds Contap_ContourGen_2.gxx (typep)"<<endl;
402 TopAbs_State in2 = Domain->Classify(gp_Pnt2d(u2,v2),Tol);
403 if(in2 == TopAbs_OUT) {
406 //-- cout<<"Contap Circle : firtsp="<<firstp<<" lastp="<<lastp<<" Vtx:"<<i<<","<<i+1<<endl;
408 Line.SetValue(L.Circle());
409 if(novtx == Standard_False) {
410 Contap_Point pvtx = L.Vertex(i);
412 pvtx = L.Vertex(i+1);
415 Line.SetTransitionOnS(L.TransitionOnS());
419 novtx = Standard_False;
422 Standard_Real firstp = L.Vertex(nbvtx).ParameterOnLine();
423 Standard_Real lastp = L.Vertex(1).ParameterOnLine() + M_PI+M_PI;
424 if(Abs(firstp-lastp)>0.0000000001) {
425 Standard_Real pmid = (firstp+lastp)*0.5;
426 gp_Pnt Pmid = ElCLib::Value(pmid,L.Circle());
427 if(Adaptor3d_HSurfaceTool::GetType(Surf)==GeomAbs_Cylinder) {
428 ElSLib::Parameters(Adaptor3d_HSurfaceTool::Cylinder(Surf),Pmid,u2,v2);
430 else if(Adaptor3d_HSurfaceTool::GetType(Surf)==GeomAbs_Cone) {
431 ElSLib::Parameters(Adaptor3d_HSurfaceTool::Cone(Surf),Pmid,u2,v2);
433 else if(Adaptor3d_HSurfaceTool::GetType(Surf)==GeomAbs_Sphere) {
434 ElSLib::Parameters(Adaptor3d_HSurfaceTool::Sphere(Surf),Pmid,u2,v2);
437 //-- cout<<" Pb ds Contap_ContourGen_2.gxx (typep)"<<endl;
441 TopAbs_State in2 = Domain->Classify(gp_Pnt2d(u2,v2),Tol);
442 if(in2 == TopAbs_OUT) {
445 //-- cout<<"Contap Circle *Compl* : firtsp="<<firstp<<" lastp="<<lastp<<" Vtx:"<<i<<","<<i+1<<endl;
447 Line.SetValue(L.Circle());
448 Contap_Point pvtx = L.Vertex(nbvtx);
451 pvtx = L.Vertex(1); pvtx.SetParameter(pvtx.ParameterOnLine()+M_PI+M_PI);
453 Line.SetTransitionOnS(L.TransitionOnS());
460 //-- cout<<" ni WLine ni Lin ni Circ "<<endl;
466 //-- --------------------------------------------------------------------------------
470 static void KeepInsidePoints(const Contap_TheSearchInside& solins,
471 const Contap_TheSearch& solrst,
472 Contap_SurfFunction& Func,
473 IntSurf_SequenceOfInteriorPoint& seqpins)
476 Standard_Integer Nba = solrst.NbSegments();
477 Standard_Integer Nbp,indp,inda;
478 Standard_Real U,V,paramproj;
479 gp_Pnt2d toproj,Ptproj;
480 Standard_Boolean projok,tokeep;
481 const Handle(Adaptor3d_HSurface)& Surf = Func.Surface();
483 Nbp = solins.NbPoints();
484 for (indp=1; indp <= Nbp; indp++) {
485 tokeep = Standard_True;
486 const IntSurf_InteriorPoint& pti = solins.Value(indp);
488 toproj = gp_Pnt2d(U,V);
489 for (inda = 1; inda <= Nba; inda++) {
490 const Handle(Adaptor2d_HCurve2d)& thearc = solrst.Segment(inda).Curve();
491 projok = Contap_HContTool::Project(thearc,toproj,paramproj,Ptproj);
493 gp_Pnt pprojete = Adaptor3d_HSurfaceTool::Value(Surf,Ptproj.X(),Ptproj.Y());
494 if (pti.Value().Distance(pprojete) <= Precision::Confusion()) {
495 tokeep = Standard_False;
507 static void ComputeTangency (const Contap_TheSearch& solrst,
508 const Handle(Adaptor3d_TopolTool)& Domain,
509 Contap_SurfFunction& Func,
510 IntSurf_SequenceOfPathPoint& seqpdep,
511 TColStd_Array1OfInteger& Destination)
514 Standard_Integer i,k;
515 Standard_Integer NbPoints = solrst.NbPoints();
516 Standard_Integer seqlength = 0;
518 Standard_Real theparam,test;
519 Standard_Boolean fairpt;
520 TopAbs_Orientation arcorien,vtxorien;
521 Standard_Boolean ispassing;
525 math_Matrix D(1, 1, 1, 2);
527 gp_Vec normale, vectg, tg3drst,v1,v2;
532 IntSurf_PathPoint PPoint;
533 const Handle(Adaptor3d_HSurface)& Surf = Func.Surface();
535 for (i=1; i<= NbPoints; i++) {
537 if (Destination(i) == 0) {
539 const Contap_ThePathPointOfTheSearch& PStart = solrst.Point(i);
540 const Handle(Adaptor2d_HCurve2d)& thearc = PStart.Arc();
541 theparam = PStart.Parameter();
542 gp_Pnt2d Ptoproj=Contap_HCurve2dTool::Value(thearc,theparam);
543 //-- lbr le 15 mai 97
544 //-- On elimine les points qui sont egalement present sur une restriction solution
545 Standard_Boolean SurUneRestrictionSolution = Standard_False;
546 for(Standard_Integer restriction=1;
547 SurUneRestrictionSolution==Standard_False && restriction<=solrst.NbSegments();
549 const Handle(Adaptor2d_HCurve2d)& thearcsol = solrst.Segment(restriction).Curve();
550 Standard_Real paramproj;
552 Standard_Boolean projok = Contap_HContTool::Project(thearcsol,Ptoproj,paramproj,pproj);
554 //gp_Pnt pprojete = Adaptor3d_HSurfaceTool::Value(Surf,Ptoproj.X(),Ptoproj.Y());
556 gp_Pnt pprojete = Adaptor3d_HSurfaceTool::Value(Surf,pproj.X(),pproj.Y());
558 if ((PStart.Value()).Distance(pprojete) <= Precision::Confusion()) {
559 SurUneRestrictionSolution = Standard_True;
563 if(SurUneRestrictionSolution == Standard_False) {
564 arcorien = Domain->Orientation(thearc);
565 ispassing = (arcorien == TopAbs_INTERNAL ||
566 arcorien == TopAbs_EXTERNAL);
568 Contap_HCurve2dTool::D1(thearc,theparam,pt2d,tg2drst);
571 PPoint.SetValue(PStart.Value(),X(1),X(2));
574 if (Func.IsTangent()) {
575 PPoint.SetTangency(Standard_True);
576 Destination(i) = seqlength+1;
577 if (!PStart.IsNew()) {
578 const Handle(Adaptor3d_HVertex)& vtx = PStart.Vertex();
579 for (k=i+1; k<=NbPoints; k++) {
580 if (Destination(k) ==0) {
581 const Contap_ThePathPointOfTheSearch& PStart2 = solrst.Point(k);
582 if (!PStart2.IsNew()) {
583 const Handle(Adaptor3d_HVertex)& vtx2 = PStart2.Vertex();
584 if (Domain->Identical(vtx,vtx2)) {
585 const Handle(Adaptor2d_HCurve2d)& thearc2 = PStart2.Arc();
586 theparam = PStart2.Parameter();
587 arcorien = Domain->Orientation(thearc2);
588 ispassing = ispassing && (arcorien == TopAbs_INTERNAL ||
589 arcorien == TopAbs_EXTERNAL);
591 pt2d = Contap_HCurve2dTool::Value(thearc2,theparam);
594 PPoint.AddUV(X(1),X(2));
595 Destination(k) = seqlength+1;
601 PPoint.SetPassing(ispassing);
602 seqpdep.Append(PPoint);
605 else { // on a un point de depart potentiel
607 vectg = Func.Direction3d();
608 dirtg = Func.Direction2d();
611 // Adaptor3d_HSurfaceTool::D1(Surf,X(1),X(2),ptbid,v1,v2);
612 Contap_SurfProps::DerivAndNorm(Surf,X(1),X(2),ptbid,v1,v2,normale);
613 tg3drst = tg2drst.X()*v1 + tg2drst.Y()*v2;
614 // normale = v1.Crossed(v2);
615 if(normale.SquareMagnitude() < RealEpsilon()) {
616 //-- cout<<"\n*** Contap_ContourGen_2.gxx Normale Nulle en U:"<<X(1)<<" V:"<<X(2)<<endl;
619 test = vectg.Dot(normale.Crossed(tg3drst));
621 if (PStart.IsNew()) {
622 Standard_Real tbis = vectg.Normalized().Dot(tg3drst.Normalized());
623 if (Abs(tbis) < 1.-tole) {
625 if ((test < 0. && arcorien == TopAbs_FORWARD) ||
626 (test > 0. && arcorien == TopAbs_REVERSED)) {
630 PPoint.SetDirections(vectg,dirtg);
632 else { // on garde le point comme point d`arret (tangent)
633 PPoint.SetTangency(Standard_True);
635 PPoint.SetPassing(ispassing);
636 Destination(i) = seqlength+1;
637 seqpdep.Append(PPoint);
640 else { // traiter la transition complexe
641 gp_Dir bidnorm(1.,1.,1.);
643 Standard_Boolean tobeverified = Standard_False;
644 TopAbs_Orientation LocTrans;
645 TopTrans_CurveTransition comptrans;
646 comptrans.Reset(vectg,bidnorm,0.);
647 if (arcorien != TopAbs_INTERNAL &&
648 arcorien != TopAbs_EXTERNAL) {
650 const Handle(Adaptor3d_HVertex)& vtx = PStart.Vertex();
651 vtxorien = Domain->Orientation(vtx);
652 test = test/(vectg.Magnitude());
653 test = test/((normale.Crossed(tg3drst)).Magnitude());
655 if (Abs(test) <= tole) {
656 tobeverified = Standard_True;
657 LocTrans = TopAbs_EXTERNAL; // et pourquoi pas INTERNAL
660 if ((test > 0. && arcorien == TopAbs_FORWARD) ||
661 (test < 0. && arcorien == TopAbs_REVERSED)){
662 LocTrans = TopAbs_FORWARD;
665 LocTrans = TopAbs_REVERSED;
667 if (arcorien == TopAbs_REVERSED) {tg3drst.Reverse();} // pas deja fait ???
670 comptrans.Compare(tole,tg3drst,bidnorm,0.,LocTrans,vtxorien);
672 Destination(i) = seqlength+1;
673 for (k= i+1; k<=NbPoints; k++) {
674 if (Destination(k) == 0) {
675 const Contap_ThePathPointOfTheSearch& PStart2 = solrst.Point(k);
676 if (!PStart2.IsNew()) {
677 const Handle(Adaptor3d_HVertex)& vtx2 = PStart2.Vertex();
678 if (Domain->Identical(PStart.Vertex(),vtx2)) {
679 const Handle(Adaptor2d_HCurve2d)& thearc2 = PStart2.Arc();
680 theparam = PStart2.Parameter();
681 arcorien = Domain->Orientation(thearc2);
683 Contap_HCurve2dTool::D1(thearc2,theparam,pt2d,tg2drst);
686 PPoint.AddUV(X(1),X(2));
688 if (arcorien != TopAbs_INTERNAL &&
689 arcorien != TopAbs_EXTERNAL) {
690 ispassing = Standard_False;
691 tg3drst = tg2drst.X()*v1 + tg2drst.Y()*v2;
692 test = vectg.Dot(normale.Crossed(tg3drst));
693 test = test/(vectg.Magnitude());
694 test = test /((normale.Crossed(tg3drst)).Magnitude());
696 vtxorien = Domain->Orientation(vtx2);
697 if (Abs(test) <= tole) {
698 tobeverified = Standard_True;
699 LocTrans = TopAbs_EXTERNAL; // et pourquoi pas INTERNAL
702 if ((test > 0. && arcorien == TopAbs_FORWARD) ||
703 (test < 0. && arcorien == TopAbs_REVERSED)){
704 LocTrans = TopAbs_FORWARD;
707 LocTrans = TopAbs_REVERSED;
709 if (arcorien == TopAbs_REVERSED) {tg3drst.Reverse();} //deja fait????
712 comptrans.Compare(tole,tg3drst,bidnorm,0.,LocTrans,vtxorien);
714 Destination(k) = seqlength+1;
719 fairpt = Standard_True;
721 TopAbs_State Before = comptrans.StateBefore();
722 TopAbs_State After = comptrans.StateAfter();
723 if ((Before == TopAbs_UNKNOWN)||(After == TopAbs_UNKNOWN)) {
724 fairpt = Standard_False;
726 else if (Before == TopAbs_IN) {
727 if (After == TopAbs_IN) {
728 ispassing = Standard_True;
736 if (After !=TopAbs_IN) {
737 fairpt = Standard_False;
742 // evite de partir le long d une restriction solution
744 if (fairpt && tobeverified) {
745 for (k=i; k <=NbPoints ; k++) {
746 if (Destination(k)==seqlength + 1) {
747 theparam = solrst.Point(k).Parameter();
748 const Handle(Adaptor2d_HCurve2d)& thearc2 = solrst.Point(k).Arc();
749 arcorien = Domain->Orientation(thearc2);
751 if (arcorien == TopAbs_FORWARD ||
752 arcorien == TopAbs_REVERSED) {
753 Contap_HCurve2dTool::D1(thearc2,theparam,pt2d,tg2drst);
754 tg3drst = tg2drst.X()*v1 + tg2drst.Y()*v2;
755 vtxorien = Domain->Orientation(solrst.Point(k).Vertex());
756 if ((arcorien == TopAbs_FORWARD &&
757 vtxorien == TopAbs_REVERSED) ||
758 (arcorien == TopAbs_REVERSED &&
759 vtxorien == TopAbs_FORWARD)) {
762 test = vectg.Normalized().Dot(tg3drst.Normalized());
763 if (test >= 1. - tole) {
764 fairpt = Standard_False;
773 PPoint.SetDirections(vectg,dirtg);
774 PPoint.SetPassing(ispassing);
775 seqpdep.Append(PPoint);
778 else { // il faut remettre en "ordre" si on ne garde pas le point.
779 for (k=i; k <=NbPoints ; k++) {
780 if (Destination(k)==seqlength + 1) {
781 Destination(k) = -Destination(k);
794 IntSurf_TypeTrans ComputeTransitionOnLine(Contap_SurfFunction& SFunc,
795 const Standard_Real u,
796 const Standard_Real v,
797 const gp_Vec& tgline)
803 Adaptor3d_HSurfaceTool::D1(SFunc.Surface(),u,v,pntbid,d1u,d1v);
805 //------------------------------------------------------
806 //-- Calcul de la tangente dans l espace uv ---
807 //------------------------------------------------------
809 Standard_Real det,d1uT,d1vT,normu2,normv2,d1ud1v,alpha,beta;
810 d1uT = d1u.Dot(tgline);
811 d1vT = d1v.Dot(tgline);
812 normu2 = d1u.Dot(d1u);
813 normv2 = d1v.Dot(d1v);
814 d1ud1v = d1u.Dot(d1v);
815 det = normu2 * normv2 - d1ud1v * d1ud1v;
816 if(det<RealEpsilon()) {
817 //-- On ne doit pas passer ici !!
818 //-- cout<<" Probleme !!!"<<endl ;
819 return IntSurf_Undecided;
822 alpha = (d1uT * normv2 - d1vT * d1ud1v)/det;
823 beta = (normu2 * d1vT - d1ud1v * d1uT)/det;
824 //-----------------------------------------------------
825 //-- Calcul du Gradient de la fonction Utilisee --
826 //-- pour le contour apparent --
827 //-----------------------------------------------------
831 math_Matrix Df(1,1,1,2);
834 SFunc.Derivatives(X,Df);
838 //-----------------------------------------------------
839 //-- On calcule si la fonction --
840 //-- F(.) = Normale . Dir_Regard --
841 //-- Croit Losrque l on se deplace sur la Gauche --
842 //-- de la direction de deplacement sur la ligne. --
843 //-----------------------------------------------------
845 det = -v1*beta + v2*alpha;
847 if(det<RealEpsilon()) { // revoir le test jag 940620
848 return IntSurf_Undecided;
857 void ProcessSegments (const Contap_TheSearch& solrst,
858 Contap_TheSequenceOfLine& slin,
859 const Standard_Real TolArc,
860 Contap_SurfFunction& SFunc,
861 const Handle(Adaptor3d_TopolTool)& Domain)
864 Standard_Integer i,j,k;
865 Standard_Integer nbedg = solrst.NbSegments();
866 Standard_Integer Nblines,Nbpts;
868 Handle(Adaptor2d_HCurve2d) arcRef;
871 Contap_ThePathPointOfTheSearch PStartf,PStartl;
873 Standard_Boolean dofirst,dolast,procf,procl;
874 Standard_Real paramf =0.,paraml =0.,U;
877 gp_Vec tgline;//,norm1,norm2;
885 for (i = 1; i <= nbedg; i++) {
887 const Contap_TheSegmentOfTheSearch& thesegsol = solrst.Segment(i);
888 theline.SetValue(thesegsol.Curve());
890 // Traitement des points debut/fin du segment solution.
892 dofirst = Standard_False;
893 dolast = Standard_False;
894 procf = Standard_False;
895 procl = Standard_False;
897 if (thesegsol.HasFirstPoint()) {
898 dofirst = Standard_True;
899 PStartf = thesegsol.FirstPoint();
900 paramf = PStartf.Parameter();
902 if (thesegsol.HasLastPoint()) {
903 dolast = Standard_True;
904 PStartl = thesegsol.LastPoint();
905 paraml = PStartl.Parameter();
908 // determination de la transition
909 if (dofirst && dolast) {
910 U = (paramf+paraml)/2.;
922 Contap_HCurve2dTool::D1(thesegsol.Curve(),U,p2d,d2d);
923 Adaptor3d_HSurfaceTool::D1(SFunc.Surface(),p2d.X(),p2d.Y(),valpt,d1u,d1v);
924 tgline.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
925 IntSurf_TypeTrans tral =
926 ComputeTransitionOnLine(SFunc,p2d.X(),p2d.Y(),tgline);
928 theline.SetTransitionOnS(tral);
931 if (dofirst || dolast) {
932 Nblines = slin.Length();
933 for (j=1; j<=Nblines; j++) {
934 Nbpts = slin(j).NbVertex();
935 for (k=1; k<=Nbpts;k++) {
936 ptvtx = slin(j).Vertex(k);
938 if (ptvtx.Value().Distance(PStartf.Value()) <=TolArc) {
939 slin(j).Vertex(k).SetMultiple();
941 ptvtx.SetParameter(paramf);
947 if (ptvtx.Value().Distance(PStartl.Value()) <=TolArc) {
948 slin(j).Vertex(k).SetMultiple();
950 ptvtx.SetParameter(paraml);
956 // Si on a traite le pt debut et/ou fin, on ne doit pas recommencer si
957 // il (ils) correspond(ent) a un point multiple.
960 dofirst = Standard_False;
963 dolast = Standard_False;
968 // Si on n a pas trouve le point debut et./ou fin sur une des lignes
969 // d intersection, il faut quand-meme le placer sur la restriction solution
973 p2d = Contap_HCurve2dTool::Value(thesegsol.Curve(),paramf);
974 ptvtx.SetValue(PStartf.Value(),p2d.X(),p2d.Y());
975 ptvtx.SetParameter(paramf);
976 if (! PStartf.IsNew()) {
977 ptvtx.SetVertex(PStartf.Vertex());
982 p2d = Contap_HCurve2dTool::Value(thesegsol.Curve(),paraml);
983 ptvtx.SetValue(PStartl.Value(),p2d.X(),p2d.Y());
984 ptvtx.SetParameter(paraml);
985 if (! PStartl.IsNew()) {
986 ptvtx.SetVertex(PStartl.Vertex());
991 // il faut chercher le points internal sur les restrictions solutions.
992 if (thesegsol.HasFirstPoint() && thesegsol.HasLastPoint()) {
993 ComputeInternalPointsOnRstr(theline,paramf,paraml,SFunc);
995 LineConstructor(slin,Domain,theline,SFunc.Surface()); //-- lbr
996 //-- slin.Append(theline);
1001 void ComputeInternalPointsOnRstr
1003 const Standard_Real Paramf,
1004 const Standard_Real Paraml,
1005 Contap_SurfFunction& SFunc)
1007 // On recherche les points ou la tangente a la ligne de contour et
1008 // la direction sont alignees.
1009 // 1ere etape : recherche de changement de signe.
1010 // 2eme etape : localisation de la solution par dichotomie
1013 Standard_Integer indexinf,indexsup,i;
1014 gp_Vec tgt, vecref, vectest, vtestb, vecregard,d1u,d1v;
1018 Standard_Boolean found,ok = Standard_False,toutvu,solution;
1019 Standard_Real paramp = 0.,paraminf,paramsup,toler;
1021 if (Line.TypeContour() != Contap_Restriction) {
1025 const Handle(Adaptor2d_HCurve2d)& thearc = Line.Arc();
1027 const Handle(Adaptor3d_HSurface)& Surf = SFunc.Surface();
1028 Contap_TFunction TypeFunc(SFunc.FunctionType());
1030 Standard_Integer Nbpnts = Contap_HContTool::NbSamplesOnArc(thearc);
1032 vecregard = SFunc.Direction();
1033 toler = Contap_HCurve2dTool::Resolution(thearc,Precision::Confusion());
1034 found = Standard_False;
1037 paraminf = ((Nbpnts-indexinf)*Paramf + (indexinf-1)*Paraml)/(Nbpnts-1);
1038 Contap_HCurve2dTool::D1(thearc,paraminf,p2d,d2d);
1039 Adaptor3d_HSurfaceTool::D1(Surf,p2d.X(),p2d.Y(),pcour,d1u,d1v);
1040 tgt.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
1042 if (tgt.Magnitude() > gp::Resolution()) {
1043 if (TypeFunc == Contap_ContourPrs || TypeFunc==Contap_DraftPrs) {
1044 vecregard.SetXYZ(pcour.XYZ()-SFunc.Eye().XYZ());
1046 vecref = vecregard.Crossed(tgt);
1048 if (vecref.Magnitude() <= gp::Resolution()) {
1052 found = Standard_True;
1058 } while ((indexinf <= Nbpnts) && (!found));
1061 indexsup = indexinf +1;
1062 toutvu = (indexsup > Nbpnts);
1064 paramsup = ((Nbpnts-indexsup)*Paramf + (indexsup-1)*Paraml)/(Nbpnts-1);
1065 Contap_HCurve2dTool::D1(thearc,paramsup,p2d,d2d);
1066 Adaptor3d_HSurfaceTool::D1(Surf,p2d.X(),p2d.Y(),pcour,d1u,d1v);
1067 tgt.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
1069 if (tgt.Magnitude() > gp::Resolution()) {
1070 if (TypeFunc == Contap_ContourPrs || TypeFunc==Contap_DraftPrs) {
1071 vecregard.SetXYZ(pcour.XYZ()-SFunc.Eye().XYZ());
1073 vectest = vecregard.Crossed(tgt);
1076 vectest = gp_Vec(0.,0.,0.);
1078 if (vectest.Magnitude() <= gp::Resolution()) {
1079 // On cherche un vrai changement de signe
1083 if (vectest.Dot(vecref) < 0.) {
1084 // Essayer de converger
1085 // cout << "Changement de signe detecte" << endl;
1086 solution = Standard_False;
1088 paramp = (paraminf+paramsup)/2.;
1089 Contap_HCurve2dTool::D1(thearc,paramp,p2d,d2d);
1090 Adaptor3d_HSurfaceTool::D1(Surf,p2d.X(),p2d.Y(),pcour,d1u,d1v);
1091 tgt.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
1093 if (tgt.Magnitude() > gp::Resolution()) {
1094 if (TypeFunc == Contap_ContourPrs || TypeFunc==Contap_DraftPrs) {
1095 vecregard.SetXYZ(pcour.XYZ()-SFunc.Eye().XYZ());
1097 vtestb = vecregard.Crossed(tgt);
1100 vtestb = gp_Vec(0.,0.,0.);
1103 if ((vtestb.Magnitude() <= gp::Resolution())||
1104 (Abs(paramp-paraminf) <= toler) ||
1105 (Abs(paramp-paramsup) <= toler)) {
1106 // on est a la solution
1107 solution = Standard_True;
1110 else if (vtestb.Dot(vecref) < 0.) {
1120 // On verifie que le point trouve ne correspond pas a un ou des
1121 // vertex deja existant(s). On teste sur le parametre paramp.
1122 for (i=1; i<=Line.NbVertex(); i++) {
1123 Contap_Point& thevtx = Line.Vertex(i);
1124 if (Abs(thevtx.ParameterOnLine()-paramp) <= toler) {
1125 thevtx.SetInternal();
1126 ok = Standard_False; // on a correspondance
1129 if (ok) { // il faut alors rajouter le point
1130 Contap_Point internalp(pcour,p2d.X(),p2d.Y());
1131 internalp.SetParameter(paramp);
1132 internalp.SetInternal();
1133 Line.Add(internalp);
1136 paramsup = ((Nbpnts-indexsup)*Paramf + (indexsup-1)*Paraml)/(Nbpnts-1);
1139 indexinf = indexsup;
1141 paraminf = paramsup;
1143 toutvu = (indexsup > Nbpnts);
1148 void ComputeInternalPoints
1150 Contap_SurfFunction& SFunc,
1151 const Standard_Real ureso,
1152 const Standard_Real vreso)
1155 // On recherche les points ou la tangente a la ligne de contour et
1156 // la direction sont alignees.
1157 // 1ere etape : recheche de changement de signe.
1158 // 2eme etape : localisation de la solution par simili dichotomie
1161 Standard_Integer indexinf,indexsup,index;
1162 gp_Vec tgt, vecref, vectest, vtestb, vecregard;
1163 //gp_Pnt pprec,pcour;
1164 Standard_Boolean found,ok = Standard_False,toutvu,solution;
1165 Standard_Real paramp = 0.,U,V;
1167 math_Vector XInf(1,2),XSup(1,2),X(1,2),F(1,1);
1168 math_Matrix DF(1,1,1,2);
1169 math_Vector toler(1,2),infb(1,2),supb(1,2);
1171 if (Line.TypeContour() != Contap_Walking) {
1175 Standard_Integer Nbpnts = Line.NbPnts();
1176 const Handle(Adaptor3d_HSurface)& Surf = SFunc.Surface();
1177 Contap_TFunction TypeFunc(SFunc.FunctionType());
1179 toler(1) = ureso; //-- Trop long !!! Adaptor3d_HSurfaceTool::UResolution(Surf,SFunc.Tolerance());
1180 toler(2) = vreso; //---Beaucoup trop long !!! Adaptor3d_HSurfaceTool::VResolution(Surf,SFunc.Tolerance());
1181 infb(1) = Adaptor3d_HSurfaceTool::FirstUParameter(Surf);
1182 infb(2) = Adaptor3d_HSurfaceTool::FirstVParameter(Surf);
1183 supb(1) = Adaptor3d_HSurfaceTool::LastUParameter(Surf);
1184 supb(2) = Adaptor3d_HSurfaceTool::LastVParameter(Surf);
1186 math_FunctionSetRoot rsnld(SFunc,toler,30);
1189 vecregard = SFunc.Direction();
1191 found = Standard_False;
1193 Line.Point(indexinf).ParametersOnS2(XInf(1),XInf(2));
1194 SFunc.Values(XInf,F,DF);
1195 if (!SFunc.IsTangent()) {
1196 tgt = SFunc.Direction3d();
1197 if (TypeFunc == Contap_ContourPrs || TypeFunc == Contap_DraftPrs) {
1198 vecregard.SetXYZ(Line.Point(indexinf).Value().XYZ()-SFunc.Eye().XYZ());
1200 vecref = vecregard.Crossed(tgt);
1202 if (vecref.Magnitude() <= gp::Resolution()) {
1206 found = Standard_True;
1212 } while ((indexinf <= Nbpnts) && (!found));
1215 indexsup = indexinf +1;
1216 toutvu = (indexsup > Nbpnts);
1218 Line.Point(indexsup).ParametersOnS2(XSup(1),XSup(2));
1219 SFunc.Values(XSup,F,DF);
1220 if (!SFunc.IsTangent()) {
1221 tgt = SFunc.Direction3d();
1223 if (TypeFunc == Contap_ContourPrs || TypeFunc == Contap_DraftPrs) {
1224 vecregard.SetXYZ(Line.Point(indexsup).Value().XYZ()-SFunc.Eye().XYZ());
1226 vectest = vecregard.Crossed(tgt);
1229 vectest = gp_Vec(0.,0.,0.);
1231 if (vectest.Magnitude() <= gp::Resolution()) {
1232 // On cherche un vrai changement de signe
1236 if (vectest.Dot(vecref) < 0.) {
1237 // Essayer de converger
1238 // cout << "Changement de signe detecte" << endl;
1239 solution = Standard_False;
1241 X(1) = (XInf(1) + XSup(1)) /2.;
1242 X(2) = (XInf(2) + XSup(2)) /2.;
1243 rsnld.Perform(SFunc,X,infb,supb);
1245 if (!rsnld.IsDone()) {
1246 cout << "Echec recherche internal points" << endl;
1247 solution = Standard_True;
1248 ok = Standard_False;
1253 SFunc.Values(X,F,DF);
1254 if (Abs(F(1)) <= SFunc.Tolerance()) {
1256 if (!SFunc.IsTangent()) {
1257 tgt = SFunc.Direction3d();
1258 if (TypeFunc == Contap_ContourPrs ||
1259 TypeFunc == Contap_DraftPrs) {
1260 vecregard.SetXYZ(SFunc.Point().XYZ()-SFunc.Eye().XYZ());
1262 vtestb = vecregard.Crossed(tgt);
1265 vtestb = gp_Vec(0.,0.,0.);
1267 if ((vtestb.Magnitude() <= gp::Resolution())||
1268 (Abs(X(1)-XInf(1)) <= toler(1)
1269 && Abs(X(2)-XInf(2)) <= toler(2)) ||
1270 (Abs(X(1)-XSup(1)) <= toler(1)
1271 && Abs(X(2)-XSup(2)) <= toler(2))) {
1272 // on est a la solution
1273 solution = Standard_True;
1276 else if (vtestb.Dot(vecref) < 0.) {
1283 else { // on n est pas sur une solution
1284 cout << "Echec recherche internal points" << endl;
1285 solution = Standard_True;
1286 ok = Standard_False;
1292 Standard_Boolean newpoint = Standard_False;
1293 Line.Point(indexinf).ParametersOnS2(U,V);
1294 gp_Vec2d vinf(X(1)-U,X(2)-V);
1295 if (Abs(vinf.X()) <= toler(1) && Abs(vinf.Y()) <= toler(2)) {
1299 for (index = indexinf+1; index <= indexsup; index++) {
1300 Line.Point(index).ParametersOnS2(U,V);
1301 gp_Vec2d vsup(X(1)-U,X(2)-V);
1302 if (Abs(vsup.X()) <= toler(1) && Abs(vsup.Y()) <= toler(2)) {
1306 else if (vinf.Dot(vsup) < 0.) {
1307 // on est entre les 2 points
1309 IntSurf_PntOn2S pt2s;
1310 pt2s.SetValue(SFunc.Point(),Standard_False,X(1),X(2));
1311 Line.LineOn2S()->InsertBefore(index,pt2s);
1313 //-- Il faut decaler les parametres des vertex situes entre
1314 //-- index et NbPnts ###################################
1315 for(Standard_Integer v=1; v<=Line.NbVertex(); v++) {
1316 Contap_Point& Vertex = Line.Vertex(v);
1317 if(Vertex.ParameterOnLine() >= index) {
1318 Vertex.SetParameter(Vertex.ParameterOnLine()+1);
1323 indexsup = indexsup+1;
1324 newpoint = Standard_True;
1335 // on est sur un point de cheminement. On regarde alors
1336 // la correspondance avec un vertex existant.
1337 newpoint = Standard_True;
1338 for (v=1; v<= Line.NbVertex(); v++) {
1339 Contap_Point& Vertex = Line.Vertex(v);
1340 if(Vertex.ParameterOnLine() == paramp) {
1341 Vertex.SetInternal();
1342 newpoint = Standard_False;
1347 if (newpoint && paramp >1. && paramp < Nbpnts) {
1348 // on doit creer un nouveau vertex.
1349 Contap_Point internalp(SFunc.Point(),X(1),X(2));
1350 internalp.SetParameter(paramp);
1351 internalp.SetInternal();
1352 Line.Add(internalp);
1355 Line.Point(indexsup).ParametersOnS2(XSup(1),XSup(2));
1358 indexinf = indexsup;
1362 toutvu = (indexsup > Nbpnts);
1367 void Contap_Contour::Perform
1368 (const Handle(Adaptor3d_TopolTool)& Domain) {
1370 done = Standard_False;
1373 Standard_Integer i,j,k,Nbvt1,Nbvt2,ivt1,ivt2;
1374 Standard_Integer NbPointRst,NbPointIns;
1375 Standard_Integer Nblines, Nbpts, indfirst, indlast;
1380 gp_Vec d1u,d1v,normale,tgtrst,tgline;
1381 Standard_Real currentparam;
1382 IntSurf_Transition TLine,TArc;
1384 Contap_Line theline;
1385 Contap_Point ptdeb,ptfin;
1386 Contap_ThePathPointOfTheSearch PStartf,PStartl;
1388 // Standard_Real TolArc = 1.e-5;
1389 Standard_Real TolArc = Precision::Confusion();
1391 const Handle(Adaptor3d_HSurface)& Surf = mySFunc.Surface();
1393 Standard_Real EpsU = Adaptor3d_HSurfaceTool::UResolution(Surf,Precision::Confusion());
1394 Standard_Real EpsV = Adaptor3d_HSurfaceTool::VResolution(Surf,Precision::Confusion());
1395 Standard_Real Preci = Min(EpsU,EpsV);
1396 // Standard_Real Fleche = 5.e-1;
1397 // Standard_Real Pas = 5.e-2;
1398 Standard_Real Fleche = 0.01;
1399 Standard_Real Pas = 0.005;
1400 // lbr: Il y avait Pas 0.2 -> Manque des Inters sur restr ; devrait faire un mini de 5 pts par lignes
1401 //-- le 23 janvier 98 0.05 -> 0.01
1404 //-- ******************************************************************************** Janvier 98
1405 Bnd_Box B1; Standard_Boolean Box1OK = Standard_True;
1407 Standard_Real Uinf = Surf->FirstUParameter();
1408 Standard_Real Vinf = Surf->FirstVParameter();
1409 Standard_Real Usup = Surf->LastUParameter();
1410 Standard_Real Vsup = Surf->LastVParameter();
1412 Standard_Boolean Uinfinfinite = Precision::IsNegativeInfinite(Uinf);
1413 Standard_Boolean Usupinfinite = Precision::IsPositiveInfinite(Usup);
1414 Standard_Boolean Vinfinfinite = Precision::IsNegativeInfinite(Vinf);
1415 Standard_Boolean Vsupinfinite = Precision::IsPositiveInfinite(Vsup);
1417 if( Uinfinfinite || Usupinfinite || Vinfinfinite || Vsupinfinite) {
1418 Box1OK = Standard_False;
1421 BndLib_AddSurface::Add(Surf->Surface(),1e-8,B1);
1423 Standard_Real x0,y0,z0,x1,y1,z1,dx,dy,dz;
1425 B1.Get(x0,y0,z0,x1,y1,z1);
1435 if(dx>10000.0) dx=10000.0;
1438 //-- ********************************************************************************
1443 //jag 940616 SFunc.Set(1.e-8); // tolerance sur la fonction
1444 mySFunc.Set(Precision::Confusion()); // tolerance sur la fonction
1446 Standard_Boolean RecheckOnRegularity = Standard_True;
1447 solrst.Perform(myAFunc,Domain,TolArc,TolArc,RecheckOnRegularity);
1449 if (!solrst.IsDone()) {
1453 NbPointRst = solrst.NbPoints();
1454 IntSurf_SequenceOfPathPoint seqpdep;
1455 TColStd_Array1OfInteger Destination(1,NbPointRst+1);
1456 Destination.Init(0);
1457 if (NbPointRst != 0) {
1458 ComputeTangency(solrst,Domain,mySFunc,seqpdep,Destination);
1461 //jag 940616 solins.Perform(SFunc,Surf,Domain,1.e-6); // 1.e-6 : tolerance dans l espace.
1462 solins.Perform(mySFunc,Surf,Domain,Precision::Confusion());
1464 NbPointIns = solins.NbPoints();
1465 IntSurf_SequenceOfInteriorPoint seqpins;
1467 if (NbPointIns != 0) {
1468 Standard_Boolean bKeepAllPoints = Standard_False;
1470 if(solrst.NbSegments() <= 0) {
1471 if(mySFunc.FunctionType() == Contap_ContourStd) {
1472 const Handle(Adaptor3d_HSurface)& SurfToCheck = mySFunc.Surface();
1473 if(Adaptor3d_HSurfaceTool::GetType(SurfToCheck) == GeomAbs_Torus) {
1474 gp_Torus aTor = Adaptor3d_HSurfaceTool::Torus(SurfToCheck);
1475 gp_Dir aTorDir = aTor.Axis().Direction();
1476 gp_Dir aProjDir = mySFunc.Direction();
1478 if(aTorDir.Dot(aProjDir) < Precision::Confusion()) {
1479 bKeepAllPoints = Standard_True;
1485 if(bKeepAllPoints) {
1486 Standard_Integer Nbp = solins.NbPoints(), indp;
1487 for (indp=1; indp <= Nbp; indp++) {
1488 const IntSurf_InteriorPoint& pti = solins.Value(indp);
1489 seqpins.Append(pti);
1494 KeepInsidePoints(solins,solrst,mySFunc,seqpins);
1498 if (seqpdep.Length() != 0 || seqpins.Length() != 0) {
1500 Standard_Boolean theToFillHoles = Standard_True;
1501 Contap_TheIWalking iwalk(Preci,Fleche,Pas,theToFillHoles);
1502 iwalk.Perform(seqpdep,seqpins,mySFunc ,Surf);
1503 if(!iwalk.IsDone()) {
1507 Nblines = iwalk.NbLines();
1508 for (j=1; j<=Nblines; j++) {
1509 IntSurf_TypeTrans TypeTransOnS = IntSurf_Undecided;
1510 const Handle(Contap_TheIWLineOfTheIWalking)& iwline = iwalk.Value(j);
1511 Nbpts = iwline->NbPoints();
1512 theline.SetLineOn2S(iwline->Line());
1514 // jag 941018 On calcule une seule fois la transition
1516 tgline = iwline->TangentVector(k);
1517 iwline->Line()->Value(k).ParametersOnS2(U,V);
1518 TypeTransOnS = ComputeTransitionOnLine(mySFunc,U,V,tgline);
1519 theline.SetTransitionOnS(TypeTransOnS);
1521 //---------------------------------------------------------------------
1522 //-- On ajoute a la liste des vertex les 1er et dernier points de la -
1523 //-- ligne de cheminement si ceux-ci ne sont pas presents -
1524 //---------------------------------------------------------------------
1526 if (iwline->HasFirstPoint()) {
1527 indfirst = iwline->FirstPointIndex();
1528 const IntSurf_PathPoint& PPoint = seqpdep(indfirst);
1529 Standard_Integer themult = PPoint.Multiplicity();
1530 for (i=NbPointRst; i>=1; i--) {
1531 if (Destination(i) == indfirst) {
1532 PPoint.Parameters(themult,U,V);
1533 ptdeb.SetValue(PPoint.Value(),U,V);
1534 ptdeb.SetParameter(1.0);
1536 const Contap_ThePathPointOfTheSearch& PStart = solrst.Point(i);
1537 const Handle(Adaptor2d_HCurve2d)& currentarc = PStart.Arc();
1538 currentparam = PStart.Parameter();
1539 if (!iwline->IsTangentAtBegining()) {
1541 Contap_HCurve2dTool::D1(currentarc,currentparam,pt2d,d2d);
1542 Contap_SurfProps::DerivAndNorm(Surf,pt2d.X(),pt2d.Y(),
1543 ptonsurf,d1u,d1v,normale);
1544 tgtrst = d2d.X()*d1u;
1545 tgtrst.Add(d2d.Y()*d1v);
1547 IntSurf::MakeTransition(PPoint.Direction3d(),tgtrst,normale,
1551 else {// a voir. En effet, on a cheminer. Si on est sur un point
1552 // debut, on sait qu'on rentre dans la matiere
1557 ptdeb.SetArc(currentarc,currentparam,TLine,TArc);
1559 if (!solrst.Point(i).IsNew()) {
1560 ptdeb.SetVertex(PStart.Vertex());
1568 iwline->Value(1).ParametersOnS2(U,V);
1569 ptdeb.SetValue(theline.Point(1).Value(),U,V);
1570 ptdeb.SetParameter(1.0);
1574 if (iwline->HasLastPoint()) {
1575 indlast = iwline->LastPointIndex();
1576 const IntSurf_PathPoint& PPoint = seqpdep(indlast);
1577 Standard_Integer themult = PPoint.Multiplicity();
1578 for (i=NbPointRst; i>=1; i--) {
1579 if (Destination(i) == indlast) {
1580 PPoint.Parameters(themult,U,V);
1581 ptfin.SetValue(PPoint.Value(),U,V);
1582 ptfin.SetParameter((Standard_Real)(Nbpts));
1583 const Contap_ThePathPointOfTheSearch& PStart = solrst.Point(i);
1584 const Handle(Adaptor2d_HCurve2d)& currentarc = PStart.Arc();
1585 currentparam = PStart.Parameter();
1587 if (!iwline->IsTangentAtEnd()) {
1589 Contap_HCurve2dTool::D1(currentarc,currentparam,pt2d,d2d);
1591 Contap_SurfProps::DerivAndNorm(Surf,pt2d.X(),pt2d.Y(),
1592 ptonsurf,d1u,d1v,normale);
1593 tgtrst = d2d.X()*d1u;
1594 tgtrst.Add(d2d.Y()*d1v);
1595 IntSurf::MakeTransition(PPoint.Direction3d().Reversed(),
1596 tgtrst,normale,TLine,TArc);
1603 ptfin.SetArc(currentarc,currentparam,TLine,TArc);
1605 if (!solrst.Point(i).IsNew()) {
1606 ptfin.SetVertex(PStart.Vertex());
1614 iwline->Value(Nbpts).ParametersOnS2(U,V);
1615 ptfin.SetValue(theline.Point(Nbpts).Value(),U,V);
1616 ptfin.SetParameter((Standard_Real)(Nbpts));
1620 ComputeInternalPoints(theline,mySFunc,EpsU,EpsV);
1621 LineConstructor(slin,Domain,theline,Surf); //-- lbr
1622 //-- slin.Append(theline);
1623 theline.ResetSeqOfVertex();
1627 Nblines = slin.Length();
1628 for (j=1; j<=Nblines-1; j++) {
1629 const Contap_Line& theli = slin(j);
1630 Nbvt1 = theli.NbVertex();
1631 for (ivt1=1; ivt1<=Nbvt1; ivt1++) {
1632 if (!theli.Vertex(ivt1).IsOnArc()) {
1633 const gp_Pnt& pttg1 = theli.Vertex(ivt1).Value();
1635 for (k=j+1; k<=Nblines;k++) {
1636 const Contap_Line& theli2 = slin(k);
1637 Nbvt2 = theli2.NbVertex();
1638 for (ivt2=1; ivt2<=Nbvt2; ivt2++) {
1639 if (!theli2.Vertex(ivt2).IsOnArc()) {
1640 const gp_Pnt& pttg2 = theli2.Vertex(ivt2).Value();
1642 if (pttg1.Distance(pttg2) <= TolArc) {
1643 theli.Vertex(ivt1).SetMultiple();
1644 theli2.Vertex(ivt2).SetMultiple();
1654 // jag 940620 On ajoute le traitement des restrictions solutions.
1656 if (solrst.NbSegments() !=0) {
1657 ProcessSegments(solrst,slin,TolArc,mySFunc,Domain);
1661 // Ajout crad pour depanner CMA en attendant mieux
1662 if (solrst.NbSegments() !=0) {
1664 Nblines = slin.Length();
1665 for (j=1; j<=Nblines; j++) {
1666 const Contap_Line& theli = slin(j);
1667 if (theli.TypeContour() == Contap_Walking) {
1668 Nbvt1 = theli.NbVertex();
1669 for (ivt1=1; ivt1<=Nbvt1; ivt1++) {
1670 Contap_Point& ptvt = theli.Vertex(ivt1);
1671 if (!ptvt.IsOnArc() && !ptvt.IsMultiple()) {
1672 Standard_Real Up,Vp;
1673 ptvt.Parameters(Up,Vp);
1674 gp_Pnt2d toproj(Up,Vp);
1675 Standard_Boolean projok;
1676 for (k=1; k<=Nblines;k++) {
1677 if (slin(k).TypeContour() == Contap_Restriction) {
1678 const Handle(Adaptor2d_HCurve2d)& thearc = slin(k).Arc();
1679 Standard_Real paramproj;
1681 projok = Contap_HContTool::Project(thearc,toproj,paramproj,Ptproj);
1684 Standard_Real dist = Ptproj.Distance(gp_Pnt2d(Up,Vp));
1685 if (dist <= Preci) {
1686 // Calcul de la transition
1688 Contap_HCurve2dTool::D1(thearc,paramproj,Ptproj,d2d);
1689 // Adaptor3d_HSurfaceTool::D1(Surf,Ptproj.X(),Ptproj.Y(),
1690 // ptonsurf,d1u,d1v);
1691 // normale = d1u.Crossed(d1v);
1693 Contap_SurfProps::DerivAndNorm
1694 (Surf,Ptproj.X(),Ptproj.Y(),ptonsurf,d1u,d1v,normale);
1696 tgtrst = d2d.X()*d1u;
1697 tgtrst.Add(d2d.Y()*d1v);
1698 Standard_Integer Paraml =
1699 (Standard_Integer) ptvt.ParameterOnLine();
1701 if (Paraml == theli.NbPnts()) {
1702 tgline = gp_Vec(theli.Point(Paraml-1).Value(),
1706 tgline = gp_Vec(ptvt.Value(),
1707 theli.Point(Paraml+1).Value());
1709 IntSurf::MakeTransition(tgline,tgtrst,normale,
1711 ptvt.SetArc(thearc,paramproj,TLine,TArc);
1713 ptdeb.SetValue(ptonsurf,Ptproj.X(),Ptproj.Y());
1714 ptdeb.SetParameter(paramproj);
1715 ptdeb.SetMultiple();
1720 projok = Standard_False;
1725 projok = Standard_False;
1736 done = Standard_True;
1739 static Standard_Boolean FindLine(Contap_Line& Line,
1740 const Handle(Adaptor3d_HSurface)& Surf,
1741 const gp_Pnt2d& Pt2d,
1743 Standard_Real& Paramin,
1747 // Standard_Integer i;
1750 Standard_Real para,dist;
1751 Standard_Real dismin = RealLast();
1753 Contap_SurfProps::Normale(Surf,Pt2d.X(),Pt2d.Y(),Ptref,Norm);
1755 if (Line.TypeContour() == Contap_Lin) {
1756 gp_Lin lin(Line.Line());
1757 para = ElCLib::Parameter(lin,Ptref);
1758 ElCLib::D1(para,lin,pt,tg);
1759 dist = pt.Distance(Ptref) + Abs(Norm.Dot(lin.Direction()));
1761 else { // Contap__Circle
1762 gp_Circ cir(Line.Circle());
1763 para = ElCLib::Parameter(cir,Ptref);
1764 ElCLib::D1(para,cir,pt,tg);
1765 dist = pt.Distance(Ptref)+Abs(Norm.Dot(tg/cir.Radius()));
1767 if (dist < dismin) {
1773 if (ptmin.SquareDistance(Ptref) <= Tolpetit) {
1774 return Standard_True;
1777 return Standard_False;
1782 static void PutPointsOnLine (const Contap_TheSearch& solrst,
1783 const Handle(Adaptor3d_HSurface)& Surf,
1784 Contap_TheSequenceOfLine& slin)
1787 Standard_Integer i,l;//,index;
1788 Standard_Integer NbPoints = solrst.NbPoints();
1790 Standard_Real theparam;
1792 IntSurf_Transition TLine,TArc;
1793 Standard_Boolean goon;
1799 gp_Vec vectg,normale,tgtrst;
1800 Standard_Real paramlin = 0.0;
1803 Standard_Integer nbLin = slin.Length();
1804 for(l=1;l<=nbLin;l++) {
1805 Contap_Line& Line=slin.ChangeValue(l);
1806 for (i=1; i<= NbPoints; i++) {
1808 const Contap_ThePathPointOfTheSearch& PStart = solrst.Point(i);
1809 const Handle(Adaptor2d_HCurve2d)& thearc = PStart.Arc();
1810 theparam = PStart.Parameter();
1812 Contap_HCurve2dTool::D1(thearc,theparam,pt2d,d2d);
1813 goon = FindLine(Line,Surf,pt2d,ptonsurf,paramlin,vectg,normale);
1815 Contap_Point PPoint;
1820 Adaptor3d_HSurfaceTool::D1(Surf,pt2d.X(),pt2d.Y(),bidpt,d1u,d1v);
1821 PPoint.SetValue(ptonsurf,pt2d.X(),pt2d.Y());
1822 if (normale.Magnitude() < RealEpsilon()) {
1827 // Petit test qui devrait permettre de bien traiter les pointes
1828 // des cones, et les sommets d`une sphere. Il faudrait peut-etre
1829 // rajouter une methode dans SurfProps
1831 if (Abs(d2d.Y()) <= Precision::Confusion()) {
1832 tgtrst = d1v.Crossed(normale);
1837 tgtrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
1839 IntSurf::MakeTransition(vectg,tgtrst,normale,TLine,TArc);
1842 PPoint.SetArc(thearc,theparam, TLine, TArc);
1843 PPoint.SetParameter(paramlin);
1844 if (!PStart.IsNew()) {
1845 PPoint.SetVertex(PStart.Vertex());
1854 //----------------------------------------------------------------------------------
1855 //-- Orientation des contours Apparents quand ceux-ci sont des lignes ou des cercles
1856 //-- On prend un point de la ligne ou du cercle ---> P
1857 //-- On projete ce point sur la surface P ---> u,v
1858 //-- et on evalue la transition au point u,v
1859 //----------------------------------------------------------------------------------
1861 IntSurf_TypeTrans ComputeTransitionOngpLine
1862 (Contap_SurfFunction& SFunc,
1865 const Handle(Adaptor3d_HSurface)& Surf=SFunc.Surface();
1866 GeomAbs_SurfaceType typS = Adaptor3d_HSurfaceTool::GetType(Surf);
1869 ElCLib::D1(0.0,L,P,T);
1870 Standard_Real u = 0.,v = 0.;
1872 case GeomAbs_Cylinder: {
1873 ElSLib::Parameters(Adaptor3d_HSurfaceTool::Cylinder(Surf),P,u,v);
1876 case GeomAbs_Cone: {
1877 ElSLib::Parameters(Adaptor3d_HSurfaceTool::Cone(Surf),P,u,v);
1880 case GeomAbs_Sphere: {
1881 ElSLib::Parameters(Adaptor3d_HSurfaceTool::Sphere(Surf),P,u,v);
1887 return(ComputeTransitionOnLine(SFunc,u,v,T));
1891 IntSurf_TypeTrans ComputeTransitionOngpCircle
1892 (Contap_SurfFunction& SFunc,
1895 const Handle(Adaptor3d_HSurface)& Surf=SFunc.Surface();
1896 GeomAbs_SurfaceType typS = Adaptor3d_HSurfaceTool::GetType(Surf);
1899 ElCLib::D1(0.0,C,P,T);
1900 Standard_Real u = 0.,v = 0.;
1902 case GeomAbs_Cylinder: {
1903 ElSLib::Parameters(Adaptor3d_HSurfaceTool::Cylinder(Surf),P,u,v);
1906 case GeomAbs_Cone: {
1907 ElSLib::Parameters(Adaptor3d_HSurfaceTool::Cone(Surf),P,u,v);
1910 case GeomAbs_Sphere: {
1911 ElSLib::Parameters(Adaptor3d_HSurfaceTool::Sphere(Surf),P,u,v);
1917 return(ComputeTransitionOnLine(SFunc,u,v,T));
1921 void Contap_Contour::PerformAna(const Handle(Adaptor3d_TopolTool)& Domain)
1924 done = Standard_False;
1927 Standard_Real TolArc = 1.e-5;
1929 Standard_Integer nbCont, nbPointRst, i;
1932 Contap_ContAna contana;
1933 Contap_Line theline;
1934 const Handle(Adaptor3d_HSurface)& Surf = mySFunc.Surface();
1935 Contap_TFunction TypeFunc(mySFunc.FunctionType());
1936 Standard_Boolean PerformSolRst = Standard_True;
1938 GeomAbs_SurfaceType typS = Adaptor3d_HSurfaceTool::GetType(Surf);
1943 gp_Pln pl(Adaptor3d_HSurfaceTool::Plane(Surf));
1945 case Contap_ContourStd:
1947 gp_Dir Dirpln(pl.Axis().Direction());
1948 if (Abs(mySFunc.Direction().Dot(Dirpln)) > Precision::Angular()) {
1949 // Aucun point du plan n`est solution, en particulier aucun point
1951 PerformSolRst = Standard_False;
1955 case Contap_ContourPrs:
1957 gp_Pnt Eye(mySFunc.Eye());
1958 if (pl.Distance(Eye) > Precision::Confusion()) {
1959 // Aucun point du plan n`est solution, en particulier aucun point
1961 PerformSolRst = Standard_False;
1965 case Contap_DraftStd:
1967 gp_Dir Dirpln(pl.Axis().Direction());
1968 Standard_Real Sina = Sin(mySFunc.Angle());
1969 if (Abs(mySFunc.Direction().Dot(Dirpln)+ Sina) > //voir SurfFunction
1970 Precision::Angular()) {
1972 PerformSolRst = Standard_False;
1976 case Contap_DraftPrs:
1984 case GeomAbs_Sphere:
1987 case Contap_ContourStd:
1989 contana.Perform(Adaptor3d_HSurfaceTool::Sphere(Surf),mySFunc.Direction());
1992 case Contap_ContourPrs:
1994 contana.Perform(Adaptor3d_HSurfaceTool::Sphere(Surf),mySFunc.Eye());
1997 case Contap_DraftStd:
1999 contana.Perform(Adaptor3d_HSurfaceTool::Sphere(Surf),
2000 mySFunc.Direction(),mySFunc.Angle());
2003 case Contap_DraftPrs:
2011 case GeomAbs_Cylinder:
2014 case Contap_ContourStd:
2016 contana.Perform(Adaptor3d_HSurfaceTool::Cylinder(Surf),mySFunc.Direction());
2019 case Contap_ContourPrs:
2021 contana.Perform(Adaptor3d_HSurfaceTool::Cylinder(Surf),mySFunc.Eye());
2024 case Contap_DraftStd:
2026 contana.Perform(Adaptor3d_HSurfaceTool::Cylinder(Surf),
2027 mySFunc.Direction(),mySFunc.Angle());
2030 case Contap_DraftPrs:
2041 case Contap_ContourStd:
2043 contana.Perform(Adaptor3d_HSurfaceTool::Cone(Surf),mySFunc.Direction());
2046 case Contap_ContourPrs:
2048 contana.Perform(Adaptor3d_HSurfaceTool::Cone(Surf),mySFunc.Eye());
2051 case Contap_DraftStd:
2053 contana.Perform(Adaptor3d_HSurfaceTool::Cone(Surf),
2054 mySFunc.Direction(),mySFunc.Angle());
2057 case Contap_DraftPrs:
2068 if (typS != GeomAbs_Plane) {
2070 if (!contana.IsDone()) {
2074 nbCont = contana.NbContours();
2076 if (contana.NbContours() == 0) {
2077 done = Standard_True;
2081 GeomAbs_CurveType typL = contana.TypeContour();
2082 if (typL == GeomAbs_Circle) {
2083 theline.SetValue(contana.Circle());
2084 IntSurf_TypeTrans TransCircle;
2085 TransCircle = ComputeTransitionOngpCircle(mySFunc,contana.Circle());
2086 theline.SetTransitionOnS(TransCircle);
2087 slin.Append(theline);
2089 else if (typL == GeomAbs_Line) {
2090 for (i=1; i<=nbCont; i++) {
2091 theline.SetValue(contana.Line(i));
2092 IntSurf_TypeTrans TransLine;
2093 TransLine = ComputeTransitionOngpLine(mySFunc,contana.Line(i));
2094 theline.SetTransitionOnS(TransLine);
2095 slin.Append(theline);
2100 if (typS == GeomAbs_Cone) {
2102 gp_Cone thecone(Adaptor3d_HSurfaceTool::Cone(Surf));
2103 ElSLib::Parameters(thecone,thecone.Apex(),u,v);
2104 Contap_Point vtxapex(thecone.Apex(),u,v);
2105 vtxapex.SetInternal();
2106 vtxapex.SetMultiple();
2107 for (i=1; i<=nbCont i++) {
2108 slin.ChangeValue(i).Add(vtxapex);
2117 solrst.Perform(myAFunc,Domain,TolArc,TolArc);
2118 if (!solrst.IsDone()) {
2121 nbPointRst = solrst.NbPoints();
2123 if (nbPointRst != 0) {
2124 PutPointsOnLine(solrst,Surf,slin);
2127 if (solrst.NbSegments() !=0) {
2128 ProcessSegments(solrst,slin,TolArc,mySFunc,Domain);
2133 //Standard_Boolean oneremov;
2134 Standard_Integer nblinto = slin.Length();
2135 TColStd_SequenceOfInteger SeqToDestroy;
2137 //-- cout<<" Construct Contour_3 nblin = "<<nblinto<<endl;
2138 for(i=1; i<= nblinto ; i++) {
2139 //-- cout<<" nbvtx : "<<slin.Value(i).NbVertex()<<endl;
2140 //--if(slin.Value(i).NbVertex() > 1) {
2141 if(slin.Value(i).TypeContour() != Contap_Restriction) {
2142 LineConstructor(slin,Domain,slin.ChangeValue(i),Surf);
2143 SeqToDestroy.Append(i);
2147 for(i=SeqToDestroy.Length(); i>=1; i--) {
2148 slin.Remove(SeqToDestroy.Value(i));
2152 done = Standard_True;