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