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 | |
42cf5bc1 |
17 | |
18 | #include <BRep_Tool.hxx> |
7fd59977 |
19 | #include <BRepAdaptor_Curve.hxx> |
20 | #include <BRepAdaptor_Curve2d.hxx> |
7fd59977 |
21 | #include <gp_Vec.hxx> |
22 | #include <Precision.hxx> |
42cf5bc1 |
23 | #include <Standard_ProgramError.hxx> |
24 | #include <TopoDS.hxx> |
25 | #include <TopoDS_Shape.hxx> |
26 | #include <TopOpeBRepDS_CurvePointInterference.hxx> |
27 | #include <TopOpeBRepDS_define.hxx> |
28 | #include <TopOpeBRepDS_Edge3dInterferenceTool.hxx> |
29 | #include <TopOpeBRepDS_EdgeVertexInterference.hxx> |
30 | #include <TopOpeBRepDS_Interference.hxx> |
7fd59977 |
31 | #include <TopOpeBRepTool_EXPORT.hxx> |
32 | #include <TopOpeBRepTool_TOOL.hxx> |
7fd59977 |
33 | |
34 | #define M_FORWARD(st) (st == TopAbs_FORWARD) |
35 | #define M_REVERSED(st) (st == TopAbs_REVERSED) |
36 | |
37 | static void FUN_Raise() |
38 | { |
9775fa61 |
39 | throw Standard_ProgramError("Edge3dInterferenceTool"); |
7fd59977 |
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; |
7fd59977 |
95 | if (ok) ok = (dist <= tol); |
96 | } |
97 | return ok; |
98 | } |
99 | |
100 | static Standard_Boolean FUN_keepIonF |
101 | (const gp_Vec& tgref, const Standard_Real& parE, const TopoDS_Edge& E, const TopoDS_Face& F, |
102 | const Standard_Real& tola) |
103 | // returns true if an interference I=(TonF,G=point/vertex,S=<E>) |
104 | // is to add to the Edge3dInterferenceTool resolving 3d complex transitions |
105 | // on edge E |
106 | { |
107 | gp_Vec tmp; Standard_Boolean ok = TopOpeBRepTool_TOOL::TggeomE(parE,E,tmp); |
108 | if (!ok) return Standard_False; |
109 | gp_Dir tgE = gp_Dir(tmp); |
110 | Standard_Real prod = Abs(tgref.Dot(tgE)); |
111 | if (Abs(1-prod) < tola) return Standard_False; // <Eref> & <E> are tangent edges |
112 | gp_Vec dd; ok = FUN_tool_nggeomF(parE,E,F,dd); gp_Dir ngF(dd); |
113 | if (!ok) return Standard_False; |
114 | prod = Abs((tgref^tgE).Dot(ngF)); |
115 | if (Abs(1-prod) < tola) return Standard_False; |
116 | return Standard_True; |
117 | } |
118 | |
119 | // ---------------------------------------------------------------------- |
120 | // EDGE/FACE interferences reducing : |
121 | // |
122 | // ---------------------------------------------------------------------- |
123 | |
124 | //======================================================================= |
125 | //function : TopOpeBRepDS_Edge3dInterferenceTool |
126 | //purpose : |
127 | //======================================================================= |
128 | |
129 | TopOpeBRepDS_Edge3dInterferenceTool::TopOpeBRepDS_Edge3dInterferenceTool() |
130 | : myFaceOriented(0),myrefdef(Standard_False) |
131 | { |
132 | } |
133 | |
134 | |
135 | //======================================================================= |
136 | //function : InitPointVertex |
137 | //purpose : Initializes reference data for edge/face complex transition |
138 | //======================================================================= |
139 | // I = (TonF, G=POINT/VERTEX, S=<E>) interference on <Eref> |
140 | // G has parameter <paronEref> on <Eref>, <paronE> on <E> |
141 | |
142 | void TopOpeBRepDS_Edge3dInterferenceTool::InitPointVertex |
143 | (const Standard_Integer IsVertex, const TopoDS_Shape& VonOO) |
144 | { |
145 | myIsVertex = IsVertex; |
146 | if (IsVertex > 1) myVonOO = VonOO; |
147 | } |
148 | |
149 | //======================================================================= |
150 | //function : Init |
151 | //purpose : Initializes reference data for edge/face complex transition |
152 | //======================================================================= |
153 | // I = (T on <F>, G=POINT/VERTEX, S=<E>) interference on <Eref> |
154 | // G has parameter <paronEref> on <Eref>, <paronE> on <E> |
155 | // -- <E> is edge of <F> -- |
156 | |
157 | void TopOpeBRepDS_Edge3dInterferenceTool::Init |
158 | (const TopoDS_Shape& Eref, |
159 | const TopoDS_Shape& E, const TopoDS_Shape& F, |
160 | const Handle(TopOpeBRepDS_Interference)& I) |
161 | { |
162 | const TopoDS_Edge& EEref = TopoDS::Edge(Eref); |
163 | const TopoDS_Edge& EE = TopoDS::Edge(E); |
164 | const TopoDS_Face& FF = TopoDS::Face(F); |
165 | myrefdef = Standard_False; |
166 | |
167 | myTole = Precision::Angular(); // NYI |
168 | |
d20d815b |
169 | Standard_Real pref=0.0; Standard_Boolean ok = ::FUN_hasparam(I, pref); |
7fd59977 |
170 | if (!ok) {FUN_Raise(); return;} |
171 | // <myP3d> : |
172 | { |
173 | BRepAdaptor_Curve BC(EEref); |
174 | myP3d = BC.Value(pref); |
175 | } |
176 | gp_Vec tmp; ok = TopOpeBRepTool_TOOL::TggeomE(pref,EEref,tmp); |
177 | if (!ok) {FUN_Raise(); return;} |
178 | gp_Dir tgref(tmp); |
179 | |
180 | Standard_Real pOO; ok = ::FUN_paronOOE(EE,myIsVertex,myVonOO,myP3d,pOO); |
181 | if (!ok) {FUN_Raise(); return;} |
182 | ok = TopOpeBRepTool_TOOL::TggeomE(pOO,EE,tmp); |
183 | if (!ok) {FUN_Raise(); return;} |
184 | gp_Dir tgOO(tmp); |
185 | |
186 | Standard_Real dot = tgref.Dot(tgOO); |
187 | dot = 1 - Abs(dot); |
188 | Standard_Real tola = Precision::Confusion(); |
189 | Standard_Boolean Esdm = (Abs(dot) < tola); |
190 | if (Esdm) return; |
191 | // NYI : il faut rejeter les interf I = (T,G,S=E) / E sdm with Eref |
192 | |
193 | // <myrefdef> : |
194 | ok = ::FUN_keepIonF(tgref,pOO,EE,FF,myTole); |
195 | if (!ok) { |
196 | // <Eref> is tangent to <F>, |
197 | // If the transition is FORWARD or REVERSED, it describes a 2d |
198 | // transition (while crossing <E> on <F>), we do not keep it. |
199 | const TopAbs_Orientation& O = I->Transition().Orientation(TopAbs_IN); |
200 | Standard_Boolean is2d = M_FORWARD(O) || M_REVERSED(O); |
201 | if (is2d) return; |
202 | } |
203 | myrefdef = Standard_True; |
204 | |
205 | // <myFaceOriented> : |
206 | myFaceOriented = I->Transition().Index(); |
207 | |
208 | // <myTgtref> |
209 | myTgtref = tgref; |
210 | |
211 | gp_Dir Norm = tgOO^tgref; |
212 | myTool.Reset(tgOO, Norm); |
213 | } |
214 | |
215 | |
216 | //======================================================================= |
217 | //function : Add |
218 | //purpose : |
219 | //======================================================================= |
220 | // I = (T on <F>, G=POINT/VERTEX, S=<E>) interference on <Eref> |
221 | void TopOpeBRepDS_Edge3dInterferenceTool::Add |
222 | (const TopoDS_Shape& Eref,const TopoDS_Shape& E, const TopoDS_Shape& F,const Handle(TopOpeBRepDS_Interference)& I) |
223 | { |
224 | if (!myrefdef) { |
225 | Init(Eref,E,F,I); |
226 | // return; |
227 | } |
228 | |
229 | if (!myrefdef) return; |
230 | |
231 | const TopoDS_Edge& EE = TopoDS::Edge(E); |
232 | const TopoDS_Face& FF = TopoDS::Face(F); |
233 | |
234 | Standard_Real pOO; Standard_Boolean ok = ::FUN_paronOOE(EE,myIsVertex,myVonOO,myP3d,pOO); |
235 | if (!ok) return; |
236 | gp_Pnt2d uv; |
237 | { |
238 | BRepAdaptor_Curve2d BC2d(EE,FF); |
239 | uv = BC2d.Value(pOO); |
240 | } |
241 | |
242 | ok = ::FUN_keepIonF(myTgtref,pOO,EE,FF,myTole); |
243 | if (!ok) { |
244 | const TopAbs_Orientation& O = I->Transition().Orientation(TopAbs_IN); |
245 | Standard_Boolean is2d = M_FORWARD(O) || M_REVERSED(O); |
246 | if (is2d) return; |
247 | } |
248 | |
249 | TopAbs_Orientation oriloc = I->Transition().Orientation(TopAbs_IN); |
250 | TopAbs_Orientation oritan; ok = FUN_tool_orientEinFFORWARD(EE, FF, oritan); // xpu : 30/12/97 |
251 | if (!ok) return; |
252 | |
253 | gp_Dir Norm(FUN_tool_nggeomF(uv,FF)); |
254 | myTool.Compare(myTole, Norm, oriloc, oritan); |
255 | } |
256 | |
257 | |
258 | //======================================================================= |
259 | //function : Transition |
260 | //purpose : |
261 | //======================================================================= |
262 | |
263 | void TopOpeBRepDS_Edge3dInterferenceTool::Transition(const Handle(TopOpeBRepDS_Interference)& I) const |
264 | { |
265 | TopOpeBRepDS_Transition& T = I->ChangeTransition(); |
266 | I->Support(myFaceOriented); |
267 | |
268 | TopAbs_State stb = myTool.StateBefore(); |
269 | TopAbs_State sta = myTool.StateAfter(); |
270 | T.Set(stb,sta); |
271 | } |