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 #define Tolpetit 1.e-10 // pour dist au carre
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) {Standard_ConstructionError::Raise();}
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();
311 for(Standard_Integer j=firstp; j<=lastp; j++) {
312 LineOn2S->Add(L.Point(j));
314 Line.SetLineOn2S(LineOn2S);
315 Contap_Point pvtx = L.Vertex(i);
316 pvtx.SetParameter(1);
319 pvtx = L.Vertex(i+1);
320 pvtx.SetParameter(lastp-firstp+1);
322 Line.SetTransitionOnS(L.TransitionOnS());
328 else if(typl==Contap_Lin) {
329 Standard_Real u2,v2;// u1,v1;
330 Standard_Integer nbvtx = L.NbVertex();
331 //-- cout<<" Lin -> "<<nbvtx<<" vtx"<<endl;
332 for(Standard_Integer i=1;i<nbvtx;i++) {
333 Standard_Real firstp = L.Vertex(i).ParameterOnLine();
334 Standard_Real lastp = L.Vertex(i+1).ParameterOnLine();
336 Standard_Real pmid = (firstp+lastp)*0.5;
337 gp_Pnt Pmid = ElCLib::Value(pmid,L.Line());
338 if(Adaptor3d_HSurfaceTool::GetType(Surf)==GeomAbs_Cylinder) {
339 ElSLib::Parameters(Adaptor3d_HSurfaceTool::Cylinder(Surf),Pmid,u2,v2);
341 else if(Adaptor3d_HSurfaceTool::GetType(Surf)==GeomAbs_Cone) {
342 ElSLib::Parameters(Adaptor3d_HSurfaceTool::Cone(Surf),Pmid,u2,v2);
345 //-- cout<<" Pb ds Contap_ContourGen_2.gxx (type)"<<endl;
349 TopAbs_State in2 = Domain->Classify(gp_Pnt2d(u2,v2),Tol);
350 if(in2 == TopAbs_OUT) {
353 //-- cout<<"Contap Lin : firtsp="<<firstp<<" lastp="<<lastp<<" Vtx:"<<i<<","<<i+1<<endl;
355 Line.SetValue(L.Line());
356 Contap_Point pvtx = L.Vertex(i);
359 pvtx = L.Vertex(i+1);
361 Line.SetTransitionOnS(L.TransitionOnS());
367 else if(typl==Contap_Circle) {
368 Standard_Real u2,v2; //u1,v1,
369 Standard_Integer nbvtx = L.NbVertex();
370 //-- cout<<" Circ -> "<<nbvtx<<" vtx"<<endl;
371 Standard_Boolean novtx = Standard_True;
372 if(nbvtx) novtx=Standard_False;
373 for(Standard_Integer i=1;i<nbvtx || novtx;i++) {
374 Standard_Real firstp=0,lastp=M_PI+M_PI;
375 if(novtx == Standard_False) {
376 firstp = L.Vertex(i).ParameterOnLine();
377 lastp = L.Vertex(i+1).ParameterOnLine();
379 if(Abs(firstp-lastp)>0.000000001) {
380 Standard_Real pmid = (firstp+lastp)*0.5;
381 gp_Pnt Pmid = ElCLib::Value(pmid,L.Circle());
382 if(Adaptor3d_HSurfaceTool::GetType(Surf)==GeomAbs_Cylinder) {
383 ElSLib::Parameters(Adaptor3d_HSurfaceTool::Cylinder(Surf),Pmid,u2,v2);
385 else if(Adaptor3d_HSurfaceTool::GetType(Surf)==GeomAbs_Cone) {
386 ElSLib::Parameters(Adaptor3d_HSurfaceTool::Cone(Surf),Pmid,u2,v2);
388 else if(Adaptor3d_HSurfaceTool::GetType(Surf)==GeomAbs_Sphere) {
389 ElSLib::Parameters(Adaptor3d_HSurfaceTool::Sphere(Surf),Pmid,u2,v2);
392 //-- cout<<" Pb ds Contap_ContourGen_2.gxx (typep)"<<endl;
396 TopAbs_State in2 = Domain->Classify(gp_Pnt2d(u2,v2),Tol);
397 if(in2 == TopAbs_OUT) {
400 //-- cout<<"Contap Circle : firtsp="<<firstp<<" lastp="<<lastp<<" Vtx:"<<i<<","<<i+1<<endl;
402 Line.SetValue(L.Circle());
403 if(novtx == Standard_False) {
404 Contap_Point pvtx = L.Vertex(i);
406 pvtx = L.Vertex(i+1);
409 Line.SetTransitionOnS(L.TransitionOnS());
413 novtx = Standard_False;
416 Standard_Real firstp = L.Vertex(nbvtx).ParameterOnLine();
417 Standard_Real lastp = L.Vertex(1).ParameterOnLine() + M_PI+M_PI;
418 if(Abs(firstp-lastp)>0.0000000001) {
419 Standard_Real pmid = (firstp+lastp)*0.5;
420 gp_Pnt Pmid = ElCLib::Value(pmid,L.Circle());
421 if(Adaptor3d_HSurfaceTool::GetType(Surf)==GeomAbs_Cylinder) {
422 ElSLib::Parameters(Adaptor3d_HSurfaceTool::Cylinder(Surf),Pmid,u2,v2);
424 else if(Adaptor3d_HSurfaceTool::GetType(Surf)==GeomAbs_Cone) {
425 ElSLib::Parameters(Adaptor3d_HSurfaceTool::Cone(Surf),Pmid,u2,v2);
427 else if(Adaptor3d_HSurfaceTool::GetType(Surf)==GeomAbs_Sphere) {
428 ElSLib::Parameters(Adaptor3d_HSurfaceTool::Sphere(Surf),Pmid,u2,v2);
431 //-- cout<<" Pb ds Contap_ContourGen_2.gxx (typep)"<<endl;
435 TopAbs_State in2 = Domain->Classify(gp_Pnt2d(u2,v2),Tol);
436 if(in2 == TopAbs_OUT) {
439 //-- cout<<"Contap Circle *Compl* : firtsp="<<firstp<<" lastp="<<lastp<<" Vtx:"<<i<<","<<i+1<<endl;
441 Line.SetValue(L.Circle());
442 Contap_Point pvtx = L.Vertex(nbvtx);
445 pvtx = L.Vertex(1); pvtx.SetParameter(pvtx.ParameterOnLine()+M_PI+M_PI);
447 Line.SetTransitionOnS(L.TransitionOnS());
454 //-- cout<<" ni WLine ni Lin ni Circ "<<endl;
460 //-- --------------------------------------------------------------------------------
464 static void KeepInsidePoints(const Contap_TheSearchInside& solins,
465 const Contap_TheSearch& solrst,
466 Contap_SurfFunction& Func,
467 IntSurf_SequenceOfInteriorPoint& seqpins)
470 Standard_Integer Nba = solrst.NbSegments();
471 if (Nba <= 0) return;
472 Standard_Integer Nbp,indp,inda;
473 Standard_Real U,V,paramproj;
474 gp_Pnt2d toproj,Ptproj;
475 Standard_Boolean projok,tokeep;
476 const Handle(Adaptor3d_HSurface)& Surf = Func.Surface();
478 Nbp = solins.NbPoints();
479 for (indp=1; indp <= Nbp; indp++) {
480 tokeep = Standard_True;
481 const IntSurf_InteriorPoint& pti = solins.Value(indp);
483 toproj = gp_Pnt2d(U,V);
484 for (inda = 1; inda <= Nba; inda++) {
485 const Handle(Adaptor2d_HCurve2d)& thearc = solrst.Segment(inda).Curve();
486 projok = Contap_HContTool::Project(thearc,toproj,paramproj,Ptproj);
488 gp_Pnt pprojete = Adaptor3d_HSurfaceTool::Value(Surf,Ptproj.X(),Ptproj.Y());
489 if (pti.Value().Distance(pprojete) <= Precision::Confusion()) {
490 tokeep = Standard_False;
502 static void ComputeTangency (const Contap_TheSearch& solrst,
503 const Handle(Adaptor3d_TopolTool)& Domain,
504 Contap_SurfFunction& Func,
505 IntSurf_SequenceOfPathPoint& seqpdep,
506 TColStd_Array1OfInteger& Destination)
509 Standard_Integer i,k;
510 Standard_Integer NbPoints = solrst.NbPoints();
511 Standard_Integer seqlength = 0;
513 Standard_Real theparam,test;
514 Standard_Boolean fairpt;
515 TopAbs_Orientation arcorien,vtxorien;
516 Standard_Boolean ispassing;
520 math_Matrix D(1, 1, 1, 2);
522 gp_Vec normale, vectg, tg3drst,v1,v2;
527 IntSurf_PathPoint PPoint;
528 const Handle(Adaptor3d_HSurface)& Surf = Func.Surface();
530 for (i=1; i<= NbPoints; i++) {
532 if (Destination(i) == 0) {
534 const Contap_ThePathPointOfTheSearch& PStart = solrst.Point(i);
535 const Handle(Adaptor2d_HCurve2d)& thearc = PStart.Arc();
536 theparam = PStart.Parameter();
537 gp_Pnt2d Ptoproj=Contap_HCurve2dTool::Value(thearc,theparam);
538 //-- lbr le 15 mai 97
539 //-- On elimine les points qui sont egalement present sur une restriction solution
540 Standard_Boolean SurUneRestrictionSolution = Standard_False;
541 for(Standard_Integer restriction=1;
542 SurUneRestrictionSolution==Standard_False && restriction<=solrst.NbSegments();
544 const Handle(Adaptor2d_HCurve2d)& thearcsol = solrst.Segment(restriction).Curve();
545 Standard_Real paramproj;
547 Standard_Boolean projok = Contap_HContTool::Project(thearcsol,Ptoproj,paramproj,pproj);
549 //gp_Pnt pprojete = Adaptor3d_HSurfaceTool::Value(Surf,Ptoproj.X(),Ptoproj.Y());
551 gp_Pnt pprojete = Adaptor3d_HSurfaceTool::Value(Surf,pproj.X(),pproj.Y());
553 if ((PStart.Value()).Distance(pprojete) <= Precision::Confusion()) {
554 SurUneRestrictionSolution = Standard_True;
558 if(SurUneRestrictionSolution == Standard_False) {
559 arcorien = Domain->Orientation(thearc);
560 ispassing = (arcorien == TopAbs_INTERNAL ||
561 arcorien == TopAbs_EXTERNAL);
563 Contap_HCurve2dTool::D1(thearc,theparam,pt2d,tg2drst);
566 PPoint.SetValue(PStart.Value(),X(1),X(2));
569 if (Func.IsTangent()) {
570 PPoint.SetTangency(Standard_True);
571 Destination(i) = seqlength+1;
572 if (!PStart.IsNew()) {
573 const Handle(Adaptor3d_HVertex)& vtx = PStart.Vertex();
574 for (k=i+1; k<=NbPoints; k++) {
575 if (Destination(k) ==0) {
576 const Contap_ThePathPointOfTheSearch& PStart2 = solrst.Point(k);
577 if (!PStart2.IsNew()) {
578 const Handle(Adaptor3d_HVertex)& vtx2 = PStart2.Vertex();
579 if (Domain->Identical(vtx,vtx2)) {
580 const Handle(Adaptor2d_HCurve2d)& thearc2 = PStart2.Arc();
581 theparam = PStart2.Parameter();
582 arcorien = Domain->Orientation(thearc2);
583 ispassing = ispassing && (arcorien == TopAbs_INTERNAL ||
584 arcorien == TopAbs_EXTERNAL);
586 pt2d = Contap_HCurve2dTool::Value(thearc2,theparam);
589 PPoint.AddUV(X(1),X(2));
590 Destination(k) = seqlength+1;
596 PPoint.SetPassing(ispassing);
597 seqpdep.Append(PPoint);
600 else { // on a un point de depart potentiel
602 vectg = Func.Direction3d();
603 dirtg = Func.Direction2d();
606 // Adaptor3d_HSurfaceTool::D1(Surf,X(1),X(2),ptbid,v1,v2);
607 Contap_SurfProps::DerivAndNorm(Surf,X(1),X(2),ptbid,v1,v2,normale);
608 tg3drst = tg2drst.X()*v1 + tg2drst.Y()*v2;
609 // normale = v1.Crossed(v2);
610 if(normale.SquareMagnitude() < RealEpsilon()) {
611 //-- cout<<"\n*** Contap_ContourGen_2.gxx Normale Nulle en U:"<<X(1)<<" V:"<<X(2)<<endl;
614 test = vectg.Dot(normale.Crossed(tg3drst));
616 if (PStart.IsNew()) {
617 Standard_Real tbis = vectg.Normalized().Dot(tg3drst.Normalized());
618 if (Abs(tbis) < 1.-tole) {
620 if ((test < 0. && arcorien == TopAbs_FORWARD) ||
621 (test > 0. && arcorien == TopAbs_REVERSED)) {
625 PPoint.SetDirections(vectg,dirtg);
627 else { // on garde le point comme point d`arret (tangent)
628 PPoint.SetTangency(Standard_True);
630 PPoint.SetPassing(ispassing);
631 Destination(i) = seqlength+1;
632 seqpdep.Append(PPoint);
635 else { // traiter la transition complexe
636 gp_Dir bidnorm(1.,1.,1.);
638 Standard_Boolean tobeverified = Standard_False;
639 TopAbs_Orientation LocTrans;
640 TopTrans_CurveTransition comptrans;
641 comptrans.Reset(vectg,bidnorm,0.);
642 if (arcorien != TopAbs_INTERNAL &&
643 arcorien != TopAbs_EXTERNAL) {
645 const Handle(Adaptor3d_HVertex)& vtx = PStart.Vertex();
646 vtxorien = Domain->Orientation(vtx);
647 test = test/(vectg.Magnitude());
648 test = test/((normale.Crossed(tg3drst)).Magnitude());
650 if (Abs(test) <= tole) {
651 tobeverified = Standard_True;
652 LocTrans = TopAbs_EXTERNAL; // et pourquoi pas INTERNAL
655 if ((test > 0. && arcorien == TopAbs_FORWARD) ||
656 (test < 0. && arcorien == TopAbs_REVERSED)){
657 LocTrans = TopAbs_FORWARD;
660 LocTrans = TopAbs_REVERSED;
662 if (arcorien == TopAbs_REVERSED) {tg3drst.Reverse();} // pas deja fait ???
665 comptrans.Compare(tole,tg3drst,bidnorm,0.,LocTrans,vtxorien);
667 Destination(i) = seqlength+1;
668 for (k= i+1; k<=NbPoints; k++) {
669 if (Destination(k) == 0) {
670 const Contap_ThePathPointOfTheSearch& PStart2 = solrst.Point(k);
671 if (!PStart2.IsNew()) {
672 const Handle(Adaptor3d_HVertex)& vtx2 = PStart2.Vertex();
673 if (Domain->Identical(PStart.Vertex(),vtx2)) {
674 const Handle(Adaptor2d_HCurve2d)& thearc2 = PStart2.Arc();
675 theparam = PStart2.Parameter();
676 arcorien = Domain->Orientation(thearc2);
678 Contap_HCurve2dTool::D1(thearc2,theparam,pt2d,tg2drst);
681 PPoint.AddUV(X(1),X(2));
683 if (arcorien != TopAbs_INTERNAL &&
684 arcorien != TopAbs_EXTERNAL) {
685 ispassing = Standard_False;
686 tg3drst = tg2drst.X()*v1 + tg2drst.Y()*v2;
687 test = vectg.Dot(normale.Crossed(tg3drst));
688 test = test/(vectg.Magnitude());
689 test = test /((normale.Crossed(tg3drst)).Magnitude());
691 vtxorien = Domain->Orientation(vtx2);
692 if (Abs(test) <= tole) {
693 tobeverified = Standard_True;
694 LocTrans = TopAbs_EXTERNAL; // et pourquoi pas INTERNAL
697 if ((test > 0. && arcorien == TopAbs_FORWARD) ||
698 (test < 0. && arcorien == TopAbs_REVERSED)){
699 LocTrans = TopAbs_FORWARD;
702 LocTrans = TopAbs_REVERSED;
704 if (arcorien == TopAbs_REVERSED) {tg3drst.Reverse();} //deja fait????
707 comptrans.Compare(tole,tg3drst,bidnorm,0.,LocTrans,vtxorien);
709 Destination(k) = seqlength+1;
714 fairpt = Standard_True;
716 TopAbs_State Before = comptrans.StateBefore();
717 TopAbs_State After = comptrans.StateAfter();
718 if ((Before == TopAbs_UNKNOWN)||(After == TopAbs_UNKNOWN)) {
719 fairpt = Standard_False;
721 else if (Before == TopAbs_IN) {
722 if (After == TopAbs_IN) {
723 ispassing = Standard_True;
731 if (After !=TopAbs_IN) {
732 fairpt = Standard_False;
737 // evite de partir le long d une restriction solution
739 if (fairpt && tobeverified) {
740 for (k=i; k <=NbPoints ; k++) {
741 if (Destination(k)==seqlength + 1) {
742 theparam = solrst.Point(k).Parameter();
743 const Handle(Adaptor2d_HCurve2d)& thearc2 = solrst.Point(k).Arc();
744 arcorien = Domain->Orientation(thearc2);
746 if (arcorien == TopAbs_FORWARD ||
747 arcorien == TopAbs_REVERSED) {
748 Contap_HCurve2dTool::D1(thearc2,theparam,pt2d,tg2drst);
749 tg3drst = tg2drst.X()*v1 + tg2drst.Y()*v2;
750 vtxorien = Domain->Orientation(solrst.Point(k).Vertex());
751 if ((arcorien == TopAbs_FORWARD &&
752 vtxorien == TopAbs_REVERSED) ||
753 (arcorien == TopAbs_REVERSED &&
754 vtxorien == TopAbs_FORWARD)) {
757 test = vectg.Normalized().Dot(tg3drst.Normalized());
758 if (test >= 1. - tole) {
759 fairpt = Standard_False;
768 PPoint.SetDirections(vectg,dirtg);
769 PPoint.SetPassing(ispassing);
770 seqpdep.Append(PPoint);
773 else { // il faut remettre en "ordre" si on ne garde pas le point.
774 for (k=i; k <=NbPoints ; k++) {
775 if (Destination(k)==seqlength + 1) {
776 Destination(k) = -Destination(k);
789 IntSurf_TypeTrans ComputeTransitionOnLine(Contap_SurfFunction& SFunc,
790 const Standard_Real u,
791 const Standard_Real v,
792 const gp_Vec& tgline)
798 Adaptor3d_HSurfaceTool::D1(SFunc.Surface(),u,v,pntbid,d1u,d1v);
800 //------------------------------------------------------
801 //-- Calcul de la tangente dans l espace uv ---
802 //------------------------------------------------------
804 Standard_Real det,d1uT,d1vT,normu2,normv2,d1ud1v,alpha,beta;
805 d1uT = d1u.Dot(tgline);
806 d1vT = d1v.Dot(tgline);
807 normu2 = d1u.Dot(d1u);
808 normv2 = d1v.Dot(d1v);
809 d1ud1v = d1u.Dot(d1v);
810 det = normu2 * normv2 - d1ud1v * d1ud1v;
811 if(det<RealEpsilon()) {
812 //-- On ne doit pas passer ici !!
813 //-- cout<<" Probleme !!!"<<endl ;
814 return IntSurf_Undecided;
817 alpha = (d1uT * normv2 - d1vT * d1ud1v)/det;
818 beta = (normu2 * d1vT - d1ud1v * d1uT)/det;
819 //-----------------------------------------------------
820 //-- Calcul du Gradient de la fonction Utilisee --
821 //-- pour le contour apparent --
822 //-----------------------------------------------------
826 math_Matrix Df(1,1,1,2);
829 SFunc.Derivatives(X,Df);
833 //-----------------------------------------------------
834 //-- On calcule si la fonction --
835 //-- F(.) = Normale . Dir_Regard --
836 //-- Croit Losrque l on se deplace sur la Gauche --
837 //-- de la direction de deplacement sur la ligne. --
838 //-----------------------------------------------------
840 det = -v1*beta + v2*alpha;
842 if(det<RealEpsilon()) { // revoir le test jag 940620
843 return IntSurf_Undecided;
852 void ProcessSegments (const Contap_TheSearch& solrst,
853 Contap_TheSequenceOfLine& slin,
854 const Standard_Real TolArc,
855 Contap_SurfFunction& SFunc,
856 const Handle(Adaptor3d_TopolTool)& Domain)
859 Standard_Integer i,j,k;
860 Standard_Integer nbedg = solrst.NbSegments();
861 Standard_Integer Nblines,Nbpts;
863 Handle(Adaptor2d_HCurve2d) arcRef;
866 Contap_ThePathPointOfTheSearch PStartf,PStartl;
868 Standard_Boolean dofirst,dolast,procf,procl;
869 Standard_Real paramf =0.,paraml =0.,U;
872 gp_Vec tgline;//,norm1,norm2;
880 for (i = 1; i <= nbedg; i++) {
882 const Contap_TheSegmentOfTheSearch& thesegsol = solrst.Segment(i);
883 theline.SetValue(thesegsol.Curve());
885 // Traitement des points debut/fin du segment solution.
887 dofirst = Standard_False;
888 dolast = Standard_False;
889 procf = Standard_False;
890 procl = Standard_False;
892 if (thesegsol.HasFirstPoint()) {
893 dofirst = Standard_True;
894 PStartf = thesegsol.FirstPoint();
895 paramf = PStartf.Parameter();
897 if (thesegsol.HasLastPoint()) {
898 dolast = Standard_True;
899 PStartl = thesegsol.LastPoint();
900 paraml = PStartl.Parameter();
903 // determination de la transition
904 if (dofirst && dolast) {
905 U = (paramf+paraml)/2.;
917 Contap_HCurve2dTool::D1(thesegsol.Curve(),U,p2d,d2d);
918 Adaptor3d_HSurfaceTool::D1(SFunc.Surface(),p2d.X(),p2d.Y(),valpt,d1u,d1v);
919 tgline.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
920 IntSurf_TypeTrans tral =
921 ComputeTransitionOnLine(SFunc,p2d.X(),p2d.Y(),tgline);
923 theline.SetTransitionOnS(tral);
926 if (dofirst || dolast) {
927 Nblines = slin.Length();
928 for (j=1; j<=Nblines; j++) {
929 Nbpts = slin(j).NbVertex();
930 for (k=1; k<=Nbpts;k++) {
931 ptvtx = slin(j).Vertex(k);
933 if (ptvtx.Value().Distance(PStartf.Value()) <=TolArc) {
934 slin(j).Vertex(k).SetMultiple();
936 ptvtx.SetParameter(paramf);
942 if (ptvtx.Value().Distance(PStartl.Value()) <=TolArc) {
943 slin(j).Vertex(k).SetMultiple();
945 ptvtx.SetParameter(paraml);
951 // Si on a traite le pt debut et/ou fin, on ne doit pas recommencer si
952 // il (ils) correspond(ent) a un point multiple.
955 dofirst = Standard_False;
958 dolast = Standard_False;
963 // Si on n a pas trouve le point debut et./ou fin sur une des lignes
964 // d intersection, il faut quand-meme le placer sur la restriction solution
968 p2d = Contap_HCurve2dTool::Value(thesegsol.Curve(),paramf);
969 ptvtx.SetValue(PStartf.Value(),p2d.X(),p2d.Y());
970 ptvtx.SetParameter(paramf);
971 if (! PStartf.IsNew()) {
972 ptvtx.SetVertex(PStartf.Vertex());
977 p2d = Contap_HCurve2dTool::Value(thesegsol.Curve(),paraml);
978 ptvtx.SetValue(PStartl.Value(),p2d.X(),p2d.Y());
979 ptvtx.SetParameter(paraml);
980 if (! PStartl.IsNew()) {
981 ptvtx.SetVertex(PStartl.Vertex());
986 // il faut chercher le points internal sur les restrictions solutions.
987 if (thesegsol.HasFirstPoint() && thesegsol.HasLastPoint()) {
988 ComputeInternalPointsOnRstr(theline,paramf,paraml,SFunc);
990 LineConstructor(slin,Domain,theline,SFunc.Surface()); //-- lbr
991 //-- slin.Append(theline);
996 void ComputeInternalPointsOnRstr
998 const Standard_Real Paramf,
999 const Standard_Real Paraml,
1000 Contap_SurfFunction& SFunc)
1002 // On recherche les points ou la tangente a la ligne de contour et
1003 // la direction sont alignees.
1004 // 1ere etape : recherche de changement de signe.
1005 // 2eme etape : localisation de la solution par dichotomie
1008 Standard_Integer indexinf,indexsup,i;
1009 gp_Vec tgt, vecref, vectest, vtestb, vecregard,d1u,d1v;
1013 Standard_Boolean found,ok = Standard_False,toutvu,solution;
1014 Standard_Real paramp = 0.,paraminf,paramsup,toler;
1016 if (Line.TypeContour() != Contap_Restriction) {
1020 const Handle(Adaptor2d_HCurve2d)& thearc = Line.Arc();
1022 const Handle(Adaptor3d_HSurface)& Surf = SFunc.Surface();
1023 Contap_TFunction TypeFunc(SFunc.FunctionType());
1025 Standard_Integer Nbpnts = Contap_HContTool::NbSamplesOnArc(thearc);
1027 vecregard = SFunc.Direction();
1028 toler = Contap_HCurve2dTool::Resolution(thearc,Precision::Confusion());
1029 found = Standard_False;
1032 paraminf = ((Nbpnts-indexinf)*Paramf + (indexinf-1)*Paraml)/(Nbpnts-1);
1033 Contap_HCurve2dTool::D1(thearc,paraminf,p2d,d2d);
1034 Adaptor3d_HSurfaceTool::D1(Surf,p2d.X(),p2d.Y(),pcour,d1u,d1v);
1035 tgt.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
1037 if (tgt.Magnitude() > gp::Resolution()) {
1038 if (TypeFunc == Contap_ContourPrs || TypeFunc==Contap_DraftPrs) {
1039 vecregard.SetXYZ(pcour.XYZ()-SFunc.Eye().XYZ());
1041 vecref = vecregard.Crossed(tgt);
1043 if (vecref.Magnitude() <= gp::Resolution()) {
1047 found = Standard_True;
1053 } while ((indexinf <= Nbpnts) && (!found));
1056 indexsup = indexinf +1;
1057 toutvu = (indexsup > Nbpnts);
1059 paramsup = ((Nbpnts-indexsup)*Paramf + (indexsup-1)*Paraml)/(Nbpnts-1);
1060 Contap_HCurve2dTool::D1(thearc,paramsup,p2d,d2d);
1061 Adaptor3d_HSurfaceTool::D1(Surf,p2d.X(),p2d.Y(),pcour,d1u,d1v);
1062 tgt.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
1064 if (tgt.Magnitude() > gp::Resolution()) {
1065 if (TypeFunc == Contap_ContourPrs || TypeFunc==Contap_DraftPrs) {
1066 vecregard.SetXYZ(pcour.XYZ()-SFunc.Eye().XYZ());
1068 vectest = vecregard.Crossed(tgt);
1071 vectest = gp_Vec(0.,0.,0.);
1073 if (vectest.Magnitude() <= gp::Resolution()) {
1074 // On cherche un vrai changement de signe
1078 if (vectest.Dot(vecref) < 0.) {
1079 // Essayer de converger
1080 // cout << "Changement de signe detecte" << endl;
1081 solution = Standard_False;
1083 paramp = (paraminf+paramsup)/2.;
1084 Contap_HCurve2dTool::D1(thearc,paramp,p2d,d2d);
1085 Adaptor3d_HSurfaceTool::D1(Surf,p2d.X(),p2d.Y(),pcour,d1u,d1v);
1086 tgt.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
1088 if (tgt.Magnitude() > gp::Resolution()) {
1089 if (TypeFunc == Contap_ContourPrs || TypeFunc==Contap_DraftPrs) {
1090 vecregard.SetXYZ(pcour.XYZ()-SFunc.Eye().XYZ());
1092 vtestb = vecregard.Crossed(tgt);
1095 vtestb = gp_Vec(0.,0.,0.);
1098 if ((vtestb.Magnitude() <= gp::Resolution())||
1099 (Abs(paramp-paraminf) <= toler) ||
1100 (Abs(paramp-paramsup) <= toler)) {
1101 // on est a la solution
1102 solution = Standard_True;
1105 else if (vtestb.Dot(vecref) < 0.) {
1115 // On verifie que le point trouve ne correspond pas a un ou des
1116 // vertex deja existant(s). On teste sur le parametre paramp.
1117 for (i=1; i<=Line.NbVertex(); i++) {
1118 Contap_Point& thevtx = Line.Vertex(i);
1119 if (Abs(thevtx.ParameterOnLine()-paramp) <= toler) {
1120 thevtx.SetInternal();
1121 ok = Standard_False; // on a correspondance
1124 if (ok) { // il faut alors rajouter le point
1125 Contap_Point internalp(pcour,p2d.X(),p2d.Y());
1126 internalp.SetParameter(paramp);
1127 internalp.SetInternal();
1128 Line.Add(internalp);
1131 paramsup = ((Nbpnts-indexsup)*Paramf + (indexsup-1)*Paraml)/(Nbpnts-1);
1134 indexinf = indexsup;
1136 paraminf = paramsup;
1138 toutvu = (indexsup > Nbpnts);
1143 void ComputeInternalPoints
1145 Contap_SurfFunction& SFunc,
1146 const Standard_Real ureso,
1147 const Standard_Real vreso)
1150 // On recherche les points ou la tangente a la ligne de contour et
1151 // la direction sont alignees.
1152 // 1ere etape : recheche de changement de signe.
1153 // 2eme etape : localisation de la solution par simili dichotomie
1156 Standard_Integer indexinf,indexsup,index;
1157 gp_Vec tgt, vecref, vectest, vtestb, vecregard;
1158 //gp_Pnt pprec,pcour;
1159 Standard_Boolean found,ok = Standard_False,toutvu,solution;
1160 Standard_Real paramp = 0.,U,V;
1162 math_Vector XInf(1,2),XSup(1,2),X(1,2),F(1,1);
1163 math_Matrix DF(1,1,1,2);
1164 math_Vector toler(1,2),infb(1,2),supb(1,2);
1166 if (Line.TypeContour() != Contap_Walking) {
1170 Standard_Integer Nbpnts = Line.NbPnts();
1171 const Handle(Adaptor3d_HSurface)& Surf = SFunc.Surface();
1172 Contap_TFunction TypeFunc(SFunc.FunctionType());
1174 toler(1) = ureso; //-- Trop long !!! Adaptor3d_HSurfaceTool::UResolution(Surf,SFunc.Tolerance());
1175 toler(2) = vreso; //---Beaucoup trop long !!! Adaptor3d_HSurfaceTool::VResolution(Surf,SFunc.Tolerance());
1176 infb(1) = Adaptor3d_HSurfaceTool::FirstUParameter(Surf);
1177 infb(2) = Adaptor3d_HSurfaceTool::FirstVParameter(Surf);
1178 supb(1) = Adaptor3d_HSurfaceTool::LastUParameter(Surf);
1179 supb(2) = Adaptor3d_HSurfaceTool::LastVParameter(Surf);
1181 math_FunctionSetRoot rsnld(SFunc,toler,30);
1184 vecregard = SFunc.Direction();
1186 found = Standard_False;
1188 Line.Point(indexinf).ParametersOnS2(XInf(1),XInf(2));
1189 SFunc.Values(XInf,F,DF);
1190 if (!SFunc.IsTangent()) {
1191 tgt = SFunc.Direction3d();
1192 if (TypeFunc == Contap_ContourPrs || TypeFunc == Contap_DraftPrs) {
1193 vecregard.SetXYZ(Line.Point(indexinf).Value().XYZ()-SFunc.Eye().XYZ());
1195 vecref = vecregard.Crossed(tgt);
1197 if (vecref.Magnitude() <= gp::Resolution()) {
1201 found = Standard_True;
1207 } while ((indexinf <= Nbpnts) && (!found));
1210 indexsup = indexinf +1;
1211 toutvu = (indexsup > Nbpnts);
1213 Line.Point(indexsup).ParametersOnS2(XSup(1),XSup(2));
1214 SFunc.Values(XSup,F,DF);
1215 if (!SFunc.IsTangent()) {
1216 tgt = SFunc.Direction3d();
1218 if (TypeFunc == Contap_ContourPrs || TypeFunc == Contap_DraftPrs) {
1219 vecregard.SetXYZ(Line.Point(indexsup).Value().XYZ()-SFunc.Eye().XYZ());
1221 vectest = vecregard.Crossed(tgt);
1224 vectest = gp_Vec(0.,0.,0.);
1226 if (vectest.Magnitude() <= gp::Resolution()) {
1227 // On cherche un vrai changement de signe
1231 if (vectest.Dot(vecref) < 0.) {
1232 // Essayer de converger
1233 // cout << "Changement de signe detecte" << endl;
1234 solution = Standard_False;
1236 X(1) = (XInf(1) + XSup(1)) /2.;
1237 X(2) = (XInf(2) + XSup(2)) /2.;
1238 rsnld.Perform(SFunc,X,infb,supb);
1240 if (!rsnld.IsDone()) {
1241 cout << "Echec recherche internal points" << endl;
1242 solution = Standard_True;
1243 ok = Standard_False;
1248 SFunc.Values(X,F,DF);
1249 if (Abs(F(1)) <= SFunc.Tolerance()) {
1251 if (!SFunc.IsTangent()) {
1252 tgt = SFunc.Direction3d();
1253 if (TypeFunc == Contap_ContourPrs ||
1254 TypeFunc == Contap_DraftPrs) {
1255 vecregard.SetXYZ(SFunc.Point().XYZ()-SFunc.Eye().XYZ());
1257 vtestb = vecregard.Crossed(tgt);
1260 vtestb = gp_Vec(0.,0.,0.);
1262 if ((vtestb.Magnitude() <= gp::Resolution())||
1263 (Abs(X(1)-XInf(1)) <= toler(1)
1264 && Abs(X(2)-XInf(2)) <= toler(2)) ||
1265 (Abs(X(1)-XSup(1)) <= toler(1)
1266 && Abs(X(2)-XSup(2)) <= toler(2))) {
1267 // on est a la solution
1268 solution = Standard_True;
1271 else if (vtestb.Dot(vecref) < 0.) {
1278 else { // on n est pas sur une solution
1279 cout << "Echec recherche internal points" << endl;
1280 solution = Standard_True;
1281 ok = Standard_False;
1287 Standard_Boolean newpoint = Standard_False;
1288 Line.Point(indexinf).ParametersOnS2(U,V);
1289 gp_Vec2d vinf(X(1)-U,X(2)-V);
1290 if (Abs(vinf.X()) <= toler(1) && Abs(vinf.Y()) <= toler(2)) {
1294 for (index = indexinf+1; index <= indexsup; index++) {
1295 Line.Point(index).ParametersOnS2(U,V);
1296 gp_Vec2d vsup(X(1)-U,X(2)-V);
1297 if (Abs(vsup.X()) <= toler(1) && Abs(vsup.Y()) <= toler(2)) {
1301 else if (vinf.Dot(vsup) < 0.) {
1302 // on est entre les 2 points
1304 IntSurf_PntOn2S pt2s;
1305 pt2s.SetValue(SFunc.Point(),Standard_False,X(1),X(2));
1306 Line.LineOn2S()->InsertBefore(index,pt2s);
1308 //-- Il faut decaler les parametres des vertex situes entre
1309 //-- index et NbPnts ###################################
1310 for(Standard_Integer v=1; v<=Line.NbVertex(); v++) {
1311 Contap_Point& Vertex = Line.Vertex(v);
1312 if(Vertex.ParameterOnLine() >= index) {
1313 Vertex.SetParameter(Vertex.ParameterOnLine()+1);
1318 indexsup = indexsup+1;
1319 newpoint = Standard_True;
1330 // on est sur un point de cheminement. On regarde alors
1331 // la correspondance avec un vertex existant.
1332 newpoint = Standard_True;
1333 for (v=1; v<= Line.NbVertex(); v++) {
1334 Contap_Point& Vertex = Line.Vertex(v);
1335 if(Vertex.ParameterOnLine() == paramp) {
1336 Vertex.SetInternal();
1337 newpoint = Standard_False;
1342 if (newpoint && paramp >1. && paramp < Nbpnts) {
1343 // on doit creer un nouveau vertex.
1344 Contap_Point internalp(SFunc.Point(),X(1),X(2));
1345 internalp.SetParameter(paramp);
1346 internalp.SetInternal();
1347 Line.Add(internalp);
1350 Line.Point(indexsup).ParametersOnS2(XSup(1),XSup(2));
1353 indexinf = indexsup;
1357 toutvu = (indexsup > Nbpnts);
1362 void Contap_Contour::Perform
1363 (const Handle(Adaptor3d_TopolTool)& Domain) {
1365 done = Standard_False;
1368 Standard_Integer i,j,k,Nbvt1,Nbvt2,ivt1,ivt2;
1369 Standard_Integer NbPointRst,NbPointIns;
1370 Standard_Integer Nblines, Nbpts, indfirst, indlast;
1375 gp_Vec d1u,d1v,normale,tgtrst,tgline;
1376 Standard_Real currentparam;
1377 IntSurf_Transition TLine,TArc;
1379 Contap_Line theline;
1380 Contap_Point ptdeb,ptfin;
1381 Contap_ThePathPointOfTheSearch PStartf,PStartl;
1383 // Standard_Real TolArc = 1.e-5;
1384 Standard_Real TolArc = Precision::Confusion();
1386 const Handle(Adaptor3d_HSurface)& Surf = mySFunc.Surface();
1388 Standard_Real EpsU = Adaptor3d_HSurfaceTool::UResolution(Surf,Precision::Confusion());
1389 Standard_Real EpsV = Adaptor3d_HSurfaceTool::VResolution(Surf,Precision::Confusion());
1390 Standard_Real Preci = Min(EpsU,EpsV);
1391 // Standard_Real Fleche = 5.e-1;
1392 // Standard_Real Pas = 5.e-2;
1393 Standard_Real Fleche = 0.01;
1394 Standard_Real Pas = 0.005;
1395 // lbr: Il y avait Pas 0.2 -> Manque des Inters sur restr ; devrait faire un mini de 5 pts par lignes
1396 //-- le 23 janvier 98 0.05 -> 0.01
1399 //-- ******************************************************************************** Janvier 98
1400 Bnd_Box B1; Standard_Boolean Box1OK = Standard_True;
1402 Standard_Real Uinf = Surf->FirstUParameter();
1403 Standard_Real Vinf = Surf->FirstVParameter();
1404 Standard_Real Usup = Surf->LastUParameter();
1405 Standard_Real Vsup = Surf->LastVParameter();
1407 Standard_Boolean Uinfinfinite = Precision::IsNegativeInfinite(Uinf);
1408 Standard_Boolean Usupinfinite = Precision::IsPositiveInfinite(Usup);
1409 Standard_Boolean Vinfinfinite = Precision::IsNegativeInfinite(Vinf);
1410 Standard_Boolean Vsupinfinite = Precision::IsPositiveInfinite(Vsup);
1412 if( Uinfinfinite || Usupinfinite || Vinfinfinite || Vsupinfinite) {
1413 Box1OK = Standard_False;
1416 BndLib_AddSurface::Add(Surf->Surface(),1e-8,B1);
1418 Standard_Real x0,y0,z0,x1,y1,z1,dx,dy,dz;
1420 B1.Get(x0,y0,z0,x1,y1,z1);
1430 if(dx>10000.0) dx=10000.0;
1433 //-- ********************************************************************************
1438 //jag 940616 SFunc.Set(1.e-8); // tolerance sur la fonction
1439 mySFunc.Set(Precision::Confusion()); // tolerance sur la fonction
1441 Standard_Boolean RecheckOnRegularity = Standard_True;
1442 solrst.Perform(myAFunc,Domain,TolArc,TolArc,RecheckOnRegularity);
1444 if (!solrst.IsDone()) {
1448 NbPointRst = solrst.NbPoints();
1449 IntSurf_SequenceOfPathPoint seqpdep;
1450 TColStd_Array1OfInteger Destination(1,NbPointRst+1);
1451 Destination.Init(0);
1452 if (NbPointRst != 0) {
1453 ComputeTangency(solrst,Domain,mySFunc,seqpdep,Destination);
1456 //jag 940616 solins.Perform(SFunc,Surf,Domain,1.e-6); // 1.e-6 : tolerance dans l espace.
1457 solins.Perform(mySFunc,Surf,Domain,Precision::Confusion());
1459 NbPointIns = solins.NbPoints();
1460 IntSurf_SequenceOfInteriorPoint seqpins;
1462 if (NbPointIns != 0) {
1463 Standard_Boolean bKeepAllPoints = Standard_False;
1465 if(solrst.NbSegments() <= 0) {
1466 if(mySFunc.FunctionType() == Contap_ContourStd) {
1467 const Handle(Adaptor3d_HSurface)& Surf = mySFunc.Surface();
1468 if(Adaptor3d_HSurfaceTool::GetType(Surf) == GeomAbs_Torus) {
1469 gp_Torus aTor = Adaptor3d_HSurfaceTool::Torus(Surf);
1470 gp_Dir aTorDir = aTor.Axis().Direction();
1471 gp_Dir aProjDir = mySFunc.Direction();
1473 if(aTorDir.Dot(aProjDir) < Precision::Confusion()) {
1474 bKeepAllPoints = Standard_True;
1480 if(bKeepAllPoints) {
1481 Standard_Integer Nbp = solins.NbPoints(), indp;
1482 for (indp=1; indp <= Nbp; indp++) {
1483 const IntSurf_InteriorPoint& pti = solins.Value(indp);
1484 seqpins.Append(pti);
1489 KeepInsidePoints(solins,solrst,mySFunc,seqpins);
1493 if (seqpdep.Length() != 0 || seqpins.Length() != 0) {
1495 Contap_TheIWalking iwalk(Preci,Fleche,Pas);
1496 iwalk.Perform(seqpdep,seqpins,mySFunc ,Surf);
1497 if(!iwalk.IsDone()) {
1501 Nblines = iwalk.NbLines();
1502 for (j=1; j<=Nblines; j++) {
1503 IntSurf_TypeTrans TypeTransOnS = IntSurf_Undecided;
1504 const Handle(Contap_TheIWLineOfTheIWalking)& iwline = iwalk.Value(j);
1505 Nbpts = iwline->NbPoints();
1506 theline.SetLineOn2S(iwline->Line());
1508 // jag 941018 On calcule une seule fois la transition
1510 tgline = iwline->TangentVector(k);
1511 iwline->Line()->Value(k).ParametersOnS2(U,V);
1512 TypeTransOnS = ComputeTransitionOnLine(mySFunc,U,V,tgline);
1513 theline.SetTransitionOnS(TypeTransOnS);
1515 //---------------------------------------------------------------------
1516 //-- On ajoute a la liste des vertex les 1er et dernier points de la -
1517 //-- ligne de cheminement si ceux-ci ne sont pas presents -
1518 //---------------------------------------------------------------------
1520 if (iwline->HasFirstPoint()) {
1521 indfirst = iwline->FirstPointIndex();
1522 const IntSurf_PathPoint& PPoint = seqpdep(indfirst);
1523 Standard_Integer themult = PPoint.Multiplicity();
1524 for (i=NbPointRst; i>=1; i--) {
1525 if (Destination(i) == indfirst) {
1526 PPoint.Parameters(themult,U,V);
1527 ptdeb.SetValue(PPoint.Value(),U,V);
1528 ptdeb.SetParameter(1.0);
1530 const Contap_ThePathPointOfTheSearch& PStart = solrst.Point(i);
1531 const Handle(Adaptor2d_HCurve2d)& currentarc = PStart.Arc();
1532 currentparam = PStart.Parameter();
1533 if (!iwline->IsTangentAtBegining()) {
1535 Contap_HCurve2dTool::D1(currentarc,currentparam,pt2d,d2d);
1536 Contap_SurfProps::DerivAndNorm(Surf,pt2d.X(),pt2d.Y(),
1537 ptonsurf,d1u,d1v,normale);
1538 tgtrst = d2d.X()*d1u;
1539 tgtrst.Add(d2d.Y()*d1v);
1541 IntSurf::MakeTransition(PPoint.Direction3d(),tgtrst,normale,
1545 else {// a voir. En effet, on a cheminer. Si on est sur un point
1546 // debut, on sait qu'on rentre dans la matiere
1551 ptdeb.SetArc(currentarc,currentparam,TLine,TArc);
1553 if (!solrst.Point(i).IsNew()) {
1554 ptdeb.SetVertex(PStart.Vertex());
1562 iwline->Value(1).ParametersOnS2(U,V);
1563 ptdeb.SetValue(theline.Point(1).Value(),U,V);
1564 ptdeb.SetParameter(1.0);
1568 if (iwline->HasLastPoint()) {
1569 indlast = iwline->LastPointIndex();
1570 const IntSurf_PathPoint& PPoint = seqpdep(indlast);
1571 Standard_Integer themult = PPoint.Multiplicity();
1572 for (i=NbPointRst; i>=1; i--) {
1573 if (Destination(i) == indlast) {
1574 PPoint.Parameters(themult,U,V);
1575 ptfin.SetValue(PPoint.Value(),U,V);
1576 ptfin.SetParameter((Standard_Real)(Nbpts));
1577 const Contap_ThePathPointOfTheSearch& PStart = solrst.Point(i);
1578 const Handle(Adaptor2d_HCurve2d)& currentarc = PStart.Arc();
1579 currentparam = PStart.Parameter();
1581 if (!iwline->IsTangentAtEnd()) {
1583 Contap_HCurve2dTool::D1(currentarc,currentparam,pt2d,d2d);
1585 Contap_SurfProps::DerivAndNorm(Surf,pt2d.X(),pt2d.Y(),
1586 ptonsurf,d1u,d1v,normale);
1587 tgtrst = d2d.X()*d1u;
1588 tgtrst.Add(d2d.Y()*d1v);
1589 IntSurf::MakeTransition(PPoint.Direction3d().Reversed(),
1590 tgtrst,normale,TLine,TArc);
1597 ptfin.SetArc(currentarc,currentparam,TLine,TArc);
1599 if (!solrst.Point(i).IsNew()) {
1600 ptfin.SetVertex(PStart.Vertex());
1608 iwline->Value(Nbpts).ParametersOnS2(U,V);
1609 ptfin.SetValue(theline.Point(Nbpts).Value(),U,V);
1610 ptfin.SetParameter((Standard_Real)(Nbpts));
1614 ComputeInternalPoints(theline,mySFunc,EpsU,EpsV);
1615 LineConstructor(slin,Domain,theline,Surf); //-- lbr
1616 //-- slin.Append(theline);
1617 theline.ResetSeqOfVertex();
1621 Nblines = slin.Length();
1622 for (j=1; j<=Nblines-1; j++) {
1623 const Contap_Line& theli = slin(j);
1624 Nbvt1 = theli.NbVertex();
1625 for (ivt1=1; ivt1<=Nbvt1; ivt1++) {
1626 if (!theli.Vertex(ivt1).IsOnArc()) {
1627 const gp_Pnt& pttg1 = theli.Vertex(ivt1).Value();
1629 for (k=j+1; k<=Nblines;k++) {
1630 const Contap_Line& theli2 = slin(k);
1631 Nbvt2 = theli2.NbVertex();
1632 for (ivt2=1; ivt2<=Nbvt2; ivt2++) {
1633 if (!theli2.Vertex(ivt2).IsOnArc()) {
1634 const gp_Pnt& pttg2 = theli2.Vertex(ivt2).Value();
1636 if (pttg1.Distance(pttg2) <= TolArc) {
1637 theli.Vertex(ivt1).SetMultiple();
1638 theli2.Vertex(ivt2).SetMultiple();
1648 // jag 940620 On ajoute le traitement des restrictions solutions.
1650 if (solrst.NbSegments() !=0) {
1651 ProcessSegments(solrst,slin,TolArc,mySFunc,Domain);
1655 // Ajout crad pour depanner CMA en attendant mieux
1656 if (solrst.NbSegments() !=0) {
1658 Nblines = slin.Length();
1659 for (j=1; j<=Nblines; j++) {
1660 const Contap_Line& theli = slin(j);
1661 if (theli.TypeContour() == Contap_Walking) {
1662 Nbvt1 = theli.NbVertex();
1663 for (ivt1=1; ivt1<=Nbvt1; ivt1++) {
1664 Contap_Point& ptvt = theli.Vertex(ivt1);
1665 if (!ptvt.IsOnArc() && !ptvt.IsMultiple()) {
1666 Standard_Real Up,Vp;
1667 ptvt.Parameters(Up,Vp);
1668 gp_Pnt2d toproj(Up,Vp);
1669 Standard_Boolean projok;
1670 for (k=1; k<=Nblines;k++) {
1671 if (slin(k).TypeContour() == Contap_Restriction) {
1672 const Handle(Adaptor2d_HCurve2d)& thearc = slin(k).Arc();
1673 Standard_Real paramproj;
1675 projok = Contap_HContTool::Project(thearc,toproj,paramproj,Ptproj);
1678 Standard_Real dist = Ptproj.Distance(gp_Pnt2d(Up,Vp));
1679 if (dist <= Preci) {
1680 // Calcul de la transition
1682 Contap_HCurve2dTool::D1(thearc,paramproj,Ptproj,d2d);
1683 // Adaptor3d_HSurfaceTool::D1(Surf,Ptproj.X(),Ptproj.Y(),
1684 // ptonsurf,d1u,d1v);
1685 // normale = d1u.Crossed(d1v);
1687 Contap_SurfProps::DerivAndNorm
1688 (Surf,Ptproj.X(),Ptproj.Y(),ptonsurf,d1u,d1v,normale);
1690 tgtrst = d2d.X()*d1u;
1691 tgtrst.Add(d2d.Y()*d1v);
1692 Standard_Integer Paraml =
1693 (Standard_Integer) ptvt.ParameterOnLine();
1695 if (Paraml == theli.NbPnts()) {
1696 tgline = gp_Vec(theli.Point(Paraml-1).Value(),
1700 tgline = gp_Vec(ptvt.Value(),
1701 theli.Point(Paraml+1).Value());
1703 IntSurf::MakeTransition(tgline,tgtrst,normale,
1705 ptvt.SetArc(thearc,paramproj,TLine,TArc);
1707 ptdeb.SetValue(ptonsurf,Ptproj.X(),Ptproj.Y());
1708 ptdeb.SetParameter(paramproj);
1709 ptdeb.SetMultiple();
1714 projok = Standard_False;
1719 projok = Standard_False;
1730 done = Standard_True;
1733 static Standard_Boolean FindLine(Contap_Line& Line,
1734 const Handle(Adaptor3d_HSurface)& Surf,
1735 const gp_Pnt2d& Pt2d,
1737 Standard_Real& Paramin,
1741 // Standard_Integer i;
1744 Standard_Real para,dist;
1745 Standard_Real dismin = RealLast();
1747 Contap_SurfProps::Normale(Surf,Pt2d.X(),Pt2d.Y(),Ptref,Norm);
1749 if (Line.TypeContour() == Contap_Lin) {
1750 gp_Lin lin(Line.Line());
1751 para = ElCLib::Parameter(lin,Ptref);
1752 ElCLib::D1(para,lin,pt,tg);
1753 dist = pt.Distance(Ptref) + Abs(Norm.Dot(lin.Direction()));
1755 else { // Contap__Circle
1756 gp_Circ cir(Line.Circle());
1757 para = ElCLib::Parameter(cir,Ptref);
1758 ElCLib::D1(para,cir,pt,tg);
1759 dist = pt.Distance(Ptref)+Abs(Norm.Dot(tg/cir.Radius()));
1761 if (dist < dismin) {
1767 if (ptmin.SquareDistance(Ptref) <= Tolpetit) {
1768 return Standard_True;
1771 return Standard_False;
1776 static void PutPointsOnLine (const Contap_TheSearch& solrst,
1777 const Handle(Adaptor3d_HSurface)& Surf,
1778 Contap_TheSequenceOfLine& slin)
1781 Standard_Integer i,l;//,index;
1782 Standard_Integer NbPoints = solrst.NbPoints();
1784 Standard_Real theparam;
1786 IntSurf_Transition TLine,TArc;
1787 Standard_Boolean goon;
1793 gp_Vec vectg,normale,tgtrst;
1794 Standard_Real paramlin = 0.0;
1797 Standard_Integer nbLin = slin.Length();
1798 for(l=1;l<=nbLin;l++) {
1799 Contap_Line& Line=slin.ChangeValue(l);
1800 for (i=1; i<= NbPoints; i++) {
1802 const Contap_ThePathPointOfTheSearch& PStart = solrst.Point(i);
1803 const Handle(Adaptor2d_HCurve2d)& thearc = PStart.Arc();
1804 theparam = PStart.Parameter();
1806 Contap_HCurve2dTool::D1(thearc,theparam,pt2d,d2d);
1807 goon = FindLine(Line,Surf,pt2d,ptonsurf,paramlin,vectg,normale);
1809 Contap_Point PPoint;
1814 Adaptor3d_HSurfaceTool::D1(Surf,pt2d.X(),pt2d.Y(),bidpt,d1u,d1v);
1815 PPoint.SetValue(ptonsurf,pt2d.X(),pt2d.Y());
1816 if (normale.Magnitude() < RealEpsilon()) {
1821 // Petit test qui devrait permettre de bien traiter les pointes
1822 // des cones, et les sommets d`une sphere. Il faudrait peut-etre
1823 // rajouter une methode dans SurfProps
1825 if (Abs(d2d.Y()) <= Precision::Confusion()) {
1826 tgtrst = d1v.Crossed(normale);
1831 tgtrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
1833 IntSurf::MakeTransition(vectg,tgtrst,normale,TLine,TArc);
1836 PPoint.SetArc(thearc,theparam, TLine, TArc);
1837 PPoint.SetParameter(paramlin);
1838 if (!PStart.IsNew()) {
1839 PPoint.SetVertex(PStart.Vertex());
1848 //----------------------------------------------------------------------------------
1849 //-- Orientation des contours Apparents quand ceux-ci sont des lignes ou des cercles
1850 //-- On prend un point de la ligne ou du cercle ---> P
1851 //-- On projete ce point sur la surface P ---> u,v
1852 //-- et on evalue la transition au point u,v
1853 //----------------------------------------------------------------------------------
1855 IntSurf_TypeTrans ComputeTransitionOngpLine
1856 (Contap_SurfFunction& SFunc,
1859 const Handle(Adaptor3d_HSurface)& Surf=SFunc.Surface();
1860 GeomAbs_SurfaceType typS = Adaptor3d_HSurfaceTool::GetType(Surf);
1863 ElCLib::D1(0.0,L,P,T);
1864 Standard_Real u = 0.,v = 0.;
1866 case GeomAbs_Cylinder: {
1867 ElSLib::Parameters(Adaptor3d_HSurfaceTool::Cylinder(Surf),P,u,v);
1870 case GeomAbs_Cone: {
1871 ElSLib::Parameters(Adaptor3d_HSurfaceTool::Cone(Surf),P,u,v);
1874 case GeomAbs_Sphere: {
1875 ElSLib::Parameters(Adaptor3d_HSurfaceTool::Sphere(Surf),P,u,v);
1881 return(ComputeTransitionOnLine(SFunc,u,v,T));
1885 IntSurf_TypeTrans ComputeTransitionOngpCircle
1886 (Contap_SurfFunction& SFunc,
1889 const Handle(Adaptor3d_HSurface)& Surf=SFunc.Surface();
1890 GeomAbs_SurfaceType typS = Adaptor3d_HSurfaceTool::GetType(Surf);
1893 ElCLib::D1(0.0,C,P,T);
1894 Standard_Real u = 0.,v = 0.;
1896 case GeomAbs_Cylinder: {
1897 ElSLib::Parameters(Adaptor3d_HSurfaceTool::Cylinder(Surf),P,u,v);
1900 case GeomAbs_Cone: {
1901 ElSLib::Parameters(Adaptor3d_HSurfaceTool::Cone(Surf),P,u,v);
1904 case GeomAbs_Sphere: {
1905 ElSLib::Parameters(Adaptor3d_HSurfaceTool::Sphere(Surf),P,u,v);
1911 return(ComputeTransitionOnLine(SFunc,u,v,T));
1915 void Contap_Contour::PerformAna(const Handle(Adaptor3d_TopolTool)& Domain)
1918 done = Standard_False;
1921 Standard_Real TolArc = 1.e-5;
1923 Standard_Integer nbCont, nbPointRst, i;
1926 Contap_ContAna contana;
1927 Contap_Line theline;
1928 const Handle(Adaptor3d_HSurface)& Surf = mySFunc.Surface();
1929 Contap_TFunction TypeFunc(mySFunc.FunctionType());
1930 Standard_Boolean PerformSolRst = Standard_True;
1932 GeomAbs_SurfaceType typS = Adaptor3d_HSurfaceTool::GetType(Surf);
1937 gp_Pln pl(Adaptor3d_HSurfaceTool::Plane(Surf));
1939 case Contap_ContourStd:
1941 gp_Dir Dirpln(pl.Axis().Direction());
1942 if (Abs(mySFunc.Direction().Dot(Dirpln)) > Precision::Angular()) {
1943 // Aucun point du plan n`est solution, en particulier aucun point
1945 PerformSolRst = Standard_False;
1949 case Contap_ContourPrs:
1951 gp_Pnt Eye(mySFunc.Eye());
1952 if (pl.Distance(Eye) > Precision::Confusion()) {
1953 // Aucun point du plan n`est solution, en particulier aucun point
1955 PerformSolRst = Standard_False;
1959 case Contap_DraftStd:
1961 gp_Dir Dirpln(pl.Axis().Direction());
1962 Standard_Real Sina = Sin(mySFunc.Angle());
1963 if (Abs(mySFunc.Direction().Dot(Dirpln)+ Sina) > //voir SurfFunction
1964 Precision::Angular()) {
1966 PerformSolRst = Standard_False;
1970 case Contap_DraftPrs:
1978 case GeomAbs_Sphere:
1981 case Contap_ContourStd:
1983 contana.Perform(Adaptor3d_HSurfaceTool::Sphere(Surf),mySFunc.Direction());
1986 case Contap_ContourPrs:
1988 contana.Perform(Adaptor3d_HSurfaceTool::Sphere(Surf),mySFunc.Eye());
1991 case Contap_DraftStd:
1993 contana.Perform(Adaptor3d_HSurfaceTool::Sphere(Surf),
1994 mySFunc.Direction(),mySFunc.Angle());
1997 case Contap_DraftPrs:
2005 case GeomAbs_Cylinder:
2008 case Contap_ContourStd:
2010 contana.Perform(Adaptor3d_HSurfaceTool::Cylinder(Surf),mySFunc.Direction());
2013 case Contap_ContourPrs:
2015 contana.Perform(Adaptor3d_HSurfaceTool::Cylinder(Surf),mySFunc.Eye());
2018 case Contap_DraftStd:
2020 contana.Perform(Adaptor3d_HSurfaceTool::Cylinder(Surf),
2021 mySFunc.Direction(),mySFunc.Angle());
2024 case Contap_DraftPrs:
2035 case Contap_ContourStd:
2037 contana.Perform(Adaptor3d_HSurfaceTool::Cone(Surf),mySFunc.Direction());
2040 case Contap_ContourPrs:
2042 contana.Perform(Adaptor3d_HSurfaceTool::Cone(Surf),mySFunc.Eye());
2045 case Contap_DraftStd:
2047 contana.Perform(Adaptor3d_HSurfaceTool::Cone(Surf),
2048 mySFunc.Direction(),mySFunc.Angle());
2051 case Contap_DraftPrs:
2062 if (typS != GeomAbs_Plane) {
2064 if (!contana.IsDone()) {
2068 nbCont = contana.NbContours();
2070 if (contana.NbContours() == 0) {
2071 done = Standard_True;
2075 GeomAbs_CurveType typL = contana.TypeContour();
2076 if (typL == GeomAbs_Circle) {
2077 theline.SetValue(contana.Circle());
2078 IntSurf_TypeTrans TransCircle;
2079 TransCircle = ComputeTransitionOngpCircle(mySFunc,contana.Circle());
2080 theline.SetTransitionOnS(TransCircle);
2081 slin.Append(theline);
2083 else if (typL == GeomAbs_Line) {
2084 for (i=1; i<=nbCont; i++) {
2085 theline.SetValue(contana.Line(i));
2086 IntSurf_TypeTrans TransLine;
2087 TransLine = ComputeTransitionOngpLine(mySFunc,contana.Line(i));
2088 theline.SetTransitionOnS(TransLine);
2089 slin.Append(theline);
2094 if (typS == GeomAbs_Cone) {
2096 gp_Cone thecone(Adaptor3d_HSurfaceTool::Cone(Surf));
2097 ElSLib::Parameters(thecone,thecone.Apex(),u,v);
2098 Contap_Point vtxapex(thecone.Apex(),u,v);
2099 vtxapex.SetInternal();
2100 vtxapex.SetMultiple();
2101 for (i=1; i<=nbCont i++) {
2102 slin.ChangeValue(i).Add(vtxapex);
2111 solrst.Perform(myAFunc,Domain,TolArc,TolArc);
2112 if (!solrst.IsDone()) {
2115 nbPointRst = solrst.NbPoints();
2117 if (nbPointRst != 0) {
2118 PutPointsOnLine(solrst,Surf,slin);
2121 if (solrst.NbSegments() !=0) {
2122 ProcessSegments(solrst,slin,TolArc,mySFunc,Domain);
2127 //Standard_Boolean oneremov;
2128 Standard_Integer nblinto = slin.Length();
2129 TColStd_SequenceOfInteger SeqToDestroy;
2131 //-- cout<<" Construct Contour_3 nblin = "<<nblinto<<endl;
2132 for(i=1; i<= nblinto ; i++) {
2133 //-- cout<<" nbvtx : "<<slin.Value(i).NbVertex()<<endl;
2134 //--if(slin.Value(i).NbVertex() > 1) {
2135 if(slin.Value(i).TypeContour() != Contap_Restriction) {
2136 LineConstructor(slin,Domain,slin.ChangeValue(i),Surf);
2137 SeqToDestroy.Append(i);
2141 for(i=SeqToDestroy.Length(); i>=1; i--) {
2142 slin.Remove(SeqToDestroy.Value(i));
2146 done = Standard_True;