b311480e |
1 | // Created on: 1995-08-04 |
2 | // Created by: Jean Yves LEBEY |
3 | // Copyright (c) 1995-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 | // |
973c2be1 |
8 | // This library is free software; you can redistribute it and / or modify it |
9 | // under the terms of the GNU Lesser General Public version 2.1 as published |
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 | |
17 | #include <TopOpeBRep_FacesFiller.ixx> |
18 | |
19 | #ifdef DRAW |
20 | #include <TopOpeBRepDS_DRAW.hxx> |
21 | #endif |
22 | |
23 | #include <Standard_DomainError.hxx> |
24 | #include <Geom_Surface.hxx> |
25 | #include <Geom_Curve.hxx> |
26 | #include <Geom2d_Curve.hxx> |
27 | #include <Precision.hxx> |
28 | #include <TopoDS.hxx> |
29 | #include <TopExp.hxx> |
30 | #include <BRep_Tool.hxx> |
31 | #include <gp_Vec.hxx> |
32 | |
33 | #include <TopOpeBRepTool_EXPORT.hxx> |
34 | #include <TopOpeBRepTool_SC.hxx> |
35 | #include <TopOpeBRepTool_TOOL.hxx> |
36 | #include <TopOpeBRepTool_ShapeTool.hxx> |
37 | #include <TopOpeBRepTool_makeTransition.hxx> |
38 | |
39 | #include <TopOpeBRepDS_define.hxx> |
40 | #include <TopOpeBRepDS_EXPORT.hxx> |
41 | #include <TopOpeBRepDS_ProcessInterferencesTool.hxx> |
42 | #include <TopOpeBRepDS_Config.hxx> |
43 | #include <TopOpeBRepDS_Curve.hxx> |
44 | #include <TopOpeBRepDS_PointIterator.hxx> |
45 | #include <TopOpeBRepDS_Dumper.hxx> |
46 | |
47 | #include <TopOpeBRep_define.hxx> |
48 | #include <TopOpeBRep_FFTransitionTool.hxx> |
49 | #include <TopOpeBRep_PointGeomTool.hxx> |
50 | #include <TopOpeBRep.hxx> |
51 | |
52 | #define M_ON(st) (st == TopAbs_ON) |
53 | #define M_UNKNOWN(st) (st == TopAbs_UNKNOWN) |
54 | #define M_REVERSED(st) (st == TopAbs_REVERSED) |
55 | |
56 | #ifdef DEB |
1d0a9d4d |
57 | extern Standard_Boolean TopOpeBRepDS_GettraceISTO(); |
58 | extern Standard_Boolean TopOpeBRepDS_GettraceDSF(); |
59 | extern Standard_Boolean TopOpeBRepDS_GettraceDSP(); |
60 | extern Standard_Boolean TopOpeBRepDS_GettraceSPSX(const Standard_Integer i); |
61 | extern Standard_Boolean TopOpeBRep_GettraceNVP(Standard_Integer a,Standard_Integer b,Standard_Integer c,Standard_Integer d,Standard_Integer e); |
62 | extern Standard_Boolean GLOBAL_bvpr = Standard_False;void debvpr(){}; |
63 | void debvprmess(Standard_Integer f1,Standard_Integer f2,Standard_Integer il,Standard_Integer vp,Standard_Integer si) |
7fd59977 |
64 | {cout<<"f1,f2,il,vp,si : "<<f1<<","<<f2<<","<<il<<","<<vp<<","<<si<<endl;cout.flush();debvpr();} |
65 | void debpoint(Standard_Integer i) {cout<<"+ debpoint"<<i<<endl;} |
66 | void debvertex(Standard_Integer i){cout<<"+ debvertex"<<i<<endl;} |
7fd59977 |
67 | |
68 | Standard_EXPORT void debarc(const Standard_Integer i) {cout<<"+ debarc "<<i<<endl;} |
69 | Standard_EXPORT void debooarc(const Standard_Integer i) {cout<<"+ debooarc "<<i<<endl;} |
70 | #endif |
71 | |
72 | Standard_EXPORT Standard_Boolean FDS_LOIinfsup(const TopOpeBRepDS_DataStructure& BDS,const TopoDS_Edge& E,const Standard_Real pE,const Standard_Integer GIP, |
73 | const TopOpeBRepDS_ListOfInterference& LOI, Standard_Real& pbef, Standard_Real& paft, Standard_Boolean& isonboundper); |
74 | Standard_EXPORT Standard_Boolean FUNBREP_topokpart |
75 | (const Handle(TopOpeBRepDS_Interference)& Ifound,const TopOpeBRepDS_ListOfInterference& DSCIL, |
76 | const TopOpeBRep_LineInter& L,const TopOpeBRep_VPointInter& VP, |
77 | const TopOpeBRepDS_DataStructure& BDS,const TopoDS_Shape& E,const TopoDS_Shape& F,const Standard_Real toluv, |
78 | Standard_Real& parline,TopOpeBRepDS_Transition& transLine); |
79 | |
80 | //----------------------------------------------------------------------- |
81 | // Search, among a list of interferences accessed by the iterator <IT>, |
82 | // a geometry whose parameter on edge point is identical to <par>. |
83 | // return True if such an interference has been found, False else. |
84 | // if True, iterator <IT> points (by the Value() method) on the first |
85 | // interference found. |
86 | //----------------------------------------------------------------------- |
87 | |
88 | Standard_EXPORT Standard_Boolean FUN_GetGonParameter |
89 | (TopOpeBRepDS_ListIteratorOfListOfInterference& it, const Standard_Real& par, const Standard_Real& tolp, |
90 | Standard_Integer& G, TopOpeBRepDS_Kind& GT) |
91 | { |
92 | while (it.More()) { |
93 | const Handle(TopOpeBRepDS_Interference)& I = it.Value(); |
94 | Standard_Real ipar; Standard_Boolean haspar = FDS_Parameter(I,ipar); |
95 | if (!haspar) {it.Next(); continue;} |
96 | Standard_Boolean samepar = (Abs(par-ipar) < tolp); |
97 | if (!samepar){it.Next(); continue;} |
98 | TopOpeBRepDS_Kind ST; Standard_Integer S; FDS_data(I,GT,G,ST,S); |
99 | return Standard_True; |
100 | } |
101 | return Standard_False; |
102 | } |
103 | |
104 | static Standard_Boolean FUN_INlos(const TopoDS_Shape& S, const TopTools_ListOfShape& loS) |
105 | { |
106 | TopTools_ListIteratorOfListOfShape it(loS); |
107 | for (; it.More(); it.Next()) |
108 | if (it.Value().IsSame(S)) return Standard_True; |
109 | return Standard_False; |
110 | } |
111 | |
112 | //======================================================================= |
113 | //function : ProcessVPIonR |
114 | //purpose : |
115 | //======================================================================= |
116 | |
117 | void TopOpeBRep_FacesFiller::ProcessVPIonR |
118 | (TopOpeBRep_VPointInterIterator& VPI, |
119 | const TopOpeBRepDS_Transition& Trans, |
120 | const TopoDS_Shape& Face, |
121 | const Standard_Integer ShapeIndex) //1,2 |
122 | { |
123 | const TopOpeBRep_VPointInter& VP = VPI.CurrentVP(); |
124 | ProcessVPonR(VP,Trans,Face,ShapeIndex); |
125 | } // ProcessVPIonR |
126 | |
127 | //----------------------------------------------------------------------- |
128 | static void FUN_transForWL |
129 | (const TopOpeBRep_LineInter& L, |
130 | const Standard_Integer iVP, |
131 | const Standard_Integer ShapeIndex, |
132 | TopOpeBRepDS_Transition& transLine) |
133 | //----------------------------------------------------------------------- |
134 | { |
135 | // premier VP avec indetermine : on prend le complement |
136 | // du suivant determine |
137 | TopOpeBRep_VPointInterIterator VPIbis; |
138 | for (VPIbis.Init(L); |
139 | VPIbis.More(); VPIbis.Next()) { |
140 | const TopOpeBRep_VPointInter& VPbis = VPIbis.CurrentVP(); |
141 | Standard_Boolean tokeep = VPbis.Keep(); |
142 | if ( !tokeep ) continue; |
143 | Standard_Integer iVPbis = VPIbis.CurrentVPIndex(); |
144 | if ( iVPbis <= iVP ) continue; |
145 | Standard_Integer absindexbis = VPbis.ShapeIndex(); // 0,1,2,3 |
146 | Standard_Integer shapeindexbis = (absindexbis == 3) ? ShapeIndex : absindexbis; |
147 | if ( shapeindexbis == 0 ) continue; |
148 | const TopoDS_Shape& edgebis = VPbis.Edge(shapeindexbis); |
149 | TopAbs_Orientation edgeoribis = edgebis.Orientation(); |
150 | TopOpeBRepDS_Transition transLinebis; |
151 | transLinebis = |
152 | TopOpeBRep_FFTransitionTool::ProcessLineTransition |
153 | (VPbis,shapeindexbis,edgeoribis); |
154 | Standard_Boolean trliunkbis = transLinebis.IsUnknown(); |
155 | if ( trliunkbis ) continue; |
156 | transLine = transLinebis.Complement(); |
157 | break; |
158 | } |
159 | } |
160 | |
161 | //----------------------------------------------------------------------- |
162 | static void FUN_VPgeometryfound |
163 | (TopOpeBRep_FacesFiller& FF, |
164 | const TopOpeBRep_LineInter& L, |
165 | const TopOpeBRep_VPointInter& VP, |
166 | const Standard_Integer ShapeIndex, |
167 | const Handle(TopOpeBRepDS_HDataStructure)& HDS, |
168 | const TopOpeBRepDS_ListOfInterference& DSCIL, |
169 | TopOpeBRepDS_Kind& PVKind, Standard_Integer& PVIndex, |
170 | Standard_Boolean& EPIfound, Handle(TopOpeBRepDS_Interference)& IEPI, |
171 | Standard_Boolean& CPIfound, Handle(TopOpeBRepDS_Interference)& ICPI, |
172 | Standard_Boolean& OOEPIfound, Handle(TopOpeBRepDS_Interference)& IOOEPI) // (only if on2edges) |
173 | //----------------------------------------------------------------------- |
174 | { |
175 | Standard_Boolean Lrest = (L.TypeLineCurve() == TopOpeBRep_RESTRICTION); |
176 | TopoDS_Shape Erest; Standard_Real parErest=0; Standard_Integer rkErest=0; |
177 | if (Lrest) { |
178 | Erest = L.Arc(); parErest = VP.ParameterOnLine(); |
179 | Standard_Boolean isedge1 = L.ArcIsEdge(1); Standard_Boolean isedge2 = L.ArcIsEdge(2); |
180 | rkErest = (isedge1) ? 1 : (isedge2) ? 2 : 0; |
181 | } |
182 | |
183 | Standard_Integer absindex = VP.ShapeIndex(); |
184 | Standard_Integer OOabsindex = (absindex == 1) ? 2 : 1; |
498ce76b |
185 | Standard_Integer OOShapeIndex = (ShapeIndex == 1) ? 2 : 1; |
7fd59977 |
186 | Standard_Boolean on2edges = (absindex == 3) || (Lrest && (rkErest == OOabsindex)); |
187 | TopoDS_Shape edge = (rkErest == ShapeIndex)? Erest : VP.Edge(ShapeIndex); |
188 | |
189 | PVIndex = 0; // POINT or VERTEX index |
190 | EPIfound = CPIfound = OOEPIfound = Standard_False; |
191 | Standard_Real par = (rkErest == ShapeIndex)? parErest : VP.EdgeParameter(ShapeIndex); |
192 | Standard_Real tole = FUN_tool_maxtol(edge); |
193 | Standard_Real tolp = Precision::Parametric(tole); |
194 | |
195 | const TopOpeBRepDS_DataStructure& BDS = HDS->DS(); |
196 | if (BDS.HasShape(edge)) { |
7fd59977 |
197 | const TopOpeBRepDS_ListOfInterference& EPIL = BDS.ShapeInterferences(edge); |
198 | TopOpeBRepDS_ListIteratorOfListOfInterference itEPIL(EPIL); |
199 | EPIfound = FF.GetGeometry(itEPIL,VP,PVIndex,PVKind); |
200 | if (!EPIfound) { |
201 | itEPIL.Initialize(EPIL); |
202 | EPIfound = FUN_GetGonParameter(itEPIL,par,tolp,PVIndex,PVKind); |
203 | } |
204 | if (EPIfound) IEPI = itEPIL.Value(); |
205 | } |
206 | |
207 | TopOpeBRepDS_ListIteratorOfListOfInterference itCPIL(DSCIL); |
208 | #ifdef DEB |
209 | Standard_Boolean trc = Standard_False; |
210 | if (trc) {TopOpeBRepDS_Dumper DSD(HDS); TCollection_AsciiString aa("DSCIL :"); |
211 | DSD.DumpLOI(DSCIL,cout,aa);} |
212 | #endif |
213 | CPIfound = FF.GetGeometry(itCPIL,VP,PVIndex,PVKind); |
214 | if (CPIfound) ICPI = itCPIL.Value(); |
215 | |
216 | // - <VP> is of shapeindex 3 : is on <edge> and <OOedge>, |
217 | // - <VP> is of shapeindex <ShapeIndex> and <VP> is given ON another edge <OOedge> |
218 | // If <OOedge> is defined, we look among the list of interferences attached |
219 | // to the other edge <OOedge> for an interference of geometry falling into <VP>'s. |
220 | |
221 | Standard_Boolean hasOOedge = Standard_True; |
222 | if (on2edges) hasOOedge = Standard_True; |
223 | else hasOOedge = (VP.State(OOShapeIndex) == TopAbs_ON); |
224 | if ( hasOOedge ) { |
225 | TopoDS_Shape OOedge; |
498ce76b |
226 | |
7fd59977 |
227 | if (on2edges) OOedge = (rkErest == OOShapeIndex)? Erest : VP.Edge(OOShapeIndex); |
7fd59977 |
228 | else OOedge = VP.EdgeON(OOShapeIndex); |
498ce76b |
229 | |
7fd59977 |
230 | Standard_Real OOpar = 0.; |
498ce76b |
231 | |
7fd59977 |
232 | if (on2edges) OOpar = (rkErest == OOShapeIndex)? parErest : VP.EdgeParameter(OOShapeIndex); |
7fd59977 |
233 | else OOpar = VP.EdgeONParameter(OOShapeIndex); |
498ce76b |
234 | |
7fd59977 |
235 | Standard_Real tolOOe = FUN_tool_maxtol(OOedge); |
236 | Standard_Real OOtolp = Precision::Parametric(tolOOe); |
237 | if (BDS.HasShape(OOedge)) { |
7fd59977 |
238 | const TopOpeBRepDS_ListOfInterference& OOEPIL = BDS.ShapeInterferences(OOedge); |
239 | TopOpeBRepDS_ListIteratorOfListOfInterference OOitEPIL(OOEPIL); |
240 | OOEPIfound = FF.GetGeometry(OOitEPIL,VP,PVIndex,PVKind); |
241 | if (!OOEPIfound) { |
242 | OOitEPIL.Initialize(OOEPIL); |
243 | FUN_GetGonParameter(OOitEPIL,OOpar,OOtolp,PVIndex,PVKind); |
244 | } |
245 | if (OOEPIfound) IOOEPI = OOitEPIL.Value(); |
246 | } |
247 | } |
248 | } |
249 | |
250 | #define M_FINDVP (0) // only look for new vp |
251 | #define M_MKNEWVP (1) // only make newvp |
252 | #define M_GETVP (2) // steps (0) [+(1) if (O) fails] |
253 | |
254 | //----------------------------------------------------------------------- |
255 | Standard_EXPORT void FUN_VPIndex |
256 | (TopOpeBRep_FacesFiller& FF, |
257 | const TopOpeBRep_LineInter& L, |
258 | const TopOpeBRep_VPointInter& VP, |
259 | const Standard_Integer ShapeIndex, |
260 | const Handle(TopOpeBRepDS_HDataStructure)& HDS, |
261 | const TopOpeBRepDS_ListOfInterference& DSCIL, |
262 | TopOpeBRepDS_Kind& PVKind, Standard_Integer& PVIndex, // out |
263 | Standard_Boolean& EPIfound, Handle(TopOpeBRepDS_Interference)& IEPI, // out |
264 | Standard_Boolean& CPIfound, Handle(TopOpeBRepDS_Interference)& ICPI, // out |
265 | const Standard_Integer mkVP) |
266 | //----------------------------------------------------------------------- |
267 | { |
268 | PVIndex = 0; // POINT or VERTEX index |
269 | Standard_Integer OOShapeIndex = (ShapeIndex == 1) ? 2 : 1; |
270 | Standard_Boolean SIisvertex = VP.IsVertex(ShapeIndex); |
271 | Standard_Boolean OOisvertex = VP.IsVertex(OOShapeIndex); |
272 | |
273 | // search for an interference with a equal 3D geometry |
274 | // if found, set PVIndex to index of geometry found |
275 | // if not found, make a new geometry PVIndex with 3d point or vertex |
276 | |
277 | Standard_Boolean OOEPIfound = Standard_False; |
278 | Handle(TopOpeBRepDS_Interference) IOOEPI; |
279 | if ((mkVP == M_FINDVP)||(mkVP == M_GETVP)) { |
280 | FUN_VPgeometryfound (FF,L,VP,ShapeIndex,HDS,DSCIL, //in |
281 | PVKind,PVIndex, // out |
282 | EPIfound,IEPI, // out |
283 | CPIfound,ICPI, // out |
284 | OOEPIfound,IOOEPI); // out (only if on2edges) |
285 | if (mkVP == M_FINDVP) { |
286 | //JMB 27 Dec 1999 |
287 | //modified by NIZHNY-MZV Tue Apr 25 09:27:15 2000 |
288 | if (!EPIfound && !CPIfound && !OOEPIfound) |
289 | PVIndex = 0; // if we just want to find (M_FINDVP) then we must readjust PVIndex to 0 |
290 | // because OOEPIfound is not treated in the upper function. The upper function |
291 | // will detect that we found a geometry because PVIndex != 0 but as EPIfound and |
292 | // CPIfound are FALSE, the resulting VP geometry give unpredictable results. |
293 | return; |
294 | } |
295 | } |
296 | // Gfound = VP corresponds with an existing geometry of ShapeIndex |
297 | Standard_Boolean Gfound = ( EPIfound || CPIfound); |
298 | // Gfound = or with an existing geometry of OOShapeIndex |
299 | Gfound = Gfound || OOEPIfound; |
300 | |
301 | Standard_Boolean on2edges = (VP.ShapeIndex() == 3); |
302 | Standard_Boolean hasOOedge = Standard_True; |
303 | if (on2edges) hasOOedge = Standard_True; |
304 | else hasOOedge = (VP.State(OOShapeIndex) == TopAbs_ON); |
305 | // If v shares same domain with a vertex of the other shape, |
306 | // v has already been stored in the DS |
307 | |
308 | if (PVIndex == 0) PVKind = (SIisvertex || OOisvertex) ? TopOpeBRepDS_VERTEX : TopOpeBRepDS_POINT; |
309 | |
310 | if ( hasOOedge && !Gfound ) { |
311 | if ( !OOEPIfound ) { |
312 | if ( SIisvertex ) PVIndex = FF.MakeGeometry(VP,ShapeIndex,PVKind); |
313 | else if ( OOisvertex ) PVIndex = FF.MakeGeometry(VP,OOShapeIndex,PVKind); |
314 | else PVIndex = FF.MakeGeometry(VP,ShapeIndex,PVKind); |
315 | } |
316 | } |
317 | if ( !hasOOedge && !Gfound ) { |
318 | Standard_Boolean found = FF.GetFFGeometry(VP,PVKind,PVIndex); |
319 | if ( !found) { |
320 | if ( SIisvertex ) PVIndex = FF.MakeGeometry(VP,ShapeIndex,PVKind); |
321 | else if ( OOisvertex ) PVIndex = FF.MakeGeometry(VP,OOShapeIndex,PVKind); |
322 | else PVIndex = FF.MakeGeometry(VP,ShapeIndex,PVKind); |
323 | } |
324 | } |
325 | } // FUN_VPIndex |
326 | |
327 | //----------------------------------------------------------------------- |
328 | static Standard_Boolean FUN_LineRestF |
329 | (const TopoDS_Face& F, const TopOpeBRep_LineInter& L, |
330 | const TopTools_ListOfShape& ERL, TopoDS_Edge& ER) |
331 | //----------------------------------------------------------------------- |
332 | { |
333 | // returns true if <L> is ON a restriction <ER> of <F> |
334 | // <ERL> is the list of the faces intersector. |
335 | // prequesitory : <L> is on edge |
336 | TopTools_IndexedMapOfShape mapE; |
337 | TopExp::MapShapes(F,TopAbs_EDGE,mapE); |
338 | TopTools_ListIteratorOfListOfShape itER(ERL); |
339 | TopTools_ListOfShape ERLonF; |
340 | for (; itER.More(); itER.Next()){ |
341 | const TopoDS_Shape& e = itER.Value(); |
342 | if (mapE.Contains(e)) ERLonF.Append(e); |
343 | } |
344 | itER.Initialize(ERLonF); |
345 | TopTools_ListOfShape ERLonFonL; |
346 | for (; itER.More(); itER.Next()){ |
347 | const TopoDS_Shape& e = itER.Value(); |
348 | TopTools_ListOfShape eL; eL.Append(e); |
349 | Standard_Boolean isonL = TopOpeBRep_FacesFiller::LSameDomainERL(L,eL); |
350 | if (isonL) ERLonFonL.Append(e); |
351 | } |
352 | // <L> is on at most one edge restriction. |
353 | if (ERLonFonL.Extent() != 1) return Standard_False; |
354 | ER = TopoDS::Edge(ERLonFonL.First()); |
355 | return Standard_True; |
356 | } |
357 | |
358 | //----------------------------------------------------------------------- |
359 | Standard_EXPORT Standard_Boolean FUN_newtransEdge |
360 | (const Handle(TopOpeBRepDS_HDataStructure) HDS, |
361 | const TopOpeBRep_FacesFiller& FF, |
362 | const TopOpeBRep_LineInter& L, |
363 | const Standard_Boolean& Lonrest, |
364 | const TopOpeBRep_VPointInter& VP, |
365 | const TopOpeBRepDS_Kind PVKind,const Standard_Integer PVIndex, |
366 | const Standard_Integer& OOShapeIndex, |
367 | const TopoDS_Edge& edge, const TopTools_ListOfShape& ERL, TopOpeBRepDS_Transition& T) |
368 | //----------------------------------------------------------------------- |
369 | { |
370 | T.Before(TopAbs_UNKNOWN); T.After(TopAbs_UNKNOWN); |
371 | const TopoDS_Face& OOface = FF.Face(OOShapeIndex); |
372 | TopoDS_Face FIE = OOface; |
373 | { |
374 | TopAbs_Orientation oFIE = FIE.Orientation(); |
375 | if (oFIE == TopAbs_INTERNAL || oFIE == TopAbs_EXTERNAL) { |
376 | T.Set(oFIE); |
377 | return Standard_True; |
378 | } |
379 | } |
380 | |
381 | // compute of transition on edge <edge> while crossing <VP>. |
382 | // <VP> given by <paredge> on <edge>, <uv> on <OOface>, |
383 | // <paronline> on Line. |
384 | |
385 | // <C>, <pf>, <pl>, <paredge> : |
386 | Standard_Real paredge; Standard_Boolean ok = VP.ParonE(edge,paredge); if (!ok) return Standard_False; |
387 | |
388 | Standard_Real par1,par2; |
389 | if (HDS->HasShape(edge)) { |
390 | Standard_Boolean isonper; |
391 | if (PVIndex == 0) FDS_getupperlower(HDS,HDS->DS().Shape(edge),paredge,par1,par2); |
392 | else FDS_LOIinfsup(HDS->DS(),edge,paredge,PVKind,PVIndex, |
393 | HDS->DS().ShapeInterferences(edge), |
394 | par1,par2,isonper); |
395 | } |
396 | else |
397 | FUN_tool_bounds(edge,par1,par2); |
398 | |
399 | gp_Pnt2d uv = VP.SurfaceParameters(OOShapeIndex); |
400 | |
401 | #ifdef DEB |
402 | TopOpeBRepDS_Transition Tr; |
403 | #endif |
404 | // <Tr> relative to 3d <OOface> matter, |
405 | // we take into account <Tr> / 2d <OOface> only if <edge> is normal to <OOface> |
406 | Standard_Real tola = Precision::Angular()*1.e+4; //dealing with tolerances |
407 | Standard_Boolean EtgOOF = FUN_tool_EtgF(paredge,edge,uv,OOface,tola); |
408 | Standard_Boolean inERL = FUN_INlos(edge,ERL); |
409 | Standard_Boolean isse = HDS->DS().IsSectionEdge(edge); |
410 | Standard_Boolean rest = inERL || isse; |
411 | Standard_Boolean interf2d = EtgOOF && Lonrest && rest; |
412 | Standard_Boolean interf3dtg = EtgOOF && rest && !interf2d; // xpu260898 :cto902D6,(e15,p3,f9) |
7fd59977 |
413 | |
414 | Standard_Real factor = 1.e-2; |
415 | TopOpeBRepTool_makeTransition MKT; |
416 | ok = MKT.Initialize(edge,par1,par2,paredge, OOface,uv, factor); |
417 | if (!ok) return Standard_False; |
418 | Standard_Boolean isT2d = MKT.IsT2d(); |
419 | interf2d = interf2d && isT2d; |
420 | |
421 | TopAbs_State stb,sta; |
422 | if (interf2d) { |
423 | // <tgLine> : |
424 | TopoDS_Edge OOER; Standard_Boolean onOOface = Standard_False; |
425 | TopOpeBRep_TypeLineCurve typL = L.TypeLineCurve(); |
426 | if (typL == TopOpeBRep_RESTRICTION) {onOOface = Standard_True; OOER = TopoDS::Edge(L.Arc());} |
427 | else {onOOface = ::FUN_LineRestF(OOface,L,ERL,OOER);} |
428 | if (!onOOface) return Standard_False; |
429 | |
430 | Standard_Real OOpar; ok = VP.ParonE(OOER,OOpar); |
431 | if (!ok) ok = FUN_tool_parE(edge,paredge,OOER,OOpar); |
432 | if (!ok) return Standard_False; |
433 | |
434 | //xpu051098 : cto900L4 (edge18,OOface5) |
435 | ok = MKT.SetRest(OOER,OOpar); |
436 | if (!ok) return Standard_False; |
437 | } |
438 | else if (interf3dtg) { |
439 | Standard_Integer absindex = VP.ShapeIndex(); // 0,1,2,3 |
440 | Standard_Boolean on2edges = (absindex == 3); |
441 | Standard_Boolean hasONedge = (VP.State(OOShapeIndex) == TopAbs_ON); |
442 | Standard_Boolean hasOOedge = (on2edges) ? Standard_True : hasONedge; |
443 | |
444 | if ( hasOOedge ) { |
445 | TopoDS_Edge OOedge; Standard_Real OOpar = 1.e7; |
446 | if (on2edges) |
447 | {OOedge = TopoDS::Edge(VP.Edge(OOShapeIndex)); OOpar = VP.EdgeParameter(OOShapeIndex);} |
448 | else |
449 | {OOedge = TopoDS::Edge(VP.EdgeON(OOShapeIndex)); OOpar = VP.EdgeONParameter(OOShapeIndex);} |
450 | |
451 | ok = MKT.SetRest(OOedge,OOpar); |
452 | if (!ok) return Standard_False; |
453 | } |
454 | } |
455 | |
456 | ok = MKT.MkTonE(stb,sta); |
457 | if (!ok) return Standard_False; |
458 | T.Before(stb); T.After(sta); |
459 | return Standard_True; |
460 | } // FUN_newtransEdge |
461 | |
462 | //----------------------------------------------------------------------- |
463 | static void FUN_ScanInterfList(const TopOpeBRepDS_Point& PDS, const Handle(TopOpeBRepDS_HDataStructure) HDS, |
464 | const TopOpeBRepDS_ListOfInterference& loI, TopOpeBRepDS_ListOfInterference& loIfound) |
465 | //----------------------------------------------------------------------- |
466 | { |
467 | // looks among the list of interferences <loI> for interferences |
468 | // of geometry falling into <PDS>, add them to <loIfound> |
469 | TopOpeBRepDS_ListIteratorOfListOfInterference it(loI); |
470 | while ( it.More()) { |
471 | Standard_Boolean found = HDS->ScanInterfList(it,PDS); |
472 | if (found) { |
473 | loIfound.Append(it.Value()); |
474 | if (it.More()) it.Next(); |
475 | } |
476 | else return; |
477 | } |
478 | } |
479 | |
480 | static Standard_Boolean FUN_selectTRAISHAinterference(const TopOpeBRepDS_ListOfInterference& lI, const Standard_Integer ITRASHA, |
481 | TopOpeBRepDS_ListOfInterference& lITRAonISHA) |
482 | // purpose : <lITRAonISHA> = {I = (T on ITRASHA,G,S)} |
483 | { |
484 | lITRAonISHA.Clear(); |
485 | TopOpeBRepDS_ListIteratorOfListOfInterference it(lI); |
486 | for (; it.More(); it.Next()) { |
487 | const Handle(TopOpeBRepDS_Interference)& I = it.Value(); |
488 | const TopOpeBRepDS_Transition& T = I->Transition(); |
489 | Standard_Integer iTRASHA = T.Index(); |
490 | // BUG : |
491 | //POP : pb : comparaison entre 2 enum differentes : on prend la valeur correspondante |
492 | if (T.Orientation(TopAbs_IN) == TopAbs_EXTERNAL) continue; //xpu030998 |
493 | // if (T.Orientation(TopAbs_IN) == TopAbs_UNKNOWN) continue; //xpu030998 |
494 | if (iTRASHA == ITRASHA) lITRAonISHA.Append(I); |
495 | } |
496 | Standard_Boolean noIfound = lITRAonISHA.IsEmpty(); |
497 | return !noIfound; |
498 | } |
499 | |
500 | static Standard_Boolean FUN_selectGinterference(const TopOpeBRepDS_ListOfInterference& lI, const Standard_Integer G, |
501 | TopOpeBRepDS_ListOfInterference& lIonG) |
502 | { |
503 | lIonG.Clear(); |
504 | TopOpeBRepDS_ListIteratorOfListOfInterference it(lI); |
505 | for (; it.More(); it.Next()) { |
506 | const Handle(TopOpeBRepDS_Interference)& I = it.Value(); |
507 | if (I->Geometry() == G) lIonG.Append(I); |
508 | } |
509 | Standard_Boolean noIfound = lIonG.IsEmpty(); |
510 | return !noIfound; |
511 | } |
512 | |
513 | static Standard_Boolean FUN_sameGsameS(const TopOpeBRepDS_ListOfInterference& loI, const Standard_Integer& G, const Standard_Integer& S, |
514 | TopOpeBRepDS_ListOfInterference& loIfound) |
515 | { |
516 | loIfound.Clear(); |
517 | // Gets among the list <loI> the interferences of : |
518 | // geometry <G>, and support <S> |
519 | TopOpeBRepDS_PointIterator PI(loI); |
520 | for (; PI.More(); PI.Next()) { |
521 | Handle(TopOpeBRepDS_Interference) EPI = PI.Value(); |
522 | Standard_Integer GEPI = EPI->Geometry(); Standard_Integer SEPI = EPI->Support(); |
523 | if (GEPI == G && SEPI == S) loIfound.Append(EPI); |
524 | } |
525 | return (loIfound.Extent() > 0); |
526 | } |
527 | |
528 | //----------------------------------------------------------------------- |
529 | static void FUN_processCPI |
530 | (TopOpeBRep_FacesFiller& FF, |
531 | const TopOpeBRep_VPointInter& VP, |
532 | const TopoDS_Shape& F, |
533 | const Standard_Integer ShapeIndex, |
534 | const TopOpeBRep_LineInter& L, |
535 | TopOpeBRepDS_PDataStructure pDS, |
536 | const TopOpeBRepDS_Transition& transLine, |
537 | const TopOpeBRepDS_ListOfInterference& DSCIL, |
538 | const Handle(TopOpeBRepDS_Interference)& Ifound, |
539 | const Standard_Boolean& Gfound, |
540 | const TopOpeBRepDS_Kind& PVKind,const Standard_Integer& PVIndex, |
541 | Standard_Integer& keptVPnbr) |
542 | //----------------------------------------------------------------------- |
543 | { |
7fd59977 |
544 | Standard_Integer OOShapeIndex = (ShapeIndex == 1) ? 2 : 1; |
545 | |
546 | TopOpeBRepDS_Transition ttransLine = transLine; |
547 | // prequesitory : current line is not on edge. |
548 | Standard_Real parline = VP.ParameterOnLine(); |
549 | Standard_Boolean SIisvertex = VP.IsVertex(ShapeIndex); |
550 | Standard_Boolean OOisvertex = VP.IsVertex(OOShapeIndex); |
551 | const TopoDS_Shape& E = VP.Edge(ShapeIndex); |
552 | |
553 | // xpu010299 : we do not keep interferences with same parameters on curve |
554 | // PRO16120(f3,f4 -> null c1) |
555 | if (!DSCIL.IsEmpty()) { |
556 | Standard_Real par = FDS_Parameter(DSCIL.Last()); // parameter on curve |
557 | Standard_Real dd = Abs(par-parline); // en fait, ce sont des entiers |
558 | if (dd == 0) return; |
559 | } |
560 | |
561 | // dist(p2d1,p2d2) < toluv => p2d1, p2d2 are considered equal. |
562 | // NYI : compute uvtol with the original faces. By default, we set toluv = TolClass |
563 | Standard_Real toluv = 1.e-8; |
564 | Standard_Boolean keep = FUNBREP_topokpart(Ifound,DSCIL,L,VP,(*pDS),E,F,toluv,parline,ttransLine); |
565 | |
566 | #ifdef DEB |
567 | Standard_Integer trc=TopOpeBRepDS_GettraceDSF(); |
568 | if (trc){if(keep)cout<<"\t-> on garde";else cout<<"\t-> on jette";cout<<endl;} |
569 | #endif |
570 | |
571 | if (keep) { |
572 | keptVPnbr++; |
573 | if (keptVPnbr > 2) keep = Standard_False; |
574 | } |
575 | if (!keep) return; |
576 | |
577 | Handle(TopOpeBRepDS_Interference) CPI; |
578 | { |
579 | TopOpeBRepDS_Kind GKCPV; |
580 | if (Gfound) GKCPV = PVKind; |
581 | else GKCPV = (SIisvertex || OOisvertex) ? TopOpeBRepDS_VERTEX : TopOpeBRepDS_POINT; |
582 | |
583 | CPI = ::MakeCPVInterference(ttransLine,0,PVIndex,parline,GKCPV); |
584 | FF.StoreCurveInterference(CPI); |
585 | } |
586 | } |
587 | |
588 | static Standard_Boolean FUN_onedge(const TopOpeBRepDS_Point& PDS, const TopoDS_Edge& E) |
589 | { |
590 | gp_Pnt P = PDS.Point(); |
591 | Standard_Real tolP = PDS.Tolerance(); Standard_Real tolE = BRep_Tool::Tolerance(E); |
592 | Standard_Real tol = Max(tolP,tolE); |
593 | TopoDS_Vertex vf,vl; TopExp::Vertices(E,vf,vl); |
594 | gp_Pnt pf = BRep_Tool::Pnt(vf); Standard_Boolean isonf = P.IsEqual(pf,tol); |
595 | gp_Pnt pl = BRep_Tool::Pnt(vl); Standard_Boolean isonl = P.IsEqual(pl,tol); |
596 | return isonf || isonl; |
597 | } |
598 | |
599 | #ifdef DEB |
600 | Standard_EXPORT void funraise() {cout<<"!!!!!!!!!! PVIndex = 0 !!!!!!!!!!"<<endl;} |
601 | #endif |
602 | |
603 | //======================================================================= |
604 | //function : ProcessVPonR |
605 | //purpose : |
606 | //======================================================================= |
607 | |
608 | void TopOpeBRep_FacesFiller::ProcessVPonR |
609 | (const TopOpeBRep_VPointInter& VP, |
610 | const TopOpeBRepDS_Transition& Trans, |
611 | // const TopoDS_Shape& GFace, |
612 | const TopoDS_Shape& , |
613 | const Standard_Integer ShapeIndex) //1,2 |
614 | { |
615 | Standard_Integer absindex = VP.ShapeIndex(); // 0,1,2,3 |
616 | Standard_Integer iVP = VP.Index(); |
617 | Standard_Boolean OOShapeIndex = (ShapeIndex == 1) ? 2 : 1; |
618 | Standard_Boolean on2edges = (absindex == 3); |
619 | Standard_Boolean hasONedge = (VP.State(OOShapeIndex) == TopAbs_ON); |
620 | Standard_Boolean hasOOedge = (on2edges) ? Standard_True : hasONedge; |
621 | |
622 | TopoDS_Face Face = (*this).Face(ShapeIndex); |
623 | Standard_Integer iSIFace = myDS->Shape(Face); |
624 | if (iSIFace == 0) iSIFace = myDS->AddShape(Face,ShapeIndex); |
625 | TopoDS_Face OOFace = (*this).Face(OOShapeIndex); |
626 | Standard_Integer iOOFace = myDS->Shape(OOFace); |
627 | if (iOOFace == 0) iOOFace = myDS->AddShape(OOFace,OOShapeIndex); |
628 | |
629 | // current VPoint is on <edge> |
630 | Standard_Integer SIedgeIndex = 0; |
631 | const TopoDS_Edge& edge = TopoDS::Edge(VP.Edge(ShapeIndex)); |
632 | if (myDS->HasShape(edge)) SIedgeIndex = myDS->Shape(edge); |
633 | Standard_Real paredge = VP.EdgeParameter(ShapeIndex); |
634 | Standard_Boolean isrest = myDS->IsSectionEdge(edge); |
635 | Standard_Boolean closing = TopOpeBRepTool_ShapeTool::Closed(edge,Face); |
636 | Standard_Boolean dge = BRep_Tool::Degenerated(edge); |
637 | |
638 | // dummy if !<hasOOedge> |
639 | Standard_Integer OOedgeIndex = 0; |
640 | Standard_Boolean OOclosing,OOisrest; OOclosing = OOisrest = Standard_False; |
641 | TopoDS_Edge OOedge; Standard_Real OOparedge = 0.; Standard_Boolean dgOOe = Standard_False; |
642 | if ( hasOOedge ) { |
643 | if (on2edges) OOparedge = VP.EdgeParameter(OOShapeIndex); |
644 | else OOparedge = VP.EdgeONParameter(OOShapeIndex); |
645 | TopoDS_Shape OOe; |
646 | if (on2edges) OOe = VP.Edge(OOShapeIndex); |
647 | else OOe = VP.EdgeON(OOShapeIndex); |
648 | OOedge = TopoDS::Edge(OOe); |
649 | if (myDS->HasShape(OOedge)) OOedgeIndex = myDS->Shape(OOedge); |
650 | OOisrest = myDS->IsSectionEdge(OOedge); |
651 | OOclosing = TopOpeBRepTool_ShapeTool::Closed(OOedge,OOFace); |
652 | dgOOe = BRep_Tool::Degenerated(OOedge); |
653 | } |
654 | |
655 | #ifdef DEB |
656 | Standard_Boolean traceDSF = TopOpeBRepDS_GettraceDSF(); |
657 | Standard_Boolean traceDSP = TopOpeBRepDS_GettraceDSP(); |
658 | Standard_Integer ili=myLine->Index(),ivp=iVP,isi=ShapeIndex; |
659 | if(traceDSF || traceDSP){ |
660 | cout<<endl; |
661 | cout<<"trc tnvp 1 "<<myexF1<<" "<<myexF2<<" "<<ili<<" "<<ivp<<" "<<isi; |
662 | cout<<"; # VPonR "<<iVP<<" on "<<ShapeIndex<<" from "<<absindex<<endl; |
663 | } |
664 | GLOBAL_bvpr = TopOpeBRep_GettraceNVP(myexF1,myexF2,ili,ivp,isi); |
665 | if (TopOpeBRepDS_GettraceISTO()) { |
666 | cout<<"f1,f2,l,vp,si : "; |
667 | cout<<myexF1<<","<<myexF2<<","<<ili<<","<<ivp<<","<<isi<<endl; |
668 | } |
669 | if (GLOBAL_bvpr) debvprmess(myexF1,myexF2,ili,ivp,isi); |
670 | if (traceDSF){ |
671 | cout<<"VP is on";if (closing) cout<<" CLOSING"; |
672 | cout<<" edge "<<SIedgeIndex; |
673 | if(isrest) cout<<" RESTRICTION"; cout<<endl; |
674 | if (OOclosing) cout<<" on CLOSING OOedge "<<OOedgeIndex; |
675 | if(OOisrest) cout<<" RESTRICTION"; cout<<endl; |
676 | } |
677 | #endif |
678 | |
679 | // degenerated edge processing |
680 | // --------------------------- |
681 | Standard_Integer PVIndex = 0; // POINT or VERTEX index |
682 | TopOpeBRepDS_Kind PVKind; |
683 | Standard_Boolean EPIfound,CPIfound; |
684 | EPIfound = CPIfound = Standard_False; |
685 | Handle(TopOpeBRepDS_Interference) IEPI,ICPI; |
686 | ProcessVPondgE(VP, ShapeIndex, |
687 | PVKind,PVIndex, // out |
688 | EPIfound,IEPI, // out |
689 | CPIfound,ICPI); // out |
690 | Standard_Boolean foundPVIndex = (PVIndex != 0); |
691 | |
692 | |
693 | // =================================================================== |
694 | // <TransLine>, <transEdge> |
695 | // =================================================================== |
696 | |
697 | Standard_Boolean wline = (myLine->TypeLineCurve() == TopOpeBRep_WALKING); |
698 | Standard_Boolean grestriction = (myLine->TypeLineCurve() == TopOpeBRep_RESTRICTION); |
699 | Standard_Boolean glinenotoned = !wline && !grestriction && !myLineIsonEdge; |
700 | |
701 | // lasttransLine (for walking line) |
702 | // ------------- |
703 | // set lasttransLine for a WALKING line |
704 | Standard_Boolean dscilempty = myDSCIL.IsEmpty(); |
705 | Standard_Boolean setlastonwl = wline && !dscilempty; |
706 | if (setlastonwl) { //xpu171198, FRA61896 (f7,f13-> null DSC1) |
707 | Standard_Real parline = VP.ParameterOnLine(); |
708 | Standard_Real par = FDS_Parameter(myDSCIL.Last()); // parameter on curve |
709 | Standard_Real dd = Abs(par-parline); // en fait, ce sont des entiers |
710 | if (dd == 0) setlastonwl=Standard_False; |
711 | } |
712 | TopOpeBRepDS_Transition lasttransLine; if (setlastonwl) lasttransLine = myDSCIL.Last()->Transition(); |
713 | |
714 | // edgeori, transLine |
715 | // ------------------ |
716 | TopAbs_Orientation edgeori = edge.Orientation(); |
717 | TopOpeBRepDS_Transition transLine; |
718 | transLine = TopOpeBRep_FFTransitionTool::ProcessLineTransition |
719 | (VP,ShapeIndex,edgeori); |
720 | Standard_Boolean trliunk = transLine.IsUnknown(); |
721 | |
722 | // 1_ If vpmin has transition OUT/IN, and vpmax is UNKNOWN, |
723 | // we change vpmax transition as IN/OUT |
724 | // |
725 | // 2_ If vpmin is UNKNOWN (if vp is first on line and transition is UNKNOWN, |
726 | // vpmin's transition is ON/ON the OOshape) |
727 | // we change vpmin transition as OUT/IN |
728 | // |
729 | // (kpart : sphere/box, with the sphere's sewing edge lying on one boxe's |
730 | // face and one of the edge's vertices IN the same face) |
731 | |
732 | Standard_Integer iINON1,iINONn,nINON; myLine->VPBounds(iINON1,iINONn,nINON); |
733 | Standard_Boolean islastvp = (iVP == iINONn); |
734 | Standard_Boolean isfirstvp = (iVP == iINON1); |
735 | |
736 | Standard_Boolean keepvp = Standard_False; |
737 | Standard_Boolean ret1 = Standard_False; |
738 | if ( trliunk ) { |
739 | // <transLine> is unknown : |
740 | // for a walking -> |
741 | // - if <myDSCIL> is not empty, |
742 | // we set it as the last transition complemented |
743 | // - else, |
744 | // we look after an determinate transition on VP(i>iVP) |
745 | // and set transLine as this last complemented. |
746 | // |
747 | // for a gline not on edge -> |
748 | // - if the transition on edge is unknown too and !<keepvp>, |
749 | // we do not keep it. |
750 | // elsewhere -> we do not keep <VP> |
751 | |
752 | if ( wline ) { |
753 | if (setlastonwl) transLine = lasttransLine.Complement(); |
754 | else ::FUN_transForWL(*myLine,iVP,ShapeIndex,transLine); |
755 | |
756 | // walki vpfirst on 3, vplast on 0, nvpkept = 2 kept |
757 | if (transLine.IsUnknown()) { |
758 | //modified by NIZHNY-MKK Mon Jul 3 11:30:03 2000.BEGIN |
759 | Standard_Boolean keepvpfirst = dscilempty && isfirstvp && (nINON == 2); |
760 | if(absindex==3) |
761 | keepvpfirst = keepvpfirst && myLastVPison0; |
762 | //modified by NIZHNY-MKK Mon Jul 3 11:30:21 2000.END |
763 | if (keepvpfirst) transLine.Set(TopAbs_FORWARD); |
764 | #ifdef DEB |
765 | if (traceDSF) cout<<"myLastVPison0 ->"<<endl; |
766 | #endif |
767 | ret1 = Standard_False; |
768 | } |
769 | } |
770 | else if ( glinenotoned ) { |
771 | // if (islastvp) keepvp = !dscilempty; |
772 | // if (isfirstvp) keepvp = Standard_True; |
773 | if (isfirstvp) keepvp = Standard_True; |
774 | else { |
775 | if (islastvp) keepvp = !dscilempty; |
776 | else { |
777 | if(!dge && !dgOOe && (VP.IsVertexOnS1() || VP.IsVertexOnS2())) { |
778 | // If VP is on vertex we should compute at least one interference for the edge. |
779 | // This interference is necessary at least to indicate that the edge intersect something. |
780 | const TopOpeBRep_VPointInter& aFirstPoint = myLine->VPoint(iINON1); |
781 | const TopOpeBRep_VPointInter& aLastPoint = myLine->VPoint(iINONn); |
782 | |
783 | for(Standard_Integer faceindex = 1; !keepvp && faceindex <=2; faceindex++) { |
784 | Standard_Boolean VPIsVertex = (faceindex==1) ? VP.IsVertexOnS1() : VP.IsVertexOnS2(); |
785 | Standard_Boolean FirstPointIsVertex = (faceindex==1) ? aFirstPoint.IsVertexOnS1() : aFirstPoint.IsVertexOnS2(); |
786 | Standard_Boolean LastPointIsVertex = (faceindex==1) ? aLastPoint.IsVertexOnS1() : aLastPoint.IsVertexOnS2(); |
787 | if(VPIsVertex) { |
788 | const TopoDS_Shape& aV1 = (faceindex==1) ? VP.VertexOnS1() : VP.VertexOnS2(); |
789 | if(FirstPointIsVertex) { |
790 | const TopoDS_Shape& aV2 = (faceindex==1) ? aFirstPoint.VertexOnS1(): aFirstPoint.VertexOnS2(); |
791 | if(aV1.IsSame(aV2)) { |
792 | keepvp = Standard_True; |
793 | } |
794 | } |
795 | if(!keepvp && LastPointIsVertex) { |
796 | const TopoDS_Shape& aV2 = (faceindex==1) ? aLastPoint.VertexOnS1() : aLastPoint.VertexOnS2(); |
797 | if(aV1.IsSame(aV2)) { |
798 | keepvp = !dscilempty; |
799 | } |
800 | } |
801 | } |
802 | } |
803 | } |
804 | } |
805 | } |
806 | ret1 = !keepvp; |
807 | } |
808 | else |
809 | ret1 = Standard_True; |
810 | } |
811 | trliunk = transLine.IsUnknown(); |
812 | if (ret1) return; |
813 | |
814 | // Transori, transEdge |
815 | // ------------------- |
816 | TopAbs_Orientation Transori = Trans.Orientation(TopAbs_IN); |
817 | TopOpeBRepDS_Transition transEdge = TopOpeBRep_FFTransitionTool::ProcessEdgeTransition(VP,ShapeIndex,Transori); |
818 | #ifdef DEB |
819 | if(traceDSF){cout<<"trans edge on f"<<ShapeIndex<<" / f"<<OOShapeIndex<<" : "; |
820 | transEdge.Dump(cout);cout<<endl;} |
821 | #endif |
822 | |
823 | Standard_Boolean Tunknown = FDS_hasUNK(transEdge); |
824 | TopOpeBRepDS_Point PDS = TopOpeBRep_PointGeomTool::MakePoint(VP);// <VP>'s geometry |
825 | TopOpeBRepDS_ListOfInterference lITOOFonVP; // {I on <edge> = (T on <OOface>, G on <VP>, S)} |
826 | Standard_Boolean found = Standard_False; |
827 | if (SIedgeIndex != 0) { |
828 | TopOpeBRepDS_ListOfInterference lI; |
829 | const TopOpeBRepDS_ListOfInterference& lIedge = myDS->ShapeInterferences(edge); |
830 | if (PVIndex == 0) ::FUN_ScanInterfList(PDS,myHDS,lIedge,lI); |
831 | else ::FUN_selectGinterference(lIedge,PVIndex,lI); |
832 | found = ::FUN_selectTRAISHAinterference(lI,iOOFace,lITOOFonVP); |
833 | } |
834 | |
835 | // if (found && myLineINL && Tunknown) return; //xpu220998 : cto cylcong A1 (edge8,OOface4) |
836 | |
837 | // <Transori> = INTERNAL or EXTERNAL (tangent cases), compute <transEdge> |
838 | Standard_Boolean newtransEdge = (Transori == TopAbs_INTERNAL) || (Transori == TopAbs_EXTERNAL); |
839 | TopAbs_Orientation otransEdge = transEdge.Orientation(TopAbs_IN); |
840 | Standard_Boolean allINT = (Transori == TopAbs_INTERNAL) || (otransEdge == TopAbs_INTERNAL); |
841 | Standard_Boolean allEXT = (Transori == TopAbs_EXTERNAL) || (otransEdge == TopAbs_EXTERNAL); |
842 | |
843 | |
844 | newtransEdge = newtransEdge && (!allINT) && (!allEXT); |
845 | newtransEdge = newtransEdge || Tunknown; |
846 | // -> intersection fails for closing edges |
847 | // 1. <edge> touches closing <OOedge> at <VP> && <OOedge> is tangent to <OOFace>, |
848 | // intersection -> 1 forward && 1 reversed instead of internal/external. |
849 | // 2. if <edge> is tangent to <OOFace> at <VP> on walking |
850 | newtransEdge = newtransEdge || closing || OOclosing; |
851 | newtransEdge = newtransEdge && (!myLineINL); |
852 | if (newtransEdge){ |
853 | #ifdef DEB |
854 | Standard_Integer iedge = |
855 | #endif |
856 | myDS->Shape(edge); |
857 | newtransEdge = !found; |
858 | if (found) { |
859 | // Getting first transition found |
860 | // prequesitory : transition on edge / <OOF> on same geometry point is unchanged |
861 | TopOpeBRepDS_Transition Tr = lITOOFonVP.First()->Transition(); |
862 | transEdge.Before(Tr.Before()); transEdge.After(Tr.After()); |
863 | } |
864 | if (newtransEdge) { |
865 | // Compute of <transEdge> : transition on <edge> at geometry <VP> / <OOface> |
866 | // if line on a restriction OOedge of <OOface> : gets <edge> transition/<OOface> when |
867 | // at <VP> on OOedge. |
868 | // if line is not on restriction : gets <edge> transition/<OOface>. |
869 | TopOpeBRepDS_Transition Tr; |
870 | Standard_Boolean ok = FUN_newtransEdge(myHDS,(*this),(*myLine),myLineIsonEdge,VP, |
871 | PVKind,PVIndex,OOShapeIndex,edge,myERL,Tr); |
872 | if (ok) {transEdge.Before(Tr.Before()); transEdge.After(Tr.After());} |
873 | newtransEdge = ok; |
874 | } |
875 | #ifdef DEB |
876 | if (traceDSF && (found || newtransEdge)) |
877 | {if (found) cout<<"*-> found "; if (newtransEdge) cout<<"*-> new "; |
878 | cout<<"transEdge (edge "<<iedge<<",face"<<iOOFace<<") = "; TopAbs::Print(transEdge.Before(),cout); |
879 | cout<<" ";TopAbs::Print(transEdge.After(),cout);cout<<endl;} |
880 | #endif |
881 | } // newtransEdge |
882 | |
883 | Standard_Boolean tredunk = transEdge.IsUnknown(); |
884 | Standard_Boolean ret2 = Standard_False; |
885 | if ( tredunk ) { |
886 | if (!trliunk) transEdge = transLine.Complement(); |
887 | if (trliunk && !keepvp) ret2 = Standard_True; |
888 | } |
889 | if (ret2) return; |
890 | tredunk = transEdge.IsUnknown(); |
891 | |
892 | // =================================================================== |
893 | // DS geometry Management |
894 | // =================================================================== |
895 | // SI*** : data issued from shape ShapeIndex |
896 | // OO*** : data issued from other shape |
897 | |
898 | if (SIedgeIndex == 0) SIedgeIndex = myDS->AddShape(edge,ShapeIndex); |
899 | #ifdef DEB |
900 | Standard_Boolean trce = TopOpeBRepDS_GettraceSPSX(SIedgeIndex); if(trce) debarc(SIedgeIndex); |
901 | #endif |
902 | |
903 | Standard_Boolean SIisvertex = VP.IsVertex(ShapeIndex); |
904 | Standard_Boolean OOisvertex = VP.IsVertex(OOShapeIndex); |
905 | |
906 | // <PVIndex>, <PVKind> : |
907 | // -------------------- |
908 | // search for an interference with a equal 3D geometry |
909 | // if found, set <PVIndex> to index of geometry found |
910 | // if not found, make a new geometry PVIndex with 3d point or vertex |
911 | |
912 | // modified by NIZHNY-MKK Tue Apr 3 12:08:38 2001.BEGIN |
913 | Standard_Boolean ismultiplekind = foundPVIndex && !EPIfound && !CPIfound && |
914 | (SIisvertex || OOisvertex) && (PVKind == TopOpeBRepDS_POINT); |
915 | |
916 | // if (!foundPVIndex) FUN_VPIndex ((*this),(*myLine),VP,ShapeIndex,myHDS,myDSCIL, //in |
917 | if (!foundPVIndex || ismultiplekind) FUN_VPIndex ((*this),(*myLine),VP,ShapeIndex,myHDS,myDSCIL, //in |
918 | // modified by NIZHNY-MKK Tue Apr 3 12:13:17 2001.END |
919 | PVKind,PVIndex, // out |
920 | EPIfound,IEPI, // out |
921 | CPIfound,ICPI, // out |
922 | M_MKNEWVP); |
923 | if (PVIndex == 0){ |
924 | #ifdef DEB |
925 | funraise(); |
926 | #endif |
927 | } |
928 | |
929 | Standard_Boolean VPonedge=Standard_False; if (PVKind == TopOpeBRepDS_VERTEX) VPonedge=::FUN_onedge(PDS,edge); |
930 | if (myLineINL) { |
931 | Standard_Real tolang = Precision::Angular()*1.e5;//=1.e-7 NYITOLXPU |
932 | |
933 | gp_Vec tgE = FUN_tool_tggeomE(paredge,edge); |
934 | gp_Pnt2d OOuv; Standard_Boolean ok = Standard_False; |
935 | if (VPonedge) {OOuv = VP.SurfaceParameters(OOShapeIndex); ok = Standard_True;} |
936 | else {ok = FUN_tool_paronEF(OOedge,OOparedge,OOFace, OOuv);} |
937 | gp_Vec ntOOF; |
938 | if (ok) ntOOF = FUN_tool_nggeomF(OOuv,OOFace); |
939 | if (OOFace.Orientation() == TopAbs_REVERSED) ntOOF.Reverse(); |
940 | |
941 | Standard_Real tol = 1.e-7; |
942 | if (ok) ok = (tgE.Magnitude() > tol)&&(ntOOF.Magnitude() > tol); |
943 | Standard_Real dot = 1.e7; if (ok) dot = gp_Dir(tgE).Dot(gp_Dir(ntOOF)); |
944 | |
945 | |
946 | Handle(Geom_Surface) su = BRep_Tool::Surface(OOFace); |
947 | Standard_Boolean apex = FUN_tool_onapex(OOuv,su); |
948 | TopOpeBRepDS_Transition T; |
949 | if (!apex && ok && (Abs(dot) > tolang)) { |
950 | TopAbs_Orientation ori = (dot < 0.) ? TopAbs_FORWARD : TopAbs_REVERSED; |
951 | T.Set(ori); |
952 | } |
953 | |
954 | if (VPonedge && (!dge)) { |
955 | //xpu231098 : cto904C8(edge11) |
956 | // xpu131198 : CTS21802(edge31) |
957 | if (iOOFace == 0) iOOFace = myDS->AddShape(OOFace,OOShapeIndex); |
958 | Handle(TopOpeBRepDS_Interference) EPIf; |
959 | { |
960 | T.Index(iOOFace); |
961 | EPIf = MakeEPVInterference(T,iOOFace,PVIndex,paredge,PVKind,TopOpeBRepDS_FACE,SIisvertex); |
962 | } |
963 | myHDS->StoreInterference(EPIf,edge); |
964 | if (on2edges || hasONedge) { |
965 | if (OOedgeIndex == 0) OOedgeIndex = myDS->AddShape(OOedge,OOShapeIndex); |
966 | Handle(TopOpeBRepDS_Interference) EPI; |
967 | { |
968 | T.Index(iOOFace); |
969 | EPI = MakeEPVInterference(T,OOedgeIndex,PVIndex,paredge,PVKind,SIisvertex); |
970 | } |
971 | myHDS->StoreInterference(EPI,edge); |
972 | } |
973 | return; |
974 | }//VPonedge |
975 | else { |
976 | // compute interferences later on |
977 | //modified by NIZHNY-MZV Thu Dec 23 13:27:10 1999 |
978 | if(!T.IsUnknown()) { |
979 | transEdge.Before(T.Before()); |
980 | transEdge.After(T.After()); |
981 | } |
982 | } |
983 | }//myLineINL |
984 | |
7fd59977 |
985 | // Gfound = VP corresponds with an existing geometry of ShapeIndex |
986 | Standard_Boolean Gfound = ( EPIfound || CPIfound ); |
987 | #ifdef DEB |
988 | Standard_Boolean trcpv = TopOpeBRepDS_GettraceSPSX(PVIndex); |
989 | Standard_Boolean ispoint = (PVKind == TopOpeBRepDS_POINT); |
990 | if(trcpv && ispoint) debpoint(PVIndex); |
991 | if(trcpv && !ispoint) debvertex(PVIndex); |
992 | if (GLOBAL_bvpr) debvprmess(myexF1,myexF2,ili,ivp,isi); |
993 | #endif |
994 | |
995 | // =================================================================== |
996 | // Current VPoint VP is kept |
997 | // =================================================================== |
998 | |
999 | // ------------------------------------------ |
1000 | // -- Curve/(POINT,VERTEX) Interference (CPI) |
1001 | // ------------------------------------------ |
1002 | |
1003 | Standard_Boolean noCPI = myLineIsonEdge; |
1004 | noCPI = noCPI || (!on2edges && hasOOedge && (OOisrest || isrest)); |
1005 | |
1006 | Standard_Boolean condi = (!noCPI); |
1007 | condi = condi && (!myLineINL); // INL |
1008 | if (condi) { |
1009 | Standard_Integer keptVPnbr = mykeptVPnbr; |
1010 | FUN_processCPI((*this),VP,Face,ShapeIndex,(*myLine),myDS, |
1011 | transLine,myDSCIL,ICPI,Gfound,PVKind,PVIndex, |
1012 | keptVPnbr); |
1013 | mykeptVPnbr = keptVPnbr; |
1014 | } |
1015 | |
1016 | // ------------------------------------------ |
1017 | // --- Edge/(POINT,VERTEX) Interference (EPI) |
1018 | // ------------------------------------------ |
1019 | |
1020 | // if (on2edges && !Gfound && !closing) { |
1021 | Standard_Boolean condi2 = (on2edges && !closing); |
1022 | condi2 = condi2 || (hasONedge && !closing); |
1023 | if (condi2 && (!dge)) { |
1024 | if (OOedgeIndex == 0) OOedgeIndex = myDS->AddShape(OOedge,OOShapeIndex); |
1025 | |
1026 | Handle(TopOpeBRepDS_Interference) EPI; |
1027 | { |
1028 | TopOpeBRepDS_Transition T = transEdge; |
1029 | if (iOOFace == 0) iOOFace = myDS->AddShape(OOFace,OOShapeIndex); |
1030 | T.Index(iOOFace); |
1031 | EPI = MakeEPVInterference(T,OOedgeIndex,PVIndex,paredge,PVKind,SIisvertex); |
1032 | } |
1033 | myHDS->StoreInterference(EPI,edge); |
1034 | } //condi2 |
1035 | |
1036 | // =================================================================== |
1037 | // manip corrective d'un pb. d'intersection |
1038 | // - le VPoint est donne sur une restriction de ShapeIndex (1 ou 2), |
1039 | // - le VPoint est ON une restriction de l'autre shape (OOShapeIndex) |
1040 | // --> le VPoint n'est PAS donne sur restriction de OOShapeIndex NYI |
1041 | // par les intersections (a ameliorer). NYI |
1042 | // L'etat ON sur OOShapeIndex indique que le point est sur une |
1043 | // de ses restrictions : |
1044 | // - on ne met PAS le point dans les CPIs |
1045 | // - on met le point dans les EPIs de l'arete de OOShapeIndex |
1046 | // =================================================================== |
1047 | |
1048 | Standard_Boolean correctON = !on2edges && hasONedge && !dgOOe; |
1049 | Standard_Boolean correctedON = Standard_False; |
1050 | if ( correctON ) { |
1051 | TopOpeBRepDS_ListOfInterference lITFonVP; Standard_Boolean OOfound = Standard_False; |
1052 | if (OOedgeIndex != 0) { |
1053 | const TopOpeBRepDS_ListOfInterference& lIOOedge = myDS->ShapeInterferences(OOedge); |
1054 | TopOpeBRepDS_ListOfInterference lI; ::FUN_ScanInterfList(PDS,myHDS,lIOOedge,lI); |
1055 | OOfound = ::FUN_selectTRAISHAinterference(lI,iSIFace,lITFonVP); |
1056 | correctON = !OOfound; |
1057 | } |
1058 | } |
1059 | if ( correctON ) { |
1060 | #ifdef DEB |
1061 | Standard_Boolean trcooe=TopOpeBRepDS_GettraceSPSX(OOedgeIndex);if (trcooe) debooarc(OOedgeIndex); |
1062 | #endif |
1063 | if (OOedgeIndex == 0) OOedgeIndex = myDS->AddShape(OOedge,OOShapeIndex); |
1064 | |
1065 | // VP a ete classifie ON sur l'edge <OOedge>. |
1066 | // calcul de la transition <tOOedge> sur l'arete <OOedge> |
1067 | // (de l'autre face en jeu, OOShapeIndex) ou le VP est donne ON. |
1068 | // On tient compte de l'orientation de <edge> dans <Face>. |
1069 | // (bug IntPatch_Line : VP n'a pas de donnees en OOShapeIndex |
1070 | // alors qu'il est dessus) |
1071 | |
1072 | TopOpeBRepDS_Transition tOOedge; |
1073 | // distinguish wether OOedge is the edge on which geometric line lies. |
1074 | // OOedge == edge(line) ==> tOOedge = f(orientation of <edge> in <Face> FORWARD) |
1075 | // OOedge != edge(line) ==> tOOedge = f(orientation of <Face>) |
1076 | Standard_Real OOpar1,OOpar2; Standard_Boolean isonper; FDS_LOIinfsup((*myDS),OOedge,OOparedge,PVKind,PVIndex, |
1077 | myDS->ShapeInterferences(OOedge), |
1078 | OOpar1,OOpar2,isonper); |
1079 | //FDS_getupperlower(myHDS,OOedgeIndex,OOparedge,par1,par2); |
1080 | gp_Pnt2d OOuv = VP.SurfaceParameters(ShapeIndex); |
1081 | |
1082 | // <Tr> relative to 3d <OOface> matter, |
1083 | // we take into account <Tr> / 2d <OOface> only if <edge> is normal to <OOface> |
1084 | Standard_Real tola = Precision::Angular()*1.e+2; //dealing with tolerances |
1085 | |
1086 | // KK : supplying tolerances pbm (tola too small) |
1087 | Standard_Boolean EsdmEofF = myHDS->HasSameDomain(OOedge); |
1088 | if (EsdmEofF) { |
1089 | TopExp_Explorer ex; |
1090 | for (ex.Init(Face, TopAbs_EDGE); ex.More(); ex.Next()) |
1091 | if (FUN_ds_sdm(*myDS,ex.Current(),OOedge)) {EsdmEofF = Standard_True; break;} |
1092 | } |
1093 | Standard_Boolean OOEtgF = Standard_True; |
1094 | if (!EsdmEofF) OOEtgF = FUN_tool_EtgF(OOparedge,OOedge,OOuv,Face,tola); |
1095 | Standard_Boolean OOrest = FUN_INlos(edge,myERL); |
1096 | Standard_Boolean interf2d = OOEtgF && (OOisrest || OOrest); |
1097 | |
1098 | Standard_Real factor = 1.e-2; |
1099 | TopOpeBRepTool_makeTransition MKT; |
1100 | Standard_Boolean ok = MKT.Initialize(OOedge,OOpar1,OOpar2,OOparedge,Face,OOuv, factor); |
1101 | |
1102 | if (ok && !(interf2d && !MKT.IsT2d())) { |
1103 | MKT.SetRest(edge,paredge); |
1104 | TopAbs_State stb,sta; ok = MKT.MkTonE(stb,sta); |
1105 | if (ok) { |
1106 | tOOedge.Before(stb); tOOedge.After(sta); |
1107 | #ifdef DEB |
1108 | if(traceDSF){ |
1109 | cout<<"* !on2edges && TopAbs_ON *\n"; |
1110 | if(OOisrest) cout<<"* edge "<<OOedgeIndex<<" RESTRICTION *\n"; |
1111 | cout<<"Transition sur <OOedge> "<<OOedgeIndex<<" croisant <edge> "<<SIedgeIndex<<" "; |
1112 | TopAbs::Print(edgeori,cout);cout<<" ";tOOedge.Dump(cout);cout<<endl;} |
1113 | #endif |
1114 | Handle(TopOpeBRepDS_Interference) OOEPIe; |
1115 | { |
1116 | if (iSIFace == 0) iSIFace = myDS->AddShape(Face,ShapeIndex); |
1117 | TopOpeBRepDS_Transition OOT = tOOedge; OOT.Index(iSIFace); |
1118 | OOEPIe = MakeEPVInterference(OOT,SIedgeIndex,PVIndex,OOparedge,PVKind,OOisvertex); |
1119 | } |
1120 | myHDS->StoreInterference(OOEPIe,OOedge); |
1121 | |
1122 | // xpu : 09-03-98 |
1123 | // hsd3d => interf2d : only IwithSkEDGE interf |
1124 | // elsewhere : add an IwithSkFACE interference. |
1125 | Standard_Boolean addEPIf = !myLineIsonEdge; |
1126 | TopTools_ListOfShape dummy; Standard_Boolean hsd3d = FDS_HasSameDomain3d(*myDS,OOedge,&dummy); |
1127 | if (hsd3d) addEPIf = Standard_False; |
1128 | if (addEPIf) { |
1129 | TopOpeBRepDS_Transition OOT = tOOedge; OOT.Index(iSIFace); |
1130 | Handle(TopOpeBRepDS_Interference) OOEPIf = MakeEPVInterference(OOT,iSIFace,PVIndex,OOparedge,PVKind, |
1131 | TopOpeBRepDS_FACE,OOisvertex); |
1132 | myHDS->StoreInterference(OOEPIf,OOedge); |
1133 | } |
1134 | // xpu : 09-03-98 |
1135 | correctedON = Standard_True; |
1136 | } // ok |
1137 | } |
1138 | } // correctON |
1139 | |
1140 | if (correctON && !correctedON && noCPI && !myLineIsonEdge) { |
1141 | // MSV: correct ON failed, so store CPI |
1142 | Standard_Integer keptVPnbr = mykeptVPnbr; |
1143 | FUN_processCPI((*this),VP,Face,ShapeIndex,(*myLine),myDS, |
1144 | transLine,myDSCIL,ICPI,Gfound,PVKind,PVIndex, |
1145 | keptVPnbr); |
1146 | mykeptVPnbr = keptVPnbr; |
1147 | } |
1148 | |
1149 | // closing edge processing |
1150 | // ----------------------- |
1151 | if ((OOclosing || closing)&& !found) { |
1152 | ProcessVPonclosingR(VP,Face,ShapeIndex, |
1153 | transEdge, |
1154 | PVKind,PVIndex, |
1155 | EPIfound,IEPI); |
1156 | return; |
1157 | } |
1158 | |
1159 | // VP processing |
1160 | // ------------- |
1161 | |
1162 | Standard_Boolean addEPI = Standard_False; |
1163 | if (!Gfound) { |
1164 | addEPI = Standard_True; |
1165 | } |
1166 | else { // EPIfound |
1167 | TopAbs_Orientation otransEdge = transEdge.Orientation(TopAbs_IN); |
1168 | |
1169 | Standard_Boolean opporifound,memorifound; opporifound = memorifound = Standard_False; |
1170 | TopOpeBRepDS_ListOfInterference loIfound; |
1171 | const TopOpeBRepDS_ListOfInterference& EPIL = myDS->ShapeInterferences(edge); |
1172 | Standard_Boolean ok = FUN_sameGsameS(EPIL,PVIndex,iOOFace,loIfound); |
1173 | if (ok) { |
1174 | TopOpeBRepDS_PointIterator PI(loIfound); |
1175 | // on cree une EPI orientee <transEdge> ssi : |
1176 | // - il en existe deja une d'orientation opposee a TransEdge |
1177 | // - il n'en existe pas deja une d'orientation identique a TransEdge |
1178 | for (; PI.More(); PI.Next()){ |
1179 | TopAbs_Orientation oEPI = PI.Value()->Transition().Orientation(TopAbs_IN); |
1180 | if (!memorifound) memorifound = ( oEPI == otransEdge ); |
1181 | if (!opporifound) opporifound = ( oEPI == TopAbs::Complement(otransEdge) ); |
1182 | addEPI = (opporifound && ! memorifound); |
1183 | if (addEPI) break; |
1184 | } |
1185 | } |
1186 | if (!ok) addEPI = Standard_True; |
1187 | } // EPIfound |
1188 | |
1189 | #ifdef DEB |
1190 | if (GLOBAL_bvpr) debvprmess(myexF1,myexF2,ili,ivp,isi); |
1191 | #endif |
1192 | |
1193 | // xpu030998 : edge has restriction on OOface, do NOT append EPIf |
1194 | // cto904A3 (edge19,OOface14,vG16), |
1195 | if (myLineINL) { |
1196 | Standard_Real tola = Precision::Angular()*1.e+4; //dealing with tolerances |
1197 | gp_Pnt2d uv = VP.SurfaceParameters(OOShapeIndex); |
1198 | Standard_Boolean EtgOOF = FUN_tool_EtgF(paredge,edge,uv,OOFace,tola); |
1199 | Standard_Boolean inERL = FUN_INlos(edge,myERL); |
1200 | if (EtgOOF && inERL) return; // cto904A3 |
1201 | } |
1202 | |
1203 | if ( addEPI && (!dge)) { |
1204 | // ShapeIndex = 1,2 --> OOShapeIndex = 2,1 |
1205 | // point est sur une seule arete <edge> de <ShapeIndex> |
1206 | // le Support de l'interference est l'autre |
1207 | // face (OOShapeIndex) / ShapeIndex |
1208 | if (iOOFace == 0) iOOFace = myDS->AddShape(OOFace,OOShapeIndex); |
1209 | Handle(TopOpeBRepDS_Interference) EPIf; |
1210 | { |
1211 | TopOpeBRepDS_Transition T = transEdge; T.Index(iOOFace); |
1212 | EPIf = MakeEPVInterference(T,iOOFace,PVIndex,paredge,PVKind,TopOpeBRepDS_FACE,SIisvertex); |
1213 | } |
1214 | myHDS->StoreInterference(EPIf,edge); |
1215 | } // addEPI |
1216 | |
1217 | } // ProcessVPonR |