Salome HOME
Copyright update 2021
[modules/smesh.git] / src / DriverUNV / DriverUNV_W_SMDS_Mesh.cxx
1 // Copyright (C) 2007-2021  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, or (at your option) any later version.
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 "SMESHDS_GroupBase.hxx"
29
30 #include "utilities.h"
31
32 #include "UNV164_Structure.hxx"
33 #include "UNV2411_Structure.hxx"
34 #include "UNV2412_Structure.hxx"
35 #include "UNV2417_Structure.hxx"
36 #include "UNV2420_Structure.hxx"
37 #include "UNV_Utilities.hxx"
38
39 #include <Basics_Utils.hxx>
40
41 using namespace std;
42 using namespace UNV;
43
44 Driver_Mesh::Status DriverUNV_W_SMDS_Mesh::Perform()
45 {
46   Kernel_Utils::Localizer loc;
47   Status aResult = DRS_OK;
48 #if defined(WIN32) && defined(UNICODE)
49   std::wstring aFile = Kernel_Utils::utf8_decode_s(myFile);
50   std::ofstream out_stream(aFile.c_str());
51 #else
52   std::ofstream out_stream(myFile.c_str());
53 #endif
54   try{
55
56     UNV164::Write( out_stream ); // unit system
57     UNV2420::Write( out_stream, myMeshName ); // Coordinate system
58
59     std::vector< size_t > nodeLabelByID;
60     if ( myMesh->HasNumerationHoles() )
61       nodeLabelByID.resize( myMesh->MaxNodeID() + 1 );
62
63     {
64       using namespace UNV2411;
65       TDataSet aDataSet2411;
66       // -----------------------------------
67       // Storing SMDS nodes to the UNV file
68       // -----------------------------------
69       SMDS_NodeIteratorPtr aNodesIter = myMesh->nodesIterator();
70       TRecord aRec;
71       for ( aRec.label = 1; aNodesIter->more(); ++aRec.label )
72       {
73         const SMDS_MeshNode* aNode = aNodesIter->next();
74         // aRec.label    = aNode->GetID(); -- IPAL54452
75         if ( !nodeLabelByID.empty() )
76           nodeLabelByID[ aNode->GetID() ] = aRec.label;
77         aRec.coord[0] = aNode->X();
78         aRec.coord[1] = aNode->Y();
79         aRec.coord[2] = aNode->Z();
80         aDataSet2411.push_back( aRec );
81       }
82       UNV2411::Write(out_stream,aDataSet2411);
83     }
84
85     std::vector< size_t > elemLabelByID;
86     if ( !myGroups.empty() )
87       elemLabelByID.resize( myMesh->MaxElementID() + 1 );
88
89     {
90       using namespace UNV2412;
91       TDataSet aDataSet2412;
92       TRecord aRec;
93       aRec.label = 0;
94
95       // -------------------
96       // Storing SMDS Edges
97       // -------------------
98       if ( myMesh->NbEdges() )
99       {
100         SMDS_EdgeIteratorPtr anIter = myMesh->edgesIterator();
101         while ( anIter->more() )
102         {
103           const SMDS_MeshEdge* anElem = anIter->next();
104           // aRec.label = anElem->GetID();  -- IPAL54452
105           ++aRec.label;
106           if ( !elemLabelByID.empty() )
107             elemLabelByID[ anElem->GetID() ] = aRec.label;
108
109           aRec.fe_descriptor_id = anElem->IsQuadratic() ? 22 : 11;
110
111           SMDS_NodeIteratorPtr aNodesIter = anElem->nodesIteratorToUNV();
112           for ( aRec.node_labels.clear(); aNodesIter->more(); )
113           {
114             const SMDS_MeshNode* aNode = aNodesIter->next();
115             if ( nodeLabelByID.empty() )
116               aRec.node_labels.push_back( aNode->GetID() );
117             else
118               aRec.node_labels.push_back( nodeLabelByID[ aNode->GetID() ]);
119           }
120
121           aDataSet2412.push_back(aRec);
122         }
123       }
124
125       // -------------------
126       // Storing SMDS Faces
127       // -------------------
128       if ( myMesh->NbFaces() )
129       {
130         SMDS_FaceIteratorPtr anIter = myMesh->facesIterator();
131         while ( anIter->more() )
132         {
133           const SMDS_MeshFace* anElem = anIter->next();
134           if ( anElem->IsPoly() ) continue;
135
136           SMDS_NodeIteratorPtr aNodesIter = anElem->nodesIteratorToUNV();
137           for ( aRec.node_labels.clear(); aNodesIter->more();  ) {
138             const SMDS_MeshNode* aNode = aNodesIter->next();
139             if ( nodeLabelByID.empty() )
140               aRec.node_labels.push_back( aNode->GetID() );
141             else
142               aRec.node_labels.push_back( nodeLabelByID[ aNode->GetID() ]);
143           }
144           switch ( anElem->NbNodes() ) {
145           case 3: aRec.fe_descriptor_id = 41; break;
146           case 4: aRec.fe_descriptor_id = 44; break;
147           case 6: aRec.fe_descriptor_id = 42; break;
148           case 7: aRec.fe_descriptor_id = 42; break;
149           case 8: aRec.fe_descriptor_id = 45; break;
150           case 9: aRec.fe_descriptor_id = 45; aRec.node_labels.resize( 8 ); break;
151           default:
152             continue;
153           }
154           // aRec.label = anElem->GetID(); -- IPAL54452
155           ++aRec.label;
156           if ( !elemLabelByID.empty() )
157             elemLabelByID[ anElem->GetID() ] = aRec.label;
158
159           aDataSet2412.push_back(aRec);
160         }
161       }
162
163       // ---------------------
164       // Storing SMDS Volumes
165       // ---------------------
166       if ( myMesh->NbVolumes() )
167       {
168         SMDS_VolumeIteratorPtr anIter = myMesh->volumesIterator();
169         while ( anIter->more() )
170         {
171           const SMDS_MeshVolume* anElem = anIter->next();
172           if ( anElem->IsPoly() )
173             continue;
174           size_t aNbNodes = anElem->NbNodes();
175           switch( aNbNodes ) {
176           case 4:  aRec.fe_descriptor_id = 111; break;
177           case 6:  aRec.fe_descriptor_id = 112; break;
178           case 8:  aRec.fe_descriptor_id = 115; break;
179           case 10: aRec.fe_descriptor_id = 118; break;
180           case 13: aRec.fe_descriptor_id = 114; break;
181           case 15: aRec.fe_descriptor_id = 113; break;
182           case 20:
183           case 27: aRec.fe_descriptor_id = 116; aNbNodes = 20; break;
184           default:
185             continue;
186           }
187           // aRec.label = anElem->GetID(); -- IPAL54452
188           ++aRec.label;
189           if ( !elemLabelByID.empty() )
190             elemLabelByID[  anElem->GetID() ] = aRec.label;
191
192           aRec.node_labels.clear();
193           SMDS_NodeIteratorPtr aNodesIter = anElem->nodesIteratorToUNV();
194           while ( aNodesIter->more() && aRec.node_labels.size() < aNbNodes )
195           {
196             const SMDS_MeshElement* aNode = aNodesIter->next();
197             if ( nodeLabelByID.empty() )
198               aRec.node_labels.push_back( aNode->GetID() );
199             else
200               aRec.node_labels.push_back( nodeLabelByID[ aNode->GetID() ]);
201           }
202           aDataSet2412.push_back(aRec);
203         }
204       }
205       UNV2412::Write(out_stream,aDataSet2412);
206     }
207
208     // --------------------
209     // Storing SMDS Groups
210     // --------------------
211     {
212       using namespace UNV2417;
213       if ( myGroups.size() > 0 ) {
214         TRecord aRec;
215         TDataSet aDataSet2417;
216         TGroupList::const_iterator aIter = myGroups.begin();
217         for ( ; aIter != myGroups.end(); aIter++ )
218         {
219           SMESHDS_GroupBase* aGroupDS = *aIter;
220           aRec.GroupName = aGroupDS->GetStoreName();
221           aRec.NodeList.clear();
222           aRec.ElementList.clear();
223
224           SMDS_ElemIteratorPtr aIter = aGroupDS->GetElements();
225           if ( aGroupDS->GetType() == SMDSAbs_Node ) {
226             while ( aIter->more() ) {
227               const SMDS_MeshElement* aNode = aIter->next();
228               if ( nodeLabelByID.empty() )
229                 aRec.NodeList.push_back( aNode->GetID() );
230               else
231                 aRec.NodeList.push_back( nodeLabelByID[ aNode->GetID() ]);
232             }
233           }
234           else
235           {
236             while ( aIter->more() ) {
237               const SMDS_MeshElement* aElem = aIter->next();
238               if ( elemLabelByID.empty() )
239                 aRec.ElementList.push_back( aElem->GetID() );
240               else
241                 aRec.ElementList.push_back( elemLabelByID[ aElem->GetID() ]);
242             }
243           }
244           // 0019936: EDF 794 SMESH : Export UNV : Node color and group id
245           //aDataSet2417.insert(TDataSet::value_type(aGroupDS->GetID(), aRec));
246           aDataSet2417.insert(TDataSet::value_type(aGroupDS->GetID()+1, aRec));
247         }
248         UNV2417::Write(out_stream,aDataSet2417);
249         myGroups.clear();
250       }
251     }
252
253     out_stream.flush();
254     out_stream.close();
255     if (!check_file(myFile))
256       EXCEPTION(runtime_error,"ERROR: Output file not good.");
257   }
258   catch(const std::exception& exc){
259     INFOS("Follow exception was cought:\n\t"<<exc.what());
260     throw;
261   }
262   catch(...){
263     INFOS("Unknown exception was cought !!!");
264     throw;
265   }
266   return aResult;
267 }