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