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