LCOV - code coverage report
Current view: top level - ugbase/lib_grid/file_io - file_io.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 327 0
Test Date: 2025-09-21 23:31:46 Functions: 0.0 % 62 0

            Line data    Source code
       1              : /*
       2              :  * Copyright (c) 2009-2015:  G-CSC, Goethe University Frankfurt
       3              :  * Author: Sebastian Reiter
       4              :  * 
       5              :  * This file is part of UG4.
       6              :  * 
       7              :  * UG4 is free software: you can redistribute it and/or modify it under the
       8              :  * terms of the GNU Lesser General Public License version 3 (as published by the
       9              :  * Free Software Foundation) with the following additional attribution
      10              :  * requirements (according to LGPL/GPL v3 §7):
      11              :  * 
      12              :  * (1) The following notice must be displayed in the Appropriate Legal Notices
      13              :  * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
      14              :  * 
      15              :  * (2) The following notice must be displayed at a prominent place in the
      16              :  * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
      17              :  * 
      18              :  * (3) The following bibliography is recommended for citation and must be
      19              :  * preserved in all covered files:
      20              :  * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
      21              :  *   parallel geometric multigrid solver on hierarchically distributed grids.
      22              :  *   Computing and visualization in science 16, 4 (2013), 151-164"
      23              :  * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
      24              :  *   flexible software system for simulating pde based models on high performance
      25              :  *   computers. Computing and visualization in science 16, 4 (2013), 165-179"
      26              :  * 
      27              :  * This program is distributed in the hope that it will be useful,
      28              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      29              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
      30              :  * GNU Lesser General Public License for more details.
      31              :  */
      32              : 
      33              : #include <string>
      34              : #include "file_io.h"
      35              : #include "lib_grid/algorithms/attachment_util.h"
      36              : #include "common/util/path_provider.h"
      37              : #include "common/util/file_util.h"
      38              : #include "common/util/string_util.h"
      39              : #include "lib_grid/parallelization/distributed_grid.h"
      40              : #include "lib_grid/algorithms/subset_util.h"
      41              : #include "lib_grid/tools/surface_view.h"
      42              : 
      43              : #include "file_io_2df.h"
      44              : #include "file_io_art.h"
      45              : #include "file_io_asc.h"
      46              : #include "file_io_txt.h"
      47              : #include "file_io_tetgen.h"
      48              : #include "file_io_obj.h"
      49              : #include "file_io_lgm.h"
      50              : #include "file_io_lgb.h"
      51              : #include "file_io_ng.h"
      52              : #include "file_io_ug.h"
      53              : #include "file_io_dump.h"
      54              : #include "file_io_ncdf.h"
      55              : #include "file_io_ugx.h"
      56              : #include "file_io_msh.h"
      57              : #include "file_io_stl.h"
      58              : #include "file_io_tikz.h"
      59              : #include "file_io_vtu.h"
      60              : #include "file_io_swc.h"
      61              : #include "file_io_grdecl.h"
      62              : 
      63              : #ifdef UG_PARALLEL
      64              :         #include "pcl/pcl_process_communicator.h"
      65              :         #include "pcl/pcl_util.h"
      66              : #endif
      67              : 
      68              : using namespace std;
      69              : 
      70              : namespace ug
      71              : {
      72              : 
      73              : ////////////////////////////////////////////////////////////////////////////////
      74              : //      this method performs the actual loading.
      75            0 : static bool LoadGrid3d_IMPL(Grid& grid, ISubsetHandler* pSH,
      76              :                                            const char* filename, AVector3& aPos)
      77              : {
      78            0 :         string strExt = GetFilenameExtension(string(filename));
      79            0 :         strExt = ToLower(strExt);
      80              : 
      81              :         bool bAutoassignFaces = false;
      82              :         bool bSuccess = false;
      83            0 :         if(strExt.compare("txt") == 0)
      84              :         {
      85              :                 bAutoassignFaces = true;
      86            0 :                 bSuccess = LoadGridFromTXT(grid, filename, aPos);
      87              :         }
      88            0 :         else if(strExt.compare("grdecl") == 0)
      89              :         {
      90              :                 bAutoassignFaces = true;
      91            0 :                 bSuccess = LoadGridFromGRDECL(grid, filename, aPos);
      92              :         }
      93            0 :         else if(strExt.compare("obj") == 0)
      94            0 :                 bSuccess = LoadGridFromOBJ(grid, filename, aPos, NULL, pSH);
      95            0 :         else if(strExt.compare("lgb") == 0)
      96              :         {
      97              :                 int numSHs = 0;
      98            0 :                 if(pSH)
      99              :                         numSHs = 1;
     100              : 
     101            0 :                 bSuccess = LoadGridFromLGB(grid, filename, &pSH, numSHs, NULL, aPos);
     102              :         }
     103            0 :         else if(strExt.compare("2df") == 0)
     104            0 :                 bSuccess = LoadGridFrom2DF(grid, filename, pSH, aPos);
     105            0 :         else if(strExt.compare("stl") == 0)
     106            0 :                 bSuccess = LoadGridFromSTL(grid, filename, pSH, aPos);
     107            0 :         else if(strExt.compare("net") == 0)
     108            0 :                 bSuccess = LoadGridFromART(grid, filename, pSH, aPos);
     109            0 :         else if(strExt.compare("art") == 0)
     110            0 :                 bSuccess = LoadGridFromART(grid, filename, pSH, aPos);
     111            0 :         else if(strExt.compare("dat") == 0)
     112            0 :                 bSuccess = LoadGridFromART(grid, filename, pSH, aPos);
     113            0 :         else if(strExt.compare("lgm") == 0)
     114            0 :                 bSuccess = ImportGridFromLGM(grid, filename, aPos, pSH);
     115            0 :         else if(strExt.compare("ng") == 0)
     116            0 :                 bSuccess = ImportGridFromNG(grid, filename, aPos, pSH);
     117            0 :         else if(strExt.compare("dump") == 0)
     118              :         {
     119            0 :                 bSuccess = LoadGridFromDUMP(grid, filename, pSH, aPos);
     120              :         }
     121            0 :         else if(strExt.compare("ele") == 0)
     122            0 :                 return LoadGridFromELE(grid, filename, pSH, aPos);
     123            0 :         else if(strExt.compare("msh") == 0)
     124            0 :                 bSuccess = LoadGridFromMSH(grid, filename, pSH, aPos);
     125            0 :         else if(strExt.compare("smesh") == 0)
     126            0 :                 bSuccess = LoadGridFromSMESH(grid, filename, aPos, pSH);
     127            0 :         else if(strExt.compare("asc") == 0){
     128            0 :                 bSuccess = LoadGridFromASC(grid, filename, aPos);
     129              :                 bAutoassignFaces = true;
     130              :         }
     131            0 :         else if(strExt.compare("swc") == 0){
     132            0 :                 bSuccess = LoadGridFromSWC(grid, pSH, filename, aPos);
     133              :         }
     134              : 
     135            0 :         if(bAutoassignFaces && pSH)
     136              :                 pSH->assign_subset(grid.faces_begin(), grid.faces_end(), 0);
     137              : 
     138              :         return bSuccess;
     139              : }
     140              : 
     141              : 
     142            0 : static bool LoadGrid3d(Grid& grid, ISubsetHandler* psh,
     143              :                                            const char* filename, APosition1& aPos)
     144              : {
     145              :         APosition aPosTMP;
     146              :         grid.attach_to_vertices(aPosTMP);
     147            0 :         if(LoadGrid3d_IMPL(grid, psh, filename, aPosTMP)){
     148              :         //      convert the position data from 3d to the required dimension.
     149            0 :                 ConvertMathVectorAttachmentValues<Vertex>(grid, aPosTMP, aPos);
     150              :                 grid.detach_from_vertices(aPosTMP);
     151            0 :                 return true;
     152              :         }
     153              :         grid.detach_from_vertices(aPosTMP);
     154              :         return false;
     155              : }
     156              : 
     157            0 : static bool LoadGrid3d(Grid& grid, ISubsetHandler* psh,
     158              :                                            const char* filename, APosition2& aPos)
     159              : {
     160              :         APosition aPosTMP;
     161              :         grid.attach_to_vertices(aPosTMP);
     162            0 :         if(LoadGrid3d_IMPL(grid, psh, filename, aPosTMP)){
     163              :         //      convert the position data from 3d to the required dimension.
     164            0 :                 ConvertMathVectorAttachmentValues<Vertex>(grid, aPosTMP, aPos);
     165              :                 grid.detach_from_vertices(aPosTMP);
     166            0 :                 return true;
     167              :         }
     168              :         grid.detach_from_vertices(aPosTMP);
     169              :         return false;
     170              : }
     171              : 
     172              : static bool LoadGrid3d(Grid& grid, ISubsetHandler* psh,
     173              :                                            const char* filename, APosition3& aPos)
     174              : {
     175            0 :         return LoadGrid3d_IMPL(grid, psh, filename, aPos);
     176              : }
     177              : 
     178              : ////////////////////////////////////////////////////////////////////////////////
     179              : ///     This method calls specific load routines or delegates loading to LoadGrid3d
     180              : template <class TAPos>
     181            0 : static bool LoadGrid(Grid& grid, ISubsetHandler* psh,
     182              :                                          const char* filename, TAPos& aPos,
     183              :                                          int procId)
     184              : {
     185              : //      For convenience, we support multiple different standard paths, from which
     186              : //      grids may be loaded. We thus first check, where the specified file is
     187              : //      located and load it from that location afterwards.
     188              :         bool loadingGrid = true;
     189              :         #ifdef UG_PARALLEL
     190              :                 if((procId != -1) && (pcl::ProcRank() != procId))
     191              :                         loadingGrid = false;
     192              :         #endif
     193              : 
     194            0 :         grid.message_hub()->post_message(GridMessage_Creation(GMCT_CREATION_STARTS, procId));
     195              :         bool retVal = false;
     196              :         if(loadingGrid){
     197              :         //      Now perform the actual loading.
     198              :         //      first all load methods, which do accept template position types are
     199              :         //      handled. Then all those which only work with 3d position types are processed.
     200            0 :                 string tfile = FindFileInStandardPaths(filename);
     201            0 :                 if(!tfile.empty()){
     202            0 :                         if(tfile.find(".ugx") != string::npos){
     203            0 :                                 if(psh)
     204            0 :                                         retVal = LoadGridFromUGX(grid, *psh, tfile.c_str(), aPos);
     205              :                                 else{
     206              :                                 //      we have to create a temporary subset handler
     207            0 :                                         SubsetHandler shTmp(grid);
     208            0 :                                         retVal = LoadGridFromUGX(grid, shTmp, tfile.c_str(), aPos);
     209            0 :                                 }
     210              :                         }
     211            0 :                         else if(tfile.find(".vtu") != string::npos){
     212            0 :                                 if(psh)
     213            0 :                                         retVal = LoadGridFromVTU(grid, *psh, tfile.c_str(), aPos);
     214              :                                 else{
     215              :                                 //      we have to create a temporary subset handler
     216            0 :                                         SubsetHandler shTmp(grid);
     217            0 :                                         retVal = LoadGridFromVTU(grid, shTmp, tfile.c_str(), aPos);
     218            0 :                                 }
     219              :                         }
     220              :                         else{
     221              :                         //      now we'll handle those methods, which only support 3d position types.
     222            0 :                                 retVal = LoadGrid3d(grid, psh, tfile.c_str(), aPos);
     223              :                         }
     224              :                 }
     225              :         }
     226              :         
     227              :         //      declare global attachments on all processors
     228              :         #ifdef UG_PARALLEL
     229              :                 GlobalAttachments::SynchronizeDeclaredGlobalAttachments(grid, procId);
     230              :         #endif
     231              :         
     232            0 :         grid.message_hub()->post_message(GridMessage_Creation(GMCT_CREATION_STOPS, procId));
     233              :         
     234              :         
     235              :         #ifdef UG_PARALLEL
     236              :                 pcl::ProcessCommunicator procCom;
     237              :                 if(procId == -1)
     238              :                         retVal = pcl::AllProcsTrue(retVal, procCom);
     239              :                 else
     240              :                         retVal = pcl::OneProcTrue(retVal, procCom);
     241              :         #endif
     242              : 
     243            0 :         return retVal;
     244              : }
     245              : 
     246              : template <class TAPos>
     247            0 : static bool LoadGrid(Grid& grid, SPProjectionHandler* ph, size_t& num_ph, ISubsetHandler* psh, std::vector<std::string> additionalSHNames,
     248              :                                                 std::vector<SmartPtr<ISubsetHandler>> ash, const char* filename, TAPos& aPos, int procId)
     249              : {
     250              : //      For convenience, we support multiple different standard paths, from which
     251              : //      grids may be loaded. We thus first check, where the specified file is
     252              : //      located and load it from that location afterwards.
     253              :         bool loadingGrid = true;
     254              :         #ifdef UG_PARALLEL
     255              :                 if((procId != -1) && (pcl::ProcRank() != procId))
     256              :                         loadingGrid = false;
     257              :         #endif
     258              : 
     259            0 :         grid.message_hub()->post_message(GridMessage_Creation(GMCT_CREATION_STARTS, procId));
     260              : 
     261              :         bool retVal = false;
     262              :         if(loadingGrid){
     263              :         //      Now perform the actual loading.
     264              :         //      first all load methods, which do accept template position types are
     265              :         //      handled. Then all those which only work with 3d position types are processed.
     266            0 :                 string tfile = FindFileInStandardPaths(filename);
     267            0 :                 if(!tfile.empty()){
     268            0 :                         if(tfile.find(".ugx") != string::npos){
     269            0 :                                 if(psh)
     270            0 :                                         retVal = LoadGridFromUGX(grid, *ph, num_ph, *psh, additionalSHNames, ash, tfile.c_str(), aPos);
     271              :                                 else{
     272              :                                 //      we have to create a temporary subset handler
     273            0 :                                         SubsetHandler shTmp(grid);
     274            0 :                                         retVal = LoadGridFromUGX(grid, *ph, num_ph, shTmp, additionalSHNames, ash, tfile.c_str(), aPos);
     275            0 :                                 }
     276              :                         }
     277              : 
     278            0 :                         else if(tfile.find(".vtu") != string::npos){
     279            0 :                                 if(psh)
     280            0 :                                         retVal = LoadGridFromVTU(grid, *psh, tfile.c_str(), aPos);
     281              :                                 else{
     282              :                                 //      we have to create a temporary subset handler
     283            0 :                                         SubsetHandler shTmp(grid);
     284            0 :                                         retVal = LoadGridFromVTU(grid, shTmp, tfile.c_str(), aPos);
     285            0 :                                 }
     286              :                         }
     287              :                         else{
     288              :                         //      now we'll handle those methods, which only support 3d position types.
     289            0 :                                 retVal = LoadGrid3d(grid, psh, tfile.c_str(), aPos);
     290              :                         }
     291              : 
     292              :                 }
     293              :         }
     294              :         
     295              :         //      declare global attachments on all processors
     296              :         #ifdef UG_PARALLEL
     297              :                 GlobalAttachments::SynchronizeDeclaredGlobalAttachments(grid, procId);
     298              :         #endif
     299              : 
     300            0 :         grid.message_hub()->post_message(GridMessage_Creation(GMCT_CREATION_STOPS, procId));
     301              :         
     302              :         #ifdef UG_PARALLEL
     303              :                 pcl::ProcessCommunicator procCom;
     304              :                 if(procId == -1)
     305              :                         retVal = pcl::AllProcsTrue(retVal, procCom);
     306              :                 else
     307              :                         retVal = pcl::OneProcTrue(retVal, procCom);
     308              :         #endif
     309              : 
     310            0 :         return retVal;
     311              : }
     312              : 
     313              : ////////////////////////////////////////////////////////////////////////////////
     314              : template <class TAPos>
     315            0 : bool LoadGridFromFile(Grid& grid, SPProjectionHandler& ph, size_t& num_ph, ISubsetHandler& sh, vector<string> additionalSHNames,
     316              :                                                 vector<SmartPtr<ISubsetHandler>> ash, const char* filename, TAPos& aPos, int procId)
     317              : {
     318            0 :         return LoadGrid(grid, &ph, num_ph, &sh, additionalSHNames, ash, filename, aPos, procId);
     319              : }
     320              : 
     321              : template <class TAPos>
     322            0 : bool LoadGridFromFile(Grid& grid, ISubsetHandler& sh,
     323              :                                           const char* filename, TAPos& aPos, int procId)
     324              : {
     325            0 :         return LoadGrid(grid, &sh, filename, aPos, procId);
     326              : }
     327              : 
     328              : template <class TAPos>
     329            0 : bool LoadGridFromFile(Grid& grid, const char* filename, TAPos& aPos, int procId)
     330              : {
     331            0 :         return LoadGrid(grid, NULL, filename, aPos, procId);
     332              : }
     333              : 
     334            0 : bool LoadGridFromFile(Grid& grid, ISubsetHandler& sh, const char* filename, int procId)
     335              : {
     336            0 :         return LoadGrid(grid, &sh, filename, aPosition, procId);
     337              : }
     338              : 
     339            0 : bool LoadGridFromFile(Grid& grid, const char* filename, int procId)
     340              : {
     341            0 :         return LoadGrid(grid, NULL, filename, aPosition, procId);
     342              : }
     343              : 
     344              : 
     345              : ////////////////////////////////////////////////////////////////////////////////
     346              : ////////////////////////////////////////////////////////////////////////////////
     347              : //      this method performs the actual save.
     348            0 : static bool SaveGrid3d_IMPL(Grid& grid, ISubsetHandler* pSH,
     349              :                                                         const char* filename, AVector3& aPos)
     350              : {
     351            0 :         string strName = filename;
     352            0 :         if(strName.find(".txt") != string::npos)
     353            0 :                 return SaveGridToTXT(grid, filename, aPos);
     354            0 :         if(strName.find(".2df") != string::npos)
     355            0 :                 return SaveGridTo2DF(grid, filename, pSH, aPos);
     356            0 :         else if(strName.find(".obj") != string::npos)
     357            0 :                 return SaveGridToOBJ(grid, filename, aPos, NULL, pSH);
     358            0 :         else if(strName.find(".lgb") != string::npos)
     359              :         {
     360              :                 int numSHs = 0;
     361            0 :                 if(pSH)
     362              :                         numSHs = 1;
     363              : 
     364            0 :                 return SaveGridToLGB(grid, filename, &pSH, numSHs, NULL, aPos);
     365              :         }
     366            0 :         else if(strName.find(".ele") != string::npos)
     367            0 :                 return SaveGridToELE(grid, filename, pSH, aPos);
     368            0 :         else if(strName.find(".net") != string::npos)
     369            0 :                 return SaveGridToART(grid, filename, pSH, aPos);
     370            0 :         else if(strName.find(".art") != string::npos)
     371            0 :                 return SaveGridToART(grid, filename, pSH, aPos);
     372            0 :         else if(strName.find(".ncdf") != string::npos)
     373            0 :                 return SaveGridToNCDF(grid, filename, pSH, aPos);
     374            0 :         else if(strName.find(".stl") != string::npos)
     375            0 :                 return SaveGridToSTL(grid, filename, pSH, aPos);
     376            0 :         else if(strName.find(".smesh") != string::npos)
     377            0 :                 return ExportGridToSMESH(grid, filename, aPos, pSH);
     378              :         else if((strName.find(".tikz") != string::npos)
     379            0 :                         || (strName.find(".tex") != string::npos))
     380              :         {
     381            0 :                 return ExportGridToTIKZ(grid, filename, pSH, aPos);
     382              :         }
     383            0 :         else if (strName.find(".swc") != string::npos)
     384            0 :                 return ExportGridToSWC(grid, pSH, filename, aPos);
     385              : 
     386              :         return false;
     387              : }
     388              : 
     389              : ////////////////////////////////////////////////////////////////////////////////
     390            0 : static bool SaveGrid3d(Grid& grid, ISubsetHandler* psh,
     391              :                                            const char* filename, APosition1& aPos)
     392              : {
     393              :         APosition aPosTMP;
     394              :         grid.attach_to_vertices(aPosTMP);
     395              : //      convert the position data from the given dimension to 3d
     396            0 :         ConvertMathVectorAttachmentValues<Vertex>(grid, aPos, aPosTMP);
     397            0 :         if(SaveGrid3d_IMPL(grid, psh, filename, aPosTMP)){
     398              :                 grid.detach_from_vertices(aPosTMP);
     399            0 :                 return true;
     400              :         }
     401              :         grid.detach_from_vertices(aPosTMP);
     402              :         return false;
     403              : }
     404              : 
     405              : ////////////////////////////////////////////////////////////////////////////////
     406            0 : static bool SaveGrid3d(Grid& grid, ISubsetHandler* psh,
     407              :                                            const char* filename, APosition2& aPos)
     408              : {
     409              :         APosition aPosTMP;
     410              :         grid.attach_to_vertices(aPosTMP);
     411              : //      convert the position data from the given dimension to 3d
     412            0 :         ConvertMathVectorAttachmentValues<Vertex>(grid, aPos, aPosTMP);
     413            0 :         if(SaveGrid3d_IMPL(grid, psh, filename, aPosTMP)){
     414              :                 grid.detach_from_vertices(aPosTMP);
     415            0 :                 return true;
     416              :         }
     417              :         grid.detach_from_vertices(aPosTMP);
     418              :         return false;
     419              : }
     420              : 
     421              : ////////////////////////////////////////////////////////////////////////////////
     422              : static bool SaveGrid3d(Grid& grid, ISubsetHandler* psh,
     423              :                                            const char* filename, APosition3& aPos)
     424              : {
     425            0 :         return SaveGrid3d_IMPL(grid, psh, filename, aPos);
     426              : }
     427              : 
     428              : ////////////////////////////////////////////////////////////////////////////////
     429              : template <class TAPos>
     430            0 : static bool SaveGrid(Grid& grid, ISubsetHandler* psh,
     431              :                                          const char* filename, TAPos& aPos)
     432              : {
     433            0 :         string strName = filename;
     434            0 :         if(strName.find(".ugx") != string::npos){
     435              :                  #if (defined UG_PARALLEL && defined UG_DEBUG)
     436              :                  std::size_t found=strName.find(".ugx");
     437              :                  strName=strName.replace(found, 4, "");
     438              :                  int procRank=pcl::ProcRank();
     439              :                  strName=strName.append("_p");
     440              :                  strName=strName.append(std::to_string(procRank));
     441              :                  strName.append(".ugx");   
     442              :                 #endif
     443              :                 
     444            0 :                 if(psh)
     445            0 :                         return SaveGridToUGX(grid, *psh, strName.c_str(), aPos);
     446              :                 else {
     447            0 :                         SubsetHandler shTmp(grid);
     448            0 :                         return SaveGridToUGX(grid, shTmp, strName.c_str(), aPos);
     449            0 :                 }
     450              :         }
     451            0 :         else if(strName.find(".vtu") != string::npos){
     452              :                 #if (defined UG_PARALLEL && defined UG_DEBUG)
     453              :                  std::size_t found=strName.find(".vtu");
     454              :                          strName=strName.replace(found, 4, "");
     455              :                                  strName=strName.append("_p");
     456              :                  strName=strName.append(std::to_string(pcl::ProcRank()));
     457              :                  strName.append(".vtu");
     458              :                 #endif
     459            0 :                 return SaveGridToVTU(grid, psh, strName.c_str(), aPos);
     460              :         }
     461              :         else
     462            0 :                 return SaveGrid3d(grid, psh, filename, aPos);
     463              : }
     464              : 
     465              : 
     466              : ////////////////////////////////////////////////////////////////////////////////
     467              : template <class TAPos>
     468            0 : bool SaveGridToFile(Grid& grid, ISubsetHandler& sh,
     469              :                                         const char* filename, TAPos& aPos)
     470              : {
     471            0 :         return SaveGrid(grid, &sh, filename, aPos);
     472              : }
     473              : 
     474              : template <class TAPos>
     475            0 : bool SaveGridToFile(Grid& grid, const char* filename, TAPos& aPos)
     476              : {
     477            0 :         return SaveGrid(grid, NULL, filename, aPos);
     478              : }
     479              : 
     480            0 : bool SaveGridToFile(Grid& grid, ISubsetHandler& sh, const char* filename)
     481              : {
     482              : //      check whether one of the standard attachments is attached and call
     483              : //      SaveGrid with that attachment
     484            0 :         if(grid.has_vertex_attachment(aPosition))
     485            0 :                 return SaveGrid(grid, &sh, filename, aPosition);
     486            0 :         if(grid.has_vertex_attachment(aPosition2))
     487            0 :                 return SaveGrid(grid, &sh, filename, aPosition2);
     488            0 :         if(grid.has_vertex_attachment(aPosition1))
     489            0 :                 return SaveGrid(grid, &sh, filename, aPosition1);
     490              : 
     491              :         return false;
     492              : }
     493              : 
     494            0 : bool SaveGridToFile(Grid& grid, const char* filename)
     495              : {
     496              : //      check whether one of the standard attachments is attached and call
     497              : //      SaveGrid with that attachment
     498            0 :         if(grid.has_vertex_attachment(aPosition))
     499            0 :                 return SaveGrid(grid, NULL, filename, aPosition);
     500            0 :         if(grid.has_vertex_attachment(aPosition2))
     501            0 :                 return SaveGrid(grid, NULL, filename, aPosition2);
     502            0 :         if(grid.has_vertex_attachment(aPosition1))
     503            0 :                 return SaveGrid(grid, NULL, filename, aPosition1);
     504              :         return false;
     505              : }
     506              : 
     507            0 : bool SaveGridHierarchyTransformed(MultiGrid& mg, ISubsetHandler& sh,
     508              :                                                                   const char* filename, number offset)
     509              : {
     510              :         PROFILE_FUNC_GROUP("grid");
     511              :         APosition aPos;
     512              : //      uses auto-attach
     513            0 :         Grid::AttachmentAccessor<Vertex, APosition> aaPos(mg, aPos, true);
     514              : 
     515              : //      copy the existing position to aPos. We take care of dimension differences.
     516              : //      Note:   if the method was implemented for domains, this could be implemented
     517              : //                      in a nicer way.
     518            0 :         if(mg.has_vertex_attachment(aPosition))
     519            0 :                 ConvertMathVectorAttachmentValues<Vertex>(mg, aPosition, aPos);
     520            0 :         else if(mg.has_vertex_attachment(aPosition2))
     521            0 :                 ConvertMathVectorAttachmentValues<Vertex>(mg, aPosition2, aPos);
     522            0 :         else if(mg.has_vertex_attachment(aPosition1))
     523            0 :                 ConvertMathVectorAttachmentValues<Vertex>(mg, aPosition1, aPos);
     524              : 
     525              : //      iterate through all vertices and apply an offset depending on their level.
     526            0 :         for(size_t lvl = 0; lvl < mg.num_levels(); ++lvl){
     527            0 :                 for(VertexIterator iter = mg.begin<Vertex>(lvl);
     528            0 :                         iter != mg.end<Vertex>(lvl); ++iter)
     529              :                 {
     530            0 :                         aaPos[*iter].z() += (number)lvl * offset;
     531              :                 }
     532              :         }
     533              : 
     534              : //      finally save the grid
     535              :         bool writeSuccess = SaveGridToFile(mg, sh, filename, aPos);
     536              : 
     537              : //      clean up
     538              :         mg.detach_from_vertices(aPos);
     539              : 
     540            0 :         return writeSuccess;
     541              : }
     542              : 
     543            0 : bool SaveGridHierarchyTransformed(MultiGrid& mg, const char* filename,
     544              :                                                                           number offset)
     545              : {
     546              :         PROFILE_FUNC_GROUP("grid");
     547              : //      cast away constness
     548              :         SubsetHandler& sh = mg.get_hierarchy_handler();
     549              : 
     550              :         APosition aPos;
     551              : //      uses auto-attach
     552            0 :         Grid::AttachmentAccessor<Vertex, APosition> aaPos(mg, aPos, true);
     553              : 
     554              : //      copy the existing position to aPos. We take care of dimension differences.
     555              : //      Note:   if the method was implemented for domains, this could be implemented
     556              : //                      in a nicer way.
     557            0 :         if(mg.has_vertex_attachment(aPosition))
     558            0 :                 ConvertMathVectorAttachmentValues<Vertex>(mg, aPosition, aPos);
     559            0 :         else if(mg.has_vertex_attachment(aPosition2))
     560            0 :                 ConvertMathVectorAttachmentValues<Vertex>(mg, aPosition2, aPos);
     561            0 :         else if(mg.has_vertex_attachment(aPosition1))
     562            0 :                 ConvertMathVectorAttachmentValues<Vertex>(mg, aPosition1, aPos);
     563              : 
     564              : //      iterate through all vertices and apply an offset depending on their level.
     565            0 :         for(size_t lvl = 0; lvl < mg.num_levels(); ++lvl){
     566            0 :                 for(VertexIterator iter = mg.begin<Vertex>(lvl);
     567            0 :                         iter != mg.end<Vertex>(lvl); ++iter)
     568              :                 {
     569            0 :                         aaPos[*iter].z() += (number)lvl * offset;
     570              :                 }
     571              :         }
     572              : 
     573              : //      finally save the grid
     574            0 :         bool writeSuccess = SaveGridToFile(mg, sh, filename, aPos);
     575              : 
     576              : //      clean up
     577              :         mg.detach_from_vertices(aPos);
     578              : 
     579            0 :         return writeSuccess;
     580              : }
     581              : 
     582              : template <class TElem>
     583            0 : static void AssignSubsetsByInterfaceType(SubsetHandler& sh, MultiGrid& mg)
     584              : {
     585              :         const int siNormal = 0;
     586              :         const int siHMaster = 1;
     587              :         const int siHSlave = 1 << 1;
     588              :         const int siVMaster = 1 << 2;
     589              :         const int siVSlave = 1 << 3;
     590              : 
     591            0 :         const char* subsetNames[] = {"normal", "hmaster", "hslave", "hslave+hmaster",
     592              :                                                   "vmaster", "vmaster+hmaster", "vmaster+hslave",
     593              :                                                   "vmaster+hslave+hmaster", "vslave", "vslave+hmaster",
     594              :                                                   "vslave+hslave", "vslave+hslave+hmaster",
     595              :                                                   "vslave+vmaster", "vslave+vmaster+hmaster",
     596              :                                                   "vslave+vmaster+hslave", "vslave+vmaster+hmaster+hslave"};
     597              : 
     598            0 :         for(int i = 0; i < 16; ++i)
     599            0 :                 sh.subset_info(i).name = subsetNames[i];
     600              : 
     601              :         typedef typename Grid::traits<TElem>::iterator TIter;
     602            0 :         for(TIter iter = mg.begin<TElem>(); iter != mg.end<TElem>(); ++iter){
     603              :                 int status = ES_NONE;
     604              : 
     605              :                 #ifdef UG_PARALLEL
     606              :                         DistributedGridManager* distGridMgr = mg.distributed_grid_manager();
     607              :                         if(distGridMgr)
     608              :                                 status = distGridMgr->get_status(*iter);
     609              :                 #endif
     610              : 
     611              :                 int index = siNormal;
     612              :                 if(status & ES_H_MASTER)
     613              :                         index |= siHMaster;
     614              :                 if(status & ES_H_SLAVE)
     615              :                         index |= siHSlave;
     616              :                 if(status & ES_V_MASTER)
     617              :                         index |= siVMaster;
     618              :                 if(status & ES_V_SLAVE)
     619              :                         index |= siVSlave;
     620              : 
     621            0 :                 sh.assign_subset(*iter, index);
     622              :         }
     623            0 : }
     624              : 
     625            0 : bool SaveParallelGridLayout(MultiGrid& mg, const char* filename, number offset)
     626              : {
     627              :         PROFILE_FUNC_GROUP("grid");
     628              : 
     629              :         APosition aPos;
     630              : //      uses auto-attach
     631            0 :         Grid::AttachmentAccessor<Vertex, APosition> aaPos(mg, aPos, true);
     632              : 
     633              : //      copy the existing position to aPos. We take care of dimension differences.
     634              : //      Note:   if the method was implemented for domains, this could be implemented
     635              : //                      in a nicer way.
     636            0 :         if(mg.has_vertex_attachment(aPosition))
     637            0 :                 ConvertMathVectorAttachmentValues<Vertex>(mg, aPosition, aPos);
     638            0 :         else if(mg.has_vertex_attachment(aPosition2))
     639            0 :                 ConvertMathVectorAttachmentValues<Vertex>(mg, aPosition2, aPos);
     640            0 :         else if(mg.has_vertex_attachment(aPosition1))
     641            0 :                 ConvertMathVectorAttachmentValues<Vertex>(mg, aPosition1, aPos);
     642              : 
     643              : //      iterate through all vertices and apply an offset depending on their level.
     644            0 :         for(size_t lvl = 0; lvl < mg.num_levels(); ++lvl){
     645            0 :                 for(VertexIterator iter = mg.begin<Vertex>(lvl);
     646            0 :                         iter != mg.end<Vertex>(lvl); ++iter)
     647              :                 {
     648            0 :                         aaPos[*iter].z() += (number)lvl * offset;
     649              :                 }
     650              :         }
     651              : 
     652              : //      create a subset handler which holds different subsets for the different interface types
     653            0 :         SubsetHandler sh(mg);
     654              : 
     655            0 :         AssignSubsetsByInterfaceType<Vertex>(sh, mg);
     656            0 :         AssignSubsetsByInterfaceType<Edge>(sh, mg);
     657            0 :         AssignSubsetsByInterfaceType<Face>(sh, mg);
     658            0 :         AssignSubsetsByInterfaceType<Volume>(sh, mg);
     659              : 
     660            0 :         AssignSubsetColors(sh);
     661            0 :         EraseEmptySubsets(sh);
     662              : 
     663              : //      finally save the grid
     664              :         bool writeSuccess = SaveGridToFile(mg, sh, filename, aPos);
     665              : 
     666              : //      clean up
     667              :         mg.detach_from_vertices(aPos);
     668              : 
     669            0 :         return writeSuccess;
     670            0 : }
     671              : 
     672              : template <class TElem>
     673            0 : static void AssignSubsetsBySurfaceViewState(SubsetHandler& sh, const SurfaceView& sv,
     674              :                                                                                         MultiGrid& mg)
     675              : {
     676              :         typedef typename Grid::traits<TElem>::iterator TIter;
     677            0 :         for(TIter iter = mg.begin<TElem>(); iter != mg.end<TElem>(); ++iter){
     678              :                 TElem* e = *iter;
     679              : 
     680            0 :                 sh.assign_subset(e, sv.surface_state(e).get());
     681              :         }
     682            0 :         for(int i = 0; i < sh.num_subsets(); ++i)
     683            0 :                 sh.subset_info(i).name = "unknown";
     684            0 :         sh.subset_info(SurfaceView::MG_SHADOW_PURE).name = "shadow-pure";
     685            0 :         sh.subset_info(SurfaceView::MG_SURFACE_PURE).name = "surface-pure";
     686            0 :         sh.subset_info(SurfaceView::MG_SURFACE_RIM).name = "surface-rim";
     687            0 :         sh.subset_info(SurfaceView::MG_SHADOW_RIM_COPY).name = "shadow-rim-copy";
     688            0 :         sh.subset_info(SurfaceView::MG_SHADOW_RIM_NONCOPY).name = "shadow-rim-noncopy";
     689              :         //EraseEmptySubsets(sh);
     690            0 : }
     691              : 
     692            0 : bool SaveSurfaceViewTransformed(MultiGrid& mg, const SurfaceView& sv,
     693              :                                                                 const char* filename, number offset)
     694              : {
     695              :         PROFILE_FUNC_GROUP("grid");
     696              : 
     697              :         APosition aPos;
     698              : //      uses auto-attach
     699            0 :         Grid::AttachmentAccessor<Vertex, APosition> aaPos(mg, aPos, true);
     700              : 
     701              : //      copy the existing position to aPos. We take care of dimension differences.
     702              : //      Note:   if the method was implemented for domains, this could be implemented
     703              : //                      in a nicer way.
     704            0 :         if(mg.has_vertex_attachment(aPosition))
     705            0 :                 ConvertMathVectorAttachmentValues<Vertex>(mg, aPosition, aPos);
     706            0 :         else if(mg.has_vertex_attachment(aPosition2))
     707            0 :                 ConvertMathVectorAttachmentValues<Vertex>(mg, aPosition2, aPos);
     708            0 :         else if(mg.has_vertex_attachment(aPosition1))
     709            0 :                 ConvertMathVectorAttachmentValues<Vertex>(mg, aPosition1, aPos);
     710              : 
     711              : //      iterate through all vertices and apply an offset depending on their level.
     712            0 :         for(size_t lvl = 0; lvl < mg.num_levels(); ++lvl){
     713            0 :                 for(VertexIterator iter = mg.begin<Vertex>(lvl);
     714            0 :                         iter != mg.end<Vertex>(lvl); ++iter)
     715              :                 {
     716            0 :                         aaPos[*iter].z() += (number)lvl * offset;
     717              :                 }
     718              :         }
     719              : 
     720              : //      create a subset handler which holds different subsets for the different interface types
     721            0 :         SubsetHandler sh(mg);
     722              : 
     723            0 :         AssignSubsetsBySurfaceViewState<Vertex>(sh, sv, mg);
     724            0 :         AssignSubsetsBySurfaceViewState<Edge>(sh, sv, mg);
     725            0 :         AssignSubsetsBySurfaceViewState<Face>(sh, sv, mg);
     726            0 :         AssignSubsetsBySurfaceViewState<Volume>(sh, sv, mg);
     727              : 
     728            0 :         AssignSubsetColors(sh);
     729            0 :         EraseEmptySubsets(sh);
     730              : 
     731              : //      finally save the grid
     732              :         bool writeSuccess = SaveGridToFile(mg, sh, filename, aPos);
     733              : 
     734              : //      clean up
     735              :         mg.detach_from_vertices(aPos);
     736              : 
     737            0 :         return writeSuccess;
     738            0 : }
     739              : 
     740              : template<class TElem>
     741            0 : void CopyGridLevelElements(MultiGrid& srcMG, Grid& destGrid,
     742              :                                            ISubsetHandler& srcSH, ISubsetHandler& destSH,
     743              :                                                    int lvl, AVertex& aNewVrt)
     744              : {
     745              :         Grid::VertexAttachmentAccessor<AVertex> aaNewVrt(srcMG, aNewVrt);
     746            0 :         GridObjectCollection goc = srcMG.get_grid_objects();
     747              :         CustomVertexGroup vrts;
     748              : 
     749              :         typedef typename Grid::traits<TElem>::iterator iter_t;
     750              : 
     751            0 :         for(iter_t eIter = goc.begin<TElem>(lvl); eIter != goc.end<TElem>(lvl); ++eIter)
     752              :         {
     753              :                 TElem* e = *eIter;
     754            0 :                 vrts.resize(e->num_vertices());
     755              : 
     756            0 :                 for(size_t iv = 0; iv < e->num_vertices(); ++iv)
     757              :                 {
     758            0 :                         vrts.set_vertex(iv, aaNewVrt[e->vertex(iv)]);
     759              :                 }
     760              : 
     761            0 :                 TElem* ne = *destGrid.create_by_cloning(e, vrts);
     762            0 :                 destSH.assign_subset(ne, srcSH.get_subset_index(e));
     763              :         }
     764            0 : }
     765              : 
     766              : template <class TAPos>
     767            0 : void CopyGridLevel(MultiGrid& srcMG, Grid& destGrid,
     768              :                                    ISubsetHandler& srcSH, ISubsetHandler& destSH,
     769              :                                    int lvl, TAPos aPos)
     770              : {
     771              :         Grid::VertexAttachmentAccessor<TAPos> aaPos(destGrid, aPos);
     772              :         Grid::VertexAttachmentAccessor<TAPos> aaSrcPos(srcMG, aPos);
     773            0 :         GridObjectCollection goc = srcMG.get_grid_objects();
     774              : 
     775              :         AVertex aNewVrt;
     776            0 :         srcMG.attach_to_vertices(aNewVrt);
     777              :         Grid::VertexAttachmentAccessor<AVertex> aaNewVrt(srcMG, aNewVrt);
     778              : 
     779            0 :         for(int si = destSH.num_subsets(); si < srcSH.num_subsets(); ++si)
     780              :         {
     781            0 :                 destSH.subset_info(si) = srcSH.subset_info(si);
     782              :         }
     783              : 
     784            0 :         for(VertexIterator vrtIter = goc.begin<Vertex>(lvl); vrtIter != goc.end<Vertex>(lvl); ++vrtIter)
     785              :         {
     786              :                 Vertex* srcVrt  = *vrtIter;
     787            0 :                 Vertex* destVrt = *destGrid.create_by_cloning(srcVrt);
     788              : 
     789            0 :                 aaNewVrt[srcVrt] = destVrt;
     790              :                 aaPos[destVrt] = aaSrcPos[srcVrt];
     791            0 :                 destSH.assign_subset(destVrt, srcSH.get_subset_index(srcVrt));
     792              :         }
     793              : 
     794            0 :         CopyGridLevelElements<Edge>(srcMG, destGrid, srcSH, destSH, lvl, aNewVrt);
     795            0 :         CopyGridLevelElements<Face>(srcMG, destGrid, srcSH, destSH, lvl, aNewVrt);
     796            0 :         CopyGridLevelElements<Volume>(srcMG, destGrid, srcSH, destSH, lvl, aNewVrt);
     797              : 
     798              :         srcMG.detach_from_vertices(aNewVrt);
     799            0 : }
     800              : 
     801              : template <class TAPos>
     802            0 : void CopyGrid(Grid& srcGrid, Grid& destGrid,
     803              :                           ISubsetHandler& srcSH, ISubsetHandler& destSH,
     804              :                           TAPos aPos)
     805              : {
     806              :         Grid::VertexAttachmentAccessor<TAPos> aaPos(destGrid, aPos);
     807              :         Grid::VertexAttachmentAccessor<TAPos> aaSrcPos(srcGrid, aPos);
     808            0 :         GridObjectCollection goc = srcGrid.get_grid_objects();
     809              : 
     810              :         AVertex aNewVrt;
     811              :         srcGrid.attach_to_vertices(aNewVrt);
     812              :         Grid::VertexAttachmentAccessor<AVertex> aaNewVrt(srcGrid, aNewVrt);
     813              : 
     814            0 :         for(int si = destSH.num_subsets(); si < srcSH.num_subsets(); ++si)
     815              :         {
     816            0 :                 destSH.subset_info(si) = srcSH.subset_info(si);
     817              :         }
     818              : 
     819            0 :         for(VertexIterator vrtIter = goc.begin<Vertex>(); vrtIter != goc.end<Vertex>(); ++vrtIter)
     820              :         {
     821              :                 Vertex* srcVrt  = *vrtIter;
     822            0 :                 Vertex* destVrt = *destGrid.create_by_cloning(srcVrt);
     823            0 :                 aaNewVrt[srcVrt] = destVrt;
     824              :                 aaPos[destVrt] = aaSrcPos[srcVrt];
     825            0 :                 destSH.assign_subset(destVrt, srcSH.get_subset_index(srcVrt));
     826              :         }
     827              : 
     828            0 :         CopyGridElements<Edge>(srcGrid, destGrid, srcSH, destSH, aNewVrt);
     829            0 :         CopyGridElements<Face>(srcGrid, destGrid, srcSH, destSH,  aNewVrt);
     830            0 :         CopyGridElements<Volume>(srcGrid, destGrid, srcSH, destSH, aNewVrt);
     831              : 
     832              :         srcGrid.detach_from_vertices(aNewVrt);
     833            0 : }
     834              : 
     835              : template <class TAPos>
     836            0 : bool SaveGridLevel(MultiGrid& srcMG, ISubsetHandler& srcSH,
     837              :                                    int lvl, const char* filename, TAPos aPos)
     838              : {
     839            0 :         Grid destGrid;
     840            0 :         SubsetHandler destSH(destGrid);
     841              : 
     842            0 :         destGrid.attach_to_vertices(aPos);
     843              : 
     844            0 :         CopyGridLevel(srcMG, destGrid, srcSH, destSH, lvl, aPos);
     845            0 :         SaveGridToFile(destGrid, destSH, filename);
     846              : 
     847            0 :         return true;
     848            0 : }
     849              : 
     850              : template <typename TAPos>
     851            0 : void MergeGrids
     852              : (
     853              :         Grid& mrgGrid,
     854              :         Grid& grid,
     855              :         ISubsetHandler& mrgSH,
     856              :         ISubsetHandler& sh,
     857              :         TAPos aPos,
     858              :         bool joinSubsets
     859              : )
     860              : {
     861              :         // add offset to not join subsets with same index
     862            0 :         int subsetBaseInd = joinSubsets ? 0 : mrgSH.num_subsets();
     863              : 
     864              :         // attach data
     865              :         AVertex aVrt;
     866              :         grid.attach_to_vertices(aVrt);
     867              : 
     868              :         // attachments accessors for position and vertex index
     869            0 :         Grid::AttachmentAccessor<Vertex, TAPos> aaPosMRG(mrgGrid, aPos, true);
     870            0 :         Grid::AttachmentAccessor<Vertex, TAPos> aaPos(grid, aPos, true);
     871              :         Grid::AttachmentAccessor<Vertex, AVertex> aaVrt(grid, aVrt);
     872              : 
     873              :         // copy vertices
     874              :         for (VertexIterator iter = grid.begin<Vertex>();
     875            0 :                         iter != grid.end<Vertex>(); ++iter)
     876              :         {
     877            0 :                 Vertex* nvrt = *mrgGrid.create_by_cloning(*iter);
     878              :                 aaPosMRG[nvrt] = aaPos[*iter];
     879            0 :                 aaVrt[*iter] = nvrt;
     880            0 :                 mrgSH.assign_subset(nvrt, subsetBaseInd + sh.get_subset_index(*iter));
     881              :         }
     882              : 
     883              :         //      copy edges
     884            0 :         EdgeDescriptor ed;
     885              :         for (EdgeIterator iter = grid.begin<Edge>();
     886            0 :                         iter != grid.end<Edge>(); ++iter)
     887              :         {
     888              :                 Edge* eSrc = *iter;
     889            0 :                 ed.set_vertices(aaVrt[eSrc->vertex(0)], aaVrt[eSrc->vertex(1)]);
     890            0 :                 Edge* e = *mrgGrid.create_by_cloning(eSrc, ed);
     891            0 :                 mrgSH.assign_subset(e, subsetBaseInd + sh.get_subset_index(eSrc));
     892              :         }
     893              : 
     894              :         //      copy faces
     895            0 :         FaceDescriptor fd;
     896              :         for (FaceIterator iter = grid.begin<Face>();
     897            0 :                 iter != grid.end<Face>(); ++iter)
     898              :         {
     899              :                 Face* fSrc = *iter;
     900            0 :                 fd.set_num_vertices((uint)fSrc->num_vertices());
     901            0 :                 for (size_t i = 0; i < fd.num_vertices(); ++i) {
     902            0 :                         fd.set_vertex((uint)i, aaVrt[fSrc->vertex(i)]);
     903              :                 }
     904            0 :                 Face* f = *mrgGrid.create_by_cloning(fSrc, fd);
     905            0 :                 mrgSH.assign_subset(f, subsetBaseInd + sh.get_subset_index(fSrc));
     906              :         }
     907              : 
     908              :         // copy volumes
     909            0 :         VolumeDescriptor vd;
     910              :         for (VolumeIterator iter = grid.begin<Volume>();
     911            0 :                         iter != grid.end<Volume>(); ++iter)
     912              :         {
     913              :                 Volume* vSrc = *iter;
     914            0 :                 vd.set_num_vertices((uint)vSrc->num_vertices());
     915            0 :                 for (size_t i = 0; i < vd.num_vertices(); ++i) {
     916            0 :                         vd.set_vertex((uint)i, aaVrt[vSrc->vertex(i)]);
     917              :                 }
     918              : 
     919            0 :                 Volume* v = *mrgGrid.create_by_cloning(vSrc, vd);
     920            0 :                 mrgSH.assign_subset(v, subsetBaseInd + sh.get_subset_index(vSrc));
     921              :         }
     922              : 
     923              :         // remove the temporary attachment
     924              :         mrgGrid.detach_from_vertices(aVrt);
     925              : 
     926              :         // overwrite subset names
     927            0 :         for (int i_sub = 0; i_sub < sh.num_subsets(); ++i_sub){
     928            0 :                 mrgSH.subset_info(subsetBaseInd + i_sub) = sh.subset_info(i_sub);
     929              :         }
     930            0 : }
     931              : 
     932            0 : bool SaveGridLevelToFile(MultiGrid& srcMG, ISubsetHandler& srcSH, int lvl, const char* filename)
     933              : {
     934              : //      check whether one of the standard attachments is attached and call
     935              : //      SaveGridLevel with that attachment
     936              :         /*#ifdef UG_PARALLEL
     937              :             std::size_t found=filename.find(".ugx")
     938              :             if(found != string::npos){
     939              :                 filename=filename.replace(found, 4, "");    
     940              :             }
     941              :             filename=filename.append(std::to_string(pcl::ProRank()));
     942              :             if(found != string::npos){
     943              :                         filename.append(".ugx");
     944              :             }
     945              :         #endif*/
     946            0 :         if(srcMG.has_vertex_attachment(aPosition))
     947            0 :                 return SaveGridLevel(srcMG, srcSH, lvl, filename, aPosition);
     948            0 :         if(srcMG.has_vertex_attachment(aPosition2))
     949            0 :                 return SaveGridLevel(srcMG, srcSH, lvl, filename, aPosition2);
     950            0 :         if(srcMG.has_vertex_attachment(aPosition1))
     951            0 :                 return SaveGridLevel(srcMG, srcSH, lvl, filename, aPosition1);
     952              : 
     953              :         return false;
     954              : }       
     955              : 
     956              : ////////////////////////////////////////////////////////////////////////////////
     957              : ////////////////////////////////////////////////////////////////////////////////
     958              : //      explicit template instantiation
     959              : template bool LoadGridFromFile(Grid&, ISubsetHandler&, const char*, AVector1&, int);
     960              : template bool LoadGridFromFile(Grid&, ISubsetHandler&, const char*, AVector2&, int);
     961              : template bool LoadGridFromFile(Grid&, ISubsetHandler&, const char*, AVector3&, int);
     962              : 
     963              : template bool LoadGridFromFile(Grid&, const char*, AVector1&, int);
     964              : template bool LoadGridFromFile(Grid&, const char*, AVector2&, int);
     965              : template bool LoadGridFromFile(Grid&, const char*, AVector3&, int);
     966              : 
     967              : template bool LoadGridFromFile(Grid&, SPProjectionHandler&, size_t&, ISubsetHandler&, std::vector<std::string>, std::vector<SmartPtr<ISubsetHandler>>, const char*, AVector1&, int);
     968              : template bool LoadGridFromFile(Grid&, SPProjectionHandler&, size_t&, ISubsetHandler&, std::vector<std::string>, std::vector<SmartPtr<ISubsetHandler>>, const char*, AVector2&, int);
     969              : template bool LoadGridFromFile(Grid&, SPProjectionHandler&, size_t&, ISubsetHandler&, std::vector<std::string>, std::vector<SmartPtr<ISubsetHandler>>, const char*, AVector3&, int);
     970              : 
     971              : template bool SaveGridToFile(Grid&, ISubsetHandler&, const char*, AVector1&);
     972              : template bool SaveGridToFile(Grid&, ISubsetHandler&, const char*, AVector2&);
     973              : template bool SaveGridToFile(Grid&, ISubsetHandler&, const char*, AVector3&);
     974              : 
     975              : template bool SaveGridToFile(Grid&, const char*, AVector1&);
     976              : template bool SaveGridToFile(Grid&, const char*, AVector2&);
     977              : template bool SaveGridToFile(Grid&, const char*, AVector3&);
     978              : 
     979              : template void CopyGrid(Grid&, Grid&, ISubsetHandler&, ISubsetHandler&, APosition1);
     980              : template void CopyGrid(Grid&, Grid&, ISubsetHandler&, ISubsetHandler&, APosition2);
     981              : template void CopyGrid(Grid&, Grid&, ISubsetHandler&, ISubsetHandler&, APosition3);
     982              : 
     983              : template void MergeGrids(Grid&, Grid&, ISubsetHandler&, ISubsetHandler&, APosition1, bool);
     984              : template void MergeGrids(Grid&, Grid&, ISubsetHandler&, ISubsetHandler&, APosition2, bool);
     985              : template void MergeGrids(Grid&, Grid&, ISubsetHandler&, ISubsetHandler&, APosition3, bool);
     986              : 
     987              : }//     end of namespace
        

Generated by: LCOV version 2.0-1