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 Standard_Integer Nbp,indp,inda;
472 Standard_Real U,V,paramproj;
473 gp_Pnt2d toproj,Ptproj;
474 Standard_Boolean projok,tokeep;
475 const Handle(Adaptor3d_HSurface)& Surf = Func.Surface();
477 Nbp = solins.NbPoints();
478 for (indp=1; indp <= Nbp; indp++) {
479 tokeep = Standard_True;
480 const IntSurf_InteriorPoint& pti = solins.Value(indp);
482 toproj = gp_Pnt2d(U,V);
483 for (inda = 1; inda <= Nba; inda++) {
484 const Handle(Adaptor2d_HCurve2d)& thearc = solrst.Segment(inda).Curve();
485 projok = Contap_HContTool::Project(thearc,toproj,paramproj,Ptproj);
487 gp_Pnt pprojete = Adaptor3d_HSurfaceTool::Value(Surf,Ptproj.X(),Ptproj.Y());
488 if (pti.Value().Distance(pprojete) <= Precision::Confusion()) {
489 tokeep = Standard_False;
501 static void ComputeTangency (const Contap_TheSearch& solrst,
502 const Handle(Adaptor3d_TopolTool)& Domain,
503 Contap_SurfFunction& Func,
504 IntSurf_SequenceOfPathPoint& seqpdep,
505 TColStd_Array1OfInteger& Destination)
508 Standard_Integer i,k;
509 Standard_Integer NbPoints = solrst.NbPoints();
510 Standard_Integer seqlength = 0;
512 Standard_Real theparam,test;
513 Standard_Boolean fairpt;
514 TopAbs_Orientation arcorien,vtxorien;
515 Standard_Boolean ispassing;
519 math_Matrix D(1, 1, 1, 2);
521 gp_Vec normale, vectg, tg3drst,v1,v2;
526 IntSurf_PathPoint PPoint;
527 const Handle(Adaptor3d_HSurface)& Surf = Func.Surface();
529 for (i=1; i<= NbPoints; i++) {
531 if (Destination(i) == 0) {
533 const Contap_ThePathPointOfTheSearch& PStart = solrst.Point(i);
534 const Handle(Adaptor2d_HCurve2d)& thearc = PStart.Arc();
535 theparam = PStart.Parameter();
536 gp_Pnt2d Ptoproj=Contap_HCurve2dTool::Value(thearc,theparam);
537 //-- lbr le 15 mai 97
538 //-- On elimine les points qui sont egalement present sur une restriction solution
539 Standard_Boolean SurUneRestrictionSolution = Standard_False;
540 for(Standard_Integer restriction=1;
541 SurUneRestrictionSolution==Standard_False && restriction<=solrst.NbSegments();
543 const Handle(Adaptor2d_HCurve2d)& thearcsol = solrst.Segment(restriction).Curve();
544 Standard_Real paramproj;
546 Standard_Boolean projok = Contap_HContTool::Project(thearcsol,Ptoproj,paramproj,pproj);
548 //gp_Pnt pprojete = Adaptor3d_HSurfaceTool::Value(Surf,Ptoproj.X(),Ptoproj.Y());
550 gp_Pnt pprojete = Adaptor3d_HSurfaceTool::Value(Surf,pproj.X(),pproj.Y());
552 if ((PStart.Value()).Distance(pprojete) <= Precision::Confusion()) {
553 SurUneRestrictionSolution = Standard_True;
557 if(SurUneRestrictionSolution == Standard_False) {
558 arcorien = Domain->Orientation(thearc);
559 ispassing = (arcorien == TopAbs_INTERNAL ||
560 arcorien == TopAbs_EXTERNAL);
562 Contap_HCurve2dTool::D1(thearc,theparam,pt2d,tg2drst);
565 PPoint.SetValue(PStart.Value(),X(1),X(2));
568 if (Func.IsTangent()) {
569 PPoint.SetTangency(Standard_True);
570 Destination(i) = seqlength+1;
571 if (!PStart.IsNew()) {
572 const Handle(Adaptor3d_HVertex)& vtx = PStart.Vertex();
573 for (k=i+1; k<=NbPoints; k++) {
574 if (Destination(k) ==0) {
575 const Contap_ThePathPointOfTheSearch& PStart2 = solrst.Point(k);
576 if (!PStart2.IsNew()) {
577 const Handle(Adaptor3d_HVertex)& vtx2 = PStart2.Vertex();
578 if (Domain->Identical(vtx,vtx2)) {
579 const Handle(Adaptor2d_HCurve2d)& thearc2 = PStart2.Arc();
580 theparam = PStart2.Parameter();
581 arcorien = Domain->Orientation(thearc2);
582 ispassing = ispassing && (arcorien == TopAbs_INTERNAL ||
583 arcorien == TopAbs_EXTERNAL);
585 pt2d = Contap_HCurve2dTool::Value(thearc2,theparam);
588 PPoint.AddUV(X(1),X(2));
589 Destination(k) = seqlength+1;
595 PPoint.SetPassing(ispassing);
596 seqpdep.Append(PPoint);
599 else { // on a un point de depart potentiel
601 vectg = Func.Direction3d();
602 dirtg = Func.Direction2d();
605 // Adaptor3d_HSurfaceTool::D1(Surf,X(1),X(2),ptbid,v1,v2);
606 Contap_SurfProps::DerivAndNorm(Surf,X(1),X(2),ptbid,v1,v2,normale);
607 tg3drst = tg2drst.X()*v1 + tg2drst.Y()*v2;
608 // normale = v1.Crossed(v2);
609 if(normale.SquareMagnitude() < RealEpsilon()) {
610 //-- cout<<"\n*** Contap_ContourGen_2.gxx Normale Nulle en U:"<<X(1)<<" V:"<<X(2)<<endl;
613 test = vectg.Dot(normale.Crossed(tg3drst));
615 if (PStart.IsNew()) {
616 Standard_Real tbis = vectg.Normalized().Dot(tg3drst.Normalized());
617 if (Abs(tbis) < 1.-tole) {
619 if ((test < 0. && arcorien == TopAbs_FORWARD) ||
620 (test > 0. && arcorien == TopAbs_REVERSED)) {
624 PPoint.SetDirections(vectg,dirtg);
626 else { // on garde le point comme point d`arret (tangent)
627 PPoint.SetTangency(Standard_True);
629 PPoint.SetPassing(ispassing);
630 Destination(i) = seqlength+1;
631 seqpdep.Append(PPoint);
634 else { // traiter la transition complexe
635 gp_Dir bidnorm(1.,1.,1.);
637 Standard_Boolean tobeverified = Standard_False;
638 TopAbs_Orientation LocTrans;
639 TopTrans_CurveTransition comptrans;
640 comptrans.Reset(vectg,bidnorm,0.);
641 if (arcorien != TopAbs_INTERNAL &&
642 arcorien != TopAbs_EXTERNAL) {
644 const Handle(Adaptor3d_HVertex)& vtx = PStart.Vertex();
645 vtxorien = Domain->Orientation(vtx);
646 test = test/(vectg.Magnitude());
647 test = test/((normale.Crossed(tg3drst)).Magnitude());
649 if (Abs(test) <= tole) {
650 tobeverified = Standard_True;
651 LocTrans = TopAbs_EXTERNAL; // et pourquoi pas INTERNAL
654 if ((test > 0. && arcorien == TopAbs_FORWARD) ||
655 (test < 0. && arcorien == TopAbs_REVERSED)){
656 LocTrans = TopAbs_FORWARD;
659 LocTrans = TopAbs_REVERSED;
661 if (arcorien == TopAbs_REVERSED) {tg3drst.Reverse();} // pas deja fait ???
664 comptrans.Compare(tole,tg3drst,bidnorm,0.,LocTrans,vtxorien);
666 Destination(i) = seqlength+1;
667 for (k= i+1; k<=NbPoints; k++) {
668 if (Destination(k) == 0) {
669 const Contap_ThePathPointOfTheSearch& PStart2 = solrst.Point(k);
670 if (!PStart2.IsNew()) {
671 const Handle(Adaptor3d_HVertex)& vtx2 = PStart2.Vertex();
672 if (Domain->Identical(PStart.Vertex(),vtx2)) {
673 const Handle(Adaptor2d_HCurve2d)& thearc2 = PStart2.Arc();
674 theparam = PStart2.Parameter();
675 arcorien = Domain->Orientation(thearc2);
677 Contap_HCurve2dTool::D1(thearc2,theparam,pt2d,tg2drst);
680 PPoint.AddUV(X(1),X(2));
682 if (arcorien != TopAbs_INTERNAL &&
683 arcorien != TopAbs_EXTERNAL) {
684 ispassing = Standard_False;
685 tg3drst = tg2drst.X()*v1 + tg2drst.Y()*v2;
686 test = vectg.Dot(normale.Crossed(tg3drst));
687 test = test/(vectg.Magnitude());
688 test = test /((normale.Crossed(tg3drst)).Magnitude());
690 vtxorien = Domain->Orientation(vtx2);
691 if (Abs(test) <= tole) {
692 tobeverified = Standard_True;
693 LocTrans = TopAbs_EXTERNAL; // et pourquoi pas INTERNAL
696 if ((test > 0. && arcorien == TopAbs_FORWARD) ||
697 (test < 0. && arcorien == TopAbs_REVERSED)){
698 LocTrans = TopAbs_FORWARD;
701 LocTrans = TopAbs_REVERSED;
703 if (arcorien == TopAbs_REVERSED) {tg3drst.Reverse();} //deja fait????
706 comptrans.Compare(tole,tg3drst,bidnorm,0.,LocTrans,vtxorien);
708 Destination(k) = seqlength+1;
713 fairpt = Standard_True;
715 TopAbs_State Before = comptrans.StateBefore();
716 TopAbs_State After = comptrans.StateAfter();
717 if ((Before == TopAbs_UNKNOWN)||(After == TopAbs_UNKNOWN)) {
718 fairpt = Standard_False;
720 else if (Before == TopAbs_IN) {
721 if (After == TopAbs_IN) {
722 ispassing = Standard_True;
730 if (After !=TopAbs_IN) {
731 fairpt = Standard_False;
736 // evite de partir le long d une restriction solution
738 if (fairpt && tobeverified) {
739 for (k=i; k <=NbPoints ; k++) {
740 if (Destination(k)==seqlength + 1) {
741 theparam = solrst.Point(k).Parameter();
742 const Handle(Adaptor2d_HCurve2d)& thearc2 = solrst.Point(k).Arc();
743 arcorien = Domain->Orientation(thearc2);
745 if (arcorien == TopAbs_FORWARD ||
746 arcorien == TopAbs_REVERSED) {
747 Contap_HCurve2dTool::D1(thearc2,theparam,pt2d,tg2drst);
748 tg3drst = tg2drst.X()*v1 + tg2drst.Y()*v2;
749 vtxorien = Domain->Orientation(solrst.Point(k).Vertex());
750 if ((arcorien == TopAbs_FORWARD &&
751 vtxorien == TopAbs_REVERSED) ||
752 (arcorien == TopAbs_REVERSED &&
753 vtxorien == TopAbs_FORWARD)) {
756 test = vectg.Normalized().Dot(tg3drst.Normalized());
757 if (test >= 1. - tole) {
758 fairpt = Standard_False;
767 PPoint.SetDirections(vectg,dirtg);
768 PPoint.SetPassing(ispassing);
769 seqpdep.Append(PPoint);
772 else { // il faut remettre en "ordre" si on ne garde pas le point.
773 for (k=i; k <=NbPoints ; k++) {
774 if (Destination(k)==seqlength + 1) {
775 Destination(k) = -Destination(k);
788 IntSurf_TypeTrans ComputeTransitionOnLine(Contap_SurfFunction& SFunc,
789 const Standard_Real u,
790 const Standard_Real v,
791 const gp_Vec& tgline)
797 Adaptor3d_HSurfaceTool::D1(SFunc.Surface(),u,v,pntbid,d1u,d1v);
799 //------------------------------------------------------
800 //-- Calcul de la tangente dans l espace uv ---
801 //------------------------------------------------------
803 Standard_Real det,d1uT,d1vT,normu2,normv2,d1ud1v,alpha,beta;
804 d1uT = d1u.Dot(tgline);
805 d1vT = d1v.Dot(tgline);
806 normu2 = d1u.Dot(d1u);
807 normv2 = d1v.Dot(d1v);
808 d1ud1v = d1u.Dot(d1v);
809 det = normu2 * normv2 - d1ud1v * d1ud1v;
810 if(det<RealEpsilon()) {
811 //-- On ne doit pas passer ici !!
812 //-- cout<<" Probleme !!!"<<endl ;
813 return IntSurf_Undecided;
816 alpha = (d1uT * normv2 - d1vT * d1ud1v)/det;
817 beta = (normu2 * d1vT - d1ud1v * d1uT)/det;
818 //-----------------------------------------------------
819 //-- Calcul du Gradient de la fonction Utilisee --
820 //-- pour le contour apparent --
821 //-----------------------------------------------------
825 math_Matrix Df(1,1,1,2);
828 SFunc.Derivatives(X,Df);
832 //-----------------------------------------------------
833 //-- On calcule si la fonction --
834 //-- F(.) = Normale . Dir_Regard --
835 //-- Croit Losrque l on se deplace sur la Gauche --
836 //-- de la direction de deplacement sur la ligne. --
837 //-----------------------------------------------------
839 det = -v1*beta + v2*alpha;
841 if(det<RealEpsilon()) { // revoir le test jag 940620
842 return IntSurf_Undecided;
851 void ProcessSegments (const Contap_TheSearch& solrst,
852 Contap_TheSequenceOfLine& slin,
853 const Standard_Real TolArc,
854 Contap_SurfFunction& SFunc,
855 const Handle(Adaptor3d_TopolTool)& Domain)
858 Standard_Integer i,j,k;
859 Standard_Integer nbedg = solrst.NbSegments();
860 Standard_Integer Nblines,Nbpts;
862 Handle(Adaptor2d_HCurve2d) arcRef;
865 Contap_ThePathPointOfTheSearch PStartf,PStartl;
867 Standard_Boolean dofirst,dolast,procf,procl;
868 Standard_Real paramf =0.,paraml =0.,U;
871 gp_Vec tgline;//,norm1,norm2;
879 for (i = 1; i <= nbedg; i++) {
881 const Contap_TheSegmentOfTheSearch& thesegsol = solrst.Segment(i);
882 theline.SetValue(thesegsol.Curve());
884 // Traitement des points debut/fin du segment solution.
886 dofirst = Standard_False;
887 dolast = Standard_False;
888 procf = Standard_False;
889 procl = Standard_False;
891 if (thesegsol.HasFirstPoint()) {
892 dofirst = Standard_True;
893 PStartf = thesegsol.FirstPoint();
894 paramf = PStartf.Parameter();
896 if (thesegsol.HasLastPoint()) {
897 dolast = Standard_True;
898 PStartl = thesegsol.LastPoint();
899 paraml = PStartl.Parameter();
902 // determination de la transition
903 if (dofirst && dolast) {
904 U = (paramf+paraml)/2.;
916 Contap_HCurve2dTool::D1(thesegsol.Curve(),U,p2d,d2d);
917 Adaptor3d_HSurfaceTool::D1(SFunc.Surface(),p2d.X(),p2d.Y(),valpt,d1u,d1v);
918 tgline.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
919 IntSurf_TypeTrans tral =
920 ComputeTransitionOnLine(SFunc,p2d.X(),p2d.Y(),tgline);
922 theline.SetTransitionOnS(tral);
925 if (dofirst || dolast) {
926 Nblines = slin.Length();
927 for (j=1; j<=Nblines; j++) {
928 Nbpts = slin(j).NbVertex();
929 for (k=1; k<=Nbpts;k++) {
930 ptvtx = slin(j).Vertex(k);
932 if (ptvtx.Value().Distance(PStartf.Value()) <=TolArc) {
933 slin(j).Vertex(k).SetMultiple();
935 ptvtx.SetParameter(paramf);
941 if (ptvtx.Value().Distance(PStartl.Value()) <=TolArc) {
942 slin(j).Vertex(k).SetMultiple();
944 ptvtx.SetParameter(paraml);
950 // Si on a traite le pt debut et/ou fin, on ne doit pas recommencer si
951 // il (ils) correspond(ent) a un point multiple.
954 dofirst = Standard_False;
957 dolast = Standard_False;
962 // Si on n a pas trouve le point debut et./ou fin sur une des lignes
963 // d intersection, il faut quand-meme le placer sur la restriction solution
967 p2d = Contap_HCurve2dTool::Value(thesegsol.Curve(),paramf);
968 ptvtx.SetValue(PStartf.Value(),p2d.X(),p2d.Y());
969 ptvtx.SetParameter(paramf);
970 if (! PStartf.IsNew()) {
971 ptvtx.SetVertex(PStartf.Vertex());
976 p2d = Contap_HCurve2dTool::Value(thesegsol.Curve(),paraml);
977 ptvtx.SetValue(PStartl.Value(),p2d.X(),p2d.Y());
978 ptvtx.SetParameter(paraml);
979 if (! PStartl.IsNew()) {
980 ptvtx.SetVertex(PStartl.Vertex());
985 // il faut chercher le points internal sur les restrictions solutions.
986 if (thesegsol.HasFirstPoint() && thesegsol.HasLastPoint()) {
987 ComputeInternalPointsOnRstr(theline,paramf,paraml,SFunc);
989 LineConstructor(slin,Domain,theline,SFunc.Surface()); //-- lbr
990 //-- slin.Append(theline);
995 void ComputeInternalPointsOnRstr
997 const Standard_Real Paramf,
998 const Standard_Real Paraml,
999 Contap_SurfFunction& SFunc)
1001 // On recherche les points ou la tangente a la ligne de contour et
1002 // la direction sont alignees.
1003 // 1ere etape : recherche de changement de signe.
1004 // 2eme etape : localisation de la solution par dichotomie
1007 Standard_Integer indexinf,indexsup,i;
1008 gp_Vec tgt, vecref, vectest, vtestb, vecregard,d1u,d1v;
1012 Standard_Boolean found,ok = Standard_False,toutvu,solution;
1013 Standard_Real paramp = 0.,paraminf,paramsup,toler;
1015 if (Line.TypeContour() != Contap_Restriction) {
1019 const Handle(Adaptor2d_HCurve2d)& thearc = Line.Arc();
1021 const Handle(Adaptor3d_HSurface)& Surf = SFunc.Surface();
1022 Contap_TFunction TypeFunc(SFunc.FunctionType());
1024 Standard_Integer Nbpnts = Contap_HContTool::NbSamplesOnArc(thearc);
1026 vecregard = SFunc.Direction();
1027 toler = Contap_HCurve2dTool::Resolution(thearc,Precision::Confusion());
1028 found = Standard_False;
1031 paraminf = ((Nbpnts-indexinf)*Paramf + (indexinf-1)*Paraml)/(Nbpnts-1);
1032 Contap_HCurve2dTool::D1(thearc,paraminf,p2d,d2d);
1033 Adaptor3d_HSurfaceTool::D1(Surf,p2d.X(),p2d.Y(),pcour,d1u,d1v);
1034 tgt.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
1036 if (tgt.Magnitude() > gp::Resolution()) {
1037 if (TypeFunc == Contap_ContourPrs || TypeFunc==Contap_DraftPrs) {
1038 vecregard.SetXYZ(pcour.XYZ()-SFunc.Eye().XYZ());
1040 vecref = vecregard.Crossed(tgt);
1042 if (vecref.Magnitude() <= gp::Resolution()) {
1046 found = Standard_True;
1052 } while ((indexinf <= Nbpnts) && (!found));
1055 indexsup = indexinf +1;
1056 toutvu = (indexsup > Nbpnts);
1058 paramsup = ((Nbpnts-indexsup)*Paramf + (indexsup-1)*Paraml)/(Nbpnts-1);
1059 Contap_HCurve2dTool::D1(thearc,paramsup,p2d,d2d);
1060 Adaptor3d_HSurfaceTool::D1(Surf,p2d.X(),p2d.Y(),pcour,d1u,d1v);
1061 tgt.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
1063 if (tgt.Magnitude() > gp::Resolution()) {
1064 if (TypeFunc == Contap_ContourPrs || TypeFunc==Contap_DraftPrs) {
1065 vecregard.SetXYZ(pcour.XYZ()-SFunc.Eye().XYZ());
1067 vectest = vecregard.Crossed(tgt);
1070 vectest = gp_Vec(0.,0.,0.);
1072 if (vectest.Magnitude() <= gp::Resolution()) {
1073 // On cherche un vrai changement de signe
1077 if (vectest.Dot(vecref) < 0.) {
1078 // Essayer de converger
1079 // cout << "Changement de signe detecte" << endl;
1080 solution = Standard_False;
1082 paramp = (paraminf+paramsup)/2.;
1083 Contap_HCurve2dTool::D1(thearc,paramp,p2d,d2d);
1084 Adaptor3d_HSurfaceTool::D1(Surf,p2d.X(),p2d.Y(),pcour,d1u,d1v);
1085 tgt.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
1087 if (tgt.Magnitude() > gp::Resolution()) {
1088 if (TypeFunc == Contap_ContourPrs || TypeFunc==Contap_DraftPrs) {
1089 vecregard.SetXYZ(pcour.XYZ()-SFunc.Eye().XYZ());
1091 vtestb = vecregard.Crossed(tgt);
1094 vtestb = gp_Vec(0.,0.,0.);
1097 if ((vtestb.Magnitude() <= gp::Resolution())||
1098 (Abs(paramp-paraminf) <= toler) ||
1099 (Abs(paramp-paramsup) <= toler)) {
1100 // on est a la solution
1101 solution = Standard_True;
1104 else if (vtestb.Dot(vecref) < 0.) {
1114 // On verifie que le point trouve ne correspond pas a un ou des
1115 // vertex deja existant(s). On teste sur le parametre paramp.
1116 for (i=1; i<=Line.NbVertex(); i++) {
1117 Contap_Point& thevtx = Line.Vertex(i);
1118 if (Abs(thevtx.ParameterOnLine()-paramp) <= toler) {
1119 thevtx.SetInternal();
1120 ok = Standard_False; // on a correspondance
1123 if (ok) { // il faut alors rajouter le point
1124 Contap_Point internalp(pcour,p2d.X(),p2d.Y());
1125 internalp.SetParameter(paramp);
1126 internalp.SetInternal();
1127 Line.Add(internalp);
1130 paramsup = ((Nbpnts-indexsup)*Paramf + (indexsup-1)*Paraml)/(Nbpnts-1);
1133 indexinf = indexsup;
1135 paraminf = paramsup;
1137 toutvu = (indexsup > Nbpnts);
1142 void ComputeInternalPoints
1144 Contap_SurfFunction& SFunc,
1145 const Standard_Real ureso,
1146 const Standard_Real vreso)
1149 // On recherche les points ou la tangente a la ligne de contour et
1150 // la direction sont alignees.
1151 // 1ere etape : recheche de changement de signe.
1152 // 2eme etape : localisation de la solution par simili dichotomie
1155 Standard_Integer indexinf,indexsup,index;
1156 gp_Vec tgt, vecref, vectest, vtestb, vecregard;
1157 //gp_Pnt pprec,pcour;
1158 Standard_Boolean found,ok = Standard_False,toutvu,solution;
1159 Standard_Real paramp = 0.,U,V;
1161 math_Vector XInf(1,2),XSup(1,2),X(1,2),F(1,1);
1162 math_Matrix DF(1,1,1,2);
1163 math_Vector toler(1,2),infb(1,2),supb(1,2);
1165 if (Line.TypeContour() != Contap_Walking) {
1169 Standard_Integer Nbpnts = Line.NbPnts();
1170 const Handle(Adaptor3d_HSurface)& Surf = SFunc.Surface();
1171 Contap_TFunction TypeFunc(SFunc.FunctionType());
1173 toler(1) = ureso; //-- Trop long !!! Adaptor3d_HSurfaceTool::UResolution(Surf,SFunc.Tolerance());
1174 toler(2) = vreso; //---Beaucoup trop long !!! Adaptor3d_HSurfaceTool::VResolution(Surf,SFunc.Tolerance());
1175 infb(1) = Adaptor3d_HSurfaceTool::FirstUParameter(Surf);
1176 infb(2) = Adaptor3d_HSurfaceTool::FirstVParameter(Surf);
1177 supb(1) = Adaptor3d_HSurfaceTool::LastUParameter(Surf);
1178 supb(2) = Adaptor3d_HSurfaceTool::LastVParameter(Surf);
1180 math_FunctionSetRoot rsnld(SFunc,toler,30);
1183 vecregard = SFunc.Direction();
1185 found = Standard_False;
1187 Line.Point(indexinf).ParametersOnS2(XInf(1),XInf(2));
1188 SFunc.Values(XInf,F,DF);
1189 if (!SFunc.IsTangent()) {
1190 tgt = SFunc.Direction3d();
1191 if (TypeFunc == Contap_ContourPrs || TypeFunc == Contap_DraftPrs) {
1192 vecregard.SetXYZ(Line.Point(indexinf).Value().XYZ()-SFunc.Eye().XYZ());
1194 vecref = vecregard.Crossed(tgt);
1196 if (vecref.Magnitude() <= gp::Resolution()) {
1200 found = Standard_True;
1206 } while ((indexinf <= Nbpnts) && (!found));
1209 indexsup = indexinf +1;
1210 toutvu = (indexsup > Nbpnts);
1212 Line.Point(indexsup).ParametersOnS2(XSup(1),XSup(2));
1213 SFunc.Values(XSup,F,DF);
1214 if (!SFunc.IsTangent()) {
1215 tgt = SFunc.Direction3d();
1217 if (TypeFunc == Contap_ContourPrs || TypeFunc == Contap_DraftPrs) {
1218 vecregard.SetXYZ(Line.Point(indexsup).Value().XYZ()-SFunc.Eye().XYZ());
1220 vectest = vecregard.Crossed(tgt);
1223 vectest = gp_Vec(0.,0.,0.);
1225 if (vectest.Magnitude() <= gp::Resolution()) {
1226 // On cherche un vrai changement de signe
1230 if (vectest.Dot(vecref) < 0.) {
1231 // Essayer de converger
1232 // cout << "Changement de signe detecte" << endl;
1233 solution = Standard_False;
1235 X(1) = (XInf(1) + XSup(1)) /2.;
1236 X(2) = (XInf(2) + XSup(2)) /2.;
1237 rsnld.Perform(SFunc,X,infb,supb);
1239 if (!rsnld.IsDone()) {
1240 cout << "Echec recherche internal points" << endl;
1241 solution = Standard_True;
1242 ok = Standard_False;
1247 SFunc.Values(X,F,DF);
1248 if (Abs(F(1)) <= SFunc.Tolerance()) {
1250 if (!SFunc.IsTangent()) {
1251 tgt = SFunc.Direction3d();
1252 if (TypeFunc == Contap_ContourPrs ||
1253 TypeFunc == Contap_DraftPrs) {
1254 vecregard.SetXYZ(SFunc.Point().XYZ()-SFunc.Eye().XYZ());
1256 vtestb = vecregard.Crossed(tgt);
1259 vtestb = gp_Vec(0.,0.,0.);
1261 if ((vtestb.Magnitude() <= gp::Resolution())||
1262 (Abs(X(1)-XInf(1)) <= toler(1)
1263 && Abs(X(2)-XInf(2)) <= toler(2)) ||
1264 (Abs(X(1)-XSup(1)) <= toler(1)
1265 && Abs(X(2)-XSup(2)) <= toler(2))) {
1266 // on est a la solution
1267 solution = Standard_True;
1270 else if (vtestb.Dot(vecref) < 0.) {
1277 else { // on n est pas sur une solution
1278 cout << "Echec recherche internal points" << endl;
1279 solution = Standard_True;
1280 ok = Standard_False;
1286 Standard_Boolean newpoint = Standard_False;
1287 Line.Point(indexinf).ParametersOnS2(U,V);
1288 gp_Vec2d vinf(X(1)-U,X(2)-V);
1289 if (Abs(vinf.X()) <= toler(1) && Abs(vinf.Y()) <= toler(2)) {
1293 for (index = indexinf+1; index <= indexsup; index++) {
1294 Line.Point(index).ParametersOnS2(U,V);
1295 gp_Vec2d vsup(X(1)-U,X(2)-V);
1296 if (Abs(vsup.X()) <= toler(1) && Abs(vsup.Y()) <= toler(2)) {
1300 else if (vinf.Dot(vsup) < 0.) {
1301 // on est entre les 2 points
1303 IntSurf_PntOn2S pt2s;
1304 pt2s.SetValue(SFunc.Point(),Standard_False,X(1),X(2));
1305 Line.LineOn2S()->InsertBefore(index,pt2s);
1307 //-- Il faut decaler les parametres des vertex situes entre
1308 //-- index et NbPnts ###################################
1309 for(Standard_Integer v=1; v<=Line.NbVertex(); v++) {
1310 Contap_Point& Vertex = Line.Vertex(v);
1311 if(Vertex.ParameterOnLine() >= index) {
1312 Vertex.SetParameter(Vertex.ParameterOnLine()+1);
1317 indexsup = indexsup+1;
1318 newpoint = Standard_True;
1329 // on est sur un point de cheminement. On regarde alors
1330 // la correspondance avec un vertex existant.
1331 newpoint = Standard_True;
1332 for (v=1; v<= Line.NbVertex(); v++) {
1333 Contap_Point& Vertex = Line.Vertex(v);
1334 if(Vertex.ParameterOnLine() == paramp) {
1335 Vertex.SetInternal();
1336 newpoint = Standard_False;
1341 if (newpoint && paramp >1. && paramp < Nbpnts) {
1342 // on doit creer un nouveau vertex.
1343 Contap_Point internalp(SFunc.Point(),X(1),X(2));
1344 internalp.SetParameter(paramp);
1345 internalp.SetInternal();
1346 Line.Add(internalp);
1349 Line.Point(indexsup).ParametersOnS2(XSup(1),XSup(2));
1352 indexinf = indexsup;
1356 toutvu = (indexsup > Nbpnts);
1361 void Contap_Contour::Perform
1362 (const Handle(Adaptor3d_TopolTool)& Domain) {
1364 done = Standard_False;
1367 Standard_Integer i,j,k,Nbvt1,Nbvt2,ivt1,ivt2;
1368 Standard_Integer NbPointRst,NbPointIns;
1369 Standard_Integer Nblines, Nbpts, indfirst, indlast;
1374 gp_Vec d1u,d1v,normale,tgtrst,tgline;
1375 Standard_Real currentparam;
1376 IntSurf_Transition TLine,TArc;
1378 Contap_Line theline;
1379 Contap_Point ptdeb,ptfin;
1380 Contap_ThePathPointOfTheSearch PStartf,PStartl;
1382 // Standard_Real TolArc = 1.e-5;
1383 Standard_Real TolArc = Precision::Confusion();
1385 const Handle(Adaptor3d_HSurface)& Surf = mySFunc.Surface();
1387 Standard_Real EpsU = Adaptor3d_HSurfaceTool::UResolution(Surf,Precision::Confusion());
1388 Standard_Real EpsV = Adaptor3d_HSurfaceTool::VResolution(Surf,Precision::Confusion());
1389 Standard_Real Preci = Min(EpsU,EpsV);
1390 // Standard_Real Fleche = 5.e-1;
1391 // Standard_Real Pas = 5.e-2;
1392 Standard_Real Fleche = 0.01;
1393 Standard_Real Pas = 0.005;
1394 // lbr: Il y avait Pas 0.2 -> Manque des Inters sur restr ; devrait faire un mini de 5 pts par lignes
1395 //-- le 23 janvier 98 0.05 -> 0.01
1398 //-- ******************************************************************************** Janvier 98
1399 Bnd_Box B1; Standard_Boolean Box1OK = Standard_True;
1401 Standard_Real Uinf = Surf->FirstUParameter();
1402 Standard_Real Vinf = Surf->FirstVParameter();
1403 Standard_Real Usup = Surf->LastUParameter();
1404 Standard_Real Vsup = Surf->LastVParameter();
1406 Standard_Boolean Uinfinfinite = Precision::IsNegativeInfinite(Uinf);
1407 Standard_Boolean Usupinfinite = Precision::IsPositiveInfinite(Usup);
1408 Standard_Boolean Vinfinfinite = Precision::IsNegativeInfinite(Vinf);
1409 Standard_Boolean Vsupinfinite = Precision::IsPositiveInfinite(Vsup);
1411 if( Uinfinfinite || Usupinfinite || Vinfinfinite || Vsupinfinite) {
1412 Box1OK = Standard_False;
1415 BndLib_AddSurface::Add(Surf->Surface(),1e-8,B1);
1417 Standard_Real x0,y0,z0,x1,y1,z1,dx,dy,dz;
1419 B1.Get(x0,y0,z0,x1,y1,z1);
1429 if(dx>10000.0) dx=10000.0;
1432 //-- ********************************************************************************
1437 //jag 940616 SFunc.Set(1.e-8); // tolerance sur la fonction
1438 mySFunc.Set(Precision::Confusion()); // tolerance sur la fonction
1440 Standard_Boolean RecheckOnRegularity = Standard_True;
1441 solrst.Perform(myAFunc,Domain,TolArc,TolArc,RecheckOnRegularity);
1443 if (!solrst.IsDone()) {
1447 NbPointRst = solrst.NbPoints();
1448 IntSurf_SequenceOfPathPoint seqpdep;
1449 TColStd_Array1OfInteger Destination(1,NbPointRst+1);
1450 Destination.Init(0);
1451 if (NbPointRst != 0) {
1452 ComputeTangency(solrst,Domain,mySFunc,seqpdep,Destination);
1455 //jag 940616 solins.Perform(SFunc,Surf,Domain,1.e-6); // 1.e-6 : tolerance dans l espace.
1456 solins.Perform(mySFunc,Surf,Domain,Precision::Confusion());
1458 NbPointIns = solins.NbPoints();
1459 IntSurf_SequenceOfInteriorPoint seqpins;
1461 if (NbPointIns != 0) {
1462 Standard_Boolean bKeepAllPoints = Standard_False;
1464 if(solrst.NbSegments() <= 0) {
1465 if(mySFunc.FunctionType() == Contap_ContourStd) {
1466 const Handle(Adaptor3d_HSurface)& SurfToCheck = mySFunc.Surface();
1467 if(Adaptor3d_HSurfaceTool::GetType(SurfToCheck) == GeomAbs_Torus) {
1468 gp_Torus aTor = Adaptor3d_HSurfaceTool::Torus(SurfToCheck);
1469 gp_Dir aTorDir = aTor.Axis().Direction();
1470 gp_Dir aProjDir = mySFunc.Direction();
1472 if(aTorDir.Dot(aProjDir) < Precision::Confusion()) {
1473 bKeepAllPoints = Standard_True;
1479 if(bKeepAllPoints) {
1480 Standard_Integer Nbp = solins.NbPoints(), indp;
1481 for (indp=1; indp <= Nbp; indp++) {
1482 const IntSurf_InteriorPoint& pti = solins.Value(indp);
1483 seqpins.Append(pti);
1488 KeepInsidePoints(solins,solrst,mySFunc,seqpins);
1492 if (seqpdep.Length() != 0 || seqpins.Length() != 0) {
1494 Standard_Boolean theToFillHoles = Standard_True;
1495 Contap_TheIWalking iwalk(Preci,Fleche,Pas,theToFillHoles);
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;