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.hxx>
19 #include <Adaptor2d_Curve2d.hxx>
20 #include <BRepAdaptor_Curve2d.hxx>
21 #include <BRepAdaptor_Surface.hxx>
22 #include <Geom_Circle.hxx>
23 #include <Geom_Curve.hxx>
24 #include <Geom_Ellipse.hxx>
25 #include <Geom_Hyperbola.hxx>
26 #include <Geom_Line.hxx>
27 #include <Geom_Parabola.hxx>
28 #include <Geom_TrimmedCurve.hxx>
29 #include <GeomAbs_SurfaceType.hxx>
31 #include <IntPatch_ALine.hxx>
32 #include <IntPatch_ALineToWLine.hxx>
33 #include <IntPatch_GLine.hxx>
34 #include <IntPatch_IType.hxx>
35 #include <IntPatch_Line.hxx>
36 #include <IntPatch_RLine.hxx>
37 #include <IntPatch_SequenceOfLine.hxx>
38 #include <IntPatch_WLine.hxx>
39 #include <IntSurf_Quadric.hxx>
40 #include <Standard_NotImplemented.hxx>
41 #include <Standard_ProgramError.hxx>
42 #include <TCollection_AsciiString.hxx>
44 #include <TopoDS_Face.hxx>
45 #include <TopoDS_Shape.hxx>
46 #include <TopOpeBRep.hxx>
47 #include <TopOpeBRep_Bipoint.hxx>
48 #include <TopOpeBRep_FFTransitionTool.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 //=======================================================================
347 Standard_Real TopOpeBRep_LineInter::Period() const
349 Standard_Real aFirst = 0.0, aLast = 0.0;
350 Bounds (aFirst, aLast);
351 return (aLast - aFirst);
354 //=======================================================================
357 //=======================================================================
358 void TopOpeBRep_LineInter::Bounds (Standard_Real& theFirst, Standard_Real& theLast) const
360 theFirst = 0.0; theLast = 0.0;
363 TopOpeBRep_LineInter* aPtr = const_cast<TopOpeBRep_LineInter*>(this); // NYI deconst
364 aPtr->SetOK (Standard_False);
370 theLast = Curve()->Period();
373 if (myILG->HasFirstPoint())
375 theFirst = myILG->FirstPoint().ParameterOnLine();
378 if (myILG->HasLastPoint())
380 theLast = myILG->LastPoint().ParameterOnLine();
384 //=======================================================================
385 //function : HasVInternal
387 //=======================================================================
389 Standard_Boolean TopOpeBRep_LineInter::HasVInternal()
391 TopOpeBRep_VPointInterIterator VPI(*this);
392 for (; VPI.More(); VPI.Next()) {
393 if (VPI.CurrentVP().IsInternal()) return Standard_True;
395 return Standard_False;
399 //=======================================================================
400 //function : NbWPoint
402 //=======================================================================
404 Standard_Integer TopOpeBRep_LineInter::NbWPoint() const
406 switch (myTypeLineCurve)
408 case TopOpeBRep_WALKING : return myILW->NbPnts();
416 //=======================================================================
419 //=======================================================================
421 const TopOpeBRep_WPointInter& TopOpeBRep_LineInter::WPoint(const Standard_Integer IW)
423 switch (myTypeLineCurve)
425 case TopOpeBRep_RESTRICTION : myCurrentWP.Set(myILR->Point(IW)); break;
426 case TopOpeBRep_WALKING : myCurrentWP.Set(myILW->Point(IW)); break;
432 //=======================================================================
435 //=======================================================================
437 Handle(Geom_Curve) TopOpeBRep_LineInter::Curve() const
439 // Build the 3d curve
440 Handle(Geom_Curve) C3D;
441 switch (myTypeLineCurve) {
442 case TopOpeBRep_LINE :
443 C3D = new Geom_Line(myILG->Line()); break;
444 case TopOpeBRep_CIRCLE :
445 C3D = new Geom_Circle(myILG->Circle()); break;
446 case TopOpeBRep_ELLIPSE :
447 C3D = new Geom_Ellipse(myILG->Ellipse()); break;
448 case TopOpeBRep_PARABOLA :
449 C3D = new Geom_Parabola(myILG->Parabola()); break;
450 case TopOpeBRep_HYPERBOLA :
451 C3D = new Geom_Hyperbola(myILG->Hyperbola()); break;
453 TopOpeBRep_LineInter* p = (TopOpeBRep_LineInter*)this; // NYI deconst
454 p->SetOK(Standard_False);
460 //=======================================================================
463 //=======================================================================
465 Handle(Geom_Curve) TopOpeBRep_LineInter::Curve
466 (const Standard_Real parmin, const Standard_Real parmax) const
468 // Build the trimmed 3d curve
469 Handle(Geom_Curve) C3D = Curve();
470 Handle(Geom_TrimmedCurve) TC3D = new Geom_TrimmedCurve(C3D,parmin,parmax);
472 if ( TopOpeBRep_GettraceCONIC() ) {
473 std::cout<<"TopOpeBRep_LineInter::Curve on a ";
474 TopOpeBRep::Print(myTypeLineCurve,std::cout);std::cout<<std::endl;
475 std::cout<<" ... Trimmed from "<<parmin<<" to "<<parmax<<std::endl;
481 //=======================================================================
484 //=======================================================================
486 const TopoDS_Shape& TopOpeBRep_LineInter::Arc() const
488 if (myTypeLineCurve == TopOpeBRep_RESTRICTION) {
489 if(myILR->IsArcOnS1()) {
490 const Handle(Adaptor2d_Curve2d)& AHC2D = myILR->ArcOnS1();
491 const BRepAdaptor_Curve2d& BC2DP = *((BRepAdaptor_Curve2d*)AHC2D.get());
492 const TopoDS_Shape& S = BC2DP.Edge();
496 const Handle(Adaptor2d_Curve2d)& AHC2D = myILR->ArcOnS2();
497 const BRepAdaptor_Curve2d& BC2DP = *((BRepAdaptor_Curve2d*)AHC2D.get());
498 const TopoDS_Shape& S = BC2DP.Edge();
506 //=======================================================================
507 //function : ArcIsEdge
509 //=======================================================================
511 Standard_Boolean TopOpeBRep_LineInter::ArcIsEdge(const Standard_Integer Index) const
513 if (myTypeLineCurve == TopOpeBRep_RESTRICTION) {
514 const Standard_Boolean r = myILR->IsArcOnS1();
515 return ( Index == 2 ? !r : r );
517 return Standard_False;
520 //=======================================================================
521 //function : HasFirstPoint
523 //=======================================================================
525 Standard_Boolean TopOpeBRep_LineInter::HasFirstPoint() const
528 throw Standard_ProgramError("TopOpeBRep_LineInter::HasFirstPoint sur line != GLine");
529 return myILG->HasFirstPoint();
532 //=======================================================================
533 //function : HasLastPoint
535 //=======================================================================
537 Standard_Boolean TopOpeBRep_LineInter::HasLastPoint() const
540 throw Standard_ProgramError("TopOpeBRep_LineInter::HasLastPoint sur line != GLine");
541 return myILG->HasLastPoint();
544 //=======================================================================
545 //function : ComputeFaceFaceTransition
547 //=======================================================================
549 void TopOpeBRep_LineInter::ComputeFaceFaceTransition()
551 TopAbs_Orientation F1ori = myF1.Orientation();
552 TopAbs_Orientation F2ori = myF2.Orientation();
553 myLineTonF1=TopOpeBRep_FFTransitionTool::ProcessFaceTransition(*this,1,F2ori);
554 myLineTonF2=TopOpeBRep_FFTransitionTool::ProcessFaceTransition(*this,2,F1ori);
557 //=======================================================================
558 //function : FaceFaceTransition
560 //=======================================================================
561 const TopOpeBRepDS_Transition& TopOpeBRep_LineInter::FaceFaceTransition
562 (const Standard_Integer I) const
564 if (I == 1) return myLineTonF1;
565 if (I == 2) return myLineTonF2;
566 throw Standard_ProgramError("TopOpeBRep_LineInter::FaceFaceTransition");
569 //=======================================================================
570 //function : DumpType
572 //=======================================================================
574 void TopOpeBRep_LineInter::DumpType()const
577 TopOpeBRep::Print(myTypeLineCurve,std::cout);
581 //=======================================================================
582 //function : DumpVPoint
584 //=======================================================================
586 void TopOpeBRep_LineInter::DumpVPoint
588 (const Standard_Integer ,
589 const TCollection_AsciiString& ,
590 const TCollection_AsciiString& ) const
593 (const Standard_Integer I,
594 const TCollection_AsciiString& s1,
595 const TCollection_AsciiString& s2) const
597 const TopOpeBRep_VPointInter& VP = VPoint(I);
598 const gp_Pnt& P = VP.Value();
600 std::cout<<"L"<<Index()<<"P"<<VP.Index();
601 if (VP.Keep()) std::cout<<"K";
602 std::cout<<" "<<P.X()<<" "<<P.Y()<<" "<<P.Z();
607 //=======================================================================
608 //function : DumpBipoint
610 //=======================================================================
612 void TopOpeBRep_LineInter::DumpBipoint
614 (const TopOpeBRep_Bipoint& ,
615 const TCollection_AsciiString& ,
616 const TCollection_AsciiString& ) const
619 (const TopOpeBRep_Bipoint& bip,
620 const TCollection_AsciiString& s1,
621 const TCollection_AsciiString& s2) const
623 Standard_Integer i1 = bip.I1();
624 Standard_Integer i2 = bip.I2();
626 std::cout<<"("<<i1<<","<<i2<<")";
631 //=======================================================================
634 //=======================================================================
636 void TopOpeBRep_LineInter::SetOK(const Standard_Boolean B)
641 //=======================================================================
642 //function : SetTraceIndex
644 //=======================================================================
646 void TopOpeBRep_LineInter::SetTraceIndex(const Standard_Integer exF1,
647 const Standard_Integer exF2)
653 //=======================================================================
654 //function : GetTraceIndex
656 //=======================================================================
658 void TopOpeBRep_LineInter::GetTraceIndex(Standard_Integer& exF1,
659 Standard_Integer& exF2)const
665 //=======================================================================
666 //function : DumpLineTransitions
668 //=======================================================================
669 Standard_OStream& TopOpeBRep_LineInter::DumpLineTransitions(Standard_OStream& OS) const
672 OS<<"transition from f1 / f2 "; TopAbs::Print(myF2.Orientation(),OS);
673 OS<<"transition from f2 / f1 "; TopAbs::Print(myF1.Orientation(),OS);