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