Salome HOME
Merge from V5_1_3_BR branch (07/12/09)
[modules/smesh.git] / src / DriverUNV / DriverUNV_W_SMDS_Mesh.cxx
1 //  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 //  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 //  This library is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU Lesser General Public
8 //  License as published by the Free Software Foundation; either
9 //  version 2.1 of the License.
10 //
11 //  This library is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 //  Lesser General Public License for more details.
15 //
16 //  You should have received a copy of the GNU Lesser General Public
17 //  License along with this library; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 #include <algorithm>
23
24 #include "DriverUNV_W_SMDS_Mesh.h"
25
26 #include "SMDS_Mesh.hxx"
27 #include "SMDS_QuadraticEdge.hxx"
28 #include "SMDS_QuadraticFaceOfNodes.hxx"
29 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
30 #include "SMESHDS_GroupBase.hxx"
31
32 #include "utilities.h"
33
34 #include "UNV2411_Structure.hxx"
35 #include "UNV2412_Structure.hxx"
36 #include "UNV2417_Structure.hxx"
37 #include "UNV_Utilities.hxx"
38
39 #include <Basics_Utils.hxx>
40
41 using namespace std;
42 using namespace UNV;
43
44 namespace{
45   typedef std::vector<size_t> TConnect;
46
47   int GetConnect(const SMDS_ElemIteratorPtr& theNodesIter, 
48                  TConnect& theConnect)
49   {
50     theConnect.clear();
51     for(; theNodesIter->more();){
52       const SMDS_MeshElement* anElem = theNodesIter->next();
53       theConnect.push_back(anElem->GetID());
54     }
55     return theConnect.size();
56   }
57   
58 }
59
60 Driver_Mesh::Status DriverUNV_W_SMDS_Mesh::Perform()
61 {
62   Kernel_Utils::Localizer loc;
63   Status aResult = DRS_OK;
64   std::ofstream out_stream(myFile.c_str());
65   try{
66     {
67       using namespace UNV2411;
68       TDataSet aDataSet2411;
69       // Storing SMDS nodes to the UNV file
70       //-----------------------------------
71       MESSAGE("Perform - myMesh->NbNodes() = "<<myMesh->NbNodes());
72       SMDS_NodeIteratorPtr aNodesIter = myMesh->nodesIterator();
73       for(; aNodesIter->more();){
74         const SMDS_MeshNode* aNode = aNodesIter->next();
75         TRecord aRec;
76         aRec.coord[0] = aNode->X();
77         aRec.coord[1] = aNode->Y();
78         aRec.coord[2] = aNode->Z();
79         const TNodeLab& aLabel = aNode->GetID();
80         aDataSet2411.insert(TDataSet::value_type(aLabel,aRec));
81       }
82       MESSAGE("Perform - aDataSet2411.size() = "<<aDataSet2411.size());
83       UNV2411::Write(out_stream,aDataSet2411);
84     }
85     {
86       using namespace UNV2412;
87       TDataSet aDataSet2412;
88       TConnect aConnect;
89
90       // Storing SMDS Edges
91       MESSAGE("Perform - myMesh->NbEdges() = "<<myMesh->NbEdges());
92       if(myMesh->NbEdges()){
93         SMDS_EdgeIteratorPtr anIter = myMesh->edgesIterator();
94         for(; anIter->more();){
95           const SMDS_MeshEdge* anElem = anIter->next();
96           TElementLab aLabel = anElem->GetID();
97           int aNbNodes = anElem->NbNodes();
98           TRecord aRec;
99           aRec.node_labels.reserve(aNbNodes);
100           SMDS_ElemIteratorPtr aNodesIter;
101           if( anElem->IsQuadratic() ) {
102             aNodesIter = static_cast<const SMDS_QuadraticEdge* >
103               ( anElem )->interlacedNodesElemIterator();
104             aRec.fe_descriptor_id = 22;
105           } else {
106             aNodesIter = anElem->nodesIterator();
107             aRec.fe_descriptor_id = 11;
108           }
109           for(; aNodesIter->more();){
110             const SMDS_MeshElement* aNode = aNodesIter->next();
111             aRec.node_labels.push_back(aNode->GetID());
112           }
113           aDataSet2412.insert(TDataSet::value_type(aLabel,aRec));
114         }
115         MESSAGE("Perform - aDataSet2412.size() = "<<aDataSet2412.size());
116       }
117
118       MESSAGE("Perform - myMesh->NbFaces() = "<<myMesh->NbFaces());
119       if(myMesh->NbFaces()){
120         SMDS_FaceIteratorPtr anIter = myMesh->facesIterator();
121         for(; anIter->more();){
122           const SMDS_MeshFace* anElem = anIter->next();
123           TElementLab aLabel = anElem->GetID();
124           int aNbNodes = anElem->NbNodes();
125           TRecord aRec;
126           aRec.node_labels.reserve(aNbNodes);
127           SMDS_ElemIteratorPtr aNodesIter;
128           if( anElem->IsQuadratic() )
129             aNodesIter = static_cast<const SMDS_QuadraticFaceOfNodes* >
130               ( anElem )->interlacedNodesElemIterator();
131           else
132             aNodesIter = anElem->nodesIterator();
133           for(; aNodesIter->more();){
134             const SMDS_MeshElement* aNode = aNodesIter->next();
135             aRec.node_labels.push_back(aNode->GetID());
136           }
137           switch(aNbNodes){
138           case 3:
139             aRec.fe_descriptor_id = 41;
140             break;
141           case 4:
142             aRec.fe_descriptor_id = 44;
143             break;
144           case 6:
145             aRec.fe_descriptor_id = 42;
146             break;
147           case 8:
148             aRec.fe_descriptor_id = 45;
149             break;
150           default:
151             continue;
152           }
153           aDataSet2412.insert(TDataSet::value_type(aLabel,aRec));
154         }
155         MESSAGE("Perform - aDataSet2412.size() = "<<aDataSet2412.size());
156       }
157
158       MESSAGE("Perform - myMesh->NbVolumes() = "<<myMesh->NbVolumes());
159       if(myMesh->NbVolumes()){
160         SMDS_VolumeIteratorPtr anIter = myMesh->volumesIterator();
161         for(; anIter->more();){
162           const SMDS_MeshVolume* anElem = anIter->next();
163           TElementLab aLabel = anElem->GetID();
164
165           int aNbNodes = anElem->NbNodes();
166           SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIterator();
167           if ( anElem->IsPoly() ) {
168             if ( const SMDS_PolyhedralVolumeOfNodes* ph =
169                  dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*> (anElem))
170             {
171               aNbNodes = ph->NbUniqueNodes();
172               aNodesIter = ph->uniqueNodesIterator();
173             }
174           }
175           aConnect.resize(aNbNodes);
176           GetConnect(aNodesIter,aConnect);
177
178           int anId = -1;
179           int* aConn = NULL;
180           switch(aNbNodes){
181           case 4: {
182             static int anIds[] = {0,2,1,3};
183             aConn = anIds;
184             anId = 111;
185             break;
186           }
187           case 6: {
188             static int anIds[] = {0,2,1,3,5,4};
189             aConn = anIds;
190             anId = 112;
191             break;
192           }
193           case 8: {
194             static int anIds[] = {0,3,2,1,4,7,6,5};
195             aConn = anIds;
196             anId = 115;
197             break;
198           }
199           case 10: {
200             static int anIds[] = {0,4,2,9,5,3, 1,6,8, 7};
201             aConn = anIds;
202             anId = 118;
203             break;
204           }
205           case 13: {
206             static int anIds[] = {0,6,4,2,7,5,3,1,8,11,10,9,12};
207             aConn = anIds;
208             anId = 114;
209             break;
210           }
211           case 15: {
212             static int anIds[] = {0,4,2,9,13,11,5,3,1,14,12,10,6,8,7};
213             aConn = anIds;
214             anId = 113;
215             break;
216           }
217           case 20: {
218             static int anIds[] = {0,6, 4,2, 12,18,16,14,7, 5, 3, 1, 19,17,15,13,8, 11,10,9};
219             aConn = anIds;
220             anId = 116;
221             break;
222           }
223           default:
224             continue;
225           }
226           if(aConn){
227             TRecord aRec;
228             aRec.fe_descriptor_id = anId;
229             aRec.node_labels.resize(aNbNodes);
230             for(int aNodeId = 0; aNodeId < aNbNodes; aNodeId++){
231               aRec.node_labels[aConn[aNodeId]] = aConnect[aNodeId];
232             }
233             aDataSet2412.insert(TDataSet::value_type(aLabel,aRec));
234           }
235         }
236         MESSAGE("Perform - aDataSet2412.size() = "<<aDataSet2412.size());
237       }
238       UNV2412::Write(out_stream,aDataSet2412);
239     }
240     {
241       using namespace UNV2417;
242       if (myGroups.size() > 0) {
243         TDataSet aDataSet2417;
244         TGroupList::const_iterator aIter = myGroups.begin();
245         for (; aIter != myGroups.end(); aIter++) {
246           SMESHDS_GroupBase* aGroupDS = *aIter;
247           TRecord aRec;
248           aRec.GroupName = aGroupDS->GetStoreName();
249
250           int i;
251           SMDS_ElemIteratorPtr aIter = aGroupDS->GetElements();
252           if (aGroupDS->GetType() == SMDSAbs_Node) {
253             aRec.NodeList.resize(aGroupDS->Extent());
254             i = 0;
255             while (aIter->more()) {
256               const SMDS_MeshElement* aElem = aIter->next();
257               aRec.NodeList[i] = aElem->GetID(); 
258               i++;
259             }
260           } else {
261             aRec.ElementList.resize(aGroupDS->Extent());
262             i = 0;
263             while (aIter->more()) {
264               const SMDS_MeshElement* aElem = aIter->next();
265               aRec.ElementList[i] = aElem->GetID(); 
266               i++;
267             }
268           }
269           // 0019936: EDF 794 SMESH : Export UNV : Node color and group id
270           //aDataSet2417.insert(TDataSet::value_type(aGroupDS->GetID(), aRec));
271           aDataSet2417.insert(TDataSet::value_type(aGroupDS->GetID()+1, aRec));
272         }
273         UNV2417::Write(out_stream,aDataSet2417);
274         myGroups.clear();
275       }
276     }
277     /*    {
278       using namespace UNV2417;
279       TDataSet aDataSet2417;
280       for ( TGroupsMap::iterator it = myGroupsMap.begin(); it != myGroupsMap.end(); it++ ) {
281         SMESH_Group*       aGroup   = it->second;
282         SMESHDS_GroupBase* aGroupDS = aGroup->GetGroupDS();
283         if ( aGroupDS ) {
284           TRecord aRec;
285           aRec.GroupName = aGroup->GetName();
286           int i;
287           SMDS_ElemIteratorPtr aIter = aGroupDS->GetElements();
288           if (aGroupDS->GetType() == SMDSAbs_Node) {
289             aRec.NodeList.resize(aGroupDS->Extent());
290             i = 0;
291             while (aIter->more()) {
292               const SMDS_MeshElement* aElem = aIter->next();
293               aRec.NodeList[i] = aElem->GetID(); 
294               i++;
295             }
296           } else {
297             aRec.ElementList.resize(aGroupDS->Extent());
298             i = 0;
299             while (aIter->more()) {
300               const SMDS_MeshElement* aElem = aIter->next();
301               aRec.ElementList[i] = aElem->GetID(); 
302               i++;
303             }
304           }
305           aDataSet2417.insert(TDataSet::value_type(aGroupDS->GetID(), aRec));
306         }
307       }
308       UNV2417::Write(out_stream,aDataSet2417);
309       }*/
310
311     out_stream.flush();
312     out_stream.close();
313     if (!check_file(myFile))
314       EXCEPTION(runtime_error,"ERROR: Output file not good.");
315   }
316   catch(const std::exception& exc){
317     INFOS("Follow exception was cought:\n\t"<<exc.what());
318     throw;
319   }
320   catch(...){
321     INFOS("Unknown exception was cought !!!");
322     throw;
323   }
324   return aResult;
325 }