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