Integration of OCCT 6.5.0 from SVN
[occt.git] / src / TopOpeBRep / TopOpeBRep_vprclo.cxx
1 // File:        TopOpeBRep_FacesFiller_VPonR.cxx
2 // Created:     Fri Aug  4 10:57:30 1995
3 // Author:      Jean Yves LEBEY
4 //              <jyl@meteox>
5
6 #include <TopOpeBRep_FacesFiller.ixx>
7
8 #include <TopOpeBRepTool_ShapeTool.hxx>
9 #include <TopOpeBRepTool_EXPORT.hxx>
10 #include <TopOpeBRepTool_makeTransition.hxx>
11
12 #include <TopOpeBRepDS_PointIterator.hxx>
13 #include <TopOpeBRepDS_define.hxx>
14 #include <TopOpeBRepDS_repvg.hxx> // LOIinfsup
15 #include <TopOpeBRepDS_EXPORT.hxx>
16
17 #include <TopOpeBRep_define.hxx>
18
19 #include <Precision.hxx>
20 #include <TopoDS.hxx>
21 #include <TopExp.hxx>
22 #include <BRep_Tool.hxx>
23 #include <BRepAdaptor_Curve.hxx>
24 #include <gp_Vec.hxx>
25
26
27 #define M_ON(st)       (st == TopAbs_ON) 
28 #define M_REVERSED(st) (st == TopAbs_REVERSED) 
29
30 #ifdef DEB
31 Standard_EXPORT Standard_Boolean TopOpeBRepDS_GettraceDSF();
32 Standard_EXPORT Standard_Boolean TopOpeBRepDS_GettraceSPSX(const Standard_Integer i1);
33 Standard_EXPORT void debarc(const Standard_Integer i);
34 Standard_EXPORT void debooarc(const Standard_Integer i);
35 #endif
36
37 Standard_EXPORT Handle(TopOpeBRepDS_Interference) MakeEPVInterference
38 (const TopOpeBRepDS_Transition& T, // transition
39  const Standard_Integer S, // curve/edge index
40  const Standard_Integer G, // point/vertex index
41  const Standard_Real P, // parameter of G on S
42  const TopOpeBRepDS_Kind GK,
43  const Standard_Boolean B); // G is a vertex (or not) of the interference master
44 Standard_EXPORT Handle(TopOpeBRepDS_Interference) MakeEPVInterference
45 (const TopOpeBRepDS_Transition& T, // transition
46  const Standard_Integer S, // curve/edge index
47  const Standard_Integer G, // point/vertex index
48  const Standard_Real P, // parameter of G on S
49  const TopOpeBRepDS_Kind GK, // POINT/VERTEX
50  const TopOpeBRepDS_Kind SK,
51  const Standard_Boolean B); // G is a vertex (or not) of the interference master
52
53
54 static Standard_Boolean FUN_INlos(const TopoDS_Shape& S, const TopTools_ListOfShape& loS)
55 {
56   TopTools_ListIteratorOfListOfShape it(loS);
57   for (; it.More(); it.Next())
58     if (it.Value().IsSame(S)) return Standard_True;
59   return Standard_False;
60 }
61
62 //=======================================================================
63 //function : GetEdgeTrans
64 //purpose  : Computes E<Sind> transition on <F> at point <VP>
65 //           Computes FORWARD or REVERSED transitions,
66 //           returns transition UNKNOWN elsewhere.
67 //=======================================================================
68 TopOpeBRepDS_Transition TopOpeBRep_FacesFiller::GetEdgeTrans(const TopOpeBRep_VPointInter& VP,const TopOpeBRepDS_Kind PVKind,
69                          const Standard_Integer PVIndex,const Standard_Integer ShapeIndex,const TopoDS_Face& F)
70 {
71   // VP is on couture <Ec> of rank <sind>
72   //       on face <F> of rank <oosind>. 
73   Standard_Integer OOShapeIndex = (ShapeIndex == 1) ? 2 : 1;
74   Standard_Integer vpsind = VP.ShapeIndex();
75   Standard_Boolean on2edges = (vpsind == 3);
76   Standard_Boolean isvalid = on2edges || (vpsind == ShapeIndex);
77   if (!isvalid) Standard_Failure::Raise("TopOpeBRep_FacesFiller::GetEdgeTrans");
78   
79   const TopoDS_Edge& edge = TopoDS::Edge(VP.Edge(ShapeIndex));
80   Standard_Real paredge = VP.EdgeParameter(ShapeIndex);
81
82   TopoDS_Edge OOedge;
83 #ifdef DEB
84   Standard_Real OOparedge;
85 #else
86   Standard_Real OOparedge=0;
87 #endif
88   Standard_Boolean hasONedge = (VP.State(OOShapeIndex) == TopAbs_ON);
89   Standard_Boolean hasOOedge = (on2edges) ? Standard_True : hasONedge;
90   if ( hasOOedge ) {
91     if (on2edges) OOparedge = VP.EdgeParameter(OOShapeIndex);
92     else          OOparedge = VP.EdgeONParameter(OOShapeIndex);
93     TopoDS_Shape OOe;
94     if (on2edges) OOe = VP.Edge(OOShapeIndex);
95     else          OOe = VP.EdgeON(OOShapeIndex);
96     OOedge = TopoDS::Edge(OOe);
97   }  
98   gp_Pnt2d OOuv = VP.SurfaceParameters(OOShapeIndex);
99   
100   Standard_Real par1,par2; 
101   Standard_Integer SIedgeIndex = (myHDS->HasShape(edge)) ? myHDS->Shape(edge) : 0;
102 //  if (SIedgeIndex != 0) FDS_getupperlower(myHDS,SIedgeIndex,paredge,par1,par2);
103   if (SIedgeIndex != 0) {
104     Standard_Boolean isonboundper;
105     FDS_LOIinfsup(myHDS->DS(),edge,paredge,PVKind,PVIndex,
106                     myHDS->DS().ShapeInterferences(edge),par1,par2,isonboundper);
107   }
108   else               
109     FUN_tool_bounds(edge,par1,par2);
110
111   TopOpeBRepDS_Transition T;
112   // xpu : 16-01-98 
113   //       <Tr> relative to 3d <OOface> matter,
114   //       we take into account <Tr> / 2d <OOface> only if <edge> is normal to <OOface>  
115   Standard_Real tola = Precision::Angular()*1.e+2; //dealing with tolerances
116   Standard_Boolean EtgF = FUN_tool_EtgF(paredge,edge,OOuv,F,tola);  
117   Standard_Boolean rest = FUN_INlos(edge,myERL);
118   Standard_Boolean isse = myHDS->DS().IsSectionEdge(edge);
119   rest = rest || isse;
120   Standard_Boolean interf2d = EtgF && hasOOedge && rest;  
121   
122   Standard_Real factor = 1.e-4; 
123   TopOpeBRepTool_makeTransition MKT; 
124   Standard_Boolean ok = MKT.Initialize(edge,par1,par2,paredge, F,OOuv, factor);  
125   if (!ok) return T; 
126   Standard_Boolean isT2d = MKT.IsT2d();
127   interf2d = interf2d && isT2d;
128   if (interf2d) ok = MKT.SetRest(OOedge,OOparedge);
129   if (!ok) return T;
130
131   TopAbs_State stb,sta; ok = MKT.MkTonE(stb,sta);  
132   if (!ok) return T; 
133   T.Before(stb); T.After(sta);
134   return T;
135 }
136
137 //=======================================================================
138 //function : ProcessVPonclosingR
139 //purpose  : SUPPLYING INTPATCH when <VP> is on closing arc.
140 //=======================================================================
141 void TopOpeBRep_FacesFiller::ProcessVPonclosingR(const TopOpeBRep_VPointInter& VP,
142 //                                const TopoDS_Shape& GFace,
143                                 const TopoDS_Shape& ,
144                                 const Standard_Integer ShapeIndex,
145                                 const TopOpeBRepDS_Transition& transEdge,const TopOpeBRepDS_Kind PVKind, const Standard_Integer PVIndex,
146 //                              const Standard_Boolean EPIfound,
147                                 const Standard_Boolean ,
148 //                                const Handle(TopOpeBRepDS_Interference)& IEPI)
149                                 const Handle(TopOpeBRepDS_Interference)& )
150 {
151 //  Standard_Boolean isvertex = VP.IsVertex(ShapeIndex);
152   Standard_Boolean isvertex = (PVKind == TopOpeBRepDS_VERTEX);
153   Standard_Integer absindex = VP.ShapeIndex(); // 0,1,2,3
154 #ifdef DEB
155   Standard_Integer iVP =
156 #endif
157             VP.Index();
158   Standard_Boolean OOShapeIndex = (ShapeIndex == 1) ? 2 : 1;
159   Standard_Boolean on2edges = (absindex == 3);
160   Standard_Boolean hasONedge = (VP.State(OOShapeIndex) == TopAbs_ON);
161   Standard_Boolean hasOOedge = (on2edges) ? Standard_True : hasONedge;
162
163   TopoDS_Face Face = (*this).Face(ShapeIndex);
164 #ifdef DEB
165   Standard_Integer iSIFace =
166 #endif
167                 myDS->Shape(Face);
168   TopoDS_Face OOFace = (*this).Face(OOShapeIndex);
169   Standard_Integer iOOFace = myDS->Shape(OOFace);
170   if (iOOFace == 0) iOOFace = myDS->AddShape(OOFace,OOShapeIndex);
171
172   // current VPoint is on <edge>
173   Standard_Integer SIedgeIndex = 0;
174   const TopoDS_Edge& edge = TopoDS::Edge(VP.Edge(ShapeIndex));
175   if (myDS->HasShape(edge)) SIedgeIndex = myDS->Shape(edge);
176   else                      myDS->AddShape(edge,ShapeIndex);
177 #ifdef DEB
178   Standard_Boolean isrest =
179 #endif
180                myDS->IsSectionEdge(edge);
181 #ifdef DEB
182   Standard_Boolean closing =
183 #endif
184                 TopOpeBRepTool_ShapeTool::Closed(edge,Face);
185   Standard_Real paredge = VP.EdgeParameter(ShapeIndex);
186   
187   // dummy if !<hasOOedge>
188   Standard_Integer OOedgeIndex = 0; 
189   Standard_Boolean OOclosing,OOisrest; OOclosing = OOisrest = Standard_False;
190   TopoDS_Edge OOedge;
191   if ( hasOOedge ) {
192     TopoDS_Shape OOe;
193     if (on2edges) OOe = VP.Edge(OOShapeIndex);
194     else          OOe = VP.EdgeON(OOShapeIndex);
195     OOedge = TopoDS::Edge(OOe);
196     OOisrest = myDS->IsSectionEdge(OOedge);
197     OOclosing = TopOpeBRepTool_ShapeTool::Closed(OOedge,OOFace);
198     if (myDS->HasShape(OOedge)) OOedgeIndex = myDS->Shape(OOedge);
199     else                        OOedgeIndex = myDS->AddShape(OOedge,OOShapeIndex);
200   }
201   
202 #ifdef DEB
203   Standard_Boolean traceDSF = TopOpeBRepDS_GettraceDSF();
204   Standard_Boolean trce = TopOpeBRepDS_GettraceSPSX(SIedgeIndex);   if(trce) debarc(SIedgeIndex);
205   Standard_Boolean trcooe = TopOpeBRepDS_GettraceSPSX(OOedgeIndex); if(trcooe) debooarc(OOedgeIndex);
206 #endif
207
208   // ===================================================================
209   //             --- Edge/(POINT,VERTEX) Interference (EPI) creation ---
210   // ===================================================================
211   
212   // 1. <edge> enters or outers myF<OOShapeIndex> at <VP>,
213   //  transition <transEdge> returned by IntPatch is valid (FORWARD/REVERSED).
214   // 2. <edge> is tangent to myF<OOShapeIndex> : 
215   //  transEdge should be INTERNAL/EXTERNAL.
216   
217   Standard_Boolean Tunk = transEdge.IsUnknown();
218 #ifdef DEB
219   if (!Tunk && traceDSF) cout<<"-> on closing : transAdd = "<<endl;
220 #endif
221   TopOpeBRepDS_Transition transAdd;
222   Standard_Boolean newtransEdge = Tunk;
223   if (newtransEdge) transAdd = GetEdgeTrans(VP,PVKind,PVIndex,ShapeIndex,OOFace);
224   else              transAdd = transEdge;
225
226   // !!! if the compute of <transAdd> fails, we add transEdge.
227   // hasOOedge  : <VP> is ON edge <edge> and ON <OOFace>
228   // !hasOOedge : <VP> is ON edge <edge> and IN <OOFace>  
229   {      
230     TopOpeBRepDS_Transition T = transAdd; T.Index(iOOFace);
231     Handle(TopOpeBRepDS_Interference) EPI = ::MakeEPVInterference
232       (T,iOOFace,PVIndex,paredge,PVKind,TopOpeBRepDS_FACE,isvertex);
233     myHDS->StoreInterference(EPI,edge);
234   }  
235   if (hasOOedge) {
236     TopOpeBRepDS_Transition T = transAdd; T.Index(iOOFace);
237     Handle(TopOpeBRepDS_Interference) EPI = ::MakeEPVInterference
238         (T,OOedgeIndex,PVIndex,paredge,PVKind,isvertex);
239     myHDS->StoreInterference(EPI,edge);
240   }
241
242 } // ProcessVPonclosingR