0025418: Debug output to be limited to OCC development environment
[occt.git] / src / TopOpeBRepDS / TopOpeBRepDS_Edge3dInterferenceTool.cxx
CommitLineData
b311480e 1// Created on: 1997-12-24
2// Created by: Prestataire Xuan PHAM PHU
3// Copyright (c) 1997-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 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
973c2be1 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.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 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
34static void FUN_Raise()
35{
36 Standard_ProgramError::Raise("Edge3dInterferenceTool");
0797d9d3 37#ifdef OCCT_DEBUG
7fd59977 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
61static 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
83static 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;
0797d9d3 95#ifdef OCCT_DEBUG
7fd59977 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
104static 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
133TopOpeBRepDS_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
146void 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
161void 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
d20d815b 173 Standard_Real pref=0.0; Standard_Boolean ok = ::FUN_hasparam(I, pref);
7fd59977 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>
225void 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
267void 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}