0024428: Implementation of LGPL license
[occt.git] / src / ShapeExtend / ShapeExtend_Explorer.cxx
1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
5 // This library is free software; you can redistribute it and / or modify it
6 // under the terms of the GNU Lesser General Public version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14 //szv#4 S4163
15 #include <ShapeExtend_Explorer.ixx>
16 #include <TopoDS_Wire.hxx>
17 #include <TopoDS_Shell.hxx>
18 #include <TopoDS_Compound.hxx>
19 #include <TopoDS_Iterator.hxx>
20 #include <TopExp_Explorer.hxx>
21 #include <TopTools_ListIteratorOfListOfShape.hxx>
22 #include <BRep_Builder.hxx>
23
24 //=======================================================================
25 //function : ShapeExtend_Explorer
26 //purpose  : 
27 //=======================================================================
28
29 ShapeExtend_Explorer::ShapeExtend_Explorer()
30 {
31 }
32
33 //=======================================================================
34 //function : CompoundFromSeq
35 //purpose  : 
36 //=======================================================================
37
38 TopoDS_Shape ShapeExtend_Explorer::CompoundFromSeq
39   (const Handle(TopTools_HSequenceOfShape)& seqval) const
40 {
41   BRep_Builder B;
42   TopoDS_Compound C;
43   B.MakeCompound(C);
44   Standard_Integer i,n = seqval->Length();
45   for (i = 1; i <= n ; i ++)  B.Add(C,seqval->Value(i));
46   return C;
47 }
48
49 //=======================================================================
50 //function : SeqFromCompound
51 //purpose  : 
52 //=======================================================================
53
54 static void FillList (const Handle(TopTools_HSequenceOfShape)& list,
55                       const TopoDS_Shape& comp, const Standard_Boolean expcomp)
56 {
57   for (TopoDS_Iterator it (comp); it.More(); it.Next()) {
58     TopoDS_Shape sub = it.Value();
59     if (sub.ShapeType() != TopAbs_COMPOUND) list->Append (sub);
60     else if (!expcomp) list->Append (sub);
61     else FillList (list,sub,expcomp);
62   }
63 }
64
65 Handle(TopTools_HSequenceOfShape) ShapeExtend_Explorer::SeqFromCompound
66        (const TopoDS_Shape& comp, const Standard_Boolean expcomp) const
67 {
68   Handle(TopTools_HSequenceOfShape) list = new TopTools_HSequenceOfShape();
69   if (comp.IsNull()) return list;
70   if (comp.ShapeType() != TopAbs_COMPOUND) {
71     list->Append (comp);
72     return list;
73   }
74   FillList (list,comp,expcomp);
75   return list;
76 }
77
78 //=======================================================================
79 //function : ListFromSeq
80 //purpose  : 
81 //=======================================================================
82
83 void ShapeExtend_Explorer::ListFromSeq (const Handle(TopTools_HSequenceOfShape)& seqval,
84                                        TopTools_ListOfShape& lisval,
85                                        const Standard_Boolean clear) const
86 {
87   if (clear) lisval.Clear();
88   if (seqval.IsNull()) return;
89   Standard_Integer i, nb = seqval->Length();
90   for (i = 1; i <= nb; i ++) lisval.Append (seqval->Value(i));
91 }
92
93 //=======================================================================
94 //function : SeqFromList
95 //purpose  : 
96 //=======================================================================
97
98 Handle(TopTools_HSequenceOfShape) ShapeExtend_Explorer::SeqFromList
99        (const TopTools_ListOfShape& lisval) const
100 {
101   Handle(TopTools_HSequenceOfShape) seqval = new TopTools_HSequenceOfShape();
102   TopTools_ListIteratorOfListOfShape it;
103   for (it.Initialize(lisval); it.More(); it.Next()) seqval->Append (it.Value());
104   return seqval;
105 }
106
107 //=======================================================================
108 //function : ShapeType
109 //purpose  : 
110 //=======================================================================
111
112 TopAbs_ShapeEnum ShapeExtend_Explorer::ShapeType (const TopoDS_Shape& shape,
113                                                  const Standard_Boolean compound) const
114 {
115   if (shape.IsNull()) return TopAbs_SHAPE;
116   TopAbs_ShapeEnum res = shape.ShapeType();
117   if (!compound || res != TopAbs_COMPOUND) return res;
118   res = TopAbs_SHAPE;
119   for (TopoDS_Iterator iter(shape); iter.More(); iter.Next()) {
120     TopoDS_Shape sh = iter.Value();
121     if (sh.IsNull()) continue;
122     TopAbs_ShapeEnum typ = sh.ShapeType();
123     if (typ == TopAbs_COMPOUND) typ = ShapeType (sh,compound);
124     if (res == TopAbs_SHAPE) res = typ;
125     //   Egalite : OK;  Pseudo-Egalite : EDGE/WIRE ou FACE/SHELL
126     else if (res == TopAbs_EDGE  && typ == TopAbs_WIRE)  res = typ;
127     else if (res == TopAbs_WIRE  && typ == TopAbs_EDGE)  continue;
128     else if (res == TopAbs_FACE  && typ == TopAbs_SHELL) res = typ;
129     else if (res == TopAbs_SHELL && typ == TopAbs_FACE)  continue;
130     else if (res != typ) return TopAbs_COMPOUND;
131   }
132   return res;
133 }
134
135 //=======================================================================
136 //function : SortedCompound
137 //purpose  : 
138 //=======================================================================
139
140 TopoDS_Shape ShapeExtend_Explorer::SortedCompound (const TopoDS_Shape& shape,
141                                                   const TopAbs_ShapeEnum type,
142                                                   const Standard_Boolean explore,
143                                                   const Standard_Boolean compound) const
144 {
145   if (shape.IsNull()) return shape;
146   TopAbs_ShapeEnum typ = shape.ShapeType();
147   TopoDS_Shape sh, sh0;
148   Standard_Integer nb = 0;
149
150   //  Compound : on le prend, soit tel quel, soit son contenu
151   if (typ == TopAbs_COMPOUND || typ == TopAbs_COMPSOLID) {
152     TopoDS_Compound C;
153     BRep_Builder B;
154     B.MakeCompound (C);
155     for (TopoDS_Iterator it(shape); it.More(); it.Next()) {
156       sh0 = SortedCompound (it.Value(),type,explore,compound);
157       if (sh0.IsNull()) continue;
158       sh = sh0;
159       typ = sh.ShapeType();
160       if (typ == TopAbs_COMPOUND && !compound) {
161         for (TopoDS_Iterator it2 (sh); it2.More(); it2.Next())
162           {  nb ++;  sh = it2.Value();  B.Add (C, sh);  }
163       }
164       else  {  nb ++;  B.Add (C,sh);  }
165     }
166     if (nb == 0) C.Nullify();
167     else if (nb == 1) return sh;
168     return C;
169   }
170
171   //   Egalite : OK;  Pseudo-Egalite : EDGE/WIRE ou FACE/SHELL
172   if (typ == type) return shape;
173   if (typ == TopAbs_EDGE && type == TopAbs_WIRE) {
174     BRep_Builder B;
175     TopoDS_Wire W;
176     B.MakeWire (W);
177     B.Add (W,shape);
178     return W;
179   }
180   if (typ == TopAbs_FACE && type == TopAbs_SHELL) {
181     BRep_Builder B;
182     TopoDS_Shell S;
183     B.MakeShell (S);
184     B.Add (S,shape);
185     return S;
186   }
187
188   //   Le reste : selon exploration
189   if (!explore) {
190     TopoDS_Shape nulsh;
191     return nulsh;
192   }
193
194   //  Ici, on doit explorer
195   //  SOLID + mode COMPOUND : reconduire les SHELLs
196   if (typ == TopAbs_SOLID && compound) {
197     TopoDS_Compound C;
198     BRep_Builder B;
199     B.MakeCompound (C);
200     for (TopoDS_Iterator it(shape); it.More(); it.Next()) {
201       sh0 = SortedCompound (it.Value(),type,explore,compound);
202       if (sh0.IsNull()) continue;
203       sh = sh0;
204       nb ++;  B.Add (C,sh);
205     }
206     if (nb == 0) C.Nullify();
207     else if (nb == 1) return sh;
208     return C;
209   }
210
211   //  Exploration classique
212   TopoDS_Compound CC;
213   BRep_Builder BB;
214   BB.MakeCompound(CC);
215   //Standard_Integer iena = Standard_False; //szv#4:S4163:12Mar99 unused
216   for (TopExp_Explorer expl (shape,type); expl.More(); expl.Next()) {
217     nb ++;  sh = expl.Current();
218     BB.Add (CC,sh);
219   }
220   if (nb == 0) CC.Nullify();
221   else if (nb == 1) return sh;
222   return CC;
223 }
224
225 //=======================================================================
226 //function : DispatchList
227 //purpose  : 
228 //=======================================================================
229
230 void ShapeExtend_Explorer::DispatchList (const Handle(TopTools_HSequenceOfShape)& list,
231                                          Handle(TopTools_HSequenceOfShape)& vertices,
232                                          Handle(TopTools_HSequenceOfShape)& edges,
233                                          Handle(TopTools_HSequenceOfShape)& wires,
234                                          Handle(TopTools_HSequenceOfShape)& faces,
235                                          Handle(TopTools_HSequenceOfShape)& shells,
236                                          Handle(TopTools_HSequenceOfShape)& solids,
237                                          Handle(TopTools_HSequenceOfShape)& compsols,
238                                          Handle(TopTools_HSequenceOfShape)& compounds) const
239 {
240   if (list.IsNull()) return;
241   if (vertices.IsNull())  vertices  = new TopTools_HSequenceOfShape();
242   if (edges.IsNull())     edges     = new TopTools_HSequenceOfShape();
243   if (wires.IsNull())     wires     = new TopTools_HSequenceOfShape();
244   if (faces.IsNull())     faces     = new TopTools_HSequenceOfShape();
245   if (shells.IsNull())    shells    = new TopTools_HSequenceOfShape();
246   if (solids.IsNull())    solids    = new TopTools_HSequenceOfShape();
247   if (compsols.IsNull())  compsols  = new TopTools_HSequenceOfShape();
248   if (compounds.IsNull()) compounds = new TopTools_HSequenceOfShape();
249
250   Standard_Integer i,nb = list->Length();
251   for (i = 1; i <= nb; i ++) {
252     TopoDS_Shape sh = list->Value(i);
253     if (sh.IsNull()) continue;
254     switch (sh.ShapeType()) {
255       case TopAbs_VERTEX    : vertices->Append(sh); break;
256       case TopAbs_EDGE      : edges->Append(sh); break;
257       case TopAbs_WIRE      : wires->Append(sh); break;
258       case TopAbs_FACE      : faces->Append(sh); break;
259       case TopAbs_SHELL     : shells->Append(sh); break;
260       case TopAbs_SOLID     : solids->Append(sh); break;
261       case TopAbs_COMPSOLID : compsols->Append(sh); break;
262       case TopAbs_COMPOUND  : compounds->Append(sh); break;
263       default : break;
264     }
265   }
266 }