1 // Created on: 1996-03-07
2 // Created by: Jean Yves LEBEY
3 // Copyright (c) 1996-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 <Standard_NoSuchObject.hxx>
20 #include <TCollection_AsciiString.hxx>
21 #include <TopoDS_Edge.hxx>
22 #include <TopoDS_Face.hxx>
23 #include <TopoDS_Shape.hxx>
24 #include <TopoDS_Vertex.hxx>
25 #include <TopOpeBRepBuild_Builder.hxx>
26 #include <TopOpeBRepBuild_define.hxx>
27 #include <TopOpeBRepBuild_EdgeBuilder.hxx>
28 #include <TopOpeBRepBuild_FaceBuilder.hxx>
29 #include <TopOpeBRepBuild_GTopo.hxx>
30 #include <TopOpeBRepBuild_HBuilder.hxx>
31 #include <TopOpeBRepBuild_PaveSet.hxx>
32 #include <TopOpeBRepBuild_ShapeSet.hxx>
33 #include <TopOpeBRepBuild_ShellFaceSet.hxx>
34 #include <TopOpeBRepBuild_SolidBuilder.hxx>
35 #include <TopOpeBRepBuild_WireEdgeSet.hxx>
36 #include <TopOpeBRepDS_BuildTool.hxx>
37 #include <TopOpeBRepDS_CurveIterator.hxx>
38 #include <TopOpeBRepDS_EXPORT.hxx>
39 #include <TopOpeBRepDS_HDataStructure.hxx>
40 #include <TopOpeBRepDS_PointIterator.hxx>
41 #include <TopOpeBRepDS_SurfaceIterator.hxx>
42 #include <TopOpeBRepTool_ShapeExplorer.hxx>
43 
44 #ifdef DRAW
45 #include <TopOpeBRepDS_DRAW.hxx>
46 #endif
47 
48 #include <TopOpeBRepDS_EXPORT.hxx>
49 #include <TopOpeBRepDS_ProcessInterferencesTool.hxx>
50 #include <TopOpeBRepTool_EXPORT.hxx>
51 #include <TopOpeBRepTool_TOOL.hxx>
52 #include <TopOpeBRepDS_TKI.hxx>
53 #include <TopOpeBRepDS.hxx>
54 #include <BRep_Tool.hxx>
55 #include <TopoDS.hxx>
56 #include <Geom_Curve.hxx>
57 #include <Geom2d_Curve.hxx>
58 #include <Geom_Plane.hxx>
59 #include <gp_Pnt.hxx>
60 #include <gp_Pnt2d.hxx>
61 #include <ElCLib.hxx>
62 #include <ElSLib.hxx>
63 #include <Geom2dAdaptor_Curve.hxx>
64 #include <Precision.hxx>
65 #include <BRepAdaptor_Curve.hxx>
66 #include <TopOpeBRepTool_2d.hxx>
67 #include <TopOpeBRepDS_Dumper.hxx>
68 #include <Standard_ProgramError.hxx>
69 #include <TopOpeBRepDS_EdgeVertexInterference.hxx>
70 
71 #ifdef OCCT_DEBUG
72 Standard_EXPORT Standard_Boolean TopOpeBRepBuild_GetcontextNOSG();
73 #endif
74 
75 #define M_FORWARD(st) (st == TopAbs_FORWARD)
76 #define M_REVERSED(st) (st == TopAbs_REVERSED)
77 #define M_INTERNAL(st) (st == TopAbs_INTERNAL)
78 #define M_EXTERNAL(st) (st == TopAbs_EXTERNAL)
79 
80 Standard_Boolean TopOpeBRepBuild_FUN_aresamegeom(const TopoDS_Shape& S1,const TopoDS_Shape& S2);
81 
82 
83 //=======================================================================
84 //function : GMergeEdges
85 //purpose  :
86 //=======================================================================
GMergeEdges(const TopTools_ListOfShape & LE1,const TopTools_ListOfShape & LE2,const TopOpeBRepBuild_GTopo & G1)87 void TopOpeBRepBuild_Builder::GMergeEdges(const TopTools_ListOfShape& LE1,const TopTools_ListOfShape& LE2,const TopOpeBRepBuild_GTopo& G1)
88 {
89   if ( LE1.IsEmpty() ) return;
90   TopAbs_State TB1,TB2; G1.StatesON(TB1,TB2);
91 
92   const TopoDS_Shape& E1 = LE1.First();
93 #ifdef OCCT_DEBUG
94   Standard_Integer iE; Standard_Boolean tSPS1 = GtraceSPS(E1,iE);
95   if(tSPS1){
96     std::cout<<std::endl;std::cout<<"--- GMergeEdges "<<std::endl;
97     GdumpEDG(E1);
98     GdumpSAMDOM(LE1, (char *) "1 : ");
99     GdumpSAMDOM(LE2, (char *) "2 : ");
100   }
101 #endif
102 
103   myEdgeReference = TopoDS::Edge(E1);
104   TopOpeBRepBuild_PaveSet PVS(E1);
105 
106   GFillEdgesPVS(LE1,LE2,G1,PVS);
107 
108   // Create a edge builder EBU
109   TopoDS_Shape E1F = LE1.First(); E1F.Orientation(TopAbs_FORWARD);
110   TopOpeBRepBuild_PaveClassifier VCL(E1F);
111   Standard_Boolean equalpar = PVS.HasEqualParameters();
112   if (equalpar) VCL.SetFirstParameter(PVS.EqualParameters());
113   TopOpeBRepBuild_EdgeBuilder EDBU(PVS,VCL);
114 
115   // Build the new edges LEM
116   TopTools_ListOfShape LEM;
117   GEDBUMakeEdges(E1F,EDBU,LEM);
118 
119   // connect new edges as edges built TB1 on LE1 edges
120   TopTools_ListIteratorOfListOfShape it1;
121   for (it1.Initialize(LE1); it1.More(); it1.Next()) {
122     const TopoDS_Shape& E11 = it1.Value();
123     ChangeMerged(E11,TB1) = LEM;
124   }
125 
126   // connect new edges as edges built TB2 on LE2 edges
127   TopTools_ListIteratorOfListOfShape it2;
128   for (it2.Initialize(LE2); it2.More(); it2.Next()) {
129     const TopoDS_Shape& E2 = it2.Value();
130     ChangeMerged(E2,TB2) = LEM;
131   }
132 
133 } // GMergeEdges
134 
135 //=======================================================================
136 //function : GFillEdgesPVS
137 //purpose  :
138 //=======================================================================
GFillEdgesPVS(const TopTools_ListOfShape & LE1,const TopTools_ListOfShape & LE2,const TopOpeBRepBuild_GTopo & G1,TopOpeBRepBuild_PaveSet & PVS)139 void TopOpeBRepBuild_Builder::GFillEdgesPVS(const TopTools_ListOfShape& LE1,const TopTools_ListOfShape& LE2,const TopOpeBRepBuild_GTopo& G1,TopOpeBRepBuild_PaveSet& PVS)
140 {
141   if ( LE1.IsEmpty() ) return;
142   TopAbs_State TB1,TB2; G1.StatesON(TB1,TB2);
143 
144   const TopoDS_Shape& E1 = LE1.First();
145   myEdgeReference = TopoDS::Edge(E1);
146 
147   TopTools_ListIteratorOfListOfShape it1;
148   for (it1.Initialize(LE1); it1.More(); it1.Next()) {
149     const TopoDS_Shape& E11 = it1.Value();
150     Standard_Boolean ismerged = IsMerged(E11,TB1);
151 
152 #ifdef OCCT_DEBUG
153     Standard_Integer i1; Standard_Boolean tSPS1 = GtraceSPS(E11,i1);
154     if(tSPS1){
155       std::cout<<std::endl;std::cout<<"--- GFillEdgesPVS ";GdumpSHA(E11);
156       std::cout<<" ismerged : "<<ismerged<<" ";TopAbs::Print(TB1,std::cout);std::cout<<std::endl;
157     }
158 #endif
159 
160     if (!ismerged) GFillEdgePVS(E11,LE2,G1,PVS);
161   }
162 
163   TopOpeBRepBuild_GTopo G2 = G1.CopyPermuted();
164 
165   TopTools_ListIteratorOfListOfShape it2;
166   for (it2.Initialize(LE2); it2.More(); it2.Next() ) {
167     const TopoDS_Shape& E2 = it2.Value();
168     Standard_Boolean ismerged = IsMerged(E2,TB2);
169 
170 #ifdef OCCT_DEBUG
171     Standard_Integer i2; Standard_Boolean tSPS2 = GtraceSPS(E2,i2);
172     if(tSPS2){
173       std::cout<<std::endl;
174       std::cout<<"--- GFillEdgesPVS ";GdumpSHA(E2);
175       std::cout<<" ismerged : "<<ismerged<<" ";TopAbs::Print(TB2,std::cout);std::cout<<std::endl;
176     }
177 #endif
178 
179     if (!ismerged) GFillEdgePVS(E2,LE1,G2,PVS);
180   }
181 
182 } // GFillEdgesPVS
183 
184 //=======================================================================
185 //function : GFillEdgePVS
186 //purpose  :
187 //=======================================================================
GFillEdgePVS(const TopoDS_Shape & E,const TopTools_ListOfShape &,const TopOpeBRepBuild_GTopo & G,TopOpeBRepBuild_PaveSet & PVS)188 void TopOpeBRepBuild_Builder::GFillEdgePVS(const TopoDS_Shape& E,
189                                            const TopTools_ListOfShape& /*LE2*/,
190                                            const TopOpeBRepBuild_GTopo& G,
191                                            TopOpeBRepBuild_PaveSet& PVS)
192 {
193   TopAbs_ShapeEnum t1,t2;
194   G.Type(t1,t2);
195   TopAbs_State TB1,TB2;
196   G.StatesON(TB1,TB2);
197 
198   // work on a FORWARD edge EF
199   TopoDS_Shape EF = E;
200   EF.Orientation(TopAbs_FORWARD);
201   // Add the point/vertex topology build/found on edge EF in PVS
202   GFillPointTopologyPVS(EF,G,PVS);
203 
204 } // GFillEdgePVS
205 
206 // --- iterer sur EPit jusqu'a la prochaine interference dont la
207 // --- transition est definie sur un shape de type SHA Before et After
FUN_MoreSHAINT(TopOpeBRepDS_PointIterator & EPit,const TopAbs_ShapeEnum SHA)208 static Standard_Boolean FUN_MoreSHAINT(TopOpeBRepDS_PointIterator& EPit,
209                                        const TopAbs_ShapeEnum SHA)
210 {
211   Standard_Boolean more = Standard_False;
212   while (EPit.More()) {
213     const Handle(TopOpeBRepDS_Interference)& I = EPit.Value();
214     const TopOpeBRepDS_Transition& T = I->Transition();
215     TopOpeBRepDS_Kind GT,ST; Standard_Integer G,S; FDS_data(I,GT,G,ST,S);
216     TopAbs_ShapeEnum SB,SA; Standard_Integer IB,IA; FDS_Tdata(I,SB,IB,SA,IA);
217 
218     TopAbs_ShapeEnum b = T.ShapeBefore(), a = T.ShapeAfter();
219     Standard_Boolean rejet = ( (b != SHA) || (a != SHA) );
220     if ( rejet ) EPit.Next();
221     else {
222       more = Standard_True;
223       break;
224     }
225   }
226   return more;
227 }
228 
229 // Unused :
230 /*#ifdef OCCT_DEBUG
231 static Standard_Integer FUN_getTRASHA(const Standard_Integer geti,
232 			  const TopOpeBRepDS_ListOfInterference& lFOR, const Standard_Integer FOR,
233 			  const TopOpeBRepDS_ListOfInterference& lREV, const Standard_Integer REV,
234 			  const TopOpeBRepDS_ListOfInterference& lINT, const Standard_Integer INT)
235 {
236   Standard_Integer trasha = 0;
237   if (geti == 1) { // get i before
238     if (REV) trasha = lREV.First()->Transition().Before();
239     if (INT) trasha = lINT.First()->Transition().Before();
240   }
241   if (geti == 2) { // get i after
242     if (FOR) trasha = lFOR.Last()->Transition().After();
243     if (INT) trasha = lINT.Last()->Transition().After();
244   }
245   return trasha;
246 }
247 #endif*/
248 
249 #ifdef OCCT_DEBUG
debfillp(const Standard_Integer i)250 void debfillp(const Standard_Integer i) {std::cout <<"+ + debfillp "<<i<<std::endl;}
debfillpon(const Standard_Integer i)251 void debfillpon(const Standard_Integer i) {std::cout <<"+ + debfillpon "<<i<<std::endl;}
debfillpin(const Standard_Integer i)252 void debfillpin(const Standard_Integer i) {std::cout <<"+ + debfillpin "<<i<<std::endl;}
debfillpou(const Standard_Integer i)253 void debfillpou(const Standard_Integer i) {std::cout <<"+ + debfillpou "<<i<<std::endl;}
debfillp2(const Standard_Integer i)254 void debfillp2(const Standard_Integer i) {std::cout <<"+ + debfillp2 "<<i<<std::endl;}
255 #endif
256 
257 //Standard_IMPORT extern Standard_Boolean GLOBAL_faces2d;
258 extern Standard_Boolean GLOBAL_faces2d;
259 
260 Standard_EXPORT Standard_Boolean FDS_SIisGIofIofSBAofTofI(const TopOpeBRepDS_DataStructure& BDS,const Standard_Integer SI,const Handle(TopOpeBRepDS_Interference)& I);
261 //Standard_IMPORT extern Standard_Boolean GLOBAL_IEtoMERGE; // xpu240498
262 Standard_IMPORT Standard_Boolean GLOBAL_IEtoMERGE; // xpu240498
263 //Standard_IMPORT extern Standard_Integer GLOBAL_issp;
264 extern Standard_Integer GLOBAL_issp;
265 //Standard_IMPORT extern Standard_Integer GLOBAL_hassd;
266 Standard_IMPORT Standard_Integer GLOBAL_hassd;
267 
FUN_isonbound(const Handle (TopOpeBRepDS_HDataStructure)& HDS,const Handle (TopOpeBRepDS_Interference)& I)268 static Standard_Boolean FUN_isonbound(const Handle(TopOpeBRepDS_HDataStructure)& HDS,
269                                       const Handle(TopOpeBRepDS_Interference)& I)
270 {
271   Standard_Integer G = I->Geometry();
272   TopOpeBRepDS_Kind KG =  I->GeometryType();
273   Standard_Boolean Gb1 = (KG == TopOpeBRepDS_VERTEX);
274   if (Gb1) {
275     Handle(TopOpeBRepDS_EdgeVertexInterference) EVI= Handle(TopOpeBRepDS_EdgeVertexInterference)::DownCast(I);
276     Standard_Boolean vhassd = HDS->HasSameDomain(HDS->DS().Shape(G));
277     Gb1 = (EVI.IsNull()) ? Standard_False : EVI->GBound();
278     Gb1 = Gb1 && !vhassd;
279   }
280   return Gb1;
281 }
282 
283 #define TheIN (1)
284 #define TheON (2)
285 #define TheOUT (3)
286 #define HASSD2d (2)
287 #define HASSD3d (3)
288 #define FIRST (1)
289 #define LAST  (2)
290 
291 //=======================================================================
292 //function : GFillPointTopologyPVS
293 //purpose  :
294 //=======================================================================
GFillPointTopologyPVS(const TopoDS_Shape & E,const TopOpeBRepBuild_GTopo & G,TopOpeBRepBuild_PaveSet & PVS)295 void TopOpeBRepBuild_Builder::GFillPointTopologyPVS(const TopoDS_Shape& E,
296                                                     const TopOpeBRepBuild_GTopo& G,
297                                                     TopOpeBRepBuild_PaveSet& PVS)
298 {
299 #ifdef OCCT_DEBUG
300 //  TopAbs_State TB1,TB2;
301 //  G.StatesON(TB1,TB2);
302 //  TopOpeBRepDS_Config GConf1 = G.Config1();
303 //  TopOpeBRepDS_Config GConf2 = G.Config2();
304 #endif
305   TopAbs_ShapeEnum t1,t2,ShapeInterf;
306   G.Type(t1,t2);
307   ShapeInterf = t1;
308   const TopOpeBRepDS_DataStructure& BDS = myDataStructure->DS();
309   const Standard_Integer iEDS = BDS.Shape(E);
310 #ifdef OCCT_DEBUG
311 //  Standard_Integer rkE = BDS.AncestorRank(E);
312 #endif
313   Standard_Boolean isSE = BDS.IsSectionEdge(TopoDS::Edge(E));
314   Standard_Boolean dgE = BRep_Tool::Degenerated(TopoDS::Edge(E));
315   Standard_Boolean isEd;
316 
317   isEd = BRep_Tool::Degenerated(TopoDS::Edge(E));
318 #ifdef OCCT_DEBUG
319 //  Standard_Boolean hsd = myDataStructure->HasSameDomain(E); //xpu170498
320 #endif
321   Standard_Boolean isfafa = BDS.Isfafa(); //xpu120598
322 
323 #ifdef OCCT_DEBUG
324   Standard_Boolean tSPSE=GtraceSPS(iEDS);
325   TCollection_AsciiString striE=TopOpeBRepDS::SPrint(TopAbs_EDGE,iEDS);
326   const TopoDS_Shape& EPVS=PVS.Edge();Standard_Integer iEPVS;Standard_Boolean tSPSEPVS=GtraceSPS(EPVS,iEPVS);
327   Standard_Boolean tSPS = tSPSE || tSPSEPVS;
328   if(tSPS){
329     std::cout<<std::endl;
330     std::cout<<"--- GFillPointTopologyPVS : ShapeInterf ";TopAbs::Print(ShapeInterf,std::cout);
331     std::cout<<",efil ";GdumpSHA(E);std::cout<<",eref ";GdumpSHA(myEdgeReference);
332     std::cout<<",ffil ";GdumpSHA(myFaceToFill);std::cout<<",fref ";GdumpSHA(myFaceReference);
333     std::cout<<std::endl;
334     debfillp(iEDS);
335   }
336 #endif
337 
338   Standard_Boolean isspin=(GLOBAL_issp==TheIN), isspou=(GLOBAL_issp==TheOUT), isspon=(GLOBAL_issp==TheON);
339   if (isSE && (GLOBAL_issp == 0)) return; // splits done in process ProcessSectionEdges
340 
341 #ifdef OCCT_DEBUG
342 //  Standard_Integer iefil = BDS.Shape(E);
343 //  Standard_Integer iffil = BDS.Shape(myFaceToFill);
344 //  Standard_Integer ieref = BDS.Shape(myEdgeReference);
345 //  Standard_Integer ifref = BDS.Shape(myFaceReference);
346   if(tSPS) {
347     if (isspon) debfillpon(iEDS);
348     if (isspin) debfillpin(iEDS);
349     if (isspou) debfillpou(iEDS);
350   }
351 #endif
352 
353   // 0.
354   //---
355   const TopOpeBRepDS_ListOfInterference& lIE = BDS.ShapeInterferences(E);
356   Standard_Boolean scanall = (isspin || isspou || isspon); // xpu161198: BUC60382 //xpu011098: CTS21180(e8on); cto900I7(e12on)
357 
358   // loiSHAINT = interferences avec les 2 proprietes
359   // - fournies par un PointIterator
360   // - dont la transition est definie / shape = ShapeInterf
361   TopOpeBRepDS_ListOfInterference loiSHAINT;
362   if (scanall) FDS_assign(lIE,loiSHAINT);
363   else {
364     TopOpeBRepDS_PointIterator EPit(lIE);
365     EPit.Init(BDS.ShapeInterferences(E));
366     Standard_Boolean addi = FUN_MoreSHAINT(EPit,ShapeInterf);
367     while (addi) {
368       const Handle(TopOpeBRepDS_Interference)& II = EPit.Value();
369       loiSHAINT.Append(II);
370       EPit.Next();
371       addi = FUN_MoreSHAINT(EPit,ShapeInterf);
372     }
373   }
374 
375   TopOpeBRepDS_TKI tki;
376   tki.FillOnGeometry(loiSHAINT);  // groupage par geometrie d'interference
377 
378   // - kp1 -
379   // BUC60093 :  only 2 G : 1 point && 1 vertex
380   // deleting interfs on G = vertex sdm && closingE
381   TopoDS_Vertex vclo; Standard_Boolean closedE = TopOpeBRepTool_TOOL::ClosedE(TopoDS::Edge(E),vclo);
382   Standard_Integer kp1 = 0;
383   if (closedE) {
384     tki.Init();
385     Standard_Integer nG = 0;
386     while (tki.More()) {
387       nG++;
388       TopOpeBRepDS_Kind Kcur;Standard_Integer Gcur;
389       tki.Value(Kcur,Gcur);
390       if (Kcur == TopOpeBRepDS_POINT) {tki.Next();continue;}
391       const TopoDS_Shape& v = BDS.Shape(Gcur);
392       TopoDS_Shape oov;
393       FUN_ds_getoov(v,myDataStructure,oov);
394       Standard_Boolean samev = v.IsSame(vclo), sameoov = oov.IsSame(vclo);
395       if (samev || sameoov) {kp1 = Gcur;}
396       tki.Next();
397     }
398     if (nG == 1) kp1 = 0; // we have only one interf on vGclo -> keep the interf
399   } //kp1
400 
401   // - kp6 - nyiReducing
402   // xpu250998    : cto900M5 (e5,p1)
403   // prequesitory : if we have I3d on Gb0 FORWARD or REVERSED, we do NOT need
404   //                interference on Gb1 to determinate split IN/OUT of edge.
405   Standard_Boolean kp6 = (!isSE);
406   if (kp6) {
407     kp6 = Standard_False;
408     TopOpeBRepDS_ListIteratorOfListOfInterference it(loiSHAINT);
409     for (; it.More(); it.Next()){
410       const Handle(TopOpeBRepDS_Interference)& I = it.Value();
411       TopOpeBRepDS_Kind ST = I->SupportType();
412       if (ST != TopOpeBRepDS_FACE) continue;
413       TopAbs_Orientation O = I->Transition().Orientation(TopAbs_IN);
414       Standard_Boolean FORREV = (O == TopAbs_FORWARD) || (O == TopAbs_REVERSED);
415       if (!FORREV) continue;
416       Standard_Boolean Gb1 = ::FUN_isonbound(myDataStructure,I);
417       if (!Gb1) {kp6 = Standard_True; break;}
418     } // it(l3dFOR+l3dREV)
419   }
420 
421   // 1.
422   //---
423   tki.Init();
424   while (tki.More()) {
425 
426     // lieu courant : Kcur,Gcur; Interferences : LICur
427     TopOpeBRepDS_Kind Kcur;
428     Standard_Integer Gcur;
429     const TopOpeBRepDS_ListOfInterference& LICur = tki.Value(Kcur,Gcur);
430     Standard_Boolean point  = (Kcur == TopOpeBRepDS_POINT); //xpu170498
431     Standard_Boolean vertex = (Kcur == TopOpeBRepDS_VERTEX);//xpu170498
432     TopoDS_Shape vGsd;
433     if (vertex) FUN_ds_getoov(BDS.Shape(Gcur), myDataStructure, vGsd); //xpu221098
434 
435     // recall : I3d=(I3dF,I3dFE) : I3dF=(T(F),G,F), I3dFE=(T(F),G,E)
436     //          I2d=I2dFE
437     //          I1d=(T(E),V,E)
438 
439     if ((Kcur == TopOpeBRepDS_VERTEX) && (kp1 == Gcur)) {tki.Next();continue;}
440     const Handle(TopOpeBRepDS_Interference)& I = LICur.First();
441     Standard_Real parSE = FDS_Parameter(I);
442     TopOpeBRepDS_ListOfInterference LICurcopy;
443     TopOpeBRepDS_ListOfInterference l3dFcur; FDS_assign(LICur,LICurcopy); Standard_Integer n3d=FUN_selectSKinterference(LICurcopy,TopOpeBRepDS_FACE,l3dFcur);
444     TopOpeBRepDS_ListOfInterference l2dFEcur; FDS_assign(LICur,LICurcopy); Standard_Integer n2d=FUN_ds_hasI2d(iEDS,LICurcopy,l2dFEcur);
445     TopOpeBRepDS_ListOfInterference l1dEcur; FDS_assign(LICur,LICurcopy);
446     FUN_selectTRASHAinterference(LICurcopy,TopAbs_EDGE,l1dEcur);
447 
448     TopAbs_State stb; Standard_Integer isb; Standard_Integer bdim;
449     TopAbs_State sta; Standard_Integer isa; Standard_Integer adim;
450     FUN_ds_GetTr(BDS,iEDS,Gcur,LICur,
451                  stb,isb,bdim,
452                  sta,isa,adim);
453     if (isSE) {
454       // before
455       Standard_Boolean bIN1d = (stb==TopAbs_IN)&&(bdim==1);
456       Standard_Boolean bIN2d = (stb==TopAbs_IN)&&(bdim==2);
457       Standard_Boolean bIN3d = (stb==TopAbs_IN)&&(bdim==3);
458 
459       Standard_Boolean bOUT2d = (stb==TopAbs_OUT)&&(bdim==2);
460       Standard_Boolean bOUT3d = (stb==TopAbs_OUT)&&(bdim==3);
461       // after
462       Standard_Boolean aIN1d = (sta==TopAbs_IN)&&(adim==1);
463       Standard_Boolean aIN2d = (sta==TopAbs_IN)&&(adim==2);
464       Standard_Boolean aIN3d = (sta==TopAbs_IN)&&(adim==3);
465 
466       Standard_Boolean aOUT2d = (sta==TopAbs_OUT)&&(adim==2);
467       Standard_Boolean aOUT3d = (sta==TopAbs_OUT)&&(adim==3);
468 
469       TopOpeBRepDS_Transition newT; Standard_Boolean INb=Standard_False,INa=Standard_False;
470       if (isfafa) {
471 	if       (isspon) {
472 	  if ((stb == TopAbs_OUT)&&(sta == TopAbs_OUT)) {tki.Next(); continue;}
473 	  INb = bIN1d;
474 	  INa = aIN1d;
475 	  newT.Index(isb); newT.ShapeBefore(TopAbs_EDGE); newT.ShapeAfter(TopAbs_EDGE);
476 	} else if (isspin) {
477 	  INb = bIN2d;
478 	  INa = aIN2d;
479 	  newT.ShapeBefore(TopAbs_FACE); newT.ShapeAfter(TopAbs_FACE);
480 	} else if (isspou) {
481 	  INb = !bOUT2d;
482 	  INa = !aOUT2d;
483 	  newT.ShapeBefore(TopAbs_FACE); newT.ShapeAfter(TopAbs_FACE);
484 	}
485       }
486       else {
487 	if       (isspon) {
488 	  if ((stb == TopAbs_OUT)&&(sta == TopAbs_OUT)) {tki.Next(); continue;}
489 	  INb = bIN1d || bIN2d;
490 	  INa = aIN1d || aIN2d;
491 	  newT.Index(isb); newT.ShapeBefore(TopAbs_EDGE); newT.ShapeAfter(TopAbs_EDGE);
492 	} else if (isspin) {
493 	  if ((stb == TopAbs_OUT)&&(sta == TopAbs_OUT)) {tki.Next(); continue;}
494 	  INb = bIN3d;
495 	  INa = aIN3d;
496 	  if (INb) newT.Index(isb);
497 	  else     newT.Index(isa);
498 	  newT.ShapeBefore(TopAbs_FACE); newT.ShapeAfter(TopAbs_FACE);
499 	} else if (isspou) {
500 	  if ((stb == TopAbs_IN)&&(sta == TopAbs_IN)) {tki.Next(); continue;}
501 	  INb = !bOUT3d;
502 	  INa = !aOUT3d;
503 	  if (bOUT3d) newT.Index(isb);
504 	  else        newT.Index(isa);
505 	  newT.ShapeBefore(TopAbs_FACE); newT.ShapeAfter(TopAbs_FACE);
506 	}
507       }
508       TopAbs_State sb = INb ? TopAbs_IN : TopAbs_OUT;
509       TopAbs_State sa = INa ? TopAbs_IN : TopAbs_OUT;
510       newT.StateBefore(sb);newT.StateAfter(sa);
511       Standard_Integer S=0; // dummy
512       Standard_Boolean B = (Kcur == TopOpeBRepDS_POINT) ? Standard_False : (Handle(TopOpeBRepDS_EdgeVertexInterference)::DownCast(I)->GBound());
513       Handle(TopOpeBRepDS_Interference) newI = MakeEPVInterference(newT,S,Gcur,parSE,Kcur,B);
514 
515       TopOpeBRepDS_ListOfInterference li; li.Append(newI); TopOpeBRepDS_PointIterator itCur(li);
516       GFillPointTopologyPVS(E,itCur,G,PVS);
517       {tki.Next(); continue;}
518     } // isSE
519 
520     // - kp3 -
521     // xpu200598 interference 2d at GPOINT
522     Standard_Boolean kp3 = (n2d > 0) && point;
523     if (kp3) l2dFEcur.First()->Transition().Orientation(TopAbs_IN);
524 
525 
526     TopOpeBRepDS_PointIterator itCur(LICur); Standard_Integer iICur=0;
527     while ( itCur.More() ) {
528       iICur++;
529       const Handle(TopOpeBRepDS_Interference)& I1=itCur.Value();
530       const TopOpeBRepDS_Transition& T1=I1->Transition();
531       T1.Orientation(TopAbs_IN);
532       TopAbs_ShapeEnum SB1,SA1;Standard_Integer IB1,IA1;TopOpeBRepDS_Kind GT1,ST1;Standard_Integer G1,S1;
533       FDS_Idata(I1,SB1,IB1,SA1,IA1,GT1,G1,ST1,S1);
534 
535       Standard_Boolean keepinterf1 = Standard_False;
536       if      (isEd) {
537 	keepinterf1 = Standard_True;
538       }
539       else {
540 	if (GLOBAL_faces2d) {  // split 2d
541 	  Standard_Boolean has2d3d = (n2d >0 && n3d >0); // JYL300998
542 	  // JYL300998 : traitement correct de cto 100 K1 e27 (chanceux auparavant, schema d'I faux)
543 	  // e27 n'est PAS arete de section mais doit etre traitee comme telle.
544 	  // e27 possede des I de nature 2d et 3d en V8
545 	  // on privilegie l'info 3d
546 	  if (has2d3d && !isSE) {
547 #ifdef OCCT_DEBUG
548 	    const Handle(TopOpeBRepDS_Interference)& i2d =
549 #endif
550                                l2dFEcur.First();
551 	    const Handle(TopOpeBRepDS_Interference)& i3d = l3dFcur.First();
552 	    Standard_Boolean id3d = (I1 == i3d);
553 	    keepinterf1 = id3d;
554 #ifdef OCCT_DEBUG
555 	    Standard_Boolean id2d = (I1 == i2d);
556 	    if (tSPS) {
557 	      std::cout<<"DEB : GFillPointTopologyPVS E"<<iEDS<<" has2d3d"<<std::endl;
558 	      if (id3d) std::cout<<"--> Interference 3d ";
559 	      if (id2d) std::cout<<"--> Interference 2d ";
560 	      if (keepinterf1) std::cout<<" traitee"<<std::endl;
561 	      else             std::cout<<" non traitee"<<std::endl;
562 	      std::cout<<std::endl;
563 	    }
564 #endif
565 	  }
566 	  else {
567 	    keepinterf1 = Standard_True; // PRO13075 tspIN(e17)
568 	  }
569 	} // split 2d
570 	else { // split 3d
571 	  keepinterf1 = (ST1 == TopOpeBRepDS_FACE); // (iICur == 1);
572 	}
573       }
574       if ( keepinterf1 ) {
575 	if (kp6) {
576 	  Standard_Boolean Gb1 = ::FUN_isonbound(myDataStructure,I1);
577 	  if (!Gb1) GFillPointTopologyPVS(E,itCur,G,PVS);
578 	}
579 	else       {
580 	  GFillPointTopologyPVS(E,itCur,G,PVS);
581 	}
582 	if (!dgE) break; // xpu140498
583       } // keepinterf1
584       itCur.Next();
585     } // itCur.More
586 
587     tki.Next();
588   } // tki.More()
589 }
590 
591 //=======================================================================
592 //function : GFillPointTopologyPVS
593 //purpose  :
594 //=======================================================================
GFillPointTopologyPVS(const TopoDS_Shape & E,const TopOpeBRepDS_PointIterator & EPit,const TopOpeBRepBuild_GTopo & G1,TopOpeBRepBuild_PaveSet & PVS) const595 void TopOpeBRepBuild_Builder::GFillPointTopologyPVS(const TopoDS_Shape& E,
596                                                     const TopOpeBRepDS_PointIterator& EPit,
597                                                     const TopOpeBRepBuild_GTopo& G1,
598                                                     TopOpeBRepBuild_PaveSet& PVS) const
599 {
600   const TopoDS_Shape& EPVS = PVS.Edge();
601 
602   //modified by NIZHNY-MZV  Mon Feb 21 14:47:34 2000
603   const Handle(TopOpeBRepDS_Interference)& I1=EPit.Value();
604   TopOpeBRepDS_Kind ST1 = I1->SupportType();
605 
606 #ifdef OCCT_DEBUG
607   Standard_Integer iE; Standard_Boolean tSPSE = GtraceSPS(E,iE);
608   Standard_Integer iEPVS; Standard_Boolean tSPSEPVS = GtraceSPS(EPVS,iEPVS);
609   Standard_Boolean tSPS = tSPSE || tSPSEPVS;
610   if ( tSPS ) debfillp(iE);
611 #endif
612 
613   TopAbs_State TB1,TB2;
614   G1.StatesON(TB1,TB2);
615   TopOpeBRepDS_Config Conf = G1.Config1();
616   TopAbs_State TB = TB1;
617 
618   // iG = index of new point or existing vertex
619   Standard_Integer iG = EPit.Current();
620   Standard_Boolean ispoint = EPit.IsPoint();
621   TopoDS_Vertex VIG; // NYI pointer
622   if (ispoint) VIG = TopoDS::Vertex(NewVertex(iG));
623   else VIG = TopoDS::Vertex(myDataStructure->Shape(iG));
624 
625   if (VIG.IsNull()) return; //PMN 17/02/99 Nothing to add.
626 
627   Standard_Boolean hasVSD = Standard_False;
628   Standard_Integer iVRE = 0; TopoDS_Shape VRE; // NYI pointer
629   if (!ispoint) {
630     hasVSD = myDataStructure->HasSameDomain(VIG);
631     if (hasVSD) { // on prend VRE = vertex reference de VIG
632       iVRE = myDataStructure->SameDomainReference(VIG);
633       VRE = TopoDS::Vertex(myDataStructure->Shape(iVRE));
634     }
635   }
636 
637   TopoDS_Vertex VPV; // NYI pointer on VRE or VIG
638   if (hasVSD) VPV = TopoDS::Vertex(VRE);
639   else        VPV = VIG;
640 //  else        VPV = TopoDS::Vertex(VIG);
641 
642   Standard_Real      par = EPit.Parameter();
643   TopAbs_Orientation ori = EPit.Orientation(TB);
644 
645 #ifdef OCCT_DEBUG
646   if ( tSPS ) debfillp(iE);
647 #endif
648 
649   Standard_Boolean samegeom = ::TopOpeBRepBuild_FUN_aresamegeom(E,EPVS);
650   if (Conf == TopOpeBRepDS_DIFFORIENTED) ori = TopAbs::Complement(ori);
651 #ifdef OCCT_DEBUG
652   if (!TopOpeBRepBuild_GetcontextNOSG()) {
653 #endif
654     if (!samegeom) ori = TopAbs::Complement(ori);
655 #ifdef OCCT_DEBUG
656   }
657 #endif
658 
659 
660   Standard_Boolean lesmemes = E.IsEqual(myEdgeReference);
661   if ( !lesmemes ) {
662     Standard_Real parref = par;
663     const TopoDS_Edge& EE = TopoDS::Edge(E);
664     GParamOnReference(VPV,EE,parref);
665 #ifdef OCCT_DEBUG
666     if(tSPS){
667       std::cout<<"par "<<par<<" / ";GdumpSHA(E);std::cout<<" --> parref "<<parref<<" / ";GdumpSHA(EPVS);
668       std::cout<<std::endl;
669     }
670 #endif
671     par = parref;
672   }
673 
674   Standard_Boolean kpbound = Standard_False;
675   {
676     TopoDS_Vertex vclo; Standard_Boolean Eclosed = TopOpeBRepTool_TOOL::ClosedE(myEdgeReference,vclo);
677 #ifdef OCCT_DEBUG
678 //    Standard_Integer ivclo = myDataStructure->Shape(vclo);
679 #endif
680     TopAbs_Orientation oriI = EPit.Orientation(TopAbs_IN);
681 //    kpbound = lesmemes && Eclosed && hasVSD && (ori == TopAbs_INTERNAL) && (TB == TopAbs_OUT); -xpu140898
682     // xpu110398 cto 009 L2 : e6ou en v11
683     // xpu140898 USA60111 : e9ou (!=0) + e7ou(=0)
684     Standard_Boolean INTEXT =       (oriI == TopAbs_INTERNAL) && (TB == TopAbs_IN);
685     INTEXT = INTEXT || ((oriI == TopAbs_EXTERNAL) && (TB == TopAbs_OUT));
686     kpbound = lesmemes && Eclosed && INTEXT;
687     if ( kpbound ) {
688       kpbound = vclo.IsSame(VIG);
689       if (!kpbound) {
690 	TopoDS_Shape VSD; Standard_Boolean ok = FUN_ds_getoov(VIG,myDataStructure->DS(),VSD);
691 	if (ok) kpbound = vclo.IsSame(VSD);
692       }
693     }
694   }
695 
696   if (!kpbound) {
697     VPV.Orientation(ori);
698     Standard_Boolean vofe = Standard_False;
699     Handle(TopOpeBRepBuild_Pave) PV = new TopOpeBRepBuild_Pave(VPV,par,vofe);
700     if (hasVSD) {
701       PV->HasSameDomain(Standard_True);
702       const TopoDS_Shape& VSD = myDataStructure->SameDomain(VPV).Value();
703       Standard_Integer iVSD = myDataStructure->Shape(VSD);
704       if (iVSD == iVRE) PV->SameDomain(VIG);
705       else              PV->SameDomain(VSD);
706     }
707     //modified by NIZHNY-MZV  Mon Feb 21 14:48:37 2000
708     PV -> InterferenceType() = ST1;
709     PVS.Append(PV);
710 
711 
712 #ifdef OCCT_DEBUG
713     gp_Pnt P = BRep_Tool::Pnt(VPV);
714     if(tSPS){std::cout<<"+";if(ispoint)std::cout<<" PDS ";else std::cout<<" VDS ";}
715     if(tSPS){std::cout<<iG<<" : ";GdumpORIPARPNT(ori,par,P);std::cout<<std::endl;}
716     if(tSPS) {
717 //      Standard_Boolean trc = Standard_False;
718 #ifdef DRAW
719       if (trc) {
720 	FUN_draw2d(par,TopoDS::Edge(E),myEdgeReference,myFaceReference);
721 	FUN_draw(VPV); FUN_draw(E); FUN_draw(myFaceReference);
722       }
723 #endif
724     }
725 #endif
726   }
727   else {
728     Standard_Real parf,parl; FUN_tool_bounds(myEdgeReference,parf,parl);
729     TopAbs_Orientation ovpv;
730     ovpv = TopAbs_FORWARD;
731     VPV.Orientation(ovpv);
732     Standard_Boolean vfofe = Standard_False;
733     Handle(TopOpeBRepBuild_Pave) PVF = new TopOpeBRepBuild_Pave(VPV,parf,vfofe);
734     if (hasVSD) {
735       PVF->HasSameDomain(Standard_True);
736       const TopoDS_Shape& VSD = myDataStructure->SameDomain(VPV).Value();
737       Standard_Integer iVSD = myDataStructure->Shape(VSD);
738       if (iVSD == iVRE) PVF->SameDomain(VIG);
739       else              PVF->SameDomain(VSD);
740     }
741     //modified by NIZHNY-MZV  Mon Feb 21 14:48:37 2000
742     PVF -> InterferenceType() = ST1;
743     PVS.Append(PVF);
744 
745 #ifdef OCCT_DEBUG
746     gp_Pnt PF = BRep_Tool::Pnt(VPV);
747     if(tSPS){std::cout<<"+";if(ispoint)std::cout<<" PDS ";else std::cout<<" VDS ";}
748     if(tSPS){std::cout<<iG<<" : ";GdumpORIPARPNT(ovpv,parf,PF);std::cout<<std::endl;}
749 #endif
750 
751     ovpv = TopAbs_REVERSED;
752     VPV.Orientation(ovpv);
753     Standard_Boolean vrofe = Standard_False;
754     Handle(TopOpeBRepBuild_Pave) PVR = new TopOpeBRepBuild_Pave(VPV,parl,vrofe);
755     if (hasVSD) {
756       PVR->HasSameDomain(Standard_True);
757       const TopoDS_Shape& VSD = myDataStructure->SameDomain(VPV).Value();
758       Standard_Integer iVSD = myDataStructure->Shape(VSD);
759       if (iVSD == iVRE) PVR->SameDomain(VIG);
760       else              PVR->SameDomain(VSD);
761     }
762     //modified by NIZHNY-MZV  Mon Feb 21 14:48:37 2000
763     PVR -> InterferenceType() = ST1;
764     PVS.Append(PVR);
765 #ifdef OCCT_DEBUG
766     gp_Pnt PR = BRep_Tool::Pnt(VPV);
767     if(tSPS){std::cout<<"+";if(ispoint)std::cout<<" PDS ";else std::cout<<" VDS ";}
768     if(tSPS){std::cout<<iG<<" : ";GdumpORIPARPNT(ovpv,parl,PR);std::cout<<std::endl;}
769 #endif
770 
771     PVS.RemovePV(Standard_False); // jyl + 980217
772   }
773 
774 }
775 
776 
777 //=======================================================================
778 //function : GParamOnReference
779 //purpose  : calcul du parametre de V sur myEdgeReference de myFaceReference
780 //           V est sur la surface de myFaceReference,
781 //           V est un vertex de E
782 //           E est une arete samedomain de myEdgeReference
783 // retourne true si ok
784 //=======================================================================
GParamOnReference(const TopoDS_Vertex & V,const TopoDS_Edge &,Standard_Real & P) const785 Standard_Boolean TopOpeBRepBuild_Builder::GParamOnReference(const TopoDS_Vertex& V,
786                                                             const TopoDS_Edge& /*E*/,
787                                                             Standard_Real& P) const
788 {
789   Handle(Geom_Surface) su = BRep_Tool::Surface(myFaceReference);
790   Handle(Geom_Plane) suplan = Handle(Geom_Plane)::DownCast(su);
791   if ( suplan.IsNull() ) {
792 #ifdef OCCT_DEBUG
793     std::cout<<"NYI : GParamOnReference : not planar"<<std::endl;
794 #endif
795     return Standard_False;
796   }
797 
798   gp_Pln pln = suplan->Pln(); gp_Pnt p3 = BRep_Tool::Pnt(V);
799   Standard_Real u,v; ElSLib::Parameters(pln,p3,u,v); gp_Pnt2d p2(u,v);
800   Standard_Real f,l,tolpc; Handle(Geom2d_Curve) C2D;
801   C2D = FC2D_CurveOnSurface(myEdgeReference,myFaceReference,f,l,tolpc);
802   if (C2D.IsNull()) throw Standard_ProgramError("TopOpeBRepBuild_Builder::GParamOnReference");
803 
804 //  Standard_Real U;
805   Geom2dAdaptor_Curve AC(C2D);
806   switch ( AC.GetType() ) {
807   case GeomAbs_Line:
808     P = ElCLib::Parameter(AC.Line(),p2); break;
809   case GeomAbs_Circle:
810     P = ElCLib::Parameter(AC.Circle(),p2); break;
811   case GeomAbs_Ellipse:
812     P = ElCLib::Parameter(AC.Ellipse(),p2); break;
813   case GeomAbs_Hyperbola:
814     P = ElCLib::Parameter(AC.Hyperbola(),p2); break;
815   case GeomAbs_Parabola:
816     P = ElCLib::Parameter(AC.Parabola(),p2); break;
817     default :
818 #ifdef OCCT_DEBUG
819       std::cout<<"NYI : GParamOnReference : OtherCurve on planar surface"<<std::endl;
820 #endif
821     return Standard_False;
822   }
823 
824   return Standard_True;
825 }
826