b311480e |
1 | // Created on: 1997-02-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 <gp_Pnt.hxx> |
19 | #include <TopoDS_Face.hxx> |
20 | #include <TopoDS_Shape.hxx> |
21 | #include <TopOpeBRep_FacesFiller.hxx> |
22 | #include <TopOpeBRep_FacesIntersector.hxx> |
23 | #include <TopOpeBRep_FFDumper.hxx> |
24 | #include <TopOpeBRep_LineInter.hxx> |
25 | #include <TopOpeBRep_PointClassifier.hxx> |
26 | #include <TopOpeBRep_VPointInter.hxx> |
27 | #include <TopOpeBRep_VPointInterClassifier.hxx> |
28 | #include <TopOpeBRep_VPointInterIterator.hxx> |
29 | #include <TopOpeBRepDS_DataStructure.hxx> |
30 | #include <TopOpeBRepDS_HDataStructure.hxx> |
31 | #include <TopOpeBRepDS_Interference.hxx> |
32 | #include <TopOpeBRepDS_Point.hxx> |
33 | #include <TopOpeBRepDS_Transition.hxx> |
7fd59977 |
34 | |
35 | #ifdef DRAW |
36 | #include <TopOpeBRep_DRAW.hxx> |
37 | #endif |
38 | |
39 | #include <gp_Vec.hxx> |
40 | #include <Geom2d_Curve.hxx> |
41 | #include <Geom2d_Line.hxx> |
42 | #include <Geom_Curve.hxx> |
43 | #include <Geom_Circle.hxx> |
44 | #include <Geom_Ellipse.hxx> |
45 | #include <Geom_Surface.hxx> |
46 | #include <GeomAPI_ProjectPointOnCurve.hxx> |
47 | #include <GeomAPI_ProjectPointOnSurf.hxx> |
48 | #include <BRep_Tool.hxx> |
49 | #include <BRepAdaptor_Curve.hxx> |
50 | //#include <BRepAdaptor_Curve2d.hxx> |
51 | #include <BRepAdaptor_Surface.hxx> |
52 | #include <TopAbs.hxx> |
53 | #include <TopExp.hxx> |
54 | #include <TopoDS.hxx> |
55 | #include <TopTools_IndexedMapOfShape.hxx> |
56 | #include <TopOpeBRepTool_ShapeTool.hxx> |
57 | #include <TopOpeBRepDS_InterferenceTool.hxx> |
58 | #include <TopOpeBRep_FFTransitionTool.hxx> |
59 | #include <TopOpeBRep_FacesIntersector.hxx> |
60 | #include <TopOpeBRep_LineInter.hxx> |
61 | #include <TopOpeBRep_VPointInter.hxx> |
62 | #include <TopOpeBRep_Bipoint.hxx> |
63 | #include <TopOpeBRep_ListOfBipoint.hxx> |
64 | #include <TopOpeBRep_ListIteratorOfListOfBipoint.hxx> |
65 | #include <TopOpeBRep_VPointInterIterator.hxx> |
66 | #include <TopOpeBRep_GeomTool.hxx> |
67 | #include <Precision.hxx> |
68 | #include <Standard_CString.hxx> |
69 | #include <Standard_ProgramError.hxx> |
70 | #include <TopOpeBRepDS_define.hxx> |
71 | #include <TopOpeBRep.hxx> |
72 | #include <TopOpeBRepTool_EXPORT.hxx> |
73 | #include <TopOpeBRepTool_SC.hxx> |
74 | |
0797d9d3 |
75 | #ifdef OCCT_DEBUG |
7fd59977 |
76 | #include <TopOpeBRep_FFDumper.hxx> |
77 | #include <Geom_TrimmedCurve.hxx> |
78 | #include <Geom_Line.hxx> |
1d0a9d4d |
79 | extern Standard_Boolean TopOpeBRep_GettraceBIPS(); |
80 | extern Standard_Boolean TopOpeBRep_GettraceDEGEN(); |
81 | extern Standard_Boolean FUN_debnull(const TopoDS_Shape& s){Standard_Boolean isnull = s.IsNull(); if (isnull) cout <<"***"; return isnull;} |
7fd59977 |
82 | #endif |
83 | |
84 | //Standard_EXPORT extern Standard_Real GLOBAL_tolFF; |
85 | Standard_EXPORTEXTERN Standard_Real GLOBAL_tolFF; |
86 | |
87 | //======================================================================= |
88 | //function : StBipVPonF |
89 | //purpose : |
90 | //======================================================================= |
91 | TopAbs_State TopOpeBRep_FacesFiller::StBipVPonF |
92 | (const TopOpeBRep_VPointInter& vpf,const TopOpeBRep_VPointInter& vpl, |
93 | const TopOpeBRep_LineInter& Lrest,const Standard_Boolean isonedge1) const |
94 | { |
95 | |
96 | #define M_OUT(st) (st == TopAbs_OUT); |
97 | #define M_IN(st) (st == TopAbs_IN); |
98 | |
99 | Standard_Integer sind = isonedge1 ? 2 : 1; |
100 | TopAbs_State stf = vpf.State(sind); |
101 | TopAbs_State stl = vpl.State(sind); |
102 | Standard_Boolean isout = M_OUT(stf); isout = isout || M_OUT(stl); |
103 | Standard_Boolean isin = M_IN(stf); isin = isin || M_IN(stl); |
104 | if (isout) return TopAbs_OUT; |
105 | if (isin) return TopAbs_IN; |
106 | |
107 | Standard_Boolean isperiodic; |
108 | const TopoDS_Edge& EArc = TopoDS::Edge(Lrest.Arc()); |
109 | BRepAdaptor_Curve BAC(EArc); |
110 | GeomAbs_CurveType CT = BAC.GetType(); |
111 | isperiodic = (CT == GeomAbs_Circle); |
112 | isperiodic = isperiodic || (CT == GeomAbs_Ellipse); |
113 | |
114 | TopOpeBRep_VPointInter vpff = vpf; |
115 | TopOpeBRep_VPointInter vpll = vpl; |
116 | |
117 | // xpu200798 : CTS21216, restriction edge 7, f8 |
118 | // purpose : periodic restriction; vpf, vpl describing restriction bounds |
119 | // if the Rline is describing the portion on curve (vpl,vpf), |
120 | // we have to commutate these bounds. |
121 | if (isperiodic) { |
0797d9d3 |
122 | #ifdef OCCT_DEBUG |
7fd59977 |
123 | // TopOpeBRep_FFDumper FFD(*this); |
124 | // cout <<"vpf :"; FFD.DumpVP(vpf,cout); |
125 | // cout <<"vpl :"; FFD.DumpVP(vpl,cout); |
126 | #endif |
127 | |
128 | Standard_Integer IArc = 0; |
129 | if (Lrest.ArcIsEdge(1)) IArc = 1; |
130 | if (Lrest.ArcIsEdge(2)) IArc = 2; |
131 | if (IArc == 0) { |
0797d9d3 |
132 | #ifdef OCCT_DEBUG |
7fd59977 |
133 | Standard_Failure::Raise("StBipVPonF"); |
134 | #endif |
135 | return TopAbs_UNKNOWN; |
136 | } |
137 | Standard_Integer ISI = (IArc == 1) ? 2 : 1; |
138 | Standard_Integer sif = vpf.ShapeIndex(); |
139 | Standard_Integer sil = vpl.ShapeIndex(); |
140 | Standard_Boolean act = ((sif == 3)||(sif == ISI)) && ((sil == 3)||(sil == ISI)); |
141 | if (act) { |
142 | TopOpeBRepDS_Transition Tf = TopOpeBRep_FFTransitionTool::ProcessLineTransition(vpf,ISI,vpf.Edge(ISI).Orientation()); |
143 | TopOpeBRepDS_Transition Tl = TopOpeBRep_FFTransitionTool::ProcessLineTransition(vpl,ISI,vpl.Edge(ISI).Orientation()); |
144 | Standard_Boolean toreverse = (Tf.Orientation(TopAbs_IN) == TopAbs_REVERSED); |
145 | toreverse = toreverse && (Tl.Orientation(TopAbs_IN) == TopAbs_FORWARD); |
146 | if (toreverse) { |
147 | vpff = vpl; |
148 | vpll = vpf; |
149 | } |
150 | } // act |
151 | } // isperiodic |
152 | |
153 | TopoDS_Shape F; |
154 | if (isonedge1) F = myF2; |
155 | else F = myF1; |
156 | Standard_Real uf = TopOpeBRep_FacesFiller::VPParamOnER (vpff,Lrest); |
157 | Standard_Real ul = TopOpeBRep_FacesFiller::VPParamOnER (vpll,Lrest); |
158 | |
159 | // NYI XPU: 16-05-97: INTPATCH -> the parametrization of a point on a |
160 | // periodized curve is INSUFFICIENT : parVP on line can be either 0. |
161 | // or period. |
162 | Standard_Boolean badparametrized = (uf > ul); |
163 | Standard_Real f,l; f = BAC.FirstParameter(); l = BAC.LastParameter(); |
164 | if (badparametrized) { |
165 | if (isperiodic) { |
166 | if (uf == l) uf = f; |
167 | if (ul == f) ul = l; |
168 | } |
169 | } |
170 | |
171 | const TopoDS_Edge& arc = TopoDS::Edge(Lrest.Arc()); |
172 | BRepAdaptor_Curve BC( arc ); |
173 | Standard_Real x = 0.789; Standard_Real parmil = (1-x)*uf + x*ul; //xpu170898 |
174 | gp_Pnt pmil = BC.Value(parmil); |
302f96fb |
175 | |
0797d9d3 |
176 | #ifdef OCCT_DEBUG |
498ce76b |
177 | #ifdef DRAW |
7fd59977 |
178 | Standard_Boolean trc = TopOpeBRep_GettraceBIPS(); |
498ce76b |
179 | if (trc) {TCollection_AsciiString aa("pmil"); FUN_brep_draw(aa,pmil);} |
180 | #endif |
7fd59977 |
181 | #endif |
7fd59977 |
182 | TopAbs_State st = FSC_StatePonFace (pmil,F,*myPShapeClassifier); |
183 | return st; |
184 | } |
185 | |
186 | //======================================================================= |
187 | //function : StateVPonFace |
188 | //purpose : |
189 | //======================================================================= |
190 | TopAbs_State TopOpeBRep_FacesFiller::StateVPonFace(const TopOpeBRep_VPointInter& VP) const |
191 | { |
192 | Standard_Integer iVP = VP.ShapeIndex(); |
193 | if (iVP == 3) return TopAbs_ON; |
194 | |
195 | Standard_Integer iother = (iVP == 1) ? 2 : 1; |
196 | TopoDS_Shape F; |
197 | if (iother == 1) F = myF1; |
198 | else F = myF2; |
199 | Standard_Real u,v; |
200 | if (iother == 1) VP.ParametersOnS1(u,v); |
201 | else VP.ParametersOnS2(u,v); |
202 | |
203 | myPShapeClassifier->SetReference(TopoDS::Face(F)); |
204 | myPShapeClassifier->StateP2DReference(gp_Pnt2d(u,v)); |
205 | TopAbs_State state = myPShapeClassifier->State(); |
206 | |
207 | return state; |
208 | } |
209 | |
210 | // ---------------------------------------------------------------------- |
211 | // Class methods |
212 | // ---------------------------------------------------------------------- |
213 | |
214 | //======================================================================= |
215 | //function : Lminmax |
216 | //purpose : Computes <pmin> and <pmax> the upper and lower bounds of <L> |
217 | // enclosing all vpoints. |
218 | //======================================================================= |
219 | void TopOpeBRep_FacesFiller::Lminmax(const TopOpeBRep_LineInter& L, |
220 | Standard_Real& pmin,Standard_Real& pmax) |
221 | { |
222 | pmin = RealLast(); |
223 | pmax = RealFirst(); |
224 | TopOpeBRep_VPointInterIterator VPI; |
225 | VPI.Init(L,Standard_False); |
226 | for (; VPI.More(); VPI.Next()) { |
227 | const TopOpeBRep_VPointInter& VP = VPI.CurrentVP(); |
7fd59977 |
228 | Standard_Real p = VP.ParameterOnLine(); |
229 | pmin = Min(pmin,p); |
230 | pmax = Max(pmax,p); |
231 | } |
232 | Standard_Real d = Abs(pmin-pmax); |
233 | Standard_Boolean id = (d <= Precision::PConfusion()); |
234 | Standard_Boolean isper = L.IsPeriodic(); |
235 | Standard_Integer n = L.NbVPoint(); |
236 | if (id && isper && n >= 2) { |
237 | Standard_Real per = L.Period(); |
238 | pmax = pmin + per; |
239 | } |
240 | } |
241 | |
242 | //======================================================================= |
243 | //function : LSameDomainERL |
244 | //purpose : Returns <True> if GLine shares a same geometric domain with |
245 | // at least one of the restriction edges of <ERL>. |
246 | //======================================================================= |
247 | Standard_Boolean TopOpeBRep_FacesFiller::LSameDomainERL(const TopOpeBRep_LineInter& L, |
248 | const TopTools_ListOfShape& ERL) |
249 | { |
250 | Standard_Boolean isone = Standard_False; |
251 | if(L.TypeLineCurve() == TopOpeBRep_WALKING) return isone; |
252 | |
253 | #ifdef DRAW |
254 | Standard_Boolean trc = Standard_False; |
255 | if (trc) {Handle(Geom_Curve) C = L.Curve(); TCollection_AsciiString aa("line"); FUN_brep_draw(aa,C);} |
256 | #endif |
257 | |
258 | Standard_Real f,l; TopOpeBRep_FacesFiller::Lminmax(L,f,l); |
259 | Standard_Real d = Abs(f-l); |
260 | |
261 | { |
262 | Standard_Boolean idINL = (L.INL() && (d == 0)); // null length line, made of VPoints only |
263 | if (idINL) return Standard_False; |
264 | } // INL |
265 | |
266 | Standard_Boolean id = (d <= Precision::PConfusion()); |
267 | if (id) return Standard_False; |
268 | |
269 | Handle(Geom_Curve) CL; TopOpeBRep_GeomTool::MakeCurve(f,l,L,CL); |
270 | Standard_Real t = 0.417789; Standard_Real p = (1-t)*f + t*l; |
271 | gp_Pnt Pm = CL->Value(p); |
272 | |
273 | TopTools_ListIteratorOfListOfShape it; it.Initialize(ERL); |
274 | for(; it.More(); it.Next()) { |
275 | const TopoDS_Edge& E = TopoDS::Edge(it.Value()); |
276 | Standard_Real tolE = BRep_Tool::Tolerance(E); |
277 | Standard_Real maxtol = Max(tolE,GLOBAL_tolFF); |
278 | BRepAdaptor_Curve BAC(E); |
279 | f = BAC.FirstParameter(); l = BAC.LastParameter(); |
280 | Standard_Boolean pinc = FUN_tool_PinC(Pm,BAC,f,l,maxtol); |
281 | if (pinc) {isone = Standard_True; break;} |
282 | } |
283 | return isone; |
284 | } |
285 | |
286 | //======================================================================= |
287 | //function : IsVPtransLok |
288 | //purpose : Computes the transition <T> of the VPoint <iVP> on the edge |
289 | // <SI12>. Returns <False> if the status is unknown. |
290 | //======================================================================= |
291 | Standard_Boolean TopOpeBRep_FacesFiller::IsVPtransLok(const TopOpeBRep_LineInter& L, |
292 | const Standard_Integer iVP,const Standard_Integer SI12, |
293 | TopOpeBRepDS_Transition& T) |
294 | { |
295 | const TopOpeBRep_VPointInter& VP = L.VPoint(iVP); |
296 | Standard_Boolean is1 = (SI12 == 1); |
297 | Standard_Boolean VPonEd = (is1 && VP.IsOnDomS1()); |
298 | VPonEd = VPonEd || (!is1 && VP.IsOnDomS2()); |
299 | if (!VPonEd) return Standard_False; |
300 | |
301 | const TopoDS_Edge& E = TopoDS::Edge(VP.Edge(SI12)); |
302 | TopAbs_Orientation O = E.Orientation(); |
303 | T = TopOpeBRep_FFTransitionTool::ProcessLineTransition(VP,SI12,O); |
304 | Standard_Boolean u = T.IsUnknown(); |
305 | return (!u); |
306 | } |
307 | |
308 | Standard_Boolean TopOpeBRep_FacesFiller::TransvpOK(const TopOpeBRep_LineInter& L, |
309 | const Standard_Integer ivp, |
310 | const Standard_Integer SI, |
311 | const Standard_Boolean isINOUT) |
312 | { |
313 | #define M_INOUT(stf,stl) ((stf == TopAbs_IN) && (stl == TopAbs_OUT)) |
314 | #define M_OUTIN(stf,stl) ((stf == TopAbs_OUT) && (stl == TopAbs_IN)) |
315 | |
316 | TopOpeBRepDS_Transition T; |
317 | Standard_Boolean ok = TopOpeBRep_FacesFiller::IsVPtransLok(L,ivp,SI,T); |
318 | if (ok) { |
319 | TopAbs_State stb = T.Before(); |
320 | TopAbs_State sta = T.After(); |
321 | if (isINOUT) ok = M_INOUT(stb,sta); |
322 | else ok = M_OUTIN(stb,sta); |
323 | } |
324 | return ok; |
325 | } |
326 | |
327 | //======================================================================= |
328 | //function : VPParamOnER |
329 | //purpose : |
330 | //======================================================================= |
331 | Standard_Real TopOpeBRep_FacesFiller::VPParamOnER(const TopOpeBRep_VPointInter& vp, |
332 | const TopOpeBRep_LineInter& Lrest) |
333 | { |
334 | // If vp(index) is an edge boundary returns the point's parameter. |
335 | |
336 | const TopoDS_Edge& E = TopoDS::Edge(Lrest.Arc()); |
7fd59977 |
337 | Standard_Boolean isedge1 = Lrest.ArcIsEdge(1); |
338 | Standard_Boolean isedge2 = Lrest.ArcIsEdge(2); |
339 | if (isedge1 && vp.IsVertexOnS1()) { |
340 | const TopoDS_Vertex& v1 = TopoDS::Vertex(vp.VertexOnS1()); |
341 | Standard_Real rr = BRep_Tool::Parameter(v1,E); |
342 | return rr; |
343 | } |
344 | if (isedge2 && vp.IsVertexOnS2()) { |
345 | const TopoDS_Vertex& v2 = TopoDS::Vertex(vp.VertexOnS2()); |
346 | Standard_Real rr = BRep_Tool::Parameter(v2,E); |
347 | return rr; |
348 | } |
349 | // vp is an intersection point,and we get it's parameter. |
350 | if (isedge1 && vp.IsOnDomS1()) return vp.ParameterOnArc1(); |
351 | if (isedge2 && vp.IsOnDomS2()) return vp.ParameterOnArc2(); |
352 | |
353 | // Else,we have to project the point on the edge restriction |
354 | Standard_Real tolee = BRep_Tool::Tolerance(E); |
355 | tolee = tolee * 1.e2; //xpu290998 : PRO15369 |
356 | Standard_Real param, dist; Standard_Boolean projok = FUN_tool_projPonE(vp.Value(),tolee,E,param,dist); |
357 | if (!projok) { |
358 | Standard_ProgramError::Raise("TopOpeBRep_FacesFiller::VPParamOnER"); |
359 | } |
360 | return param; |
361 | } |
362 | |
363 | //Standard_EXPORT Standard_Boolean FUN_EqualPonR(const TopOpeBRep_LineInter& Lrest, |
364 | Standard_EXPORT Standard_Boolean FUN_EqualPonR(const TopOpeBRep_LineInter& , |
365 | const TopOpeBRep_VPointInter& VP1, |
366 | const TopOpeBRep_VPointInter& VP2) |
367 | { |
368 | gp_Pnt P1 = VP1.Value(); gp_Pnt P2 = VP2.Value(); |
369 | Standard_Real Ptol1 = VP1.Tolerance(),Ptol2 = VP2.Tolerance(); |
370 | Standard_Real Ptol = (Ptol1 > Ptol2) ? Ptol1 : Ptol2; |
371 | Standard_Boolean Pequal = P1.IsEqual(P2,Ptol); |
372 | return Pequal; |
373 | } |
374 | Standard_EXPORT Standard_Boolean FUN_EqualponR(const TopOpeBRep_LineInter& Lrest, |
375 | const TopOpeBRep_VPointInter& VP1, |
376 | const TopOpeBRep_VPointInter& VP2) |
377 | { |
378 | Standard_Real p1 = TopOpeBRep_FacesFiller::VPParamOnER(VP1,Lrest); |
379 | Standard_Real p2 = TopOpeBRep_FacesFiller::VPParamOnER(VP2,Lrest); |
380 | Standard_Boolean pequal = fabs(p1-p2) < Precision::PConfusion(); |
381 | return pequal; |
382 | } |
383 | |
384 | //======================================================================= |
385 | //function : EqualpPOnR |
386 | //purpose : |
387 | //======================================================================= |
388 | Standard_Boolean TopOpeBRep_FacesFiller::EqualpPonR(const TopOpeBRep_LineInter& Lrest, |
389 | const TopOpeBRep_VPointInter& VP1, |
390 | const TopOpeBRep_VPointInter& VP2) |
391 | { |
392 | Standard_Boolean Pequal = ::FUN_EqualPonR(Lrest,VP1,VP2); |
393 | Standard_Boolean pequal = ::FUN_EqualponR(Lrest,VP1,VP2); |
394 | Standard_Boolean pPequal = Pequal && pequal; |
395 | return pPequal; |
396 | } |