Salome HOME
Merge from BR_V5_DEV 16Feb09
[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 using namespace std;
40 using namespace UNV;
41
42 namespace{
43   typedef std::vector<size_t> TConnect;
44
45   int GetConnect(const SMDS_ElemIteratorPtr& theNodesIter, 
46                  TConnect& theConnect)
47   {
48     theConnect.clear();
49     for(; theNodesIter->more();){
50       const SMDS_MeshElement* anElem = theNodesIter->next();
51       theConnect.push_back(anElem->GetID());
52     }
53     return theConnect.size();
54   }
55   
56 }
57
58 Driver_Mesh::Status DriverUNV_W_SMDS_Mesh::Perform()
59 {
60   Status aResult = DRS_OK;
61   std::ofstream out_stream(myFile.c_str());
62   try{
63     {
64       using namespace UNV2411;
65       TDataSet aDataSet2411;
66       // Storing SMDS nodes to the UNV file
67       //-----------------------------------
68       MESSAGE("Perform - myMesh->NbNodes() = "<<myMesh->NbNodes());
69       SMDS_NodeIteratorPtr aNodesIter = myMesh->nodesIterator();
70       for(; aNodesIter->more();){
71         const SMDS_MeshNode* aNode = aNodesIter->next();
72         TRecord aRec;
73         aRec.coord[0] = aNode->X();
74         aRec.coord[1] = aNode->Y();
75         aRec.coord[2] = aNode->Z();
76         const TNodeLab& aLabel = aNode->GetID();
77         aDataSet2411.insert(TDataSet::value_type(aLabel,aRec));
78       }
79       MESSAGE("Perform - aDataSet2411.size() = "<<aDataSet2411.size());
80       UNV2411::Write(out_stream,aDataSet2411);
81     }
82     {
83       using namespace UNV2412;
84       TDataSet aDataSet2412;
85       TConnect aConnect;
86
87       // Storing SMDS Edges
88       MESSAGE("Perform - myMesh->NbEdges() = "<<myMesh->NbEdges());
89       if(myMesh->NbEdges()){
90         SMDS_EdgeIteratorPtr anIter = myMesh->edgesIterator();
91         for(; anIter->more();){
92           const SMDS_MeshEdge* anElem = anIter->next();
93           TElementLab aLabel = anElem->GetID();
94           int aNbNodes = anElem->NbNodes();
95           TRecord aRec;
96           aRec.node_labels.reserve(aNbNodes);
97           SMDS_ElemIteratorPtr aNodesIter;
98           if( anElem->IsQuadratic() ) {
99             aNodesIter = static_cast<const SMDS_QuadraticEdge* >
100               ( anElem )->interlacedNodesElemIterator();
101             aRec.fe_descriptor_id = 22;
102           } else {
103             aNodesIter = anElem->nodesIterator();
104             aRec.fe_descriptor_id = 11;
105           }
106           for(; aNodesIter->more();){
107             const SMDS_MeshElement* aNode = aNodesIter->next();
108             aRec.node_labels.push_back(aNode->GetID());
109           }
110           aDataSet2412.insert(TDataSet::value_type(aLabel,aRec));
111         }
112         MESSAGE("Perform - aDataSet2412.size() = "<<aDataSet2412.size());
113       }
114
115       MESSAGE("Perform - myMesh->NbFaces() = "<<myMesh->NbFaces());
116       if(myMesh->NbFaces()){
117         SMDS_FaceIteratorPtr anIter = myMesh->facesIterator();
118         for(; anIter->more();){
119           const SMDS_MeshFace* anElem = anIter->next();
120           TElementLab aLabel = anElem->GetID();
121           int aNbNodes = anElem->NbNodes();
122           TRecord aRec;
123           aRec.node_labels.reserve(aNbNodes);
124           SMDS_ElemIteratorPtr aNodesIter;
125           if( anElem->IsQuadratic() )
126             aNodesIter = static_cast<const SMDS_QuadraticFaceOfNodes* >
127               ( anElem )->interlacedNodesElemIterator();
128           else
129             aNodesIter = anElem->nodesIterator();
130           for(; aNodesIter->more();){
131             const SMDS_MeshElement* aNode = aNodesIter->next();
132             aRec.node_labels.push_back(aNode->GetID());
133           }
134           switch(aNbNodes){
135           case 3:
136             aRec.fe_descriptor_id = 41;
137             break;
138           case 4:
139             aRec.fe_descriptor_id = 44;
140             break;
141           case 6:
142             aRec.fe_descriptor_id = 42;
143             break;
144           case 8:
145             aRec.fe_descriptor_id = 45;
146             break;
147           default:
148             continue;
149           }
150           aDataSet2412.insert(TDataSet::value_type(aLabel,aRec));
151         }
152         MESSAGE("Perform - aDataSet2412.size() = "<<aDataSet2412.size());
153       }
154
155       MESSAGE("Perform - myMesh->NbVolumes() = "<<myMesh->NbVolumes());
156       if(myMesh->NbVolumes()){
157         SMDS_VolumeIteratorPtr anIter = myMesh->volumesIterator();
158         for(; anIter->more();){
159           const SMDS_MeshVolume* anElem = anIter->next();
160           TElementLab aLabel = anElem->GetID();
161
162           int aNbNodes = anElem->NbNodes();
163           SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIterator();
164           if ( anElem->IsPoly() ) {
165             if ( const SMDS_PolyhedralVolumeOfNodes* ph =
166                  dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*> (anElem))
167             {
168               aNbNodes = ph->NbUniqueNodes();
169               aNodesIter = ph->uniqueNodesIterator();
170             }
171           }
172           aConnect.resize(aNbNodes);
173           GetConnect(aNodesIter,aConnect);
174
175           int anId = -1;
176           int* aConn = NULL;
177           switch(aNbNodes){
178           case 4: {
179             static int anIds[] = {0,2,1,3};
180             aConn = anIds;
181             anId = 111;
182             break;
183           }
184           case 6: {
185             static int anIds[] = {0,2,1,3,5,4};
186             aConn = anIds;
187             anId = 112;
188             break;
189           }
190           case 8: {
191             static int anIds[] = {0,3,2,1,4,7,6,5};
192             aConn = anIds;
193             anId = 115;
194             break;
195           }
196           case 10: {
197             static int anIds[] = {0,4,2,9,5,3, 1,6,8, 7};
198             aConn = anIds;
199             anId = 118;
200             break;
201           }
202           case 13: {
203             static int anIds[] = {0,6,4,2,7,5,3,1,8,11,10,9,12};
204             aConn = anIds;
205             anId = 114;
206             break;
207           }
208           case 15: {
209             static int anIds[] = {0,4,2,9,13,11,5,3,1,14,12,10,6,8,7};
210             aConn = anIds;
211             anId = 113;
212             break;
213           }
214           case 20: {
215             static int anIds[] = {0,6, 4,2, 12,18,16,14,7, 5, 3, 1, 19,17,15,13,8, 11,10,9};
216             aConn = anIds;
217             anId = 116;
218             break;
219           }
220           default:
221             continue;
222           }
223           if(aConn){
224             TRecord aRec;
225             aRec.fe_descriptor_id = anId;
226             aRec.node_labels.resize(aNbNodes);
227             for(int aNodeId = 0; aNodeId < aNbNodes; aNodeId++){
228               aRec.node_labels[aConn[aNodeId]] = aConnect[aNodeId];
229             }
230             aDataSet2412.insert(TDataSet::value_type(aLabel,aRec));
231           }
232         }
233         MESSAGE("Perform - aDataSet2412.size() = "<<aDataSet2412.size());
234       }
235       UNV2412::Write(out_stream,aDataSet2412);
236     }
237     {
238       using namespace UNV2417;
239       if (myGroups.size() > 0) {
240         TDataSet aDataSet2417;
241         TGroupList::const_iterator aIter = myGroups.begin();
242         for (; aIter != myGroups.end(); aIter++) {
243           SMESHDS_GroupBase* aGroupDS = *aIter;
244           TRecord aRec;
245           aRec.GroupName = aGroupDS->GetStoreName();
246
247           int i;
248           SMDS_ElemIteratorPtr aIter = aGroupDS->GetElements();
249           if (aGroupDS->GetType() == SMDSAbs_Node) {
250             aRec.NodeList.resize(aGroupDS->Extent());
251             i = 0;
252             while (aIter->more()) {
253               const SMDS_MeshElement* aElem = aIter->next();
254               aRec.NodeList[i] = aElem->GetID(); 
255               i++;
256             }
257           } else {
258             aRec.ElementList.resize(aGroupDS->Extent());
259             i = 0;
260             while (aIter->more()) {
261               const SMDS_MeshElement* aElem = aIter->next();
262               aRec.ElementList[i] = aElem->GetID(); 
263               i++;
264             }
265           }
266           aDataSet2417.insert(TDataSet::value_type(aGroupDS->GetID(), aRec));
267         }
268         UNV2417::Write(out_stream,aDataSet2417);
269         myGroups.clear();
270       }
271     }
272     /*    {
273       using namespace UNV2417;
274       TDataSet aDataSet2417;
275       for ( TGroupsMap::iterator it = myGroupsMap.begin(); it != myGroupsMap.end(); it++ ) {
276         SMESH_Group*       aGroup   = it->second;
277         SMESHDS_GroupBase* aGroupDS = aGroup->GetGroupDS();
278         if ( aGroupDS ) {
279           TRecord aRec;
280           aRec.GroupName = aGroup->GetName();
281           int i;
282           SMDS_ElemIteratorPtr aIter = aGroupDS->GetElements();
283           if (aGroupDS->GetType() == SMDSAbs_Node) {
284             aRec.NodeList.resize(aGroupDS->Extent());
285             i = 0;
286             while (aIter->more()) {
287               const SMDS_MeshElement* aElem = aIter->next();
288               aRec.NodeList[i] = aElem->GetID(); 
289               i++;
290             }
291           } else {
292             aRec.ElementList.resize(aGroupDS->Extent());
293             i = 0;
294             while (aIter->more()) {
295               const SMDS_MeshElement* aElem = aIter->next();
296               aRec.ElementList[i] = aElem->GetID(); 
297               i++;
298             }
299           }
300           aDataSet2417.insert(TDataSet::value_type(aGroupDS->GetID(), aRec));
301         }
302       }
303       UNV2417::Write(out_stream,aDataSet2417);
304       }*/
305
306     out_stream.flush();
307     out_stream.close();
308     if (!check_file(myFile))
309       EXCEPTION(runtime_error,"ERROR: Output file not good.");
310   }
311   catch(const std::exception& exc){
312     INFOS("Follow exception was cought:\n\t"<<exc.what());
313     throw;
314   }
315   catch(...){
316     INFOS("Unknown exception was cought !!!");
317     throw;
318   }
319   return aResult;
320 }