1 // Created on: 1993-11-10
2 // Created by: Jean Yves LEBEY
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
22 #include <TopOpeBRep_LineInter.ixx>
24 #include <TopOpeBRep.hxx>
25 #include <TopOpeBRep_VPointInter.hxx>
26 #include <TopOpeBRep_VPointInterIterator.hxx>
27 #include <TopOpeBRep_FFTransitionTool.hxx>
29 #include <IntPatch_IType.hxx>
30 #include <Geom_Line.hxx>
31 #include <Geom_Circle.hxx>
32 #include <Geom_Ellipse.hxx>
33 #include <Geom_Parabola.hxx>
34 #include <Geom_Hyperbola.hxx>
35 #include <Geom_TrimmedCurve.hxx>
36 #include <IntPatch_ALineToWLine.hxx>
37 #include <IntSurf_Quadric.hxx>
38 #include <GeomAbs_SurfaceType.hxx>
41 #include <Adaptor2d_HCurve2d.hxx>
42 #include <BRepAdaptor_Curve2d.hxx>
45 #include <Standard_ProgramError.hxx>
46 #include <Standard_NotImplemented.hxx>
49 Standard_IMPORT Standard_Boolean TopOpeBRep_GetcontextALWLNBP(Standard_Integer&);
50 Standard_IMPORT Standard_Boolean TopOpeBRep_GettraceCONIC();
51 Standard_IMPORT Standard_Boolean TopOpeBRepDS_GettraceDSF();
52 Standard_IMPORT Standard_Boolean TopOpeBRepDS_GettraceDSNC();
55 //-----------------------------------------------------------------------
56 static Handle(IntPatch_WLine) FUN_ALINETOWLINE
57 (const Handle(IntPatch_ALine)& AL,
58 const BRepAdaptor_Surface surf1,const BRepAdaptor_Surface surf2)
59 //-----------------------------------------------------------------------
61 IntSurf_Quadric Quad1,Quad2;
63 switch(surf1.GetType())
65 case GeomAbs_Plane: Quad1.SetValue(surf1.Plane()); break;
66 case GeomAbs_Cylinder: Quad1.SetValue(surf1.Cylinder()); break;
67 case GeomAbs_Sphere: Quad1.SetValue(surf1.Sphere()); break;
68 case GeomAbs_Cone: Quad1.SetValue(surf1.Cone()); break;
69 default : Standard_ProgramError::Raise
70 ("TopOpeBRep_LineInter::FUN_ALINETOWLINE"); break;
73 switch(surf2.GetType())
75 case GeomAbs_Plane: Quad2.SetValue(surf2.Plane()); break;
76 case GeomAbs_Cylinder: Quad2.SetValue(surf2.Cylinder()); break;
77 case GeomAbs_Sphere: Quad2.SetValue(surf2.Sphere()); break;
78 case GeomAbs_Cone: Quad2.SetValue(surf2.Cone()); break;
79 default : Standard_ProgramError::Raise
80 ("TopOpeBRep_LineInter::FUN_ALINETOWLINE"); break;
83 const Standard_Real deflectionmax = 0.01;
84 const Standard_Real pasUVmax = 0.05;
85 Standard_Integer nbpointsmax = 200;
87 Standard_Integer newnbp;
88 if (TopOpeBRep_GetcontextALWLNBP(newnbp)) nbpointsmax = newnbp;
91 AToL(Quad1,Quad2,deflectionmax,pasUVmax,nbpointsmax);
92 return AToL.MakeWLine(AL);
95 //=======================================================================
98 //=======================================================================
100 void TopOpeBRep_LineInter::SetLine(const Handle(IntPatch_Line)& L,
101 const BRepAdaptor_Surface& S1,
102 const BRepAdaptor_Surface& S2)
104 // load line according to its type
106 IntPatch_IType type = L->ArcType();
108 case IntPatch_Analytic : myTypeLineCurve = TopOpeBRep_ANALYTIC; break;
109 case IntPatch_Restriction : myTypeLineCurve = TopOpeBRep_RESTRICTION; break;
110 case IntPatch_Walking : myTypeLineCurve = TopOpeBRep_WALKING; break;
111 case IntPatch_Lin : myTypeLineCurve = TopOpeBRep_LINE; break;
112 case IntPatch_Circle : myTypeLineCurve = TopOpeBRep_CIRCLE; break;
113 case IntPatch_Ellipse : myTypeLineCurve = TopOpeBRep_ELLIPSE; break;
114 case IntPatch_Parabola : myTypeLineCurve = TopOpeBRep_PARABOLA; break;
115 case IntPatch_Hyperbola : myTypeLineCurve = TopOpeBRep_HYPERBOLA; break;
117 myTypeLineCurve = TopOpeBRep_OTHERTYPE;
118 SetOK(Standard_False);
123 case IntPatch_Analytic :
124 myILA = *((Handle(IntPatch_ALine)*)&L); break;
125 case IntPatch_Restriction :
126 myILR = *((Handle(IntPatch_RLine)*)&L); break;
127 case IntPatch_Walking :
128 myILW = *((Handle(IntPatch_WLine)*)&L); break;
129 default : //"geometric" line
130 myILG = *((Handle(IntPatch_GLine)*)&L); break;
133 // transform an analytic line to a walking line
134 if (myTypeLineCurve == TopOpeBRep_ANALYTIC) {
135 myILW = ::FUN_ALINETOWLINE(myILA,S1,S2);
136 myTypeLineCurve = TopOpeBRep_WALKING;
139 // number of points found on restriction(s)
140 Standard_Integer n = 0;
141 switch (myTypeLineCurve) {
142 case TopOpeBRep_ANALYTIC : n = myILA->NbVertex(); break;
143 case TopOpeBRep_RESTRICTION : n = myILR->NbVertex(); break;
144 case TopOpeBRep_WALKING : n = myILW->NbVertex(); break;
145 case TopOpeBRep_LINE : n = myILG->NbVertex(); break;
146 case TopOpeBRep_CIRCLE : n = myILG->NbVertex(); break;
147 case TopOpeBRep_ELLIPSE : n = myILG->NbVertex(); break;
148 case TopOpeBRep_PARABOLA : n = myILG->NbVertex(); break;
149 case TopOpeBRep_HYPERBOLA : n = myILG->NbVertex(); break;
151 SetOK(Standard_False);
156 // prepare VPoints from intersection points
157 myHAVP = new TopOpeBRep_HArray1OfVPointInter(0,n);
158 for (Standard_Integer i=1;i<=n;i++) {
159 TopOpeBRep_VPointInter& VP = myHAVP->ChangeValue(i);
160 switch (myTypeLineCurve) {
161 case TopOpeBRep_ANALYTIC : VP.SetPoint(myILA->Vertex(i)); break;
162 case TopOpeBRep_RESTRICTION : VP.SetPoint(myILR->Vertex(i)); break;
163 case TopOpeBRep_WALKING : VP.SetPoint(myILW->Vertex(i)); break;
164 default : VP.SetPoint(myILG->Vertex(i)); break;
170 //=======================================================================
173 //=======================================================================
175 const TopOpeBRep_VPointInter& TopOpeBRep_LineInter::VPoint(const Standard_Integer I) const
177 return myHAVP->Value(I);
180 //=======================================================================
181 //function : ChangeVPoint
183 //=======================================================================
185 TopOpeBRep_VPointInter& TopOpeBRep_LineInter::ChangeVPoint(const Standard_Integer I)
187 return myHAVP->ChangeValue(I);
190 //=======================================================================
193 //=======================================================================
195 void TopOpeBRep_LineInter::SetINL()
197 TopOpeBRep_VPointInterIterator VPI(*this);
199 myINL = Standard_False;
202 const Standard_Real p0 = VPI.CurrentVP().ParameterOnLine();
205 myINL = Standard_True;
208 for (; VPI.More(); VPI.Next() ) {
209 const Standard_Real p = VPI.CurrentVP().ParameterOnLine();
211 myINL = Standard_False;
215 myINL = Standard_True;
218 //=======================================================================
219 //function : SetIsVClosed
221 //=======================================================================
223 void TopOpeBRep_LineInter::SetIsVClosed()
226 myIsVClosed = Standard_False;
230 /*Standard_Boolean newV = Standard_True;
232 if (myTypeLineCurve != TopOpeBRep_WALKING) {
233 myIsVClosed = Standard_False;
238 TopOpeBRep_VPointInterIterator VPI(*this);
239 Standard_Integer nV = myNbVPoint;
240 Standard_Real pmin = RealLast(),pmax = RealFirst();
241 Standard_Integer imin=0, imax = 0; // index of IsOnArc VPoints
243 for (; VPI.More(); VPI.Next() ) {
244 const TopOpeBRep_VPointInter& P = VPI.CurrentVP();
245 if ( ! P.IsInternal() ) {
246 const Standard_Integer i = VPI.CurrentVPIndex();
247 const Standard_Real p = P.ParameterOnLine();
248 if ( p < pmin ) { imin = i; pmin = p; }
249 if ( p > pmax ) { imax = i; pmax = p; }
252 if ( imax == 0 ) { // no VPoint on restriction found
253 myIsVClosed = Standard_True;
257 const TopOpeBRep_VPointInter& P1 = VPoint(imin);
258 const TopOpeBRep_VPointInter& P2 = VPoint(imax);
260 const gp_Pnt& pp1 = P1.Value();
261 const gp_Pnt& pp2 = P2.Value();
263 const Standard_Real tol1 = P1.Tolerance();
264 const Standard_Real tol2 = P2.Tolerance();
265 const Standard_Real tol = Max(tol1,tol2);
267 myIsVClosed = pp1.IsEqual(pp2,tol);
270 SetOK(Standard_False);
271 myIsVClosed = Standard_False;
275 //=======================================================================
276 //function : SetHasVPonR
278 //=======================================================================
280 void TopOpeBRep_LineInter::SetHasVPonR()
282 myHasVPonR = Standard_False;
283 TopOpeBRep_VPointInterIterator VPI(*this);
284 for (; VPI.More(); VPI.Next()) {
285 const TopOpeBRep_VPointInter& P = VPI.CurrentVP();
286 if (P.IsOnDomS1() || P.IsOnDomS2()) {
287 myHasVPonR = Standard_True;
293 //=======================================================================
294 //function : SetVPBounds
296 //=======================================================================
298 void TopOpeBRep_LineInter::SetVPBounds()
300 myVPF = myVPL = myVPN = 0;
301 myVPBDefined = Standard_True;
303 TopOpeBRep_VPointInterIterator VPI(*this);
304 Standard_Integer f = myNbVPoint + 1, l = 0, n = 0;
306 for (; VPI.More(); VPI.Next()) {
307 if (VPI.CurrentVP().Keep()) {
309 const Standard_Integer i = VPI.CurrentVPIndex();
315 myVPF = f; myVPL = l; myVPN = n;
318 //=======================================================================
319 //function : VPBounds
321 //=======================================================================
323 void TopOpeBRep_LineInter::VPBounds
324 (Standard_Integer& f, Standard_Integer& l, Standard_Integer& n) const
326 if ( !myVPBDefined ) {
327 TopOpeBRep_LineInter* p = (TopOpeBRep_LineInter*)this; // NYI deconst
328 p->SetOK(Standard_False);
337 //=======================================================================
338 //function : IsPeriodic
340 //=======================================================================
342 Standard_Boolean TopOpeBRep_LineInter::IsPeriodic() const
344 switch (myTypeLineCurve)
346 case TopOpeBRep_CIRCLE :
347 case TopOpeBRep_ELLIPSE : return Standard_True;
349 return Standard_False;
352 //=======================================================================
355 //=======================================================================
357 Standard_Real TopOpeBRep_LineInter::Period() const
364 //=======================================================================
367 //=======================================================================
369 void TopOpeBRep_LineInter::Bounds(Standard_Real& First,Standard_Real& Last) const
371 if ( myILG.IsNull() ) {
372 TopOpeBRep_LineInter* p = (TopOpeBRep_LineInter*)this; // NYI deconst
373 p->SetOK(Standard_False);
377 First = 0.; Last = 0.;
379 Last = Curve()->Period();
381 if ( myILG->HasFirstPoint() )
382 First = myILG->FirstPoint().ParameterOnLine();
384 if ( myILG->HasLastPoint() )
385 Last = myILG->LastPoint().ParameterOnLine();
388 //=======================================================================
389 //function : HasVInternal
391 //=======================================================================
393 Standard_Boolean TopOpeBRep_LineInter::HasVInternal()
395 TopOpeBRep_VPointInterIterator VPI(*this);
396 for (; VPI.More(); VPI.Next()) {
397 if (VPI.CurrentVP().IsInternal()) return Standard_True;
399 return Standard_False;
403 //=======================================================================
404 //function : NbWPoint
406 //=======================================================================
408 Standard_Integer TopOpeBRep_LineInter::NbWPoint() const
410 switch (myTypeLineCurve)
412 case TopOpeBRep_WALKING : return myILW->NbPnts();
418 //=======================================================================
421 //=======================================================================
423 const TopOpeBRep_WPointInter& TopOpeBRep_LineInter::WPoint(const Standard_Integer IW)
425 switch (myTypeLineCurve)
427 case TopOpeBRep_RESTRICTION : myCurrentWP.Set(myILR->Point(IW)); break;
428 case TopOpeBRep_WALKING : myCurrentWP.Set(myILW->Point(IW)); break;
434 //=======================================================================
437 //=======================================================================
439 Handle(Geom_Curve) TopOpeBRep_LineInter::Curve() const
441 // Build the 3d curve
442 Handle(Geom_Curve) C3D;
443 switch (myTypeLineCurve) {
444 case TopOpeBRep_LINE :
445 C3D = new Geom_Line(myILG->Line()); break;
446 case TopOpeBRep_CIRCLE :
447 C3D = new Geom_Circle(myILG->Circle()); break;
448 case TopOpeBRep_ELLIPSE :
449 C3D = new Geom_Ellipse(myILG->Ellipse()); break;
450 case TopOpeBRep_PARABOLA :
451 C3D = new Geom_Parabola(myILG->Parabola()); break;
452 case TopOpeBRep_HYPERBOLA :
453 C3D = new Geom_Hyperbola(myILG->Hyperbola()); break;
455 TopOpeBRep_LineInter* p = (TopOpeBRep_LineInter*)this; // NYI deconst
456 p->SetOK(Standard_False);
462 //=======================================================================
465 //=======================================================================
467 Handle(Geom_Curve) TopOpeBRep_LineInter::Curve
468 (const Standard_Real parmin, const Standard_Real parmax) const
470 // Build the trimmed 3d curve
471 Handle(Geom_Curve) C3D = Curve();
472 Handle(Geom_TrimmedCurve) TC3D = new Geom_TrimmedCurve(C3D,parmin,parmax);
474 if ( TopOpeBRep_GettraceCONIC() ) {
475 cout<<"TopOpeBRep_LineInter::Curve on a ";
476 TopOpeBRep::Print(myTypeLineCurve,cout);cout<<endl;
477 cout<<" ... Trimmed from "<<parmin<<" to "<<parmax<<endl;
483 //=======================================================================
486 //=======================================================================
488 const TopoDS_Shape& TopOpeBRep_LineInter::Arc() const
490 if (myTypeLineCurve == TopOpeBRep_RESTRICTION) {
491 if(myILR->IsArcOnS1()) {
492 const Handle(Adaptor2d_HCurve2d)& AHC2D = myILR->ArcOnS1();
493 const BRepAdaptor_Curve2d& BC2DP = *((BRepAdaptor_Curve2d*)&(AHC2D->Curve2d()));
494 const TopoDS_Shape& S = BC2DP.Edge();
498 const Handle(Adaptor2d_HCurve2d)& AHC2D = myILR->ArcOnS2();
499 const BRepAdaptor_Curve2d& BC2DP = *((BRepAdaptor_Curve2d*)&(AHC2D->Curve2d()));
500 const TopoDS_Shape& S = BC2DP.Edge();
508 //=======================================================================
509 //function : ArcIsEdge
511 //=======================================================================
513 Standard_Boolean TopOpeBRep_LineInter::ArcIsEdge(const Standard_Integer Index) const
515 if (myTypeLineCurve == TopOpeBRep_RESTRICTION) {
516 const Standard_Boolean r = myILR->IsArcOnS1();
517 return ( Index == 2 ? !r : r );
519 return Standard_False;
522 //=======================================================================
523 //function : HasFirstPoint
525 //=======================================================================
527 Standard_Boolean TopOpeBRep_LineInter::HasFirstPoint() const
530 Standard_ProgramError::Raise("TopOpeBRep_LineInter::HasFirstPoint sur line != GLine");
531 return myILG->HasFirstPoint();
534 //=======================================================================
535 //function : HasLastPoint
537 //=======================================================================
539 Standard_Boolean TopOpeBRep_LineInter::HasLastPoint() const
542 Standard_ProgramError::Raise("TopOpeBRep_LineInter::HasLastPoint sur line != GLine");
543 return myILG->HasLastPoint();
546 //=======================================================================
547 //function : ComputeFaceFaceTransition
549 //=======================================================================
551 void TopOpeBRep_LineInter::ComputeFaceFaceTransition()
553 TopAbs_Orientation F1ori = myF1.Orientation();
554 TopAbs_Orientation F2ori = myF2.Orientation();
555 myLineTonF1=TopOpeBRep_FFTransitionTool::ProcessFaceTransition(*this,1,F2ori);
556 myLineTonF2=TopOpeBRep_FFTransitionTool::ProcessFaceTransition(*this,2,F1ori);
559 //=======================================================================
560 //function : FaceFaceTransition
562 //=======================================================================
563 const TopOpeBRepDS_Transition& TopOpeBRep_LineInter::FaceFaceTransition
564 (const Standard_Integer I) const
566 if (I == 1) return myLineTonF1;
567 if (I == 2) return myLineTonF2;
568 Standard_ProgramError::Raise("TopOpeBRep_LineInter::FaceFaceTransition");
572 //=======================================================================
573 //function : DumpType
575 //=======================================================================
577 void TopOpeBRep_LineInter::DumpType()const
580 TopOpeBRep::Print(myTypeLineCurve,cout);
584 //=======================================================================
585 //function : DumpVPoint
587 //=======================================================================
589 void TopOpeBRep_LineInter::DumpVPoint
591 (const Standard_Integer ,
592 const TCollection_AsciiString& ,
593 const TCollection_AsciiString& ) const
596 (const Standard_Integer I,
597 const TCollection_AsciiString& s1,
598 const TCollection_AsciiString& s2) const
600 const TopOpeBRep_VPointInter& VP = VPoint(I);
601 const gp_Pnt& P = VP.Value();
603 cout<<"L"<<Index()<<"P"<<VP.Index();
604 if (VP.Keep()) cout<<"K";
605 cout<<" "<<P.X()<<" "<<P.Y()<<" "<<P.Z();
610 //=======================================================================
611 //function : DumpBipoint
613 //=======================================================================
615 void TopOpeBRep_LineInter::DumpBipoint
617 (const TopOpeBRep_Bipoint& ,
618 const TCollection_AsciiString& ,
619 const TCollection_AsciiString& ) const
622 (const TopOpeBRep_Bipoint& bip,
623 const TCollection_AsciiString& s1,
624 const TCollection_AsciiString& s2) const
626 Standard_Integer i1 = bip.I1();
627 Standard_Integer i2 = bip.I2();
629 cout<<"("<<i1<<","<<i2<<")";
634 //=======================================================================
637 //=======================================================================
639 void TopOpeBRep_LineInter::SetOK(const Standard_Boolean B)
642 if (TopOpeBRepDS_GettraceDSF() || TopOpeBRepDS_GettraceDSNC()) {
644 cout<<"line "<<myIndex<<" (";
645 TopOpeBRep::Print(myTypeLineCurve,cout);cout<<") ";
646 if (!B) cout<<"OK->NOK"; else cout<<"NOK->OK";
654 //=======================================================================
655 //function : SetTraceIndex
657 //=======================================================================
659 void TopOpeBRep_LineInter::SetTraceIndex(const Standard_Integer exF1,
660 const Standard_Integer exF2)
666 //=======================================================================
667 //function : GetTraceIndex
669 //=======================================================================
671 void TopOpeBRep_LineInter::GetTraceIndex(Standard_Integer& exF1,
672 Standard_Integer& exF2)const
678 //=======================================================================
679 //function : DumpLineTransitions
681 //=======================================================================
682 Standard_OStream& TopOpeBRep_LineInter::DumpLineTransitions(Standard_OStream& OS) const
685 OS<<"transition from f1 / f2 "; TopAbs::Print(myF2.Orientation(),OS);
686 OS<<" : "; myLineTonF1.Dump(OS); OS<<endl;
687 OS<<"transition from f2 / f1 "; TopAbs::Print(myF1.Orientation(),OS);
688 OS<<" : "; myLineTonF2.Dump(OS); OS<<endl;