Salome HOME
fix reading/writting quadratic edges
[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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
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
28 #include "utilities.h"
29
30 #include "UNV2411_Structure.hxx"
31 #include "UNV2412_Structure.hxx"
32 #include "UNV_Utilities.hxx"
33
34 using namespace std;
35
36 namespace{
37   typedef std::vector<size_t> TConnect;
38
39   int GetConnect(const SMDS_ElemIteratorPtr& theNodesIter, 
40                  TConnect& theConnect)
41   {
42     theConnect.clear();
43     for(; theNodesIter->more();){
44       const SMDS_MeshElement* anElem = theNodesIter->next();
45       theConnect.push_back(anElem->GetID());
46     }
47     return theConnect.size();
48   }
49   
50 }
51
52 Driver_Mesh::Status DriverUNV_W_SMDS_Mesh::Perform()
53 {
54   Status aResult = DRS_OK;
55   std::ofstream out_stream(myFile.c_str());
56   try{
57     {
58       using namespace UNV2411;
59       TDataSet aDataSet2411;
60       // Storing SMDS nodes to the UNV file
61       //-----------------------------------
62       MESSAGE("Perform - myMesh->NbNodes() = "<<myMesh->NbNodes());
63       SMDS_NodeIteratorPtr aNodesIter = myMesh->nodesIterator();
64       for(; aNodesIter->more();){
65         const SMDS_MeshNode* aNode = aNodesIter->next();
66         TRecord aRec;
67         aRec.coord[0] = aNode->X();
68         aRec.coord[1] = aNode->Y();
69         aRec.coord[2] = aNode->Z();
70         const TNodeLab& aLabel = aNode->GetID();
71         aDataSet2411.insert(TDataSet::value_type(aLabel,aRec));
72       }
73       MESSAGE("Perform - aDataSet2411.size() = "<<aDataSet2411.size());
74       UNV2411::Write(out_stream,aDataSet2411);
75     }
76     {
77       using namespace UNV2412;
78       TDataSet aDataSet2412;
79       TConnect aConnect;
80
81       // Storing SMDS Edges
82       MESSAGE("Perform - myMesh->NbEdges() = "<<myMesh->NbEdges());
83       if(myMesh->NbEdges()){
84         SMDS_EdgeIteratorPtr anIter = myMesh->edgesIterator();
85         for(; anIter->more();){
86           const SMDS_MeshEdge* anElem = anIter->next();
87           TElementLab aLabel = anElem->GetID();
88           int aNbNodes = anElem->NbNodes();
89           TRecord aRec;
90           aRec.node_labels.reserve(aNbNodes);
91           SMDS_ElemIteratorPtr aNodesIter;
92           if( anElem->IsQuadratic() ) {
93             aNodesIter = static_cast<const SMDS_QuadraticEdge* >
94               ( anElem )->interlacedNodesElemIterator();
95             aRec.fe_descriptor_id = 22;
96           } else {
97             aNodesIter = anElem->nodesIterator();
98             aRec.fe_descriptor_id = 11;
99           }
100           for(; aNodesIter->more();){
101             const SMDS_MeshElement* aNode = aNodesIter->next();
102             aRec.node_labels.push_back(aNode->GetID());
103           }
104           aDataSet2412.insert(TDataSet::value_type(aLabel,aRec));
105         }
106         MESSAGE("Perform - aDataSet2412.size() = "<<aDataSet2412.size());
107       }
108
109       MESSAGE("Perform - myMesh->NbFaces() = "<<myMesh->NbFaces());
110       if(myMesh->NbFaces()){
111         SMDS_FaceIteratorPtr anIter = myMesh->facesIterator();
112         for(; anIter->more();){
113           const SMDS_MeshFace* anElem = anIter->next();
114           TElementLab aLabel = anElem->GetID();
115           int aNbNodes = anElem->NbNodes();
116           TRecord aRec;
117           aRec.node_labels.reserve(aNbNodes);
118           SMDS_ElemIteratorPtr aNodesIter;
119           if( anElem->IsQuadratic() )
120             aNodesIter = static_cast<const SMDS_QuadraticFaceOfNodes* >
121               ( anElem )->interlacedNodesElemIterator();
122           else
123             aNodesIter = anElem->nodesIterator();
124           for(; aNodesIter->more();){
125             const SMDS_MeshElement* aNode = aNodesIter->next();
126             aRec.node_labels.push_back(aNode->GetID());
127           }
128           switch(aNbNodes){
129           case 3:
130             aRec.fe_descriptor_id = 41;
131             break;
132           case 4:
133             aRec.fe_descriptor_id = 44;
134             break;
135           case 6:
136             aRec.fe_descriptor_id = 42;
137             break;
138           case 8:
139             aRec.fe_descriptor_id = 45;
140             break;
141           default:
142             continue;
143           }
144           aDataSet2412.insert(TDataSet::value_type(aLabel,aRec));
145         }
146         MESSAGE("Perform - aDataSet2412.size() = "<<aDataSet2412.size());
147       }
148
149       MESSAGE("Perform - myMesh->NbVolumes() = "<<myMesh->NbVolumes());
150       if(myMesh->NbVolumes()){
151         SMDS_VolumeIteratorPtr anIter = myMesh->volumesIterator();
152         for(; anIter->more();){
153           const SMDS_MeshVolume* anElem = anIter->next();
154           TElementLab aLabel = anElem->GetID();
155
156           int aNbNodes = anElem->NbNodes();
157           aConnect.resize(aNbNodes);
158
159           SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIterator();
160           GetConnect(aNodesIter,aConnect);
161
162           int anId = -1;
163           int* aConn = NULL;
164           switch(aNbNodes){
165           case 4: {
166             static int anIds[] = {0,2,1,3};
167             aConn = anIds;
168             anId = 111;
169             break;
170           }
171           case 6: {
172             static int anIds[] = {0,2,1,3,5,4};
173             aConn = anIds;
174             anId = 112;
175             break;
176           }
177           case 8: {
178             static int anIds[] = {0,3,2,1,4,7,6,5};
179             aConn = anIds;
180             anId = 115;
181             break;
182           }
183           case 10: {
184             static int anIds[] = {0,4,2,9,5,3, 1,6,8, 7};
185             aConn = anIds;
186             anId = 118;
187             break;
188           }
189           case 13: {
190             static int anIds[] = {0,6,4,2,7,5,3,1,8,11,10,9,12};
191             aConn = anIds;
192             anId = 114;
193             break;
194           }
195           case 15: {
196             static int anIds[] = {0,4,2,9,13,11,5,3,1,14,12,10,6,8,7};
197             aConn = anIds;
198             anId = 113;
199             break;
200           }
201           case 20: {
202             static int anIds[] = {0,6, 4,2, 12,18,16,14,7, 5, 3, 1, 19,17,15,13,8, 11,10,9};
203             aConn = anIds;
204             anId = 116;
205             break;
206           }
207           default:
208             continue;
209           }
210           if(aConn){
211             TRecord aRec;
212             aRec.fe_descriptor_id = anId;
213             aRec.node_labels.resize(aNbNodes);
214             for(int aNodeId = 0; aNodeId < aNbNodes; aNodeId++){
215               aRec.node_labels[aConn[aNodeId]] = aConnect[aNodeId];
216             }
217             aDataSet2412.insert(TDataSet::value_type(aLabel,aRec));
218           }
219         }
220         MESSAGE("Perform - aDataSet2412.size() = "<<aDataSet2412.size());
221       }
222       UNV2412::Write(out_stream,aDataSet2412);
223     }
224   }
225   catch(const std::exception& exc){
226     INFOS("Follow exception was cought:\n\t"<<exc.what());
227   }
228   catch(...){
229     INFOS("Unknown exception was cought !!!");
230   }
231   return aResult;
232 }