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.
18 #include <Adaptor2d_Curve2d.hxx>
19 #include <BRepAdaptor_Curve2d.hxx>
20 #include <BRepAdaptor_Surface.hxx>
21 #include <Geom_Circle.hxx>
22 #include <Geom_Curve.hxx>
23 #include <Geom_Ellipse.hxx>
24 #include <Geom_Hyperbola.hxx>
25 #include <Geom_Line.hxx>
26 #include <Geom_Parabola.hxx>
27 #include <Geom_TrimmedCurve.hxx>
28 #include <GeomAbs_SurfaceType.hxx>
30 #include <IntPatch_ALine.hxx>
31 #include <IntPatch_ALineToWLine.hxx>
32 #include <IntPatch_GLine.hxx>
33 #include <IntPatch_IType.hxx>
34 #include <IntPatch_Line.hxx>
35 #include <IntPatch_RLine.hxx>
36 #include <IntPatch_SequenceOfLine.hxx>
37 #include <IntPatch_WLine.hxx>
38 #include <IntSurf_Quadric.hxx>
39 #include <Standard_NotImplemented.hxx>
40 #include <Standard_ProgramError.hxx>
41 #include <TCollection_AsciiString.hxx>
43 #include <TopoDS_Face.hxx>
44 #include <TopoDS_Shape.hxx>
45 #include <TopOpeBRep.hxx>
46 #include <TopOpeBRep_Bipoint.hxx>
47 #include <TopOpeBRep_FFTransitionTool.hxx>
48 #include <TopOpeBRep_LineInter.hxx>
49 #include <TopOpeBRep_VPointInter.hxx>
50 #include <TopOpeBRep_VPointInterIterator.hxx>
51 #include <TopOpeBRep_WPointInter.hxx>
52 #include <TopOpeBRepDS_Transition.hxx>
54 #include <BRepAdaptor_Surface.hxx>
57 extern Standard_Boolean TopOpeBRep_GetcontextALWLNBP(Standard_Integer&);
58 extern Standard_Boolean TopOpeBRep_GettraceCONIC();
61 //-----------------------------------------------------------------------
62 static void FUN_ALINETOWLINE (const Handle(IntPatch_ALine)& AL,
63 const Handle(BRepAdaptor_Surface) surf1,
64 const Handle(BRepAdaptor_Surface) surf2,
65 IntPatch_SequenceOfLine& theLines)
67 Standard_Integer nbpointsmax = 200;
69 Standard_Integer newnbp;
70 if (TopOpeBRep_GetcontextALWLNBP(newnbp)) nbpointsmax = newnbp;
73 AToL(surf1,surf2,nbpointsmax);
75 AToL.MakeWLine(AL, theLines);
78 //=======================================================================
81 //=======================================================================
83 void TopOpeBRep_LineInter::SetLine(const Handle(IntPatch_Line)& L,
84 const BRepAdaptor_Surface& S1,
85 const BRepAdaptor_Surface& S2)
87 // load line according to its type
89 IntPatch_IType type = L->ArcType();
91 case IntPatch_Analytic : myTypeLineCurve = TopOpeBRep_ANALYTIC; break;
92 case IntPatch_Restriction : myTypeLineCurve = TopOpeBRep_RESTRICTION; break;
93 case IntPatch_Walking : myTypeLineCurve = TopOpeBRep_WALKING; break;
94 case IntPatch_Lin : myTypeLineCurve = TopOpeBRep_LINE; break;
95 case IntPatch_Circle : myTypeLineCurve = TopOpeBRep_CIRCLE; break;
96 case IntPatch_Ellipse : myTypeLineCurve = TopOpeBRep_ELLIPSE; break;
97 case IntPatch_Parabola : myTypeLineCurve = TopOpeBRep_PARABOLA; break;
98 case IntPatch_Hyperbola : myTypeLineCurve = TopOpeBRep_HYPERBOLA; break;
100 myTypeLineCurve = TopOpeBRep_OTHERTYPE;
101 SetOK(Standard_False);
106 case IntPatch_Analytic :
107 myILA = Handle(IntPatch_ALine)::DownCast (L); break;
108 case IntPatch_Restriction :
109 myILR = Handle(IntPatch_RLine)::DownCast (L); break;
110 case IntPatch_Walking :
111 myILW = Handle(IntPatch_WLine)::DownCast (L); break;
112 default : //"geometric" line
113 myILG = Handle(IntPatch_GLine)::DownCast (L); break;
116 // transform an analytic line to a walking line
117 if (myTypeLineCurve == TopOpeBRep_ANALYTIC) {
118 IntPatch_SequenceOfLine aSLin;
119 FUN_ALINETOWLINE(myILA,new BRepAdaptor_Surface(S1),
120 new BRepAdaptor_Surface(S2), aSLin);
122 if(aSLin.Length() > 0)
123 myILW = Handle(IntPatch_WLine)::DownCast(aSLin.Value(1));
125 myTypeLineCurve = TopOpeBRep_WALKING;
128 // number of points found on restriction(s)
129 Standard_Integer n = 0;
130 switch (myTypeLineCurve) {
131 case TopOpeBRep_ANALYTIC : n = myILA->NbVertex(); break;
132 case TopOpeBRep_RESTRICTION : n = myILR->NbVertex(); break;
133 case TopOpeBRep_WALKING : n = myILW->NbVertex(); break;
134 case TopOpeBRep_LINE : n = myILG->NbVertex(); break;
135 case TopOpeBRep_CIRCLE : n = myILG->NbVertex(); break;
136 case TopOpeBRep_ELLIPSE : n = myILG->NbVertex(); break;
137 case TopOpeBRep_PARABOLA : n = myILG->NbVertex(); break;
138 case TopOpeBRep_HYPERBOLA : n = myILG->NbVertex(); break;
140 SetOK(Standard_False);
145 // prepare VPoints from intersection points
146 myHAVP = new TopOpeBRep_HArray1OfVPointInter(0,n);
147 for (Standard_Integer i=1;i<=n;i++) {
148 TopOpeBRep_VPointInter& VP = myHAVP->ChangeValue(i);
149 switch (myTypeLineCurve) {
150 case TopOpeBRep_ANALYTIC : VP.SetPoint(myILA->Vertex(i)); break;
151 case TopOpeBRep_RESTRICTION : VP.SetPoint(myILR->Vertex(i)); break;
152 case TopOpeBRep_WALKING : VP.SetPoint(myILW->Vertex(i)); break;
153 default : VP.SetPoint(myILG->Vertex(i)); break;
159 //=======================================================================
162 //=======================================================================
164 const TopOpeBRep_VPointInter& TopOpeBRep_LineInter::VPoint(const Standard_Integer I) const
166 return myHAVP->Value(I);
169 //=======================================================================
170 //function : ChangeVPoint
172 //=======================================================================
174 TopOpeBRep_VPointInter& TopOpeBRep_LineInter::ChangeVPoint(const Standard_Integer I)
176 return myHAVP->ChangeValue(I);
179 //=======================================================================
182 //=======================================================================
184 void TopOpeBRep_LineInter::SetINL()
186 TopOpeBRep_VPointInterIterator VPI(*this);
188 myINL = Standard_False;
191 const Standard_Real p0 = VPI.CurrentVP().ParameterOnLine();
194 myINL = Standard_True;
197 for (; VPI.More(); VPI.Next() ) {
198 const Standard_Real p = VPI.CurrentVP().ParameterOnLine();
200 myINL = Standard_False;
204 myINL = Standard_True;
207 //=======================================================================
208 //function : SetIsVClosed
210 //=======================================================================
212 void TopOpeBRep_LineInter::SetIsVClosed()
215 myIsVClosed = Standard_False;
219 /*Standard_Boolean newV = Standard_True;
221 if (myTypeLineCurve != TopOpeBRep_WALKING) {
222 myIsVClosed = Standard_False;
227 TopOpeBRep_VPointInterIterator VPI(*this);
228 Standard_Integer nV = myNbVPoint;
229 Standard_Real pmin = RealLast(),pmax = RealFirst();
230 Standard_Integer imin=0, imax = 0; // index of IsOnArc VPoints
232 for (; VPI.More(); VPI.Next() ) {
233 const TopOpeBRep_VPointInter& P = VPI.CurrentVP();
234 if ( ! P.IsInternal() ) {
235 const Standard_Integer i = VPI.CurrentVPIndex();
236 const Standard_Real p = P.ParameterOnLine();
237 if ( p < pmin ) { imin = i; pmin = p; }
238 if ( p > pmax ) { imax = i; pmax = p; }
241 if ( imax == 0 ) { // no VPoint on restriction found
242 myIsVClosed = Standard_True;
246 const TopOpeBRep_VPointInter& P1 = VPoint(imin);
247 const TopOpeBRep_VPointInter& P2 = VPoint(imax);
249 const gp_Pnt& pp1 = P1.Value();
250 const gp_Pnt& pp2 = P2.Value();
252 const Standard_Real tol1 = P1.Tolerance();
253 const Standard_Real tol2 = P2.Tolerance();
254 const Standard_Real tol = Max(tol1,tol2);
256 myIsVClosed = pp1.IsEqual(pp2,tol);
259 SetOK(Standard_False);
260 myIsVClosed = Standard_False;
264 //=======================================================================
265 //function : SetHasVPonR
267 //=======================================================================
269 void TopOpeBRep_LineInter::SetHasVPonR()
271 myHasVPonR = Standard_False;
272 TopOpeBRep_VPointInterIterator VPI(*this);
273 for (; VPI.More(); VPI.Next()) {
274 const TopOpeBRep_VPointInter& P = VPI.CurrentVP();
275 if (P.IsOnDomS1() || P.IsOnDomS2()) {
276 myHasVPonR = Standard_True;
282 //=======================================================================
283 //function : SetVPBounds
285 //=======================================================================
287 void TopOpeBRep_LineInter::SetVPBounds()
289 myVPF = myVPL = myVPN = 0;
290 myVPBDefined = Standard_True;
292 TopOpeBRep_VPointInterIterator VPI(*this);
293 Standard_Integer f = myNbVPoint + 1, l = 0, n = 0;
295 for (; VPI.More(); VPI.Next()) {
296 if (VPI.CurrentVP().Keep()) {
298 const Standard_Integer i = VPI.CurrentVPIndex();
304 myVPF = f; myVPL = l; myVPN = n;
307 //=======================================================================
308 //function : VPBounds
310 //=======================================================================
312 void TopOpeBRep_LineInter::VPBounds
313 (Standard_Integer& f, Standard_Integer& l, Standard_Integer& n) const
315 if ( !myVPBDefined ) {
316 TopOpeBRep_LineInter* p = (TopOpeBRep_LineInter*)this; // NYI deconst
317 p->SetOK(Standard_False);
326 //=======================================================================
327 //function : IsPeriodic
329 //=======================================================================
331 Standard_Boolean TopOpeBRep_LineInter::IsPeriodic() const
333 switch (myTypeLineCurve)
335 case TopOpeBRep_CIRCLE :
336 case TopOpeBRep_ELLIPSE : return Standard_True;
340 return Standard_False;
343 //=======================================================================
346 //=======================================================================
348 Standard_Real TopOpeBRep_LineInter::Period() const
355 //=======================================================================
358 //=======================================================================
360 void TopOpeBRep_LineInter::Bounds(Standard_Real& First,Standard_Real& Last) const
362 if ( myILG.IsNull() ) {
363 TopOpeBRep_LineInter* p = (TopOpeBRep_LineInter*)this; // NYI deconst
364 p->SetOK(Standard_False);
368 First = 0.; Last = 0.;
370 Last = Curve()->Period();
372 if ( myILG->HasFirstPoint() )
373 First = myILG->FirstPoint().ParameterOnLine();
375 if ( myILG->HasLastPoint() )
376 Last = myILG->LastPoint().ParameterOnLine();
379 //=======================================================================
380 //function : HasVInternal
382 //=======================================================================
384 Standard_Boolean TopOpeBRep_LineInter::HasVInternal()
386 TopOpeBRep_VPointInterIterator VPI(*this);
387 for (; VPI.More(); VPI.Next()) {
388 if (VPI.CurrentVP().IsInternal()) return Standard_True;
390 return Standard_False;
394 //=======================================================================
395 //function : NbWPoint
397 //=======================================================================
399 Standard_Integer TopOpeBRep_LineInter::NbWPoint() const
401 switch (myTypeLineCurve)
403 case TopOpeBRep_WALKING : return myILW->NbPnts();
411 //=======================================================================
414 //=======================================================================
416 const TopOpeBRep_WPointInter& TopOpeBRep_LineInter::WPoint(const Standard_Integer IW)
418 switch (myTypeLineCurve)
420 case TopOpeBRep_RESTRICTION : myCurrentWP.Set(myILR->Point(IW)); break;
421 case TopOpeBRep_WALKING : myCurrentWP.Set(myILW->Point(IW)); break;
427 //=======================================================================
430 //=======================================================================
432 Handle(Geom_Curve) TopOpeBRep_LineInter::Curve() const
434 // Build the 3d curve
435 Handle(Geom_Curve) C3D;
436 switch (myTypeLineCurve) {
437 case TopOpeBRep_LINE :
438 C3D = new Geom_Line(myILG->Line()); break;
439 case TopOpeBRep_CIRCLE :
440 C3D = new Geom_Circle(myILG->Circle()); break;
441 case TopOpeBRep_ELLIPSE :
442 C3D = new Geom_Ellipse(myILG->Ellipse()); break;
443 case TopOpeBRep_PARABOLA :
444 C3D = new Geom_Parabola(myILG->Parabola()); break;
445 case TopOpeBRep_HYPERBOLA :
446 C3D = new Geom_Hyperbola(myILG->Hyperbola()); break;
448 TopOpeBRep_LineInter* p = (TopOpeBRep_LineInter*)this; // NYI deconst
449 p->SetOK(Standard_False);
455 //=======================================================================
458 //=======================================================================
460 Handle(Geom_Curve) TopOpeBRep_LineInter::Curve
461 (const Standard_Real parmin, const Standard_Real parmax) const
463 // Build the trimmed 3d curve
464 Handle(Geom_Curve) C3D = Curve();
465 Handle(Geom_TrimmedCurve) TC3D = new Geom_TrimmedCurve(C3D,parmin,parmax);
467 if ( TopOpeBRep_GettraceCONIC() ) {
468 std::cout<<"TopOpeBRep_LineInter::Curve on a ";
469 TopOpeBRep::Print(myTypeLineCurve,std::cout);std::cout<<std::endl;
470 std::cout<<" ... Trimmed from "<<parmin<<" to "<<parmax<<std::endl;
476 //=======================================================================
479 //=======================================================================
481 const TopoDS_Shape& TopOpeBRep_LineInter::Arc() const
483 if (myTypeLineCurve == TopOpeBRep_RESTRICTION) {
484 if(myILR->IsArcOnS1()) {
485 const Handle(Adaptor2d_Curve2d)& AHC2D = myILR->ArcOnS1();
486 const BRepAdaptor_Curve2d& BC2DP = *((BRepAdaptor_Curve2d*)AHC2D.get());
487 const TopoDS_Shape& S = BC2DP.Edge();
491 const Handle(Adaptor2d_Curve2d)& AHC2D = myILR->ArcOnS2();
492 const BRepAdaptor_Curve2d& BC2DP = *((BRepAdaptor_Curve2d*)AHC2D.get());
493 const TopoDS_Shape& S = BC2DP.Edge();
501 //=======================================================================
502 //function : ArcIsEdge
504 //=======================================================================
506 Standard_Boolean TopOpeBRep_LineInter::ArcIsEdge(const Standard_Integer Index) const
508 if (myTypeLineCurve == TopOpeBRep_RESTRICTION) {
509 const Standard_Boolean r = myILR->IsArcOnS1();
510 return ( Index == 2 ? !r : r );
512 return Standard_False;
515 //=======================================================================
516 //function : HasFirstPoint
518 //=======================================================================
520 Standard_Boolean TopOpeBRep_LineInter::HasFirstPoint() const
523 throw Standard_ProgramError("TopOpeBRep_LineInter::HasFirstPoint sur line != GLine");
524 return myILG->HasFirstPoint();
527 //=======================================================================
528 //function : HasLastPoint
530 //=======================================================================
532 Standard_Boolean TopOpeBRep_LineInter::HasLastPoint() const
535 throw Standard_ProgramError("TopOpeBRep_LineInter::HasLastPoint sur line != GLine");
536 return myILG->HasLastPoint();
539 //=======================================================================
540 //function : ComputeFaceFaceTransition
542 //=======================================================================
544 void TopOpeBRep_LineInter::ComputeFaceFaceTransition()
546 TopAbs_Orientation F1ori = myF1.Orientation();
547 TopAbs_Orientation F2ori = myF2.Orientation();
548 myLineTonF1=TopOpeBRep_FFTransitionTool::ProcessFaceTransition(*this,1,F2ori);
549 myLineTonF2=TopOpeBRep_FFTransitionTool::ProcessFaceTransition(*this,2,F1ori);
552 //=======================================================================
553 //function : FaceFaceTransition
555 //=======================================================================
556 const TopOpeBRepDS_Transition& TopOpeBRep_LineInter::FaceFaceTransition
557 (const Standard_Integer I) const
559 if (I == 1) return myLineTonF1;
560 if (I == 2) return myLineTonF2;
561 throw Standard_ProgramError("TopOpeBRep_LineInter::FaceFaceTransition");
564 //=======================================================================
565 //function : DumpType
567 //=======================================================================
569 void TopOpeBRep_LineInter::DumpType()const
572 TopOpeBRep::Print(myTypeLineCurve,std::cout);
576 //=======================================================================
577 //function : DumpVPoint
579 //=======================================================================
581 void TopOpeBRep_LineInter::DumpVPoint
583 (const Standard_Integer ,
584 const TCollection_AsciiString& ,
585 const TCollection_AsciiString& ) const
588 (const Standard_Integer I,
589 const TCollection_AsciiString& s1,
590 const TCollection_AsciiString& s2) const
592 const TopOpeBRep_VPointInter& VP = VPoint(I);
593 const gp_Pnt& P = VP.Value();
595 std::cout<<"L"<<Index()<<"P"<<VP.Index();
596 if (VP.Keep()) std::cout<<"K";
597 std::cout<<" "<<P.X()<<" "<<P.Y()<<" "<<P.Z();
602 //=======================================================================
603 //function : DumpBipoint
605 //=======================================================================
607 void TopOpeBRep_LineInter::DumpBipoint
609 (const TopOpeBRep_Bipoint& ,
610 const TCollection_AsciiString& ,
611 const TCollection_AsciiString& ) const
614 (const TopOpeBRep_Bipoint& bip,
615 const TCollection_AsciiString& s1,
616 const TCollection_AsciiString& s2) const
618 Standard_Integer i1 = bip.I1();
619 Standard_Integer i2 = bip.I2();
621 std::cout<<"("<<i1<<","<<i2<<")";
626 //=======================================================================
629 //=======================================================================
631 void TopOpeBRep_LineInter::SetOK(const Standard_Boolean B)
636 //=======================================================================
637 //function : SetTraceIndex
639 //=======================================================================
641 void TopOpeBRep_LineInter::SetTraceIndex(const Standard_Integer exF1,
642 const Standard_Integer exF2)
648 //=======================================================================
649 //function : GetTraceIndex
651 //=======================================================================
653 void TopOpeBRep_LineInter::GetTraceIndex(Standard_Integer& exF1,
654 Standard_Integer& exF2)const
660 //=======================================================================
661 //function : DumpLineTransitions
663 //=======================================================================
664 Standard_OStream& TopOpeBRep_LineInter::DumpLineTransitions(Standard_OStream& OS) const
667 OS<<"transition from f1 / f2 "; TopAbs::Print(myF2.Orientation(),OS);
668 OS<<"transition from f2 / f1 "; TopAbs::Print(myF1.Orientation(),OS);