1 // Copyright (C) 2014-2017 CEA/DEN, EDF R&D
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.
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.
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
17 // See http://www.salome-platform.org/ or
18 // email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
21 #include <Selector_Container.h>
23 #include <Selector_NameGenerator.h>
24 #include <Selector_NExplode.h>
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>
34 #include <TopoDS_Builder.hxx>
35 #include <TopoDS_Compound.hxx>
37 Selector_Container::Selector_Container() : Selector_AlgoWithSubs()
40 bool Selector_Container::select(const TopoDS_Shape theContext, const TopoDS_Shape theValue)
42 myShapeType = theValue.ShapeType();
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))
55 void Selector_Container::store()
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++) {
64 TDataStd_Integer::Set(label(), shapeTypeID(), (int)myShapeType);
67 bool Selector_Container::restore()
69 Handle(TDataStd_Integer) aShapeTypeAttr;
70 if (!label().FindAttribute(shapeTypeID(), aShapeTypeAttr))
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
84 TDF_Label Selector_Container::restoreByName(std::string theName,
85 const TopAbs_ShapeEnum theShapeType, Selector_NameGenerator* theNameGenerator)
87 myShapeType = theShapeType;
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 // there could be sub-intersections, so, [[...]] case; searching for other open-bracket
93 size_t aNextStart = theName.find('[', aStart + 1);
94 while(aNextStart != std::string::npos && aNextStart < anEndPos) {
95 anEndPos = theName.find(']', anEndPos + 1);
96 if (anEndPos == std::string::npos) {
97 return TDF_Label(); // invalid parentheses
99 aNextStart = theName.find('[', aNextStart + 1);
101 if (anEndPos == std::string::npos)
102 return TDF_Label(); // invalid parentheses
103 std::string aSubStr = theName.substr(aStart + 1, anEndPos - aStart - 1);
104 TopAbs_ShapeEnum aSubShapeType = TopAbs_FACE;
105 switch (myShapeType) {
106 case TopAbs_COMPSOLID: aSubShapeType = TopAbs_SOLID; break;
107 case TopAbs_WIRE: aSubShapeType = TopAbs_EDGE; break;
110 TDF_Label aSubContext;
111 Selector_Algo* aSubSel =
112 Selector_Algo::restoreByName(newSubLabel(), baseDocument(), aSubStr, aSubShapeType,
113 geometricalNaming(), theNameGenerator, aSubContext);
114 if (!append(aSubSel))
117 if (aSubContext.IsNull()) {
122 if (!aContext.IsNull() && !aContext.IsEqual(aSubContext)) {
123 if (!theNameGenerator->isLater(aContext, aSubContext))
124 aContext = aSubContext;
126 aContext = aSubContext;
129 return TDF_Label(); // invalid parentheses
130 aStart = anEndPos; // for recursive parenthesis set start on the current end
135 bool Selector_Container::solve(const TopoDS_Shape& theContext)
137 TopoDS_Shape aResult;
139 TopoDS_Builder aBuilder;
140 switch(myShapeType) {
141 case TopAbs_COMPOUND: {
142 TopoDS_Compound aComp;
143 aBuilder.MakeCompound(aComp);
147 case TopAbs_COMPSOLID: {
148 TopoDS_CompSolid aComp;
149 aBuilder.MakeCompSolid(aComp);
155 aBuilder.MakeShell(aShell);
161 aBuilder.MakeWire(aWire);
166 TopoDS_ListOfShape aSubSelectorShapes;
167 std::list<Selector_Algo*>::const_iterator aSubSel = list().cbegin();
168 for(; aSubSel != list().cend(); aSubSel++) {
169 if (!(*aSubSel)->solve(theContext)) {
172 aBuilder.Add(aResult, (*aSubSel)->value());
174 if (!aResult.IsNull()) {
175 Selector_Algo::store(aResult);
181 std::string Selector_Container::name(Selector_NameGenerator* theNameGenerator)
184 // add names of sub-components one by one in "[]"
185 std::list<Selector_Algo*>::const_iterator aSubSel = list().cbegin();
186 for(; aSubSel != list().cend(); aSubSel++) {
188 aResult += (*aSubSel)->name(theNameGenerator);