Salome HOME
Debug of refactored Selector
[modules/shaper.git] / src / Selector / Selector_Container.cpp
1 // Copyright (C) 2014-2017  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or
18 // email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
19 //
20
21 #include <Selector_Container.h>
22
23 #include <Selector_NameGenerator.h>
24 #include <Selector_NExplode.h>
25
26 #include <TNaming_NamedShape.hxx>
27 #include <TDataStd_Name.hxx>
28 #include <TDataStd_Integer.hxx>
29 #include <TDF_ChildIterator.hxx>
30 #include <TopTools_MapOfShape.hxx>
31 #include <TopExp_Explorer.hxx>
32 #include <BRep_Tool.hxx>
33 #include <TopoDS.hxx>
34 #include <TopoDS_Builder.hxx>
35 #include <TopoDS_Compound.hxx>
36
37 Selector_Container::Selector_Container() : Selector_AlgoWithSubs()
38 {}
39
40 bool Selector_Container::select(const TopoDS_Shape theContext, const TopoDS_Shape theValue)
41 {
42   myShapeType = theValue.ShapeType();
43
44   // iterate all sub-shapes and select them on sublabels
45   for(TopoDS_Iterator aSubIter(theValue); aSubIter.More(); aSubIter.Next()) {
46     Selector_Algo* aSubAlgo = Selector_Algo::select(theContext, aSubIter.Value(),
47       newSubLabel(), baseDocument(),
48       false, useNeighbors(), useIntersections()); //for subs no geometrical naming allowed
49     if (!append(aSubAlgo))
50       return false;
51   }
52   return true;
53 }
54
55 void Selector_Container::store()
56 {
57   storeType(Selector_Algo::SELTYPE_CONTAINER);
58   // store all sub-selectors
59   TDataStd_Integer::Set(label(), shapeTypeID(), (int)myShapeType);
60   std::list<Selector_Algo*>::const_iterator aSubSel = list().cbegin();
61   for(; aSubSel != list().cend(); aSubSel++) {
62     (*aSubSel)->store();
63   }
64   TDataStd_Integer::Set(label(), shapeTypeID(), (int)myShapeType);
65 }
66
67 bool Selector_Container::restore()
68 {
69   Handle(TDataStd_Integer) aShapeTypeAttr;
70   if (!label().FindAttribute(shapeTypeID(), aShapeTypeAttr))
71     return false;
72   myShapeType = TopAbs_ShapeEnum(aShapeTypeAttr->Get());
73   // restore sub-selectors
74   bool aSubResult = true;
75   for(TDF_ChildIterator aSub(label(), false); aSub.More(); aSub.Next()) {
76     Selector_Algo* aSubSel = restoreByLab(aSub.Value(), baseDocument());
77     if (!append(aSubSel, false)) {
78       break; // some empty label left in the end
79     }
80   }
81   return true;
82 }
83
84 TDF_Label Selector_Container::restoreByName(std::string theName,
85   const TopAbs_ShapeEnum theShapeType, Selector_NameGenerator* theNameGenerator)
86 {
87   myShapeType = theShapeType;
88   TDF_Label aContext;
89   for(size_t aStart = 0; aStart != std::string::npos; aStart = theName.find('[', aStart + 1)) {
90     size_t anEndPos = theName.find(']', aStart + 1);
91     if (anEndPos != std::string::npos) {
92       std::string aSubStr = theName.substr(aStart + 1, anEndPos - aStart - 1);
93       TopAbs_ShapeEnum aSubShapeType = TopAbs_FACE;
94       switch (myShapeType) {
95       case TopAbs_COMPSOLID: aSubShapeType = TopAbs_SOLID; break;
96       case TopAbs_WIRE: aSubShapeType = TopAbs_EDGE; break;
97       default:;
98       }
99       TDF_Label aSubContext;
100       Selector_Algo* aSubSel =
101         Selector_Algo::restoreByName(
102           newSubLabel(), baseDocument(), aSubStr, aSubShapeType, theNameGenerator, aSubContext);
103       if (!append(aSubSel))
104         return TDF_Label();
105
106       if (aSubContext.IsNull()) {
107         delete aSubSel;
108         clearSubAlgos();
109         return TDF_Label();
110       }
111       if (!aContext.IsNull() && !aContext.IsEqual(aSubContext)) {
112         if (!theNameGenerator->isLater(aContext, aSubContext))
113           aContext = aSubContext;
114       } else {
115         aContext = aSubContext;
116       }
117     } else
118       return TDF_Label(); // invalid parentheses
119   }
120   return aContext;
121 }
122
123 bool Selector_Container::solve(const TopoDS_Shape& theContext)
124 {
125   TopoDS_Shape aResult;
126
127   TopoDS_Builder aBuilder;
128   switch(myShapeType) {
129   case TopAbs_COMPOUND: {
130     TopoDS_Compound aComp;
131     aBuilder.MakeCompound(aComp);
132     aResult = aComp;
133     break;
134   }
135   case TopAbs_COMPSOLID: {
136     TopoDS_CompSolid aComp;
137     aBuilder.MakeCompSolid(aComp);
138     aResult = aComp;
139     break;
140   }
141   case TopAbs_SHELL: {
142     TopoDS_Shell aShell;
143     aBuilder.MakeShell(aShell);
144     aResult = aShell;
145     break;
146   }
147   case TopAbs_WIRE: {
148     TopoDS_Wire aWire;
149     aBuilder.MakeWire(aWire);
150     aResult = aWire;
151     break;
152   }
153   }
154   TopoDS_ListOfShape aSubSelectorShapes;
155   std::list<Selector_Algo*>::const_iterator aSubSel = list().cbegin();
156   for(; aSubSel != list().cend(); aSubSel++) {
157     if (!(*aSubSel)->solve(theContext)) {
158       return false;
159     }
160     aBuilder.Add(aResult, (*aSubSel)->value());
161   }
162   if (!aResult.IsNull()) {
163     Selector_Algo::store(aResult);
164     return true;
165   }
166   return false;
167 }
168
169 std::string Selector_Container::name(Selector_NameGenerator* theNameGenerator)
170 {
171   std::string aResult;
172   // add names of sub-components one by one in "[]"
173   std::list<Selector_Algo*>::const_iterator aSubSel = list().cbegin();
174   for(; aSubSel != list().cend(); aSubSel++) {
175     aResult += '[';
176     aResult += (*aSubSel)->name(theNameGenerator);
177     aResult += ']';
178   }
179   return aResult;
180 }