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