0025266: Debug statements in the source are getting flushed on to the console
[occt.git] / src / TopOpeBRepDS / TopOpeBRepDS_Edge3dInterferenceTool.cxx
1 // Created on: 1997-12-24
2 // Created by: Prestataire Xuan PHAM PHU
3 // Copyright (c) 1997-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_Edge3dInterferenceTool.ixx>
18 #include <TopOpeBRepDS_CurvePointInterference.hxx>
19 #include <TopOpeBRepDS_EdgeVertexInterference.hxx>
20 #include <BRepAdaptor_Curve.hxx>
21 #include <BRepAdaptor_Curve2d.hxx>
22 #include <BRep_Tool.hxx>
23 #include <TopoDS.hxx>
24 #include <gp_Vec.hxx>
25 #include <Precision.hxx>
26 #include <TopOpeBRepTool_EXPORT.hxx>
27 #include <TopOpeBRepTool_TOOL.hxx>
28 #include <TopOpeBRepDS_define.hxx>
29 #include <Standard_ProgramError.hxx>
30
31 #define M_FORWARD(st) (st == TopAbs_FORWARD)
32 #define M_REVERSED(st) (st == TopAbs_REVERSED)
33
34 static void FUN_Raise()
35 {
36   Standard_ProgramError::Raise("Edge3dInterferenceTool");
37 #ifdef TOPOPEBREPDS_DEB
38   cout <<" ************** Failure in Edge3dInterferenceTool"<<endl;
39 #endif
40 }
41
42 #define POINT        (0)
43 #define VERTEXonref  (1)
44 #define VERTEXonOO   (2)
45 #define VERTEXonOref (3)
46
47 // myIsVertex :
48 // ------------
49 // POINT :<Eref> interfers with <E> at a point
50 // <Eref> interfers with <E> at a vertex V,
51 //   VERTEXonref  : V is on shape of <Eref>
52 //   VERTEXonOO   : V is on shape of <E>
53 //   VERTEXonOref : V is on 2 shapes.
54
55 // myVonOO : only for VERTEXonOO || VERTEXonOref
56 // --------
57
58 // myP3d : only for POINT || VERTEXonref
59 // -------
60
61 static Standard_Boolean FUN_hasparam(const Handle(TopOpeBRepDS_Interference)& I, Standard_Real& paronE)
62
63   // prequesitory : shapes <SIX> -> edge <E>
64   // ? <paronE> = parameter of <G> on <E>
65   TopOpeBRepDS_Kind GT = I->GeometryType();  
66   Standard_Boolean point =  (GT == TopOpeBRepDS_POINT);
67   Standard_Boolean vertex = (GT == TopOpeBRepDS_VERTEX);
68   if (point) {
69     Handle(TopOpeBRepDS_CurvePointInterference) CPI = 
70       Handle(TopOpeBRepDS_CurvePointInterference)::DownCast(I);
71     if (CPI.IsNull()) return Standard_False;
72     paronE = CPI->Parameter();
73   }
74   if (vertex) {
75     Handle(TopOpeBRepDS_EdgeVertexInterference) EVI = 
76       Handle(TopOpeBRepDS_EdgeVertexInterference)::DownCast(I);    
77     if (EVI.IsNull()) return Standard_False;
78     paronE = EVI->Parameter(); 
79   }
80   return Standard_True;
81 }
82
83 static Standard_Boolean FUN_paronOOE
84 (const TopoDS_Edge& OOE,const Standard_Integer IsVertex, const TopoDS_Shape& VonOO, const gp_Pnt& P3d, 
85  Standard_Real& paronOOE)
86 {  
87   Standard_Boolean ok = Standard_False;
88   Standard_Boolean hasVonOO = (IsVertex > 1);
89   if (hasVonOO) ok = FUN_tool_parVonE(TopoDS::Vertex(VonOO),OOE,paronOOE);
90   else {
91     Standard_Real dist; ok = FUN_tool_projPonE(P3d,OOE,paronOOE,dist);
92     Standard_Real tol1 = BRep_Tool::Tolerance(OOE);
93     Standard_Real tol2 = tol1*1.e3;
94     Standard_Real tol = tol2; if (tol > 1.e-2) tol = 1.e-2;
95 #ifdef DEBDEB
96     cout<<"$$$$$$$$$$$$$$$$$$$$$$$$ FUN_paronOOE : dist "<<dist<<" tol1 "<<tol1<<endl;
97     cout<<"$$$$$$$$$$$$$$$$$$$$$$$$ FUN_paronOOE : dist "<<dist<<" tol "<<tol<<endl;
98 #endif
99     if (ok) ok = (dist <= tol);
100   }
101   return ok;
102 }
103
104 static Standard_Boolean FUN_keepIonF
105 (const gp_Vec& tgref, const Standard_Real& parE, const TopoDS_Edge& E, const TopoDS_Face& F,
106  const Standard_Real& tola)
107 // returns true if an interference I=(TonF,G=point/vertex,S=<E>)
108 // is to add to the Edge3dInterferenceTool resolving 3d complex transitions
109 // on edge E
110 {  
111   gp_Vec tmp; Standard_Boolean ok = TopOpeBRepTool_TOOL::TggeomE(parE,E,tmp);
112   if (!ok) return Standard_False;    
113   gp_Dir tgE = gp_Dir(tmp);
114   Standard_Real prod = Abs(tgref.Dot(tgE));
115   if (Abs(1-prod) < tola) return Standard_False; // <Eref> & <E> are tangent edges 
116   gp_Vec dd; ok = FUN_tool_nggeomF(parE,E,F,dd); gp_Dir ngF(dd);
117   if (!ok) return Standard_False;  
118   prod = Abs((tgref^tgE).Dot(ngF));
119   if (Abs(1-prod) < tola) return Standard_False;
120   return Standard_True;
121 }
122
123 // ----------------------------------------------------------------------
124 //             EDGE/FACE interferences reducing :
125 //
126 // ----------------------------------------------------------------------
127
128 //=======================================================================
129 //function : TopOpeBRepDS_Edge3dInterferenceTool
130 //purpose  : 
131 //=======================================================================
132
133 TopOpeBRepDS_Edge3dInterferenceTool::TopOpeBRepDS_Edge3dInterferenceTool()
134 :  myFaceOriented(0),myrefdef(Standard_False)
135
136 }
137
138
139 //=======================================================================
140 //function : InitPointVertex
141 //purpose  : Initializes reference data for edge/face complex transition           
142 //=======================================================================
143 // I = (TonF, G=POINT/VERTEX, S=<E>) interference on <Eref>
144 // G has parameter <paronEref> on <Eref>, <paronE> on <E>
145
146 void TopOpeBRepDS_Edge3dInterferenceTool::InitPointVertex
147 (const Standard_Integer IsVertex, const TopoDS_Shape& VonOO)
148 {
149   myIsVertex = IsVertex;
150   if (IsVertex > 1) myVonOO = VonOO;
151 }
152
153 //=======================================================================
154 //function : Init
155 //purpose  : Initializes reference data for edge/face complex transition           
156 //=======================================================================
157 // I = (T on <F>, G=POINT/VERTEX, S=<E>) interference on <Eref>
158 // G has parameter <paronEref> on <Eref>, <paronE> on <E>
159 // -- <E> is edge of <F> --
160
161 void TopOpeBRepDS_Edge3dInterferenceTool::Init
162 (const TopoDS_Shape& Eref, 
163  const TopoDS_Shape& E, const TopoDS_Shape& F, 
164  const Handle(TopOpeBRepDS_Interference)& I)
165 {  
166   const TopoDS_Edge& EEref = TopoDS::Edge(Eref);
167   const TopoDS_Edge& EE = TopoDS::Edge(E);
168   const TopoDS_Face& FF = TopoDS::Face(F);
169   myrefdef = Standard_False;
170
171   myTole = Precision::Angular(); // NYI
172
173   Standard_Real pref=0.0; Standard_Boolean ok = ::FUN_hasparam(I, pref);
174   if (!ok) {FUN_Raise(); return;}  
175   // <myP3d> :
176   {
177     BRepAdaptor_Curve BC(EEref);
178     myP3d = BC.Value(pref);
179   }
180   gp_Vec tmp; ok = TopOpeBRepTool_TOOL::TggeomE(pref,EEref,tmp); 
181   if (!ok) {FUN_Raise(); return;}  
182   gp_Dir tgref(tmp);
183   
184   Standard_Real pOO; ok = ::FUN_paronOOE(EE,myIsVertex,myVonOO,myP3d,pOO);
185   if (!ok) {FUN_Raise(); return;}
186   ok = TopOpeBRepTool_TOOL::TggeomE(pOO,EE,tmp); 
187   if (!ok) {FUN_Raise(); return;}  
188   gp_Dir tgOO(tmp);
189
190   Standard_Real dot = tgref.Dot(tgOO);
191   dot = 1 - Abs(dot);
192   Standard_Real tola = Precision::Confusion();
193   Standard_Boolean Esdm = (Abs(dot) < tola);
194   if (Esdm) return;
195   // NYI : il faut rejeter les interf I = (T,G,S=E) / E sdm with Eref
196
197   // <myrefdef> :
198   ok = ::FUN_keepIonF(tgref,pOO,EE,FF,myTole);
199   if (!ok) {
200     // <Eref> is tangent to <F>,
201     // If the transition is FORWARD or REVERSED, it describes a 2d 
202     // transition (while crossing <E> on <F>), we do not keep it.
203     const TopAbs_Orientation& O = I->Transition().Orientation(TopAbs_IN);
204     Standard_Boolean is2d = M_FORWARD(O) || M_REVERSED(O);
205     if (is2d) return;
206   }
207   myrefdef = Standard_True;
208
209   // <myFaceOriented> :
210   myFaceOriented = I->Transition().Index();
211
212   // <myTgtref>
213   myTgtref = tgref;
214
215   gp_Dir Norm = tgOO^tgref;  
216   myTool.Reset(tgOO, Norm);
217 }
218
219
220 //=======================================================================
221 //function : Add
222 //purpose  : 
223 //=======================================================================
224 // I = (T on <F>, G=POINT/VERTEX, S=<E>) interference on <Eref>
225 void TopOpeBRepDS_Edge3dInterferenceTool::Add
226 (const TopoDS_Shape& Eref,const TopoDS_Shape& E, const TopoDS_Shape& F,const Handle(TopOpeBRepDS_Interference)& I)
227 {
228   if (!myrefdef) {
229     Init(Eref,E,F,I);
230 //    return;
231   }
232
233   if (!myrefdef) return;
234
235   const TopoDS_Edge& EE = TopoDS::Edge(E);
236   const TopoDS_Face& FF = TopoDS::Face(F);
237
238   Standard_Real pOO; Standard_Boolean ok = ::FUN_paronOOE(EE,myIsVertex,myVonOO,myP3d,pOO);
239   if (!ok) return;
240   gp_Pnt2d uv;
241   {
242     BRepAdaptor_Curve2d BC2d(EE,FF);
243     uv = BC2d.Value(pOO);
244   }
245
246   ok = ::FUN_keepIonF(myTgtref,pOO,EE,FF,myTole);
247   if (!ok) {
248     const TopAbs_Orientation& O = I->Transition().Orientation(TopAbs_IN);
249     Standard_Boolean is2d = M_FORWARD(O) || M_REVERSED(O);
250     if (is2d) return;
251   }
252
253   TopAbs_Orientation oriloc = I->Transition().Orientation(TopAbs_IN);
254   TopAbs_Orientation oritan; ok = FUN_tool_orientEinFFORWARD(EE, FF, oritan); // xpu : 30/12/97
255   if (!ok) return;
256
257   gp_Dir Norm(FUN_tool_nggeomF(uv,FF)); 
258   myTool.Compare(myTole, Norm, oriloc, oritan);
259 }
260
261
262 //=======================================================================
263 //function : Transition
264 //purpose  : 
265 //=======================================================================
266
267 void TopOpeBRepDS_Edge3dInterferenceTool::Transition(const Handle(TopOpeBRepDS_Interference)& I) const 
268 {
269   TopOpeBRepDS_Transition& T = I->ChangeTransition();
270   I->Support(myFaceOriented);
271
272   TopAbs_State stb = myTool.StateBefore();
273   TopAbs_State sta = myTool.StateAfter();
274   T.Set(stb,sta);
275 }