Salome HOME
2e28fc4ebc20790aa5af652fc0bdde39e3b6e805
[modules/geom.git] / src / GEOMImpl / GEOMImpl_IBaseIEOperations.cxx
1 // Copyright (C) 2014-2020  CEA/DEN, EDF R&D, OPEN CASCADE
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 email : webmaster.salome@opencascade.com
18 //
19
20 // internal includes
21 #include "GEOMImpl_IBaseIEOperations.hxx"
22 #include "GEOMImpl_IGroupOperations.hxx"
23 #include "GEOMImpl_IFieldOperations.hxx"
24 #include "GEOMImpl_IShapesOperations.hxx"
25
26 // OCC includes
27 #include <NCollection_DataMap.hxx>
28 #include <TDF_ChildIDIterator.hxx>
29 #include <TNaming_NamedShape.hxx>
30 #include <TDataStd_Comment.hxx>
31 #include <TopTools_IndexedMapOfShape.hxx>
32 #include <TopExp.hxx>
33
34 typedef NCollection_DataMap< TCollection_ExtendedString, NCollection_List<TopoDS_Shape> >
35         DataMapOfStringListOfShape;
36
37 //=============================================================================
38 /*!
39  *  constructor
40  */
41 //=============================================================================
42 GEOMImpl_IBaseIEOperations::GEOMImpl_IBaseIEOperations(GEOM_Engine* theEngine)
43 : GEOM_IOperations(theEngine)
44 {
45   myGroupOperations = new GEOMImpl_IGroupOperations( GetEngine() );
46   myFieldOperations = new GEOMImpl_IFieldOperations( GetEngine() );
47   myShapesOperations = new GEOMImpl_IShapesOperations( GetEngine() );
48 }
49
50 //=============================================================================
51 /*!
52  *  destructor
53  */
54 //=============================================================================
55 GEOMImpl_IBaseIEOperations::~GEOMImpl_IBaseIEOperations()
56 {
57   delete myGroupOperations;
58   delete myFieldOperations;
59   delete myShapesOperations;
60 }
61
62 //=============================================================================
63 /*!
64  *  This method creates material groups for an imported object.
65  *  \param theObject the imported object.
66  */
67 //=============================================================================
68 void GEOMImpl_IBaseIEOperations::MakeMaterialGroups
69                         (const Handle(GEOM_Object) &theObject,
70                          const Handle(TColStd_HSequenceOfTransient) &theSeq)
71 {
72   TopoDS_Shape aResShape = theObject->GetValue();
73
74   if (aResShape.IsNull() == Standard_False) {
75     // Group shapes by material names.
76     Handle(GEOM_Function)      aFunction = theObject->GetLastFunction();
77     DataMapOfStringListOfShape aMapMaterialShapes;
78
79     // check all named shapes using iterator
80     TDF_ChildIDIterator anIt (aFunction->GetNamingEntry(),
81         TNaming_NamedShape::GetID(), Standard_True);
82
83     for (; anIt.More(); anIt.Next()) {
84       Handle(TNaming_NamedShape) anAttr =
85           Handle(TNaming_NamedShape)::DownCast(anIt.Value());
86
87       if (anAttr.IsNull() == Standard_False) {
88         TDF_Label                aLabel = anAttr->Label();
89         Handle(TDataStd_Comment) aComment;
90
91         if (aLabel.FindAttribute(TDataStd_Comment::GetID(), aComment)) {
92           TCollection_ExtendedString aMatName = aComment->Get();
93           TopoDS_Shape               aShape   = anAttr->Get();
94
95           if (aMapMaterialShapes.IsBound(aMatName) == Standard_False) {
96             NCollection_List<TopoDS_Shape> anEmptyList;
97
98             aMapMaterialShapes.Bind(aMatName, anEmptyList);
99           }
100
101           aMapMaterialShapes(aMatName).Append(aShape);
102         }
103       }
104     }
105
106     if (aMapMaterialShapes.IsEmpty() == Standard_False) {
107       // Construct groups.
108       TopAbs_ShapeEnum aType = aResShape.ShapeType();
109       Standard_Integer i;
110       DataMapOfStringListOfShape::Iterator aMapIter;
111
112       // Check each shape type.
113       for(i = aType; i <= TopAbs_VERTEX; i++) {
114         DataMapOfStringListOfShape::Iterator aMapIter(aMapMaterialShapes);
115
116         for (; aMapIter.More(); aMapIter.Next()) {
117           NCollection_List<TopoDS_Shape> &aShList = aMapIter.ChangeValue();
118           NCollection_List<TopoDS_Shape>::Iterator aShIter(aShList);
119           NCollection_List<TopoDS_Shape>  aShListSameType;
120
121           while (aShIter.More()) {
122             const TopoDS_Shape &aShape = aShIter.Value();
123
124             if (i == aShape.ShapeType()) {
125               // Treat this element.
126               aShListSameType.Append(aShape);
127               aShList.Remove(aShIter);
128             } else {
129               // Go to the next element.
130               aShIter.Next();
131             }
132           }
133
134           if (aShListSameType.IsEmpty() == Standard_False) {
135             // Construct a group.
136             Handle(GEOM_Object) aGroup =
137               MakeGroup(theObject, aMapIter.Key(), aShListSameType);
138
139             if (aGroup.IsNull() == Standard_False) {
140               theSeq->Append(aGroup);
141             }
142           }
143         }
144       }
145     }
146   }
147 }
148
149
150 //=============================================================================
151 /*!
152  *  This method creates a group of shapes of certain type.
153  *  \param theObject the imported object.
154  *  \param theName the material name.
155  *  \param theShapes the list of shapes to be added to this group.
156  *  \return the created group.
157  */
158 //=============================================================================
159 Handle(GEOM_Object) GEOMImpl_IBaseIEOperations::MakeGroup
160                   (const Handle(GEOM_Object)            &theObject,
161                    const TCollection_ExtendedString     &theName,
162                    const NCollection_List<TopoDS_Shape> &theShapes)
163 {
164   Handle(GEOM_Object)                aGroup;
165   TopTools_IndexedMapOfShape         anIndices;
166   Handle(TColStd_HSequenceOfInteger) aSeqIDs = new TColStd_HSequenceOfInteger;
167   NCollection_List<TopoDS_Shape>::Iterator anIter(theShapes);
168
169   TopExp::MapShapes(theObject->GetValue(), anIndices);
170
171   // Compose shape IDs.
172   for (; anIter.More(); anIter.Next()) {
173     const TopoDS_Shape &aShape = anIter.Value();
174     const Standard_Integer anIndex = anIndices.FindIndex(aShape);
175
176     if (anIndex > 0) {
177       aSeqIDs->Append(anIndex);
178     }
179   }
180
181   if (aSeqIDs->IsEmpty() == Standard_False) {
182     // Create a group.
183     const TopAbs_ShapeEnum aType  = theShapes.First().ShapeType();
184
185     aGroup = myGroupOperations->CreateGroup(theObject, aType);
186
187     if (aGroup.IsNull() == Standard_False) {
188       aGroup->GetLastFunction()->SetDescription("");
189       myGroupOperations->UnionIDs(aGroup, aSeqIDs);
190       aGroup->GetLastFunction()->SetDescription("");
191
192       // Compose the group name.
193       TCollection_AsciiString aGroupName(theName);
194
195       switch(aType) {
196         case TopAbs_VERTEX:
197           aGroupName += "_VERTEX";
198           break;
199         case TopAbs_EDGE:
200           aGroupName += "_EDGE";
201           break;
202         case TopAbs_WIRE:
203           aGroupName += "_WIRE";
204           break;
205         case TopAbs_FACE:
206           aGroupName += "_FACE";
207           break;
208         case TopAbs_SHELL:
209           aGroupName += "_SHELL";
210           break;
211         case TopAbs_SOLID:
212           aGroupName += "_SOLID";
213           break;
214         case TopAbs_COMPSOLID:
215           aGroupName += "_COMPSOLID";
216           break;
217         case TopAbs_COMPOUND:
218           aGroupName += "_COMPOUND";
219           break;
220         default:
221           aGroupName += "_SHAPE";
222           break;
223       }
224
225       aGroup->SetName(aGroupName.ToCString());
226     }
227   }
228
229   return aGroup;
230 }