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(); |
04232180 |
81 | extern Standard_Boolean FUN_debnull(const TopoDS_Shape& s){Standard_Boolean isnull = s.IsNull(); if (isnull) std::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); |
04232180 |
124 | // std::cout <<"vpf :"; FFD.DumpVP(vpf,std::cout); |
125 | // std::cout <<"vpl :"; FFD.DumpVP(vpl,std::cout); |
7fd59977 |
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 |
9775fa61 |
133 | throw Standard_Failure("StBipVPonF"); |
134 | #else |
7fd59977 |
135 | return TopAbs_UNKNOWN; |
9775fa61 |
136 | #endif |
7fd59977 |
137 | } |
138 | Standard_Integer ISI = (IArc == 1) ? 2 : 1; |
139 | Standard_Integer sif = vpf.ShapeIndex(); |
140 | Standard_Integer sil = vpl.ShapeIndex(); |
141 | Standard_Boolean act = ((sif == 3)||(sif == ISI)) && ((sil == 3)||(sil == ISI)); |
142 | if (act) { |
143 | TopOpeBRepDS_Transition Tf = TopOpeBRep_FFTransitionTool::ProcessLineTransition(vpf,ISI,vpf.Edge(ISI).Orientation()); |
144 | TopOpeBRepDS_Transition Tl = TopOpeBRep_FFTransitionTool::ProcessLineTransition(vpl,ISI,vpl.Edge(ISI).Orientation()); |
145 | Standard_Boolean toreverse = (Tf.Orientation(TopAbs_IN) == TopAbs_REVERSED); |
146 | toreverse = toreverse && (Tl.Orientation(TopAbs_IN) == TopAbs_FORWARD); |
147 | if (toreverse) { |
148 | vpff = vpl; |
149 | vpll = vpf; |
150 | } |
151 | } // act |
152 | } // isperiodic |
153 | |
154 | TopoDS_Shape F; |
155 | if (isonedge1) F = myF2; |
156 | else F = myF1; |
157 | Standard_Real uf = TopOpeBRep_FacesFiller::VPParamOnER (vpff,Lrest); |
158 | Standard_Real ul = TopOpeBRep_FacesFiller::VPParamOnER (vpll,Lrest); |
159 | |
160 | // NYI XPU: 16-05-97: INTPATCH -> the parametrization of a point on a |
161 | // periodized curve is INSUFFICIENT : parVP on line can be either 0. |
162 | // or period. |
163 | Standard_Boolean badparametrized = (uf > ul); |
164 | Standard_Real f,l; f = BAC.FirstParameter(); l = BAC.LastParameter(); |
165 | if (badparametrized) { |
166 | if (isperiodic) { |
167 | if (uf == l) uf = f; |
168 | if (ul == f) ul = l; |
169 | } |
170 | } |
171 | |
172 | const TopoDS_Edge& arc = TopoDS::Edge(Lrest.Arc()); |
173 | BRepAdaptor_Curve BC( arc ); |
174 | Standard_Real x = 0.789; Standard_Real parmil = (1-x)*uf + x*ul; //xpu170898 |
175 | gp_Pnt pmil = BC.Value(parmil); |
302f96fb |
176 | |
0797d9d3 |
177 | #ifdef OCCT_DEBUG |
498ce76b |
178 | #ifdef DRAW |
7fd59977 |
179 | Standard_Boolean trc = TopOpeBRep_GettraceBIPS(); |
498ce76b |
180 | if (trc) {TCollection_AsciiString aa("pmil"); FUN_brep_draw(aa,pmil);} |
181 | #endif |
7fd59977 |
182 | #endif |
7fd59977 |
183 | TopAbs_State st = FSC_StatePonFace (pmil,F,*myPShapeClassifier); |
184 | return st; |
185 | } |
186 | |
187 | //======================================================================= |
188 | //function : StateVPonFace |
189 | //purpose : |
190 | //======================================================================= |
191 | TopAbs_State TopOpeBRep_FacesFiller::StateVPonFace(const TopOpeBRep_VPointInter& VP) const |
192 | { |
193 | Standard_Integer iVP = VP.ShapeIndex(); |
194 | if (iVP == 3) return TopAbs_ON; |
195 | |
196 | Standard_Integer iother = (iVP == 1) ? 2 : 1; |
197 | TopoDS_Shape F; |
198 | if (iother == 1) F = myF1; |
199 | else F = myF2; |
200 | Standard_Real u,v; |
201 | if (iother == 1) VP.ParametersOnS1(u,v); |
202 | else VP.ParametersOnS2(u,v); |
203 | |
204 | myPShapeClassifier->SetReference(TopoDS::Face(F)); |
205 | myPShapeClassifier->StateP2DReference(gp_Pnt2d(u,v)); |
206 | TopAbs_State state = myPShapeClassifier->State(); |
207 | |
208 | return state; |
209 | } |
210 | |
211 | // ---------------------------------------------------------------------- |
212 | // Class methods |
213 | // ---------------------------------------------------------------------- |
214 | |
215 | //======================================================================= |
216 | //function : Lminmax |
217 | //purpose : Computes <pmin> and <pmax> the upper and lower bounds of <L> |
218 | // enclosing all vpoints. |
219 | //======================================================================= |
220 | void TopOpeBRep_FacesFiller::Lminmax(const TopOpeBRep_LineInter& L, |
221 | Standard_Real& pmin,Standard_Real& pmax) |
222 | { |
223 | pmin = RealLast(); |
224 | pmax = RealFirst(); |
225 | TopOpeBRep_VPointInterIterator VPI; |
226 | VPI.Init(L,Standard_False); |
227 | for (; VPI.More(); VPI.Next()) { |
228 | const TopOpeBRep_VPointInter& VP = VPI.CurrentVP(); |
7fd59977 |
229 | Standard_Real p = VP.ParameterOnLine(); |
230 | pmin = Min(pmin,p); |
231 | pmax = Max(pmax,p); |
232 | } |
233 | Standard_Real d = Abs(pmin-pmax); |
234 | Standard_Boolean id = (d <= Precision::PConfusion()); |
235 | Standard_Boolean isper = L.IsPeriodic(); |
236 | Standard_Integer n = L.NbVPoint(); |
237 | if (id && isper && n >= 2) { |
238 | Standard_Real per = L.Period(); |
239 | pmax = pmin + per; |
240 | } |
241 | } |
242 | |
243 | //======================================================================= |
244 | //function : LSameDomainERL |
245 | //purpose : Returns <True> if GLine shares a same geometric domain with |
246 | // at least one of the restriction edges of <ERL>. |
247 | //======================================================================= |
248 | Standard_Boolean TopOpeBRep_FacesFiller::LSameDomainERL(const TopOpeBRep_LineInter& L, |
249 | const TopTools_ListOfShape& ERL) |
250 | { |
251 | Standard_Boolean isone = Standard_False; |
252 | if(L.TypeLineCurve() == TopOpeBRep_WALKING) return isone; |
253 | |
254 | #ifdef DRAW |
255 | Standard_Boolean trc = Standard_False; |
256 | if (trc) {Handle(Geom_Curve) C = L.Curve(); TCollection_AsciiString aa("line"); FUN_brep_draw(aa,C);} |
257 | #endif |
258 | |
259 | Standard_Real f,l; TopOpeBRep_FacesFiller::Lminmax(L,f,l); |
260 | Standard_Real d = Abs(f-l); |
261 | |
262 | { |
263 | Standard_Boolean idINL = (L.INL() && (d == 0)); // null length line, made of VPoints only |
264 | if (idINL) return Standard_False; |
265 | } // INL |
266 | |
267 | Standard_Boolean id = (d <= Precision::PConfusion()); |
268 | if (id) return Standard_False; |
269 | |
270 | Handle(Geom_Curve) CL; TopOpeBRep_GeomTool::MakeCurve(f,l,L,CL); |
271 | Standard_Real t = 0.417789; Standard_Real p = (1-t)*f + t*l; |
272 | gp_Pnt Pm = CL->Value(p); |
273 | |
274 | TopTools_ListIteratorOfListOfShape it; it.Initialize(ERL); |
275 | for(; it.More(); it.Next()) { |
276 | const TopoDS_Edge& E = TopoDS::Edge(it.Value()); |
277 | Standard_Real tolE = BRep_Tool::Tolerance(E); |
278 | Standard_Real maxtol = Max(tolE,GLOBAL_tolFF); |
279 | BRepAdaptor_Curve BAC(E); |
280 | f = BAC.FirstParameter(); l = BAC.LastParameter(); |
281 | Standard_Boolean pinc = FUN_tool_PinC(Pm,BAC,f,l,maxtol); |
282 | if (pinc) {isone = Standard_True; break;} |
283 | } |
284 | return isone; |
285 | } |
286 | |
287 | //======================================================================= |
288 | //function : IsVPtransLok |
289 | //purpose : Computes the transition <T> of the VPoint <iVP> on the edge |
290 | // <SI12>. Returns <False> if the status is unknown. |
291 | //======================================================================= |
292 | Standard_Boolean TopOpeBRep_FacesFiller::IsVPtransLok(const TopOpeBRep_LineInter& L, |
293 | const Standard_Integer iVP,const Standard_Integer SI12, |
294 | TopOpeBRepDS_Transition& T) |
295 | { |
296 | const TopOpeBRep_VPointInter& VP = L.VPoint(iVP); |
297 | Standard_Boolean is1 = (SI12 == 1); |
298 | Standard_Boolean VPonEd = (is1 && VP.IsOnDomS1()); |
299 | VPonEd = VPonEd || (!is1 && VP.IsOnDomS2()); |
300 | if (!VPonEd) return Standard_False; |
301 | |
302 | const TopoDS_Edge& E = TopoDS::Edge(VP.Edge(SI12)); |
303 | TopAbs_Orientation O = E.Orientation(); |
304 | T = TopOpeBRep_FFTransitionTool::ProcessLineTransition(VP,SI12,O); |
305 | Standard_Boolean u = T.IsUnknown(); |
306 | return (!u); |
307 | } |
308 | |
309 | Standard_Boolean TopOpeBRep_FacesFiller::TransvpOK(const TopOpeBRep_LineInter& L, |
310 | const Standard_Integer ivp, |
311 | const Standard_Integer SI, |
312 | const Standard_Boolean isINOUT) |
313 | { |
314 | #define M_INOUT(stf,stl) ((stf == TopAbs_IN) && (stl == TopAbs_OUT)) |
315 | #define M_OUTIN(stf,stl) ((stf == TopAbs_OUT) && (stl == TopAbs_IN)) |
316 | |
317 | TopOpeBRepDS_Transition T; |
318 | Standard_Boolean ok = TopOpeBRep_FacesFiller::IsVPtransLok(L,ivp,SI,T); |
319 | if (ok) { |
320 | TopAbs_State stb = T.Before(); |
321 | TopAbs_State sta = T.After(); |
322 | if (isINOUT) ok = M_INOUT(stb,sta); |
323 | else ok = M_OUTIN(stb,sta); |
324 | } |
325 | return ok; |
326 | } |
327 | |
328 | //======================================================================= |
329 | //function : VPParamOnER |
330 | //purpose : |
331 | //======================================================================= |
332 | Standard_Real TopOpeBRep_FacesFiller::VPParamOnER(const TopOpeBRep_VPointInter& vp, |
333 | const TopOpeBRep_LineInter& Lrest) |
334 | { |
335 | // If vp(index) is an edge boundary returns the point's parameter. |
336 | |
337 | const TopoDS_Edge& E = TopoDS::Edge(Lrest.Arc()); |
7fd59977 |
338 | Standard_Boolean isedge1 = Lrest.ArcIsEdge(1); |
339 | Standard_Boolean isedge2 = Lrest.ArcIsEdge(2); |
340 | if (isedge1 && vp.IsVertexOnS1()) { |
341 | const TopoDS_Vertex& v1 = TopoDS::Vertex(vp.VertexOnS1()); |
342 | Standard_Real rr = BRep_Tool::Parameter(v1,E); |
343 | return rr; |
344 | } |
345 | if (isedge2 && vp.IsVertexOnS2()) { |
346 | const TopoDS_Vertex& v2 = TopoDS::Vertex(vp.VertexOnS2()); |
347 | Standard_Real rr = BRep_Tool::Parameter(v2,E); |
348 | return rr; |
349 | } |
350 | // vp is an intersection point,and we get it's parameter. |
351 | if (isedge1 && vp.IsOnDomS1()) return vp.ParameterOnArc1(); |
352 | if (isedge2 && vp.IsOnDomS2()) return vp.ParameterOnArc2(); |
353 | |
354 | // Else,we have to project the point on the edge restriction |
355 | Standard_Real tolee = BRep_Tool::Tolerance(E); |
356 | tolee = tolee * 1.e2; //xpu290998 : PRO15369 |
357 | Standard_Real param, dist; Standard_Boolean projok = FUN_tool_projPonE(vp.Value(),tolee,E,param,dist); |
358 | if (!projok) { |
9775fa61 |
359 | throw Standard_ProgramError("TopOpeBRep_FacesFiller::VPParamOnER"); |
7fd59977 |
360 | } |
361 | return param; |
362 | } |
363 | |
364 | //Standard_EXPORT Standard_Boolean FUN_EqualPonR(const TopOpeBRep_LineInter& Lrest, |
365 | Standard_EXPORT Standard_Boolean FUN_EqualPonR(const TopOpeBRep_LineInter& , |
366 | const TopOpeBRep_VPointInter& VP1, |
367 | const TopOpeBRep_VPointInter& VP2) |
368 | { |
369 | gp_Pnt P1 = VP1.Value(); gp_Pnt P2 = VP2.Value(); |
370 | Standard_Real Ptol1 = VP1.Tolerance(),Ptol2 = VP2.Tolerance(); |
371 | Standard_Real Ptol = (Ptol1 > Ptol2) ? Ptol1 : Ptol2; |
372 | Standard_Boolean Pequal = P1.IsEqual(P2,Ptol); |
373 | return Pequal; |
374 | } |
375 | Standard_EXPORT Standard_Boolean FUN_EqualponR(const TopOpeBRep_LineInter& Lrest, |
376 | const TopOpeBRep_VPointInter& VP1, |
377 | const TopOpeBRep_VPointInter& VP2) |
378 | { |
379 | Standard_Real p1 = TopOpeBRep_FacesFiller::VPParamOnER(VP1,Lrest); |
380 | Standard_Real p2 = TopOpeBRep_FacesFiller::VPParamOnER(VP2,Lrest); |
381 | Standard_Boolean pequal = fabs(p1-p2) < Precision::PConfusion(); |
382 | return pequal; |
383 | } |
384 | |
385 | //======================================================================= |
386 | //function : EqualpPOnR |
387 | //purpose : |
388 | //======================================================================= |
389 | Standard_Boolean TopOpeBRep_FacesFiller::EqualpPonR(const TopOpeBRep_LineInter& Lrest, |
390 | const TopOpeBRep_VPointInter& VP1, |
391 | const TopOpeBRep_VPointInter& VP2) |
392 | { |
393 | Standard_Boolean Pequal = ::FUN_EqualPonR(Lrest,VP1,VP2); |
394 | Standard_Boolean pequal = ::FUN_EqualponR(Lrest,VP1,VP2); |
395 | Standard_Boolean pPequal = Pequal && pequal; |
396 | return pPequal; |
397 | } |