743ef2556884c6b18f7b235a3834143e2ec09a5a
[occt.git] / src / TopOpeBRepTool / TopOpeBRepTool_BoxSort.cxx
1 // Created on: 1993-07-12
2 // Created by: Jean Yves LEBEY
3 // Copyright (c) 1993-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 <Bnd_Box.hxx>
19 #include <BRep_Tool.hxx>
20 #include <Geom_Surface.hxx>
21 #include <GeomAbs_SurfaceType.hxx>
22 #include <GeomAdaptor_Surface.hxx>
23 #include <gp_Pln.hxx>
24 #include <Standard_ProgramError.hxx>
25 #include <TopExp.hxx>
26 #include <TopExp_Explorer.hxx>
27 #include <TopoDS.hxx>
28 #include <TopoDS_Edge.hxx>
29 #include <TopoDS_Face.hxx>
30 #include <TopoDS_Shape.hxx>
31 #include <TopoDS_Vertex.hxx>
32 #include <TopOpeBRepTool_box.hxx>
33 #include <TopOpeBRepTool_BoxSort.hxx>
34 #include <TopOpeBRepTool_define.hxx>
35 #include <TopOpeBRepTool_HBoxTool.hxx>
36
37 #ifdef OCCT_DEBUG
38 #define TBOX TopOpeBRepTool_GettraceBOX()
39 #endif
40
41 #define MTOhbt Handle(TopOpeBRepTool_HBoxTool)
42 #define MTClioloi TColStd_ListIteratorOfListOfInteger
43
44 //=======================================================================
45 //function : TopOpeBRepTool_BoxSort
46 //purpose  : 
47 //=======================================================================
48 TopOpeBRepTool_BoxSort::TopOpeBRepTool_BoxSort()
49 {
50 }
51
52 //=======================================================================
53 //function : TopOpeBRepTool_BoxSort
54 //purpose  : 
55 //=======================================================================
56 TopOpeBRepTool_BoxSort::TopOpeBRepTool_BoxSort(const MTOhbt& HBT)
57 {
58   SetHBoxTool(HBT);
59 }
60
61 //modified by NIZNHY-PKV Mon Dec 16 10:26:00 2002 f
62 //=======================================================================
63 //function : ~TopOpeBRepTool_BoxSort
64 //purpose  : 
65 //=======================================================================
66 TopOpeBRepTool_BoxSort::~TopOpeBRepTool_BoxSort()
67 {
68   if (!myHBT.IsNull()) {
69     myHBT->Clear();
70   }
71 }
72 //modified by NIZNHY-PKV Mon Dec 16 10:26:02 2002 t
73
74 //=======================================================================
75 //function : SetHBoxTool
76 //purpose  : 
77 //=======================================================================
78 void TopOpeBRepTool_BoxSort::SetHBoxTool(const MTOhbt& HBT)
79 {
80   myHBT = HBT;
81 }
82
83 //=======================================================================
84 //function : HBoxTool
85 //purpose  : 
86 //=======================================================================
87 const MTOhbt& TopOpeBRepTool_BoxSort::HBoxTool() const
88 {
89   return myHBT;
90 }
91
92 //=======================================================================
93 //function : Clear
94 //purpose  : 
95 //=======================================================================
96 void TopOpeBRepTool_BoxSort::Clear()
97 {
98   myCOB.SetVoid();
99 //  myHAB.Nullify();
100 //  myHAI.Nullify();
101 }
102
103 //=======================================================================
104 //function : AddBoxes
105 //purpose  : 
106 //=======================================================================
107 void TopOpeBRepTool_BoxSort::AddBoxes(const TopoDS_Shape& S,const TopAbs_ShapeEnum TS,const TopAbs_ShapeEnum TA)
108 {
109   if (myHBT.IsNull()) myHBT = new TopOpeBRepTool_HBoxTool();
110   myHBT->AddBoxes(S,TS,TA);
111 }  
112
113 //=======================================================================
114 //function : MakeHAB
115 //purpose  : 
116 //=======================================================================
117 void TopOpeBRepTool_BoxSort::MakeHAB(const TopoDS_Shape& S,const TopAbs_ShapeEnum TS,const TopAbs_ShapeEnum TA)
118 {
119 #ifdef OCCT_DEBUG
120   TopAbs_ShapeEnum t =
121 #endif
122                        S.ShapeType();
123   Standard_Integer n = 0; TopExp_Explorer ex;
124   for (ex.Init(S,TS,TA);ex.More();ex.Next()) n++;
125
126   myHAB = new Bnd_HArray1OfBox(0,n);
127   Bnd_Array1OfBox& AB = myHAB->ChangeArray1();
128   myHAI = new TColStd_HArray1OfInteger(0,n);
129   TColStd_Array1OfInteger& AI = myHAI->ChangeArray1();
130   
131   Standard_Integer i = 0;
132   for (ex.Init(S,TS,TA);ex.More();ex.Next()) {
133     i++;
134     const TopoDS_Shape& ss = ex.Current();    
135     Standard_Boolean hb = myHBT->HasBox(ss);
136     if (!hb) myHBT->AddBox(ss);
137     Standard_Integer im = myHBT->Index(ss);
138     const Bnd_Box& B = myHBT->Box(ss);
139     AI.ChangeValue(i) = im;
140     AB.ChangeValue(i) = B;
141   }
142
143 #ifdef OCCT_DEBUG
144   if (TBOX) {
145     cout<<"# BS::MakeHAB : ";TopAbs::Print(t,cout);cout<<" : "<<n<<"\n";
146     cout.flush();
147   }
148 #endif
149
150 }
151
152 //=======================================================================
153 //function : HAB
154 //purpose  : 
155 //=======================================================================
156 const Handle(Bnd_HArray1OfBox)& TopOpeBRepTool_BoxSort::HAB() const
157 {
158   return myHAB;
159 }
160
161 //=======================================================================
162 //function : MakeHABCOB
163 //purpose  : 
164 //=======================================================================
165 void TopOpeBRepTool_BoxSort::MakeHABCOB(const Handle(Bnd_HArray1OfBox)& HAB,
166                                         Bnd_Box& COB)
167 {
168   COB.SetVoid();
169   Standard_Integer n = HAB->Upper();
170   const Bnd_Array1OfBox& AB = HAB->Array1();
171   for (Standard_Integer i = 1; i <= n; i++) {
172     const Bnd_Box& B = AB(i);
173     COB.Add(B);
174   }
175 }
176
177 //=======================================================================
178 //function : HABShape
179 //purpose  : 
180 //=======================================================================
181 const TopoDS_Shape& TopOpeBRepTool_BoxSort::HABShape(const Standard_Integer I) const
182 {
183   Standard_Integer iu = myHAI->Upper();
184   Standard_Boolean b = (I >= 1 && I <= iu);
185   if (!b) {
186     throw Standard_ProgramError("BS::Box3");
187   }
188   Standard_Integer im = myHAI->Value(I);
189   const TopoDS_Shape& S = myHBT->Shape(im);
190   return S;
191 }
192
193 //=======================================================================
194 //function : MakeCOB
195 //purpose  : 
196 //=======================================================================
197 void TopOpeBRepTool_BoxSort::MakeCOB(const TopoDS_Shape& S,const TopAbs_ShapeEnum TS,const TopAbs_ShapeEnum TA)
198 {
199   MakeHAB(S,TS,TA);
200   MakeHABCOB(myHAB,myCOB);
201   myBSB.Initialize(myCOB,myHAB);
202 #ifdef OCCT_DEBUG
203   if (TBOX) {myHBT->DumpB(myCOB);cout<<";# BS::MakeCOB"<<endl;}
204 #endif
205 }
206
207 //=======================================================================
208 //function : AddBoxesMakeCOB
209 //purpose  : 
210 //=======================================================================
211 void TopOpeBRepTool_BoxSort::AddBoxesMakeCOB(const TopoDS_Shape& S,const TopAbs_ShapeEnum TS,const TopAbs_ShapeEnum TA)
212 {
213   AddBoxes(S,TS,TA);
214   MakeCOB(S,TS,TA);
215 }
216
217 //=======================================================================
218 //function : Compare
219 //purpose  : 
220 //=======================================================================
221 const MTClioloi& TopOpeBRepTool_BoxSort::Compare(const TopoDS_Shape &S)
222 {
223   if ( myHBT.IsNull() ) myHBT = new TopOpeBRepTool_HBoxTool();
224   
225   gp_Pln P;
226   Standard_Boolean isPlane = Standard_False;
227   TopAbs_ShapeEnum t = S.ShapeType();
228   Standard_Boolean hasb = myHBT->HasBox(S);
229   if (!hasb) myHBT->AddBox(S);
230
231   myLastCompareShape = S;
232   myLastCompareShapeBox.SetVoid();
233   
234   if ( t == TopAbs_FACE) {
235     const TopoDS_Face& F = TopoDS::Face(S);
236     Standard_Boolean natu = BRep_Tool::NaturalRestriction(F);
237     if (natu) {
238       Handle(Geom_Surface) surf = BRep_Tool::Surface(F);
239       GeomAdaptor_Surface GAS(surf); 
240       GeomAbs_SurfaceType suty = GAS.GetType();
241       isPlane = (suty == GeomAbs_Plane);
242       if (isPlane) P = GAS.Plane();
243       else {
244         myLastCompareShapeBox = myHBT->Box(F);
245       }
246     }
247     else {
248       myLastCompareShapeBox = myHBT->Box(F);
249     }
250   }
251   else if (t == TopAbs_EDGE) {
252     const TopoDS_Edge& E = TopoDS::Edge(S);
253     TopoDS_Vertex V1,V2; TopExp::Vertices(E,V1,V2);
254     Standard_Boolean perso = (V1.IsNull() || V2.IsNull());
255     if (perso) {
256       myHBT->ComputeBoxOnVertices(E,myLastCompareShapeBox);
257     } 
258     else {
259       myLastCompareShapeBox = myHBT->Box(E);
260     }
261   }
262
263   const TColStd_ListOfInteger* L;
264   if (isPlane) L = &myBSB.Compare(P);
265   else L = &myBSB.Compare(myLastCompareShapeBox);
266   myIterator.Initialize(*L);
267   
268 #ifdef OCCT_DEBUG
269   if (TBOX) {
270     Standard_Integer nl = (*L).Extent();
271     cout<<"#------------------------"<<endl;
272     myHBT->DumpB(myLastCompareShapeBox);cout<<"; # BS::Compare"<<endl;
273     cout<<"# touche "<<nl<<" boites ";cout.flush();
274     Standard_Integer il;
275     for (MTClioloi idd((*L));idd.More();idd.Next()) {
276       il=idd.Value();cout<<il<<" ";cout.flush();
277     }
278     cout<<endl<<"#------------------------"<<endl;
279   }
280 #endif
281  
282  return myIterator;
283 }
284         
285 //=======================================================================
286 //function : TouchedShape
287 //purpose  : 
288 //=======================================================================
289 const TopoDS_Shape& TopOpeBRepTool_BoxSort::TouchedShape(const MTClioloi& LI) const
290 {
291   Standard_Integer icur = LI.Value();
292   const TopoDS_Shape& Scur = HABShape(icur);
293   return Scur;
294 }
295
296 //=======================================================================
297 //function : Box
298 //purpose  : 
299 //=======================================================================
300 const Bnd_Box& TopOpeBRepTool_BoxSort::Box(const TopoDS_Shape& S) const
301 {
302   if ( myHBT.IsNull() ) {
303     *((MTOhbt*)&myHBT) = new TopOpeBRepTool_HBoxTool();
304   }
305
306   if ( myHBT->HasBox(S) ) {
307     const Bnd_Box& B = myHBT->Box(S);
308     return B;
309   }
310   else if ( !myLastCompareShape.IsNull() ) {
311     if ( S.IsEqual(myLastCompareShape) ) {
312       if ( !myLastCompareShapeBox.IsVoid() ) {
313         return myLastCompareShapeBox;
314       }
315     }
316   }
317   
318   const Bnd_Box& B = myHBT->Box(S);
319   return B;
320 }