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