Salome HOME
*** empty log message ***
[modules/multipr.git] / src / MULTIPR / MULTIPR_MeshDis.cxx
index 9b93c2d070d24e43a3f6811fce359f8e9219cf5f..3c0571ea2407921bff3fd159635412867c921df0 100644 (file)
@@ -17,6 +17,7 @@
 
 #include "MULTIPR_MeshDis.hxx"
 #include "MULTIPR_Mesh.hxx"
+#include "MULTIPR_DecimationFilter.hxx"
 #include "MULTIPR_Utils.hxx"
 #include "MULTIPR_Globals.hxx"
 #include "MULTIPR_API.hxx"
@@ -240,10 +241,6 @@ void MeshDis::insertMesh(
        Mesh*       pMesh,
        int         pPosition)
 {
-       // debug
-       //cout << "INSERT PARTS BEFORE: " << endl;
-       //cout << (*this) << endl;
-       
        MeshDisPart* part = new MeshDisPart();
        
        part->create(
@@ -262,26 +259,24 @@ void MeshDis::insertMesh(
        {
                mParts[i]->mId++;
        }
-       
-       // debug
-       //cout << "INSERT PARTS AFTER: " << endl;
-       //cout << (*this) << endl;
 }
 
 
 void MeshDis::removeParts(const char* pPrefixPartName)
 {
-       // debug
-       //cout << "REMOVE PARTS BEFORE: " << endl;
-       //cout << (*this) << endl;
-       
        if (pPrefixPartName == NULL) throw NullArgumentException("", __FILE__, __LINE__);
        
+       char strPrefix[256];
+       sprintf(strPrefix, "%s_", pPrefixPartName);
+       
        for (vector<MeshDisPart*>::iterator itPart = mParts.begin() ; itPart != mParts.end() ; itPart++)
        {
                MeshDisPart* currentPart = (*itPart);
                
-               if (startWith(currentPart->getPartName(), pPrefixPartName))
+               // remove part which have the same name and all sub_parts
+               // e.g. if pPrefixPartName="PART_4" => remove "PART_4" and "PART_4_*", but not "PART41"         
+               if ((strcmp(currentPart->getPartName(), pPrefixPartName) == 0) || 
+                   startsWith(currentPart->getPartName(), strPrefix))
                {
                        mParts.erase(itPart);
                
@@ -300,10 +295,6 @@ void MeshDis::removeParts(const char* pPrefixPartName)
                        delete currentPart;
                }
        }
-       
-       // debug
-       //cout << "REMOVE PARTS AFTER: " << endl;
-       //cout << (*this) << endl;
 }
 
 
@@ -360,7 +351,7 @@ vector<string> MeshDis::getFields() const
                case MeshDisPart::MULTIPR_KEEP_AS_IT: 
                case MeshDisPart::MULTIPR_WRITE_PARTS:
                {
-                       vector<pair<string, int> > tmp = multipr::getListFields(mParts[0]->getMEDFileName());
+                       vector<pair<string, int> > tmp = multipr::getListScalarFields(mParts[0]->getMEDFileName());
        
                        for (int i = 0 ; i < tmp.size() ; i++)
                        {
@@ -370,7 +361,7 @@ vector<string> MeshDis::getFields() const
                }
                        
                case MeshDisPart::MULTIPR_WRITE_MESH:
-                       return mParts[0]->mMesh->getNameFields();
+                       return mParts[0]->mMesh->getNameScalarFields();
                
                default: 
                        throw IllegalStateException("", __FILE__, __LINE__);
@@ -393,7 +384,7 @@ int MeshDis::getTimeStamps(const char* pFieldName) const
                case MeshDisPart::MULTIPR_KEEP_AS_IT: 
                case MeshDisPart::MULTIPR_WRITE_PARTS:
                {
-                       vector<pair<string, int> > tmp = multipr::getListFields(mParts[0]->getMEDFileName());
+                       vector<pair<string, int> > tmp = multipr::getListScalarFields(mParts[0]->getMEDFileName());
                
                        for (int i = 0 ; i < tmp.size() ; i++)
                        {
@@ -448,10 +439,12 @@ string MeshDis::getPartInfo(const char* pPartName)
 
 void MeshDis::splitPart(const char* pPartName, int pNbParts, int pPartitionner)
 {
+       cout << "MULTIPR: MeshDis::splitPart()" << endl;
        if (pPartName == NULL) throw NullArgumentException("", __FILE__, __LINE__);
        if (pNbParts < 2) throw IllegalArgumentException("", __FILE__, __LINE__);
        if ((pPartitionner != MULTIPR_METIS) && (pPartitionner != MULTIPR_SCOTCH)) throw IllegalArgumentException("should be 0=METIS or 1=SCOTCH", __FILE__, __LINE__);
        
+       cout << "MULTIPR: MeshDis::splitPart(): args OK" << endl;
        //---------------------------------------------------------------------
        // Find the MED file corresponding to the given part
        //---------------------------------------------------------------------
@@ -461,6 +454,8 @@ void MeshDis::splitPart(const char* pPartName, int pNbParts, int pPartitionner)
        {
                throw IllegalArgumentException("part not found in this distributed MED file", __FILE__, __LINE__);
        }
+
+       cout << "MULTIPR: MeshDis::splitPart(): find part OK" << endl;
        
        //---------------------------------------------------------------------
        // Load the sequential MED file
@@ -468,6 +463,7 @@ void MeshDis::splitPart(const char* pPartName, int pNbParts, int pPartitionner)
        MEDSPLITTER::MESHCollection* collection;
        collection = new MEDSPLITTER::MESHCollection(part->getMEDFileName(), part->getMeshName());
        
+       cout << "MULTIPR: MeshDis::splitPart(): MEDSPLITTER collection OK" << endl;
        //---------------------------------------------------------------------
        // Partition the group
        //---------------------------------------------------------------------
@@ -487,7 +483,9 @@ void MeshDis::splitPart(const char* pPartName, int pNbParts, int pPartitionner)
        {
                try
                {
+                       cout << "MULTIPR: try to create partition using SCOTCH: #parts=" << pNbParts << endl;
                        topology = collection->createPartition(pNbParts, MEDSPLITTER::Graph::SCOTCH);
+                       cout << "MULTIPR: assigned SCOTCH" << endl;
                }
                catch (...)
                {
@@ -510,6 +508,7 @@ void MeshDis::splitPart(const char* pPartName, int pNbParts, int pPartitionner)
        }
        catch (...)
        {
+               cout << "MEDSPLITTER error: new MESHCollection()" << endl;
                throw RuntimeException("MEDSPLITTER error: new MESHCollection()", __FILE__, __LINE__);
        }
 }
@@ -559,7 +558,9 @@ void MeshDis::decimatePart(
        const char* originalFilename = part->getMEDFileName();
        string strPrefix = removeExtension(originalFilename, ".med");
        
-cout << (*this) << endl;
+       // debug
+       //cout << (*this) << endl;
+       
        //---------------------------------------------------------------------
        // Decimates the given mesh
        //---------------------------------------------------------------------
@@ -614,7 +615,87 @@ cout << (*this) << endl;
                        part->mId + 1);
        }
        
-cout << (*this) << endl;
+       // debug
+       //cout << (*this) << endl;
+}
+
+
+string MeshDis::evalDecimationParams(
+       const char* pPartName, 
+       const char* pFieldName, 
+       int         pFieldIt, 
+       const char* pFilterName,
+       const char* pFilterParams)
+{
+       MeshDisPart* part = findPart(pPartName);
+       if (part == NULL) 
+       {
+               return "";
+       }
+       
+       try
+       {
+               if (part->mMesh == NULL)
+               {
+                       part->readMED();
+               }
+       
+               multipr::DecimationFilter* filter = multipr::DecimationFilter::create(pFilterName);
+               if (filter == NULL) 
+               {
+                       return "";
+               }
+               
+               multipr::DecimationFilterGradAvg* filterGrad = dynamic_cast<multipr::DecimationFilterGradAvg*>(filter);
+               
+               if (filterGrad != NULL)
+               {
+                       int mode;
+                       
+                       int ret = sscanf(pFilterParams, "%d", &mode);
+                       
+                       // mode 2 = GET RADIUS
+                       if ((ret == 1) && (mode == 2))
+                       {
+                               double radius = part->mMesh->evalDefaultRadius(8);
+                               char res[256];
+                               sprintf(res, "%f", radius);
+                               return res;
+                       }
+                       
+                       float radius;
+                       int boxing;
+                       
+                       ret = sscanf(pFilterParams, "%d %f %d", &mode, &radius, &boxing);
+                       
+                       // mode 1 = GET GRADIENT MIN, MAX and AVG
+                       if ((ret == 3) && (mode == 1))
+                       {
+                               double gradMin = 0.1, gradAvg = 0.15, gradMax = 0.2;
+                               
+                               filterGrad->getGradientInfo(
+                                       part->mMesh,
+                                       pFieldName,
+                                       pFieldIt,
+                                       radius,
+                                       boxing,
+                                       &gradMin,
+                                       &gradAvg,
+                                       &gradMax);
+                               
+                               char res[2048];
+                               sprintf(res, "%f %f %f", gradMin, gradAvg, gradMax);
+                               return res;
+                       }
+               }
+               
+               delete filter;
+       }
+       catch(...)
+       {
+       }
+       
+       return "";
 }
 
 
@@ -684,7 +765,7 @@ void MeshDis::readDistributedMED(const char* pMEDfilename)
        
        // read number of parts
        int nbParts = atoi(charbuffer);
-       //cout << "DBG: readDistributedMED: #parts=" << nbParts << endl;
+       //cout << "readDistributedMED: #parts=" << nbParts << endl;
        
        //---------------------------------------------------------------------
        // Read infos about sub-parts
@@ -737,14 +818,13 @@ void MeshDis::readDistributedMED(const char* pMEDfilename)
        //---------------------------------------------------------------------
        fileMaster.close();
        if (fileMaster.fail()) throw IOException("i/o error while closing MED master file", __FILE__, __LINE__);
-       //cout << "DBG: readDistributedMED: close" << endl;
 }
 
 
 /**
  * Retrieves the output of MEDSPLITTER and convert it for MULTIPR.
  */
-int convertMedsplitterToMultipr(ofstream& pFileMaster, const char* pTmpFilename, int pId, MeshDisPart* pPart)
+int convertMedsplitterToMultipr(ofstream& pFileMaster, const char* pTmpFilename, int pId, MeshDisPart* pPart, string pDestPath)
 {
        MULTIPR_LOG("convert" << endl);
        
@@ -766,7 +846,7 @@ int convertMedsplitterToMultipr(ofstream& pFileMaster, const char* pTmpFilename,
 
        // read number of parts
        int nbParts = atoi(charbuffer);
-       cout << "nb parts=" << nbParts << endl;
+       //cout << "nb parts=" << nbParts << endl;
 
        char   lMeshName[MED_TAILLE_NOM + 1];
        int    lId;
@@ -797,6 +877,13 @@ int convertMedsplitterToMultipr(ofstream& pFileMaster, const char* pTmpFilename,
                
                //cout << lMeshName << " " << (pId + i) << " " << pPart->getPartName() << "_" << (i + 1) << " " << lPath << " " << lMEDFileName << endl;
                
+               string strDestFilename = pDestPath + multipr::getFilenameWithoutPath(lMEDFileName);
+               if (strcmp(lMEDFileName, strDestFilename.c_str()) != 0)
+               {
+                       multipr::copyFile(lMEDFileName, pDestPath.c_str());
+                       strcpy(lMEDFileName, strDestFilename.c_str());
+               }
+                               
                pFileMaster << lMeshName << " " << (pId + i) << " " << pPart->getPartName() << "_" << (i + 1) << " " << lPath << " " << lMEDFileName << endl;
        }
        
@@ -831,6 +918,8 @@ void MeshDis::writeDistributedMED(const char* pMEDfilenamePrefix)
                strMasterFilename = strPrefix + strExtension;
        }
        
+       string strDestPath = multipr::getPath(strMasterFilename.c_str());
+       
        MULTIPR_LOG("Create master: " << strMasterFilename << endl);
        strcpy(mMEDfilename, strMasterFilename.c_str());
        
@@ -867,6 +956,17 @@ void MeshDis::writeDistributedMED(const char* pMEDfilenamePrefix)
                        {
                                mParts[itPart]->mId = id;
                                id++;
+                               
+                               // copy file in another directory?
+                               string strSrcPath = multipr::getPath(mParts[itPart]->getMEDFileName());
+                               if (strSrcPath != strDestPath)
+                               {
+                                       cout << "Write: KEEP_AS_IT: copy file" << endl;
+                                       string strDestFilename = strDestPath + multipr::getFilenameWithoutPath(mParts[itPart]->getMEDFileName());
+                                       multipr::copyFile(mParts[itPart]->getMEDFileName(), strDestPath.c_str());
+                                       strcpy(mParts[itPart]->mMEDFileName, strDestFilename.c_str());
+                               }
+                               
                                fileMaster << (*mParts[itPart]) << endl;
                                cout << (*mParts[itPart]) << endl;
                                break;
@@ -876,6 +976,10 @@ void MeshDis::writeDistributedMED(const char* pMEDfilenamePrefix)
                        {
                                if (strlen(mParts[itPart]->getMEDFileName()) == 0) throw IOException("MED filename is empty", __FILE__, __LINE__);
                                if (mParts[itPart]->mMesh == NULL) throw IllegalStateException("invalid mesh (shoult not be NULL)", __FILE__, __LINE__);
+                               
+                               string strDestFilename = strDestPath + multipr::getFilenameWithoutPath(mParts[itPart]->getMEDFileName());
+                               strcpy(mParts[itPart]->mMEDFileName, strDestFilename.c_str());
+                               
                                mParts[itPart]->mMesh->writeMED(mParts[itPart]->getMEDFileName());
                                mParts[itPart]->mId = id;
                                id++;
@@ -893,7 +997,7 @@ void MeshDis::writeDistributedMED(const char* pMEDfilenamePrefix)
                                sprintf(tmpFilename, "%s_part", strPrefix.c_str());
                                mParts[itPart]->mCollection->write(tmpFilename);
                                mParts[itPart]->mCollection->castAllFields(*(mParts[itPart]->mOldCollection));
-                               int ret = convertMedsplitterToMultipr(fileMaster, tmpFilename, id, mParts[itPart]);
+                               int ret = convertMedsplitterToMultipr(fileMaster, tmpFilename, id, mParts[itPart], strDestPath);
                                id += ret;
                                remove(mParts[itPart]->getMEDFileName());
                                break;