1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 // This file is part of Open CASCADE Technology software library.
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.
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
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>
24 //=======================================================================
25 //function : ShapeExtend_Explorer
27 //=======================================================================
29 ShapeExtend_Explorer::ShapeExtend_Explorer()
33 //=======================================================================
34 //function : CompoundFromSeq
36 //=======================================================================
38 TopoDS_Shape ShapeExtend_Explorer::CompoundFromSeq
39 (const Handle(TopTools_HSequenceOfShape)& seqval) const
44 Standard_Integer i,n = seqval->Length();
45 for (i = 1; i <= n ; i ++) B.Add(C,seqval->Value(i));
49 //=======================================================================
50 //function : SeqFromCompound
52 //=======================================================================
54 static void FillList (const Handle(TopTools_HSequenceOfShape)& list,
55 const TopoDS_Shape& comp, const Standard_Boolean expcomp)
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);
65 Handle(TopTools_HSequenceOfShape) ShapeExtend_Explorer::SeqFromCompound
66 (const TopoDS_Shape& comp, const Standard_Boolean expcomp) const
68 Handle(TopTools_HSequenceOfShape) list = new TopTools_HSequenceOfShape();
69 if (comp.IsNull()) return list;
70 if (comp.ShapeType() != TopAbs_COMPOUND) {
74 FillList (list,comp,expcomp);
78 //=======================================================================
79 //function : ListFromSeq
81 //=======================================================================
83 void ShapeExtend_Explorer::ListFromSeq (const Handle(TopTools_HSequenceOfShape)& seqval,
84 TopTools_ListOfShape& lisval,
85 const Standard_Boolean clear) const
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));
93 //=======================================================================
94 //function : SeqFromList
96 //=======================================================================
98 Handle(TopTools_HSequenceOfShape) ShapeExtend_Explorer::SeqFromList
99 (const TopTools_ListOfShape& lisval) const
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());
107 //=======================================================================
108 //function : ShapeType
110 //=======================================================================
112 TopAbs_ShapeEnum ShapeExtend_Explorer::ShapeType (const TopoDS_Shape& shape,
113 const Standard_Boolean compound) const
115 if (shape.IsNull()) return TopAbs_SHAPE;
116 TopAbs_ShapeEnum res = shape.ShapeType();
117 if (!compound || res != TopAbs_COMPOUND) return res;
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;
135 //=======================================================================
136 //function : SortedCompound
138 //=======================================================================
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
145 if (shape.IsNull()) return shape;
146 TopAbs_ShapeEnum typ = shape.ShapeType();
147 TopoDS_Shape sh, sh0;
148 Standard_Integer nb = 0;
150 // Compound : on le prend, soit tel quel, soit son contenu
151 if (typ == TopAbs_COMPOUND || typ == TopAbs_COMPSOLID) {
155 for (TopoDS_Iterator it(shape); it.More(); it.Next()) {
156 sh0 = SortedCompound (it.Value(),type,explore,compound);
157 if (sh0.IsNull()) continue;
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); }
164 else { nb ++; B.Add (C,sh); }
166 if (nb == 0) C.Nullify();
167 else if (nb == 1) return sh;
171 // Egalite : OK; Pseudo-Egalite : EDGE/WIRE ou FACE/SHELL
172 if (typ == type) return shape;
173 if (typ == TopAbs_EDGE && type == TopAbs_WIRE) {
180 if (typ == TopAbs_FACE && type == TopAbs_SHELL) {
188 // Le reste : selon exploration
194 // Ici, on doit explorer
195 // SOLID + mode COMPOUND : reconduire les SHELLs
196 if (typ == TopAbs_SOLID && compound) {
200 for (TopoDS_Iterator it(shape); it.More(); it.Next()) {
201 sh0 = SortedCompound (it.Value(),type,explore,compound);
202 if (sh0.IsNull()) continue;
206 if (nb == 0) C.Nullify();
207 else if (nb == 1) return sh;
211 // Exploration classique
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();
220 if (nb == 0) CC.Nullify();
221 else if (nb == 1) return sh;
225 //=======================================================================
226 //function : DispatchList
228 //=======================================================================
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
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();
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;