b311480e |
1 | // Created on: 1994-11-08 |
2 | // Created by: Jean Yves LEBEY |
3 | // Copyright (c) 1994-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 | |
7fd59977 |
17 | |
7fd59977 |
18 | #include <BRep_Tool.hxx> |
19 | #include <BRepAdaptor_Curve2d.hxx> |
20 | #include <BRepAdaptor_Surface.hxx> |
21 | #include <BRepLProp_SLProps.hxx> |
42cf5bc1 |
22 | #include <Extrema_ExtPS.hxx> |
23 | #include <gp_Pnt.hxx> |
7fd59977 |
24 | #include <gp_Sphere.hxx> |
42cf5bc1 |
25 | #include <Precision.hxx> |
7fd59977 |
26 | #include <Standard_ProgramError.hxx> |
42cf5bc1 |
27 | #include <TopExp_Explorer.hxx> |
28 | #include <TopoDS.hxx> |
29 | #include <TopoDS_Shape.hxx> |
30 | #include <TopOpeBRepDS_Curve.hxx> |
31 | #include <TopOpeBRepDS_define.hxx> |
32 | #include <TopOpeBRepDS_FaceInterferenceTool.hxx> |
33 | #include <TopOpeBRepDS_Interference.hxx> |
7fd59977 |
34 | #include <TopOpeBRepDS_ProcessInterferencesTool.hxx> |
42cf5bc1 |
35 | #include <TopOpeBRepDS_ShapeShapeInterference.hxx> |
7fd59977 |
36 | #include <TopOpeBRepTool_EXPORT.hxx> |
42cf5bc1 |
37 | #include <TopOpeBRepTool_ShapeTool.hxx> |
7fd59977 |
38 | #include <TopOpeBRepTool_TOOL.hxx> |
7fd59977 |
39 | |
7fd59977 |
40 | static Standard_Boolean STATIC_TOREVERSE = Standard_False; // xpu150498 |
41 | #define M_FORWARD(ori) (ori == TopAbs_FORWARD) |
42 | #define M_REVERSED(ori) (ori == TopAbs_REVERSED) |
43 | |
44 | //------------------------------------------------------ |
9775fa61 |
45 | static void FUN_RaiseError(){throw Standard_ProgramError("TopOpeBRepDS_FaceInterferenceTool");} |
7fd59977 |
46 | |
47 | //------------------------------------------------------ |
48 | Standard_EXPORT Standard_Boolean FUN_Parameters |
49 | (const gp_Pnt& Pnt,const TopoDS_Shape& F,Standard_Real& u,Standard_Real& v) |
50 | { |
51 | BRepAdaptor_Surface Surf(TopoDS::Face(F)); |
52 | // Get 2d coord of the projection of <Pnt> on surface of <F>. |
53 | Standard_Real uvtol = Surf.Tolerance(); |
54 | Standard_Real fu=Surf.FirstUParameter(),lu=Surf.LastUParameter(); |
55 | Standard_Real fv=Surf.FirstVParameter(),lv=Surf.LastVParameter(); |
56 | Extrema_ExtPS extps(Pnt,Surf,fu,lu,fv,lv,uvtol,uvtol); |
57 | if (!extps.IsDone()) { |
58 | return Standard_False; |
59 | } |
60 | if (extps.NbExt() == 0) { |
61 | return Standard_False; |
62 | } |
63 | extps.Point(1).Parameter(u,v); |
64 | |
65 | // xpu281098 : CTS21216 (FIR, f4,e7on) |
66 | Standard_Real d2 = extps.SquareDistance(1); |
67 | Standard_Real tolF = BRep_Tool::Tolerance(TopoDS::Face(F)); |
68 | Standard_Boolean ok = (d2 < tolF*tolF*1.e6); // NYINYI |
69 | return ok; |
70 | } |
71 | |
7fd59977 |
72 | //------------------------------------------------------ |
73 | Standard_EXPORT void FUN_ComputeGeomData |
74 | (const TopoDS_Shape& F,const gp_Pnt2d& uv,gp_Dir& Norm) |
75 | { |
76 | gp_Vec ngF = FUN_tool_nggeomF(uv,TopoDS::Face(F)); |
77 | Norm = gp_Dir(ngF); |
78 | } |
79 | |
80 | //------------------------------------------------------ |
81 | static Standard_Boolean FUN_sphere(const TopoDS_Shape& F) |
82 | { |
83 | Handle(Geom_Surface) su = TopOpeBRepTool_ShapeTool::BASISSURFACE(TopoDS::Face(F)); |
84 | GeomAdaptor_Surface GAS(su); |
85 | return (GAS.GetType() == GeomAbs_Sphere); |
86 | } |
87 | |
7fd59977 |
88 | //------------------------------------------------------ |
89 | Standard_EXPORT void FUN_ComputeGeomData |
90 | (const TopoDS_Shape& F,const gp_Pnt2d& uv, |
91 | gp_Dir& Norm,gp_Dir& D1,gp_Dir& D2,Standard_Real& Cur1,Standard_Real& Cur2) |
92 | { |
93 | BRepAdaptor_Surface surf(TopoDS::Face(F)); |
94 | Standard_Real uu = uv.X(),vv = uv.Y(); |
95 | |
96 | Standard_Boolean sphere = FUN_sphere(F); |
97 | Standard_Boolean plane = FUN_tool_plane(F); |
98 | |
99 | // Getting the principle directions,the normal and the curvatures |
100 | BRepLProp_SLProps props(surf,uu,vv,2,Precision::Confusion()); |
101 | Standard_Boolean curdef = props.IsCurvatureDefined(); |
9775fa61 |
102 | if (!curdef) throw Standard_ProgramError("TopOpeBRepDS_FaceInterferenceTool::Init"); |
7fd59977 |
103 | Standard_Boolean umbilic = props.IsUmbilic(); |
104 | if (umbilic) { |
105 | Cur1 = Cur2 = props.MeanCurvature(); |
106 | |
107 | // xpu030998 : cto901A3 |
108 | Standard_Real toll = 1.e-8; |
109 | Standard_Boolean ooplane = (Abs(Cur1)<toll) && (Abs(Cur2)<toll); |
110 | plane = plane || ooplane; |
111 | |
112 | if (plane) |
113 | Norm = FUN_tool_nggeomF(uv, TopoDS::Face(F)); |
114 | else if (sphere) { |
115 | gp_Pnt center = surf.Sphere().Location(); |
116 | gp_Pnt value = surf.Value(uu,vv); |
117 | Norm = gp_Dir(gp_Vec(center,value)); // recall : input data for TopTrans_SurfaceTransition |
118 | // describes "direct" geometry |
119 | } |
120 | else |
9775fa61 |
121 | throw Standard_Failure("FUN_ComputeGeomData"); |
7fd59977 |
122 | |
123 | D1 = Norm; Standard_Real x = D1.X(),y = D1.Y(),z = D1.Z(),tol = Precision::Confusion(); |
124 | Standard_Boolean nullx = (Abs(x)<tol),nully = (Abs(y)<tol),nullz = (Abs(z)<tol); |
125 | if (nullx && nully) D2 = gp_Dir(1,0,0); |
126 | else if (nullx && nullz) D2 = gp_Dir(1,0,0); |
127 | else if (nully && nullz) D2 = gp_Dir(0,1,0); |
128 | else D2 = gp_Dir(y*z,x*z,-2.*x*y); |
129 | } |
130 | else { |
131 | Cur1 = props.MaxCurvature(); |
132 | Cur2 = props.MinCurvature(); |
133 | props.CurvatureDirections(D1,D2); |
134 | Norm = FUN_tool_nggeomF(uv,TopoDS::Face(F)); |
135 | } |
136 | } |
137 | |
138 | //======================================================================= |
139 | //function : TopOpeBRepDS_FaceInterferenceTool |
140 | //purpose : |
141 | //======================================================================= |
142 | TopOpeBRepDS_FaceInterferenceTool::TopOpeBRepDS_FaceInterferenceTool |
143 | (const TopOpeBRepDS_PDataStructure& PBDS) |
144 | : myPBDS(PBDS),myrefdef(Standard_False),myOnEdDef(Standard_False) |
145 | { |
146 | } |
147 | |
148 | //======================================================================= |
149 | //function : Init |
150 | //purpose : Initializes reference data for face/curve complex transition |
151 | //======================================================================= |
152 | void TopOpeBRepDS_FaceInterferenceTool::Init |
153 | (const TopoDS_Shape& FFI,const TopoDS_Shape& EE,const Standard_Boolean EEisnew,const Handle(TopOpeBRepDS_Interference)& Iin) |
154 | { |
c5f3a425 |
155 | Handle(TopOpeBRepDS_ShapeShapeInterference) I (Handle(TopOpeBRepDS_ShapeShapeInterference)::DownCast(Iin)); if (I.IsNull()) return; |
7fd59977 |
156 | const TopoDS_Face& FI = TopoDS::Face(FFI); |
157 | const TopoDS_Edge& E = TopoDS::Edge(EE); |
536a3cb8 |
158 | |
7fd59977 |
159 | // xpu150498 |
160 | STATIC_TOREVERSE = Standard_False; |
161 | if (EEisnew) { |
162 | Standard_Integer G = I->Geometry(); const TopoDS_Edge& EG = TopoDS::Edge(myPBDS->Shape(G)); |
163 | TopOpeBRepDS_Config cf; Standard_Boolean cfok = FDS_Config3d(E,EG,cf); |
164 | if (!cfok) { FUN_RaiseError(); return; } |
165 | if (cf == TopOpeBRepDS_DIFFORIENTED) STATIC_TOREVERSE = Standard_True; |
166 | } // xpu150498 |
167 | |
168 | myFaceOrientation = FI.Orientation(); |
169 | myFaceOriented = I->Support(); |
170 | |
171 | myEdge = E; |
172 | // Get a middle point on <E> |
173 | // Geometric data is described locally around this point. |
174 | // initialize : isLine,myParOnEd,myPntOnEd,myTole,Tgt. |
175 | |
176 | TopAbs_Orientation oEinFI; Standard_Boolean edonfa = FUN_tool_orientEinFFORWARD(E,FI,oEinFI); |
177 | // isLine = FUN_tool_line(E); |
178 | isLine = Standard_False; |
179 | |
180 | if (!myOnEdDef) { |
181 | Standard_Boolean ok = FUN_tool_findPinE(E,myPntOnEd,myParOnEd); |
182 | if (!ok) { FUN_RaiseError(); return;} |
183 | } |
184 | |
185 | myTole = Precision::Angular(); |
186 | gp_Pnt2d uv; Standard_Boolean ok = Standard_False; Standard_Real d = 0.; |
187 | if (edonfa) ok = FUN_tool_paronEF(E,myParOnEd,FI,uv); |
188 | else ok = FUN_tool_projPonF(myPntOnEd,FI,uv,d); |
189 | if (!ok) { FUN_RaiseError(); return;} |
190 | |
191 | gp_Vec tmp; ok = TopOpeBRepTool_TOOL::TggeomE(myParOnEd,E,tmp); |
192 | if (!ok) { FUN_RaiseError(); return;} |
193 | gp_Dir Tgt(tmp); |
194 | gp_Dir Norm; |
195 | if(isLine) { |
196 | FUN_ComputeGeomData(FI,uv,Norm); |
197 | myTool.Reset(Tgt,Norm); |
198 | } |
199 | else { |
200 | gp_Dir D1,D2; |
201 | Standard_Real Cur1,Cur2; |
202 | FUN_ComputeGeomData(FI,uv,Norm,D1,D2,Cur1,Cur2); |
203 | myTool.Reset(Tgt,Norm,D1,D2,Cur1,Cur2); |
204 | } |
205 | myrefdef = Standard_True; |
206 | } |
207 | |
208 | //======================================================================= |
209 | //function : Add |
210 | //purpose : |
211 | //======================================================================= |
212 | void TopOpeBRepDS_FaceInterferenceTool::Add |
213 | (const TopoDS_Shape& FFI,const TopoDS_Shape& FFT,const TopoDS_Shape& EE,const Standard_Boolean EEisnew,const Handle(TopOpeBRepDS_Interference)& Iin) |
214 | { |
c5f3a425 |
215 | Handle(TopOpeBRepDS_ShapeShapeInterference) I (Handle(TopOpeBRepDS_ShapeShapeInterference)::DownCast(Iin)); if (I.IsNull()) return; |
7fd59977 |
216 | const TopoDS_Face& FI = TopoDS::Face(FFI); |
217 | const TopoDS_Face& FT = TopoDS::Face(FFT); |
218 | const TopoDS_Edge& E = TopoDS::Edge(EE); |
536a3cb8 |
219 | myPBDS->Shape(FI); |
7fd59977 |
220 | // myPBDS->Shape(FT); |
7fd59977 |
221 | if (!E.IsSame(myEdge)) {FUN_RaiseError();return;} |
222 | |
223 | if (!myrefdef) { |
224 | Init(FI,E,EEisnew,I); // premiere interference sur face orientee : Init |
225 | return; |
226 | } |
7fd59977 |
227 | TopOpeBRepDS_Kind GT,ST; Standard_Integer G,S; FDS_data(I,GT,G,ST,S); |
7fd59977 |
228 | const TopoDS_Edge& EG = TopoDS::Edge(myPBDS->Shape(G)); |
536a3cb8 |
229 | FDS_HasSameDomain3d(*myPBDS,EG); |
7fd59977 |
230 | Standard_Boolean same = !STATIC_TOREVERSE; // xpu150498 |
231 | |
232 | TopAbs_Orientation oriloc = I->Transition().Orientation(TopAbs_IN); |
233 | // xpu150498 : CTS20205 : sp(e5) = sp(e4 of rank=1) and c3d(e5) c3d(e4) are diff oriented |
234 | // As transitions on face<iFI> are given relative to the geometry of e5, |
235 | // we have to complement them. |
236 | // cto 016 E1 |
237 | Standard_Boolean rev = !same && (M_FORWARD(oriloc) || M_REVERSED(oriloc)); //xpu150498 |
238 | if (rev) oriloc = TopAbs::Complement(oriloc); //xpu150498 |
239 | |
240 | TopAbs_Orientation oritan; |
241 | TopAbs_Orientation oriEFT; Standard_Boolean egofft = FUN_tool_orientEinFFORWARD(EG,FT,oriEFT); |
242 | TopAbs_Orientation oriEFI; Standard_Boolean egoffi = FUN_tool_orientEinFFORWARD(EG,FI,oriEFI); |
243 | if (egofft) { |
244 | oritan = oriEFT; |
245 | if (EEisnew && !same) oritan = TopAbs::Complement(oriEFT); |
246 | } |
247 | else if (egoffi) { |
248 | oritan = oriEFI; |
249 | if (EEisnew && !same) oritan = TopAbs::Complement(oriEFI); |
250 | } |
251 | else { FUN_RaiseError(); return; } |
252 | |
253 | gp_Pnt2d uv; Standard_Boolean ok = Standard_False; |
254 | if (egofft) ok = FUN_tool_paronEF(E,myParOnEd,FT,uv); |
255 | if (!ok) {Standard_Real d; ok = FUN_tool_projPonF(myPntOnEd,FT,uv,d);} |
256 | if (!ok) { FUN_RaiseError(); return;} |
257 | |
258 | gp_Dir Norm; |
259 | if(isLine) { |
260 | FUN_ComputeGeomData(FT,uv,Norm); |
261 | // if (Fori == TopAbs_REVERSED) Norm.Reverse(); |
262 | myTool.Compare(myTole,Norm,oriloc,oritan); |
263 | } |
264 | else { |
265 | gp_Dir D1,D2; Standard_Real Cur1,Cur2; |
266 | FUN_ComputeGeomData(FT,uv,Norm,D1,D2,Cur1,Cur2); |
267 | // if (Fori == TopAbs_REVERSED) Norm.Reverse(); |
268 | myTool.Compare(myTole,Norm,D1,D2,Cur1,Cur2,oriloc,oritan); |
269 | } |
270 | } |
271 | |
272 | //======================================================================= |
273 | //function : Add |
274 | //purpose : |
275 | //======================================================================= |
276 | void TopOpeBRepDS_FaceInterferenceTool::Add |
277 | //(const TopoDS_Shape& F,const TopOpeBRepDS_Curve& C,const Handle(TopOpeBRepDS_Interference)& I) |
278 | (const TopoDS_Shape& ,const TopOpeBRepDS_Curve& ,const Handle(TopOpeBRepDS_Interference)& ) |
279 | { |
280 | // NYI |
281 | } |
282 | |
283 | //======================================================================= |
284 | //function : Transition |
285 | //purpose : |
286 | //======================================================================= |
287 | void TopOpeBRepDS_FaceInterferenceTool::Transition(const Handle(TopOpeBRepDS_Interference)& I) const |
288 | { |
289 | TopOpeBRepDS_Transition& T = I->ChangeTransition(); |
290 | |
291 | if (myFaceOrientation == TopAbs_INTERNAL) { |
292 | T.Set(TopAbs_IN,TopAbs_IN); |
293 | } |
294 | else if (myFaceOrientation == TopAbs_EXTERNAL) { |
295 | T.Set(TopAbs_OUT,TopAbs_OUT); |
296 | } |
297 | else { |
298 | I->Support(myFaceOriented); |
299 | TopAbs_State stb = myTool.StateBefore(); |
300 | TopAbs_State sta = myTool.StateAfter(); |
301 | T.Set(stb,sta); |
302 | //xpu150498 |
303 | TopAbs_Orientation o = T.Orientation(TopAbs_IN); |
304 | Standard_Boolean rev = STATIC_TOREVERSE && (M_FORWARD(o) || M_REVERSED(o)); |
305 | if (rev) o = TopAbs::Complement(o); |
306 | T.Set(o); |
307 | //xpu150498 |
308 | } |
309 | } |
310 | |
311 | //======================================================================= |
312 | //function : SetEdgePntPar |
313 | //purpose : |
314 | //======================================================================= |
315 | void TopOpeBRepDS_FaceInterferenceTool::SetEdgePntPar(const gp_Pnt& P,const Standard_Real p) |
316 | { |
317 | myPntOnEd = P; |
318 | myParOnEd = p; |
319 | myOnEdDef = Standard_True; |
320 | } |
321 | |
322 | //======================================================================= |
323 | //function : GetEdgePnt |
324 | //purpose : |
325 | //======================================================================= |
326 | void TopOpeBRepDS_FaceInterferenceTool::GetEdgePntPar(gp_Pnt& P,Standard_Real& p) const |
327 | { |
9775fa61 |
328 | if (!myOnEdDef) throw Standard_ProgramError("GetEdgePntPar"); |
7fd59977 |
329 | P = myPntOnEd; |
330 | p = myParOnEd; |
331 | } |
332 | |
333 | //======================================================================= |
334 | //function : IsEdgePnt |
335 | //purpose : |
336 | //======================================================================= |
337 | |
338 | Standard_Boolean TopOpeBRepDS_FaceInterferenceTool::IsEdgePntParDef() const |
339 | { |
340 | return myOnEdDef; |
341 | } |