1 // Created on: 1995-02-07
2 // Created by: Jacques GOUSSARD
3 // Copyright (c) 1995-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.
19 #include <Adaptor2d_Curve2d.hxx>
20 #include <Adaptor3d_TopolTool.hxx>
22 #include <GeomAbs_SurfaceType.hxx>
23 #include <GeomAdaptor_Surface.hxx>
24 #include <GeomInt.hxx>
25 #include <GeomInt_LineConstructor.hxx>
26 #include <GeomInt_LineTool.hxx>
27 #include <GeomInt_ParameterAndOrientation.hxx>
28 #include <GeomInt_SequenceOfParameterAndOrientation.hxx>
29 #include <gp_Pnt2d.hxx>
30 #include <IntPatch_ALine.hxx>
31 #include <IntPatch_GLine.hxx>
32 #include <IntPatch_Line.hxx>
33 #include <IntPatch_Point.hxx>
34 #include <IntPatch_WLine.hxx>
35 #include <IntSurf_PntOn2S.hxx>
36 #include <IntSurf_Quadric.hxx>
37 #include <IntSurf_Transition.hxx>
38 #include <Precision.hxx>
39 #include <Standard_ConstructionError.hxx>
40 #include <Standard_OutOfRange.hxx>
41 #include <StdFail_NotDone.hxx>
42 #include <TColStd_IndexedMapOfInteger.hxx>
43 #include <TopAbs_Orientation.hxx>
45 static const Standard_Real TwoPI = M_PI + M_PI;
47 //=======================================================================
48 //class : GeomInt_Vertex
49 //purpose : This class has been created in order to provide possibility
50 // to sort IntPatch_Points by their parameter on line.
51 //=======================================================================
59 //! Initializes this class by IntPatch_Point
60 void SetVertex(const IntPatch_Point& theOther)
63 const Standard_Real aNewParam = ElCLib::InPeriod(theOther.ParameterOnLine(), 0.0, TwoPI);
64 SetParameter(aNewParam);
67 //! Sets Parameter on Line
68 void SetParameter(const Standard_Real theParam)
70 myVertex.SetParameter(theParam);
73 //! Returns IntPatch_Point
74 const IntPatch_Point& Getvertex() const
80 Standard_Boolean operator < (const GeomInt_Vertex& theOther) const
82 return myVertex.ParameterOnLine() < theOther.myVertex.ParameterOnLine();
86 IntPatch_Point myVertex;
90 static void Parameters(const Handle(GeomAdaptor_Surface)& myHS1,
95 static void Parameters(const Handle(GeomAdaptor_Surface)& myHS1,
96 const Handle(GeomAdaptor_Surface)& myHS2,
103 static void GLinePoint(const IntPatch_IType typl,
104 const Handle(IntPatch_GLine)& GLine,
105 const Standard_Real aT,
108 static void AdjustPeriodic(const Handle(GeomAdaptor_Surface)& myHS1,
109 const Handle(GeomAdaptor_Surface)& myHS2,
116 Standard_Boolean RejectMicroCircle(const Handle(IntPatch_GLine)& aGLine,
117 const IntPatch_IType aType,
118 const Standard_Real aTol3D);
120 static void RejectDuplicates(NCollection_Array1<GeomInt_Vertex>& theVtxArr);
122 //=======================================================================
125 //=======================================================================
126 void GeomInt_LineConstructor::Perform(const Handle(IntPatch_Line)& L)
128 Standard_Integer i,nbvtx;
129 Standard_Real firstp,lastp;
130 const Standard_Real Tol = Precision::PConfusion() * 35.0;
132 const IntPatch_IType typl = L->ArcType();
133 if(typl == IntPatch_Analytic) {
134 Standard_Real u1,v1,u2,v2;
135 Handle(IntPatch_ALine) ALine (Handle(IntPatch_ALine)::DownCast (L));
137 nbvtx = GeomInt_LineTool::NbVertex(L);
138 for(i=1;i<nbvtx;i++) {
139 firstp = GeomInt_LineTool::Vertex(L,i).ParameterOnLine();
140 lastp = GeomInt_LineTool::Vertex(L,i+1).ParameterOnLine();
142 const Standard_Real pmid = (firstp+lastp)*0.5;
143 const gp_Pnt Pmid = ALine->Value(pmid);
144 Parameters(myHS1,myHS2,Pmid,u1,v1,u2,v2);
145 AdjustPeriodic(myHS1, myHS2, u1, v1, u2, v2);
146 const TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol);
147 if(in1 != TopAbs_OUT) {
148 const TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2,v2),Tol);
149 if(in2 != TopAbs_OUT) {
156 done = Standard_True;
158 } // if(typl == IntPatch_Analytic) {
159 else if(typl == IntPatch_Walking) {
160 Standard_Real u1,v1,u2,v2;
161 Handle(IntPatch_WLine) WLine (Handle(IntPatch_WLine)::DownCast (L));
163 nbvtx = GeomInt_LineTool::NbVertex(L);
164 for(i=1;i<nbvtx;i++) {
165 firstp = GeomInt_LineTool::Vertex(L,i).ParameterOnLine();
166 lastp = GeomInt_LineTool::Vertex(L,i+1).ParameterOnLine();
169 if (lastp != firstp + 1)
171 const Standard_Integer pmid = (Standard_Integer) ((firstp + lastp) / 2);
172 const IntSurf_PntOn2S& Pmid = WLine->Point(pmid);
173 Pmid.Parameters(u1,v1,u2,v2);
174 AdjustPeriodic(myHS1, myHS2, u1, v1, u2, v2);
175 const TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1, v1), Tol);
176 if (in1 != TopAbs_OUT)
178 const TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2, v2), Tol);
179 if (in2 != TopAbs_OUT)
188 if (WLine->GetCreatingWay() == IntPatch_WLine::IntPatch_WLImpPrm)
191 //Implicit-Parametric intersector does not respect domain of
192 //the quadric surface (it takes into account the domain of the
193 //parametric surface only). It means that we cannot warrant that
194 //we have a point exactly in the quadric boundary.
195 //E.g. in the test cases "bugs modalg_5 bug25697_2",
196 //"bugs modalg_5 bug23948", "boolean bopfuse_complex G9",
197 //"boolean bopcommon_complex H7", "boolean bopcut_complex I7" etc.
198 //the WLine contains 2 points and one is out of the quadric's domain.
199 //In order to process these cases correctly, we classify a middle
200 //(between these two) point (obtained by interpolation).
202 //Other types of intersector take into account the domains of both surfaces.
203 //So, they require to reject all "outboundaried" parts of WLine. As result,
204 //more strict check (all two points of WLine are checksed) is
205 //applied in this case.
207 Standard_Real aU21, aV21, aU22, aV22;
208 const IntSurf_PntOn2S& aPfirst = WLine->Point((Standard_Integer) (firstp));
209 const IntSurf_PntOn2S& aPlast = WLine->Point((Standard_Integer) (lastp));
210 aPfirst.Parameters(u1, v1, u2, v2);
211 AdjustPeriodic(myHS1, myHS2, u1, v1, u2, v2);
212 aPlast.Parameters(aU21, aV21, aU22, aV22);
213 AdjustPeriodic(myHS1, myHS2, aU21, aV21, aU22, aV22);
215 u1 = 0.5*(u1 + aU21);
216 v1 = 0.5*(v1 + aV21);
217 u2 = 0.5*(u2 + aU22);
218 v2 = 0.5*(v2 + aV22);
220 const TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1, v1), Tol);
221 if (in1 != TopAbs_OUT)
223 const TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2, v2), Tol);
224 if (in2 != TopAbs_OUT)
233 const IntSurf_PntOn2S& Pfirst = WLine->Point((Standard_Integer) (firstp));
234 Pfirst.Parameters(u1, v1, u2, v2);
235 AdjustPeriodic(myHS1, myHS2, u1, v1, u2, v2);
236 TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1, v1), Tol);
237 if (in1 != TopAbs_OUT)
239 TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2, v2), Tol);
240 if (in2 != TopAbs_OUT)
242 const IntSurf_PntOn2S& Plast = WLine->Point((Standard_Integer) (lastp));
243 Plast.Parameters(u1, v1, u2, v2);
244 AdjustPeriodic(myHS1, myHS2, u1, v1, u2, v2);
245 in1 = myDom1->Classify(gp_Pnt2d(u1, v1), Tol);
246 if (in1 != TopAbs_OUT)
248 in2 = myDom2->Classify(gp_Pnt2d(u2, v2), Tol);
249 if (in2 != TopAbs_OUT)
262 // The One resulting curve consists of 7 segments that are
263 // connected between each other.
264 // The aim of the block is to reject these segments and have
265 // one segment instead of 7.
266 // The other reason to do that is value of TolReached3D=49.
267 // Why -? It is not known yet.
270 Standard_Integer aNbParts;
272 aNbParts = seqp.Length()/2;
274 Standard_Boolean bCond;
275 GeomAbs_SurfaceType aST1, aST2;
276 aST1 = myHS1->GetType();
277 aST2 = myHS2->GetType();
279 bCond=Standard_False;
280 if (aST1==GeomAbs_Plane) {
281 if (aST2==GeomAbs_SurfaceOfExtrusion ||
282 aST2==GeomAbs_SurfaceOfRevolution) {//+zft
286 else if (aST2==GeomAbs_Plane) {
287 if (aST1==GeomAbs_SurfaceOfExtrusion ||
288 aST1==GeomAbs_SurfaceOfRevolution) {//+zft
294 Standard_Integer aNb, anIndex, aNbTmp, jx;
295 TColStd_IndexedMapOfInteger aMap;
296 TColStd_SequenceOfReal aSeqTmp;
299 for(i=1; i<=aNb; ++i) {
301 anIndex=(Standard_Integer)lastp;
302 if (!aMap.Contains(anIndex)){
304 aSeqTmp.Append(lastp);
307 aNbTmp=aSeqTmp.Length();
308 aSeqTmp.Remove(aNbTmp);
314 aNb=aSeqTmp.Length()/2;
315 for(i=1; i<=aNb;++i) {
317 firstp=aSeqTmp(jx-1);
324 done = Standard_True;
326 }// else if(typl == IntPatch_Walking) {
328 //-----------------------------------------------------------
329 else if (typl != IntPatch_Restriction) {
332 Handle(IntPatch_GLine) GLine (Handle(IntPatch_GLine)::DownCast (L));
334 if(typl == IntPatch_Circle || typl == IntPatch_Ellipse) {
339 //----------------------------
340 Standard_Boolean intrvtested;
341 Standard_Real u1,v1,u2,v2;
343 nbvtx = GeomInt_LineTool::NbVertex(L);
344 intrvtested = Standard_False;
345 for(i=1; i<nbvtx; ++i) {
346 firstp = GeomInt_LineTool::Vertex(L,i).ParameterOnLine();
347 lastp = GeomInt_LineTool::Vertex(L,i+1).ParameterOnLine();
348 if(Abs(firstp-lastp)>Precision::PConfusion()) {
349 intrvtested = Standard_True;
350 const Standard_Real pmid = (firstp+lastp)*0.5;
352 GLinePoint(typl, GLine, pmid, Pmid);
354 Parameters(myHS1,myHS2,Pmid,u1,v1,u2,v2);
355 AdjustPeriodic(myHS1, myHS2, u1, v1, u2, v2);
356 const TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol);
357 if(in1 != TopAbs_OUT) {
358 const TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2,v2),Tol);
359 if(in2 != TopAbs_OUT) {
368 // Keep a priori. A point 2d on each
369 // surface is required to make the decision. Will be done in the caller
370 seqp.Append(GeomInt_LineTool::FirstParameter(L));
371 seqp.Append(GeomInt_LineTool::LastParameter(L));
376 } // else if (typl != IntPatch_Restriction) {
378 done = Standard_False;
380 nbvtx = GeomInt_LineTool::NbVertex(L);
381 if (nbvtx == 0) { // Keep a priori. Point 2d is required on each
382 // surface to make the decision. Will be done in the caller
383 seqp.Append(GeomInt_LineTool::FirstParameter(L));
384 seqp.Append(GeomInt_LineTool::LastParameter(L));
385 done = Standard_True;
389 GeomInt_SequenceOfParameterAndOrientation seqpss;
390 TopAbs_Orientation or1=TopAbs_FORWARD,or2=TopAbs_FORWARD;
392 for (i=1; i<=nbvtx; i++) {
393 const IntPatch_Point& thevtx = GeomInt_LineTool::Vertex(L,i);
394 const Standard_Real prm = thevtx.ParameterOnLine();
395 if (thevtx.IsOnDomS1()) {
396 switch (thevtx.TransitionLineArc1().TransitionType()) {
397 case IntSurf_In: or1 = TopAbs_FORWARD; break;
398 case IntSurf_Out: or1 = TopAbs_REVERSED; break;
399 case IntSurf_Touch: or1 = TopAbs_INTERNAL; break;
400 case IntSurf_Undecided: or1 = TopAbs_INTERNAL; break;
404 or1 = TopAbs_INTERNAL;
407 if (thevtx.IsOnDomS2()) {
408 switch (thevtx.TransitionLineArc2().TransitionType()) {
409 case IntSurf_In: or2 = TopAbs_FORWARD; break;
410 case IntSurf_Out: or2 = TopAbs_REVERSED; break;
411 case IntSurf_Touch: or2 = TopAbs_INTERNAL; break;
412 case IntSurf_Undecided: or2 = TopAbs_INTERNAL; break;
416 or2 = TopAbs_INTERNAL;
419 const Standard_Integer nbinserted = seqpss.Length();
420 Standard_Boolean inserted = Standard_False;
421 for (Standard_Integer j=1; j<=nbinserted;j++) {
422 if (Abs(prm-seqpss(j).Parameter()) <= Tol) {
424 GeomInt_ParameterAndOrientation& valj = seqpss.ChangeValue(j);
425 if (or1 != TopAbs_INTERNAL) {
426 if (valj.Orientation1() != TopAbs_INTERNAL) {
427 if (or1 != valj.Orientation1()) {
428 valj.SetOrientation1(TopAbs_INTERNAL);
432 valj.SetOrientation1(or1);
436 if (or2 != TopAbs_INTERNAL) {
437 if (valj.Orientation2() != TopAbs_INTERNAL) {
438 if (or2 != valj.Orientation2()) {
439 valj.SetOrientation2(TopAbs_INTERNAL);
443 valj.SetOrientation2(or2);
446 inserted = Standard_True;
450 if (prm < seqpss(j).Parameter()-Tol ) {
451 // insert before position j
452 seqpss.InsertBefore(j,GeomInt_ParameterAndOrientation(prm,or1,or2));
453 inserted = Standard_True;
459 seqpss.Append(GeomInt_ParameterAndOrientation(prm,or1,or2));
463 // determine the state at the beginning of line
464 Standard_Boolean trim = Standard_False;
465 Standard_Boolean dansS1 = Standard_False;
466 Standard_Boolean dansS2 = Standard_False;
468 nbvtx = seqpss.Length();
469 for (i=1; i<= nbvtx; i++) {
470 or1 = seqpss(i).Orientation1();
471 if (or1 != TopAbs_INTERNAL) {
472 trim = Standard_True;
473 dansS1 = (or1 != TopAbs_FORWARD);
480 for (i=1; i<=GeomInt_LineTool::NbVertex(L); i++ ) {
481 if (!GeomInt_LineTool::Vertex(L,i).IsOnDomS1() ) {
482 GeomInt_LineTool::Vertex(L,i).ParametersOnS1(U,V);
484 if (myDom1->Classify(PPCC,Tol) == TopAbs_OUT) {
485 done = Standard_True;
491 dansS1 = Standard_True; // Keep in doubt
494 for (i=1; i<= nbvtx; i++) {
495 or2 = seqpss(i).Orientation2();
496 if (or2 != TopAbs_INTERNAL) {
497 trim = Standard_True;
498 dansS2 = (or2 != TopAbs_FORWARD);
505 for (i=1; i<=GeomInt_LineTool::NbVertex(L); i++ ) {
506 if (!GeomInt_LineTool::Vertex(L,i).IsOnDomS2() ) {
507 GeomInt_LineTool::Vertex(L,i).ParametersOnS2(U,V);
508 if (myDom2->Classify(gp_Pnt2d(U,V),Tol) == TopAbs_OUT) {
509 done = Standard_True;
515 dansS2 = Standard_True; // Keep in doubt
518 if (!trim) { // necessarily dansS1 == dansS2 == Standard_True
519 seqp.Append(GeomInt_LineTool::FirstParameter(L));
520 seqp.Append(GeomInt_LineTool::LastParameter(L));
521 done = Standard_True;
525 // sequence seqpss is peeled to create valid ends
526 // and store them in seqp(2*i+1) and seqp(2*i+2)
527 Standard_Real thefirst = GeomInt_LineTool::FirstParameter(L);
528 Standard_Real thelast = GeomInt_LineTool::LastParameter(L);
531 for (i=1; i<=nbvtx; i++) {
532 or1 = seqpss(i).Orientation1();
533 or2 = seqpss(i).Orientation2();
534 if (dansS1 && dansS2) {
535 if (or1 == TopAbs_REVERSED){
536 dansS1 = Standard_False;
539 if (or2 == TopAbs_REVERSED){
540 dansS2 = Standard_False;
542 if (!dansS1 || !dansS2) {
543 lastp = seqpss(i).Parameter();
544 Standard_Real stofirst = Max(firstp, thefirst);
545 Standard_Real stolast = Min(lastp, thelast) ;
547 if (stolast > stofirst) {
548 seqp.Append(stofirst);
549 seqp.Append(stolast);
551 if (lastp > thelast) {
558 if (or1 == TopAbs_REVERSED) {
559 dansS1 = Standard_False;
563 if (or1 == TopAbs_FORWARD){
564 dansS1 = Standard_True;
568 if (or2 == TopAbs_REVERSED) {
569 dansS2 = Standard_False;
573 if (or2 == TopAbs_FORWARD){
574 dansS2 = Standard_True;
577 if (dansS1 && dansS2){
578 firstp = seqpss(i).Parameter();
584 if (dansS1 && dansS2) {
586 firstp = Max(firstp,thefirst);
587 if (lastp > firstp) {
592 done = Standard_True;
595 //=======================================================================
596 //function : TreatCircle
598 //=======================================================================
599 void GeomInt_LineConstructor::TreatCircle(const Handle(IntPatch_Line)& theLine,
600 const Standard_Real theTol)
602 const IntPatch_IType aType = theLine->ArcType();
603 const Handle(IntPatch_GLine) aGLine(Handle(IntPatch_GLine)::DownCast(theLine));
604 if (RejectMicroCircle(aGLine, aType, theTol))
608 //----------------------------------------
609 const Standard_Integer aNbVtx = aGLine->NbVertex();
610 NCollection_Array1<GeomInt_Vertex> aVtxArr(1, aNbVtx + 1);
611 for (Standard_Integer i = 1; i <= aNbVtx; i++)
613 aVtxArr(i).SetVertex(aGLine->Vertex(i));
616 std::sort(aVtxArr.begin(), aVtxArr.begin() + aNbVtx);
619 const Standard_Real aMinPrm = aVtxArr.First().Getvertex().ParameterOnLine() + TwoPI;
620 aVtxArr.ChangeLast().SetParameter(aMinPrm);
622 RejectDuplicates(aVtxArr);
624 std::sort(aVtxArr.begin(), aVtxArr.end());
626 Standard_Real aU1, aV1, aU2, aV2;
629 for (Standard_Integer i = aVtxArr.Lower(); i <= aVtxArr.Upper() - 1; i++)
631 const Standard_Real aT1 = aVtxArr(i).Getvertex().ParameterOnLine();
632 const Standard_Real aT2 = aVtxArr(i + 1).Getvertex().ParameterOnLine();
634 if (aT2 == RealLast())
637 const Standard_Real aTmid = (aT1 + aT2)*0.5;
638 GLinePoint(aType, aGLine, aTmid, aPmid);
640 Parameters(myHS1, myHS2, aPmid, aU1, aV1, aU2, aV2);
641 AdjustPeriodic(myHS1, myHS2, aU1, aV1, aU2, aV2);
643 aP2D.SetCoord(aU1, aV1);
644 TopAbs_State aState = myDom1->Classify(aP2D, theTol);
645 if (aState != TopAbs_OUT)
647 aP2D.SetCoord(aU2, aV2);
648 aState = myDom2->Classify(aP2D, theTol);
649 if (aState != TopAbs_OUT)
658 //=======================================================================
659 //function : AdjustPeriodic
661 //=======================================================================
662 void AdjustPeriodic(const Handle(GeomAdaptor_Surface)& myHS1,
663 const Handle(GeomAdaptor_Surface)& myHS2,
669 Standard_Boolean myHS1IsUPeriodic, myHS1IsVPeriodic;
670 const GeomAbs_SurfaceType typs1 = myHS1->GetType();
673 case GeomAbs_Cylinder:
677 myHS1IsUPeriodic = Standard_True;
678 myHS1IsVPeriodic = Standard_False;
683 myHS1IsUPeriodic = myHS1IsVPeriodic = Standard_True;
688 //-- Case of periodic biparameters is processed upstream
689 myHS1IsUPeriodic = myHS1IsVPeriodic = Standard_False;
693 Standard_Boolean myHS2IsUPeriodic, myHS2IsVPeriodic;
694 const GeomAbs_SurfaceType typs2 = myHS2->GetType();
697 case GeomAbs_Cylinder:
701 myHS2IsUPeriodic = Standard_True;
702 myHS2IsVPeriodic = Standard_False;
707 myHS2IsUPeriodic = myHS2IsVPeriodic = Standard_True;
712 //-- Case of periodic biparameters is processed upstream
713 myHS2IsUPeriodic = myHS2IsVPeriodic = Standard_False;
717 Standard_Real du, dv;
719 if (myHS1IsUPeriodic)
721 const Standard_Real lmf = M_PI + M_PI; //-- myHS1->UPeriod();
722 const Standard_Real f = myHS1->FirstUParameter();
723 const Standard_Real l = myHS1->LastUParameter();
724 GeomInt::AdjustPeriodic(u1, f, l, lmf, u1, du);
726 if (myHS1IsVPeriodic)
728 const Standard_Real lmf = M_PI + M_PI; //-- myHS1->VPeriod();
729 const Standard_Real f = myHS1->FirstVParameter();
730 const Standard_Real l = myHS1->LastVParameter();
731 GeomInt::AdjustPeriodic(v1, f, l, lmf, v1, dv);
733 if (myHS2IsUPeriodic)
735 const Standard_Real lmf = M_PI + M_PI; //-- myHS2->UPeriod();
736 const Standard_Real f = myHS2->FirstUParameter();
737 const Standard_Real l = myHS2->LastUParameter();
738 GeomInt::AdjustPeriodic(u2, f, l, lmf, u2, du);
740 if (myHS2IsVPeriodic)
742 const Standard_Real lmf = M_PI + M_PI; //-- myHS2->VPeriod();
743 const Standard_Real f = myHS2->FirstVParameter();
744 const Standard_Real l = myHS2->LastVParameter();
745 GeomInt::AdjustPeriodic(v2, f, l, lmf, v2, dv);
749 //=======================================================================
750 //function : Parameters
752 //=======================================================================
753 void Parameters(const Handle(GeomAdaptor_Surface)& myHS1,
754 const Handle(GeomAdaptor_Surface)& myHS2,
761 Parameters(myHS1, Ptref, U1, V1);
762 Parameters(myHS2, Ptref, U2, V2);
765 //=======================================================================
766 //function : Parameter
768 //=======================================================================
769 void Parameters(const Handle(GeomAdaptor_Surface)& myHS1,
774 IntSurf_Quadric quad1;
776 switch (myHS1->GetType())
779 quad1.SetValue(myHS1->Plane());
781 case GeomAbs_Cylinder:
782 quad1.SetValue(myHS1->Cylinder());
785 quad1.SetValue(myHS1->Cone());
788 quad1.SetValue(myHS1->Sphere());
791 quad1.SetValue(myHS1->Torus());
794 throw Standard_ConstructionError("GeomInt_LineConstructor::Parameters");
796 quad1.Parameters(Ptref, U1, V1);
799 //=======================================================================
800 //function : GLinePoint
802 //=======================================================================
803 void GLinePoint(const IntPatch_IType typl,
804 const Handle(IntPatch_GLine)& GLine,
805 const Standard_Real aT,
811 aP = ElCLib::Value(aT, GLine->Line());
813 case IntPatch_Circle:
814 aP = ElCLib::Value(aT, GLine->Circle());
816 case IntPatch_Ellipse:
817 aP = ElCLib::Value(aT, GLine->Ellipse());
819 case IntPatch_Hyperbola:
820 aP = ElCLib::Value(aT, GLine->Hyperbola());
822 case IntPatch_Parabola:
823 aP = ElCLib::Value(aT, GLine->Parabola());
826 throw Standard_ConstructionError("GeomInt_LineConstructor::Parameters");
830 //=======================================================================
831 //function : RejectMicroCrcles
833 //=======================================================================
834 Standard_Boolean RejectMicroCircle(const Handle(IntPatch_GLine)& aGLine,
835 const IntPatch_IType aType,
836 const Standard_Real aTol3D)
838 Standard_Boolean bRet;
843 if (aType==IntPatch_Circle) {
844 aR=aGLine->Circle().Radius();
847 else if (aType==IntPatch_Ellipse) {
848 aR=aGLine->Ellipse().MajorRadius();
854 //=======================================================================
855 //function : RejectDuplicates
856 //purpose : Finds two coincident IntPatch_Points (if they exist) and
857 // sets Parameter-On-Line fore one such point to DBL_MAX
858 // (i.e. its use in the future is forbidden).
861 // The source array must be sorted in ascending order.
862 //=======================================================================
863 void RejectDuplicates(NCollection_Array1<GeomInt_Vertex>& theVtxArr)
865 // About the value aTolPC=1000.*Precision::PConfusion(),
866 // see IntPatch_GLine::ComputeVertexParameters(...)
868 const Standard_Real aTolPC = 1000.*Precision::PConfusion();
870 //Find duplicates in a slice of the array [LowerBound, UpperBound-1].
871 //If a duplicate has been found, the element with greater index will be rejected.
872 for (Standard_Integer i = theVtxArr.Lower(); i <= theVtxArr.Upper() - 2; i++)
874 const IntPatch_Point &aVi = theVtxArr(i).Getvertex();
875 const Standard_Real aPrmi = aVi.ParameterOnLine();
877 if (aPrmi == RealLast())
880 for (Standard_Integer j = i + 1; j <= theVtxArr.Upper() - 1; j++)
882 const IntPatch_Point &aVj = theVtxArr(j).Getvertex();
883 const Standard_Real aPrmj = aVj.ParameterOnLine();
885 if (aPrmj - aPrmi < aTolPC)
887 theVtxArr(j).SetParameter(RealLast());
896 //Find duplicates with the last element of the array.
897 //If a duplicate has been found, the found element will be rejected.
898 const Standard_Real aMaxPrm = theVtxArr.Last().Getvertex().ParameterOnLine();
899 for (Standard_Integer i = theVtxArr.Upper() - 1; i > theVtxArr.Lower(); i--)
901 const IntPatch_Point &aVi = theVtxArr(i).Getvertex();
902 const Standard_Real aPrmi = aVi.ParameterOnLine();
904 if (aPrmi == RealLast())
907 if ((aMaxPrm - aPrmi) < aTolPC)
909 theVtxArr(i).SetParameter(RealLast());