1 // Created on: 1993-11-10
2 // Created by: Jean Yves LEBEY
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.
17 #include <TopOpeBRep_LineInter.ixx>
19 #include <TopOpeBRep.hxx>
20 #include <TopOpeBRep_VPointInter.hxx>
21 #include <TopOpeBRep_VPointInterIterator.hxx>
22 #include <TopOpeBRep_FFTransitionTool.hxx>
24 #include <IntPatch_IType.hxx>
25 #include <Geom_Line.hxx>
26 #include <Geom_Circle.hxx>
27 #include <Geom_Ellipse.hxx>
28 #include <Geom_Parabola.hxx>
29 #include <Geom_Hyperbola.hxx>
30 #include <Geom_TrimmedCurve.hxx>
31 #include <IntPatch_ALineToWLine.hxx>
32 #include <IntSurf_Quadric.hxx>
33 #include <GeomAbs_SurfaceType.hxx>
36 #include <Adaptor2d_HCurve2d.hxx>
37 #include <BRepAdaptor_Curve2d.hxx>
40 #include <Standard_ProgramError.hxx>
41 #include <Standard_NotImplemented.hxx>
44 extern Standard_Boolean TopOpeBRep_GetcontextALWLNBP(Standard_Integer&);
45 extern Standard_Boolean TopOpeBRep_GettraceCONIC();
46 extern Standard_Boolean TopOpeBRepDS_GettraceDSF();
47 extern Standard_Boolean TopOpeBRepDS_GettraceDSNC();
50 //-----------------------------------------------------------------------
51 static Handle(IntPatch_WLine) FUN_ALINETOWLINE
52 (const Handle(IntPatch_ALine)& AL,
53 const BRepAdaptor_Surface surf1,const BRepAdaptor_Surface surf2)
54 //-----------------------------------------------------------------------
56 IntSurf_Quadric Quad1,Quad2;
58 switch(surf1.GetType())
60 case GeomAbs_Plane: Quad1.SetValue(surf1.Plane()); break;
61 case GeomAbs_Cylinder: Quad1.SetValue(surf1.Cylinder()); break;
62 case GeomAbs_Sphere: Quad1.SetValue(surf1.Sphere()); break;
63 case GeomAbs_Cone: Quad1.SetValue(surf1.Cone()); break;
64 default : Standard_ProgramError::Raise
65 ("TopOpeBRep_LineInter::FUN_ALINETOWLINE"); break;
68 switch(surf2.GetType())
70 case GeomAbs_Plane: Quad2.SetValue(surf2.Plane()); break;
71 case GeomAbs_Cylinder: Quad2.SetValue(surf2.Cylinder()); break;
72 case GeomAbs_Sphere: Quad2.SetValue(surf2.Sphere()); break;
73 case GeomAbs_Cone: Quad2.SetValue(surf2.Cone()); break;
74 default : Standard_ProgramError::Raise
75 ("TopOpeBRep_LineInter::FUN_ALINETOWLINE"); break;
78 const Standard_Real deflectionmax = 0.01;
79 const Standard_Real pasUVmax = 0.05;
80 Standard_Integer nbpointsmax = 200;
82 Standard_Integer newnbp;
83 if (TopOpeBRep_GetcontextALWLNBP(newnbp)) nbpointsmax = newnbp;
86 AToL(Quad1,Quad2,deflectionmax,pasUVmax,nbpointsmax);
87 return AToL.MakeWLine(AL);
90 //=======================================================================
93 //=======================================================================
95 void TopOpeBRep_LineInter::SetLine(const Handle(IntPatch_Line)& L,
96 const BRepAdaptor_Surface& S1,
97 const BRepAdaptor_Surface& S2)
99 // load line according to its type
101 IntPatch_IType type = L->ArcType();
103 case IntPatch_Analytic : myTypeLineCurve = TopOpeBRep_ANALYTIC; break;
104 case IntPatch_Restriction : myTypeLineCurve = TopOpeBRep_RESTRICTION; break;
105 case IntPatch_Walking : myTypeLineCurve = TopOpeBRep_WALKING; break;
106 case IntPatch_Lin : myTypeLineCurve = TopOpeBRep_LINE; break;
107 case IntPatch_Circle : myTypeLineCurve = TopOpeBRep_CIRCLE; break;
108 case IntPatch_Ellipse : myTypeLineCurve = TopOpeBRep_ELLIPSE; break;
109 case IntPatch_Parabola : myTypeLineCurve = TopOpeBRep_PARABOLA; break;
110 case IntPatch_Hyperbola : myTypeLineCurve = TopOpeBRep_HYPERBOLA; break;
112 myTypeLineCurve = TopOpeBRep_OTHERTYPE;
113 SetOK(Standard_False);
118 case IntPatch_Analytic :
119 myILA = *((Handle(IntPatch_ALine)*)&L); break;
120 case IntPatch_Restriction :
121 myILR = *((Handle(IntPatch_RLine)*)&L); break;
122 case IntPatch_Walking :
123 myILW = *((Handle(IntPatch_WLine)*)&L); break;
124 default : //"geometric" line
125 myILG = *((Handle(IntPatch_GLine)*)&L); break;
128 // transform an analytic line to a walking line
129 if (myTypeLineCurve == TopOpeBRep_ANALYTIC) {
130 myILW = ::FUN_ALINETOWLINE(myILA,S1,S2);
131 myTypeLineCurve = TopOpeBRep_WALKING;
134 // number of points found on restriction(s)
135 Standard_Integer n = 0;
136 switch (myTypeLineCurve) {
137 case TopOpeBRep_ANALYTIC : n = myILA->NbVertex(); break;
138 case TopOpeBRep_RESTRICTION : n = myILR->NbVertex(); break;
139 case TopOpeBRep_WALKING : n = myILW->NbVertex(); break;
140 case TopOpeBRep_LINE : n = myILG->NbVertex(); break;
141 case TopOpeBRep_CIRCLE : n = myILG->NbVertex(); break;
142 case TopOpeBRep_ELLIPSE : n = myILG->NbVertex(); break;
143 case TopOpeBRep_PARABOLA : n = myILG->NbVertex(); break;
144 case TopOpeBRep_HYPERBOLA : n = myILG->NbVertex(); break;
146 SetOK(Standard_False);
151 // prepare VPoints from intersection points
152 myHAVP = new TopOpeBRep_HArray1OfVPointInter(0,n);
153 for (Standard_Integer i=1;i<=n;i++) {
154 TopOpeBRep_VPointInter& VP = myHAVP->ChangeValue(i);
155 switch (myTypeLineCurve) {
156 case TopOpeBRep_ANALYTIC : VP.SetPoint(myILA->Vertex(i)); break;
157 case TopOpeBRep_RESTRICTION : VP.SetPoint(myILR->Vertex(i)); break;
158 case TopOpeBRep_WALKING : VP.SetPoint(myILW->Vertex(i)); break;
159 default : VP.SetPoint(myILG->Vertex(i)); break;
165 //=======================================================================
168 //=======================================================================
170 const TopOpeBRep_VPointInter& TopOpeBRep_LineInter::VPoint(const Standard_Integer I) const
172 return myHAVP->Value(I);
175 //=======================================================================
176 //function : ChangeVPoint
178 //=======================================================================
180 TopOpeBRep_VPointInter& TopOpeBRep_LineInter::ChangeVPoint(const Standard_Integer I)
182 return myHAVP->ChangeValue(I);
185 //=======================================================================
188 //=======================================================================
190 void TopOpeBRep_LineInter::SetINL()
192 TopOpeBRep_VPointInterIterator VPI(*this);
194 myINL = Standard_False;
197 const Standard_Real p0 = VPI.CurrentVP().ParameterOnLine();
200 myINL = Standard_True;
203 for (; VPI.More(); VPI.Next() ) {
204 const Standard_Real p = VPI.CurrentVP().ParameterOnLine();
206 myINL = Standard_False;
210 myINL = Standard_True;
213 //=======================================================================
214 //function : SetIsVClosed
216 //=======================================================================
218 void TopOpeBRep_LineInter::SetIsVClosed()
221 myIsVClosed = Standard_False;
225 /*Standard_Boolean newV = Standard_True;
227 if (myTypeLineCurve != TopOpeBRep_WALKING) {
228 myIsVClosed = Standard_False;
233 TopOpeBRep_VPointInterIterator VPI(*this);
234 Standard_Integer nV = myNbVPoint;
235 Standard_Real pmin = RealLast(),pmax = RealFirst();
236 Standard_Integer imin=0, imax = 0; // index of IsOnArc VPoints
238 for (; VPI.More(); VPI.Next() ) {
239 const TopOpeBRep_VPointInter& P = VPI.CurrentVP();
240 if ( ! P.IsInternal() ) {
241 const Standard_Integer i = VPI.CurrentVPIndex();
242 const Standard_Real p = P.ParameterOnLine();
243 if ( p < pmin ) { imin = i; pmin = p; }
244 if ( p > pmax ) { imax = i; pmax = p; }
247 if ( imax == 0 ) { // no VPoint on restriction found
248 myIsVClosed = Standard_True;
252 const TopOpeBRep_VPointInter& P1 = VPoint(imin);
253 const TopOpeBRep_VPointInter& P2 = VPoint(imax);
255 const gp_Pnt& pp1 = P1.Value();
256 const gp_Pnt& pp2 = P2.Value();
258 const Standard_Real tol1 = P1.Tolerance();
259 const Standard_Real tol2 = P2.Tolerance();
260 const Standard_Real tol = Max(tol1,tol2);
262 myIsVClosed = pp1.IsEqual(pp2,tol);
265 SetOK(Standard_False);
266 myIsVClosed = Standard_False;
270 //=======================================================================
271 //function : SetHasVPonR
273 //=======================================================================
275 void TopOpeBRep_LineInter::SetHasVPonR()
277 myHasVPonR = Standard_False;
278 TopOpeBRep_VPointInterIterator VPI(*this);
279 for (; VPI.More(); VPI.Next()) {
280 const TopOpeBRep_VPointInter& P = VPI.CurrentVP();
281 if (P.IsOnDomS1() || P.IsOnDomS2()) {
282 myHasVPonR = Standard_True;
288 //=======================================================================
289 //function : SetVPBounds
291 //=======================================================================
293 void TopOpeBRep_LineInter::SetVPBounds()
295 myVPF = myVPL = myVPN = 0;
296 myVPBDefined = Standard_True;
298 TopOpeBRep_VPointInterIterator VPI(*this);
299 Standard_Integer f = myNbVPoint + 1, l = 0, n = 0;
301 for (; VPI.More(); VPI.Next()) {
302 if (VPI.CurrentVP().Keep()) {
304 const Standard_Integer i = VPI.CurrentVPIndex();
310 myVPF = f; myVPL = l; myVPN = n;
313 //=======================================================================
314 //function : VPBounds
316 //=======================================================================
318 void TopOpeBRep_LineInter::VPBounds
319 (Standard_Integer& f, Standard_Integer& l, Standard_Integer& n) const
321 if ( !myVPBDefined ) {
322 TopOpeBRep_LineInter* p = (TopOpeBRep_LineInter*)this; // NYI deconst
323 p->SetOK(Standard_False);
332 //=======================================================================
333 //function : IsPeriodic
335 //=======================================================================
337 Standard_Boolean TopOpeBRep_LineInter::IsPeriodic() const
339 switch (myTypeLineCurve)
341 case TopOpeBRep_CIRCLE :
342 case TopOpeBRep_ELLIPSE : return Standard_True;
346 return Standard_False;
349 //=======================================================================
352 //=======================================================================
354 Standard_Real TopOpeBRep_LineInter::Period() const
361 //=======================================================================
364 //=======================================================================
366 void TopOpeBRep_LineInter::Bounds(Standard_Real& First,Standard_Real& Last) const
368 if ( myILG.IsNull() ) {
369 TopOpeBRep_LineInter* p = (TopOpeBRep_LineInter*)this; // NYI deconst
370 p->SetOK(Standard_False);
374 First = 0.; Last = 0.;
376 Last = Curve()->Period();
378 if ( myILG->HasFirstPoint() )
379 First = myILG->FirstPoint().ParameterOnLine();
381 if ( myILG->HasLastPoint() )
382 Last = myILG->LastPoint().ParameterOnLine();
385 //=======================================================================
386 //function : HasVInternal
388 //=======================================================================
390 Standard_Boolean TopOpeBRep_LineInter::HasVInternal()
392 TopOpeBRep_VPointInterIterator VPI(*this);
393 for (; VPI.More(); VPI.Next()) {
394 if (VPI.CurrentVP().IsInternal()) return Standard_True;
396 return Standard_False;
400 //=======================================================================
401 //function : NbWPoint
403 //=======================================================================
405 Standard_Integer TopOpeBRep_LineInter::NbWPoint() const
407 switch (myTypeLineCurve)
409 case TopOpeBRep_WALKING : return myILW->NbPnts();
417 //=======================================================================
420 //=======================================================================
422 const TopOpeBRep_WPointInter& TopOpeBRep_LineInter::WPoint(const Standard_Integer IW)
424 switch (myTypeLineCurve)
426 case TopOpeBRep_RESTRICTION : myCurrentWP.Set(myILR->Point(IW)); break;
427 case TopOpeBRep_WALKING : myCurrentWP.Set(myILW->Point(IW)); break;
433 //=======================================================================
436 //=======================================================================
438 Handle(Geom_Curve) TopOpeBRep_LineInter::Curve() const
440 // Build the 3d curve
441 Handle(Geom_Curve) C3D;
442 switch (myTypeLineCurve) {
443 case TopOpeBRep_LINE :
444 C3D = new Geom_Line(myILG->Line()); break;
445 case TopOpeBRep_CIRCLE :
446 C3D = new Geom_Circle(myILG->Circle()); break;
447 case TopOpeBRep_ELLIPSE :
448 C3D = new Geom_Ellipse(myILG->Ellipse()); break;
449 case TopOpeBRep_PARABOLA :
450 C3D = new Geom_Parabola(myILG->Parabola()); break;
451 case TopOpeBRep_HYPERBOLA :
452 C3D = new Geom_Hyperbola(myILG->Hyperbola()); break;
454 TopOpeBRep_LineInter* p = (TopOpeBRep_LineInter*)this; // NYI deconst
455 p->SetOK(Standard_False);
461 //=======================================================================
464 //=======================================================================
466 Handle(Geom_Curve) TopOpeBRep_LineInter::Curve
467 (const Standard_Real parmin, const Standard_Real parmax) const
469 // Build the trimmed 3d curve
470 Handle(Geom_Curve) C3D = Curve();
471 Handle(Geom_TrimmedCurve) TC3D = new Geom_TrimmedCurve(C3D,parmin,parmax);
473 if ( TopOpeBRep_GettraceCONIC() ) {
474 cout<<"TopOpeBRep_LineInter::Curve on a ";
475 TopOpeBRep::Print(myTypeLineCurve,cout);cout<<endl;
476 cout<<" ... Trimmed from "<<parmin<<" to "<<parmax<<endl;
482 //=======================================================================
485 //=======================================================================
487 const TopoDS_Shape& TopOpeBRep_LineInter::Arc() const
489 if (myTypeLineCurve == TopOpeBRep_RESTRICTION) {
490 if(myILR->IsArcOnS1()) {
491 const Handle(Adaptor2d_HCurve2d)& AHC2D = myILR->ArcOnS1();
492 const BRepAdaptor_Curve2d& BC2DP = *((BRepAdaptor_Curve2d*)&(AHC2D->Curve2d()));
493 const TopoDS_Shape& S = BC2DP.Edge();
497 const Handle(Adaptor2d_HCurve2d)& AHC2D = myILR->ArcOnS2();
498 const BRepAdaptor_Curve2d& BC2DP = *((BRepAdaptor_Curve2d*)&(AHC2D->Curve2d()));
499 const TopoDS_Shape& S = BC2DP.Edge();
507 //=======================================================================
508 //function : ArcIsEdge
510 //=======================================================================
512 Standard_Boolean TopOpeBRep_LineInter::ArcIsEdge(const Standard_Integer Index) const
514 if (myTypeLineCurve == TopOpeBRep_RESTRICTION) {
515 const Standard_Boolean r = myILR->IsArcOnS1();
516 return ( Index == 2 ? !r : r );
518 return Standard_False;
521 //=======================================================================
522 //function : HasFirstPoint
524 //=======================================================================
526 Standard_Boolean TopOpeBRep_LineInter::HasFirstPoint() const
529 Standard_ProgramError::Raise("TopOpeBRep_LineInter::HasFirstPoint sur line != GLine");
530 return myILG->HasFirstPoint();
533 //=======================================================================
534 //function : HasLastPoint
536 //=======================================================================
538 Standard_Boolean TopOpeBRep_LineInter::HasLastPoint() const
541 Standard_ProgramError::Raise("TopOpeBRep_LineInter::HasLastPoint sur line != GLine");
542 return myILG->HasLastPoint();
545 //=======================================================================
546 //function : ComputeFaceFaceTransition
548 //=======================================================================
550 void TopOpeBRep_LineInter::ComputeFaceFaceTransition()
552 TopAbs_Orientation F1ori = myF1.Orientation();
553 TopAbs_Orientation F2ori = myF2.Orientation();
554 myLineTonF1=TopOpeBRep_FFTransitionTool::ProcessFaceTransition(*this,1,F2ori);
555 myLineTonF2=TopOpeBRep_FFTransitionTool::ProcessFaceTransition(*this,2,F1ori);
558 //=======================================================================
559 //function : FaceFaceTransition
561 //=======================================================================
562 const TopOpeBRepDS_Transition& TopOpeBRep_LineInter::FaceFaceTransition
563 (const Standard_Integer I) const
565 if (I == 1) return myLineTonF1;
566 if (I == 2) return myLineTonF2;
567 Standard_ProgramError::Raise("TopOpeBRep_LineInter::FaceFaceTransition");
571 //=======================================================================
572 //function : DumpType
574 //=======================================================================
576 void TopOpeBRep_LineInter::DumpType()const
579 TopOpeBRep::Print(myTypeLineCurve,cout);
583 //=======================================================================
584 //function : DumpVPoint
586 //=======================================================================
588 void TopOpeBRep_LineInter::DumpVPoint
590 (const Standard_Integer ,
591 const TCollection_AsciiString& ,
592 const TCollection_AsciiString& ) const
595 (const Standard_Integer I,
596 const TCollection_AsciiString& s1,
597 const TCollection_AsciiString& s2) const
599 const TopOpeBRep_VPointInter& VP = VPoint(I);
600 const gp_Pnt& P = VP.Value();
602 cout<<"L"<<Index()<<"P"<<VP.Index();
603 if (VP.Keep()) cout<<"K";
604 cout<<" "<<P.X()<<" "<<P.Y()<<" "<<P.Z();
609 //=======================================================================
610 //function : DumpBipoint
612 //=======================================================================
614 void TopOpeBRep_LineInter::DumpBipoint
616 (const TopOpeBRep_Bipoint& ,
617 const TCollection_AsciiString& ,
618 const TCollection_AsciiString& ) const
621 (const TopOpeBRep_Bipoint& bip,
622 const TCollection_AsciiString& s1,
623 const TCollection_AsciiString& s2) const
625 Standard_Integer i1 = bip.I1();
626 Standard_Integer i2 = bip.I2();
628 cout<<"("<<i1<<","<<i2<<")";
633 //=======================================================================
636 //=======================================================================
638 void TopOpeBRep_LineInter::SetOK(const Standard_Boolean B)
641 if (TopOpeBRepDS_GettraceDSF() || TopOpeBRepDS_GettraceDSNC()) {
643 cout<<"line "<<myIndex<<" (";
644 TopOpeBRep::Print(myTypeLineCurve,cout);cout<<") ";
645 if (!B) cout<<"OK->NOK"; else cout<<"NOK->OK";
653 //=======================================================================
654 //function : SetTraceIndex
656 //=======================================================================
658 void TopOpeBRep_LineInter::SetTraceIndex(const Standard_Integer exF1,
659 const Standard_Integer exF2)
665 //=======================================================================
666 //function : GetTraceIndex
668 //=======================================================================
670 void TopOpeBRep_LineInter::GetTraceIndex(Standard_Integer& exF1,
671 Standard_Integer& exF2)const
677 //=======================================================================
678 //function : DumpLineTransitions
680 //=======================================================================
681 Standard_OStream& TopOpeBRep_LineInter::DumpLineTransitions(Standard_OStream& OS) const
684 OS<<"transition from f1 / f2 "; TopAbs::Print(myF2.Orientation(),OS);
685 OS<<" : "; myLineTonF1.Dump(OS); OS<<endl;
686 OS<<"transition from f2 / f1 "; TopAbs::Print(myF1.Orientation(),OS);
687 OS<<" : "; myLineTonF2.Dump(OS); OS<<endl;