0024886: BRepOffsetAPI_NormalProjection failure
[occt.git] / src / TopOpeBRepDS / TopOpeBRepDS_EdgeInterferenceTool.cxx
1 // Created on: 1994-11-08
2 // Created by: Jean Yves LEBEY
3 // Copyright (c) 1994-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
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.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #include <TopOpeBRepDS_EdgeInterferenceTool.ixx>
18
19 #include <TopOpeBRepDS_CurvePointInterference.hxx>
20 #include <TopOpeBRepDS_EdgeVertexInterference.hxx>
21 #include <BRepLProp_CLProps.hxx>
22 #include <BRep_Tool.hxx>
23 #include <TopoDS_Iterator.hxx>
24 #include <Precision.hxx>
25 #include <TopoDS.hxx>
26 #include <TopOpeBRepTool_ShapeTool.hxx>
27 #include <Standard_ProgramError.hxx>
28
29 #ifdef DEB
30 Standard_EXPORT Standard_Boolean TopOpeBRepDS_GettracePEI();
31 #endif
32
33 //=======================================================================
34 //function : TopOpeBRepDS_EdgeInterferenceTool
35 //purpose  : 
36 //=======================================================================
37
38  TopOpeBRepDS_EdgeInterferenceTool::TopOpeBRepDS_EdgeInterferenceTool()
39 {
40 }
41
42 static Standard_Real Parameter(const Handle(TopOpeBRepDS_Interference)& I)
43
44   Standard_Real p = 0; 
45   if      ( I->IsKind(STANDARD_TYPE(TopOpeBRepDS_EdgeVertexInterference)) )
46     p = Handle(TopOpeBRepDS_EdgeVertexInterference)::DownCast(I)->Parameter();
47   else if ( I->IsKind(STANDARD_TYPE(TopOpeBRepDS_CurvePointInterference)) )
48     p = Handle(TopOpeBRepDS_CurvePointInterference)::DownCast(I)->Parameter();
49   else {
50 #ifdef DEB
51     cout<<"EdgeInterference : mauvais type d'interference"<<endl;
52 #endif
53     Standard_ProgramError::Raise("TopOpeBRepDS_EdgeInterferenceTool1");
54   }
55   return p;
56 }
57   
58
59 //=======================================================================
60 //function : Init
61 //purpose  : 
62 //=======================================================================
63
64 void TopOpeBRepDS_EdgeInterferenceTool::Init
65 (const TopoDS_Shape& E, const Handle(TopOpeBRepDS_Interference)& I)
66 {
67   myEdgeOrientation = E.Orientation();
68   myEdgeOriented    = I->Support();
69   
70   // NYI 971219 : on ne tient pas compte de l'orientation de E = arete-mere de l'interference I
71   if (myEdgeOrientation == TopAbs_INTERNAL || 
72       myEdgeOrientation == TopAbs_EXTERNAL) {
73     return;
74   }
75   
76   // la premiere arete orientee est gardee dans myEdgeOriented pour MAJ de
77   // l'arete croisee dans l'interference resultat.
78
79   // par = parametre sur l'arete croisee
80   Standard_Real par = ::Parameter(I);
81   gp_Dir T,N; Standard_Real C;
82   TopOpeBRepTool_ShapeTool::EdgeData(E,par,T,N,C);
83   myTool.Reset(T,N,C);
84 }
85
86 //=======================================================================
87 //function : Add
88 //purpose  : 
89 //=======================================================================
90
91 void TopOpeBRepDS_EdgeInterferenceTool::Add
92 (const TopoDS_Shape& E,
93  const TopoDS_Shape& V,
94  const Handle(TopOpeBRepDS_Interference)& I)
95 {
96   TopAbs_Orientation Eori = E.Orientation();
97   if (Eori == TopAbs_INTERNAL || 
98       Eori == TopAbs_EXTERNAL) {
99     return;
100   }
101
102   // premiere interference sur arete orientee : Init
103   if (myEdgeOrientation == TopAbs_INTERNAL || 
104       myEdgeOrientation == TopAbs_EXTERNAL) {
105     Init(E,I);
106     return;
107   }
108
109   // V est un sommet de E ?
110   Standard_Boolean VofE = Standard_False;
111   TopoDS_Iterator it(E,Standard_False);
112   for ( ; it.More(); it.Next() ) {
113     const TopoDS_Shape& S = it.Value();
114     if ( S.IsSame(V) ) {
115       VofE = Standard_True; 
116       break;
117     }
118   }
119  
120 #ifdef DEB
121   if (TopOpeBRepDS_GettracePEI() && !VofE) {
122     cout<<"===================== VofE = False"<<endl;
123   }
124 #endif 
125   if(!VofE)
126   {
127     return;
128   }
129   // V est un sommet de E
130   const TopoDS_Vertex& VV = TopoDS::Vertex(V);
131   const TopoDS_Edge& EE = TopoDS::Edge(E);
132   Standard_Real par = BRep_Tool::Parameter(VV,EE);
133   
134   gp_Dir T,N; Standard_Real C;
135   Standard_Real tol = TopOpeBRepTool_ShapeTool::EdgeData(E,par,T,N,C);
136   TopAbs_Orientation oriloc = I->Transition().Orientation(TopAbs_IN);
137   TopAbs_Orientation oritan = it.Value().Orientation();
138   myTool.Compare(tol,T,N,C,oriloc,oritan);
139 }
140
141 //=======================================================================
142 //function : Add
143 //purpose  : 
144 //=======================================================================
145
146 void TopOpeBRepDS_EdgeInterferenceTool::Add
147 (const TopoDS_Shape& E,
148 // const TopOpeBRepDS_Point& P,
149  const TopOpeBRepDS_Point& ,
150  const Handle(TopOpeBRepDS_Interference)& I)
151 {
152   TopAbs_Orientation Eori = E.Orientation();
153   if (Eori == TopAbs_INTERNAL || 
154       Eori == TopAbs_EXTERNAL) {
155     return;
156   }
157
158   // premiere interference sur arete orientee : Init
159   if (myEdgeOrientation == TopAbs_INTERNAL || 
160       myEdgeOrientation == TopAbs_EXTERNAL) {
161     Init(E,I);
162     return;
163   }
164
165   Standard_Real par = ::Parameter(I);
166   
167   gp_Dir T,N; Standard_Real C;
168   Standard_Real tol = TopOpeBRepTool_ShapeTool::EdgeData(E,par,T,N,C);
169   TopAbs_Orientation oriloc = I->Transition().Orientation(TopAbs_IN);
170   TopAbs_Orientation oritan = TopAbs_INTERNAL;
171   myTool.Compare(tol,T,N,C,oriloc,oritan);
172 }
173
174 //=======================================================================
175 //function : Transition
176 //purpose  : 
177 //=======================================================================
178
179 void TopOpeBRepDS_EdgeInterferenceTool::Transition
180 (const Handle(TopOpeBRepDS_Interference)& I) const 
181 {
182   TopOpeBRepDS_Transition& T = I->ChangeTransition();
183
184   if (myEdgeOrientation == TopAbs_INTERNAL) {
185     T.Set(TopAbs_IN,TopAbs_IN);
186   }
187   else if (myEdgeOrientation == TopAbs_EXTERNAL) {
188     T.Set(TopAbs_OUT,TopAbs_OUT);
189   }
190   else {
191     I->Support(myEdgeOriented);
192     T.Set(myTool.StateBefore(),myTool.StateAfter());
193   }
194 }