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 | |
34 | static 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 | |
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; |
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 | |
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 | |
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> |
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 | } |