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