1 // Project MULTIPR, IOLS WP1.2.1 - EDF/CS
2 // Partitioning/decimation module for the SALOME v3.2 platform
5 * \file MULTIPR_MeshDis.cxx
7 * \brief see MULTIPR_MeshDis.hxx
9 * \author Olivier LE ROUX - CS, Virtual Reality Dpt
14 //*****************************************************************************
16 //*****************************************************************************
18 #include "MULTIPR_MeshDis.hxx"
19 #include "MULTIPR_Mesh.hxx"
20 #include "MULTIPR_DecimationFilter.hxx"
21 #include "MULTIPR_Utils.hxx"
22 #include "MULTIPR_Globals.hxx"
23 #include "MULTIPR_API.hxx"
24 #include "MULTIPR_Exceptions.hxx"
25 #include "MULTIPR_ProgressCallback.hxx"
27 #include "MEDSPLITTER_API.hxx"
39 //*****************************************************************************
40 // Global variables (exported)
41 //*****************************************************************************
43 MULTIPR_ProgressCallback* gProgressCallback = NULL;
46 //*****************************************************************************
47 // Class MeshDisEntry implementation
48 //*****************************************************************************
50 MeshDisPart::MeshDisPart()
54 mOldCollection = NULL;
60 MeshDisPart::~MeshDisPart()
66 void MeshDisPart::reset()
68 mToDoOnNextWrite = MULTIPR_UNDEFINED;
74 mMEDFileName[0] = '\0';
84 if (mCollection != NULL)
90 if (mOldCollection != NULL)
92 delete mOldCollection;
93 mOldCollection = NULL;
98 const char* MeshDisPart::getMEDFileNameSuffix() const
100 // "agregat100grains_12pas_grain97.med" -> "grain97"
101 // "agregat100grains_12pas_grain100_part2.med" -> "grain100_part2"
102 // "aagregat100grains_12pas_grain98_gradmoy-low-25.0-0.3.med" -> "grain98_gradmoy-low-25-0.3"
104 string prefix = removeExtension(mMEDFileName, ".med");
105 prefix.erase(0, prefix.rfind("grain"));
106 return prefix.c_str();
110 void MeshDisPart::create(
111 OnNextWrite pToDoOnNextWrite,
112 const char* pMeshName,
114 const char* pPartName,
116 const char* pMEDFileName,
119 if (pToDoOnNextWrite == MULTIPR_UNDEFINED) throw IllegalArgumentException("", __FILE__, __LINE__);
120 if (pMeshName == NULL) throw NullArgumentException("", __FILE__, __LINE__);
121 if (pId < 1) throw IllegalArgumentException("", __FILE__, __LINE__);
122 if (pPartName == NULL) throw NullArgumentException("", __FILE__, __LINE__);
123 if (pPath == NULL) throw NullArgumentException("", __FILE__, __LINE__);
124 if (pMEDFileName == NULL) throw NullArgumentException("", __FILE__, __LINE__);
128 mToDoOnNextWrite = pToDoOnNextWrite;
129 strcpy(mMeshName, pMeshName);
131 strcpy(mPartName, pPartName);
132 strcpy(mPath, pPath);
133 strcpy(mMEDFileName, pMEDFileName);
139 void MeshDisPart::readMED()
141 if (mMesh != NULL) throw IllegalStateException("", __FILE__, __LINE__);
142 if (mCollection != NULL) throw IllegalStateException("", __FILE__, __LINE__);
143 if (mOldCollection != NULL) throw IllegalStateException("", __FILE__, __LINE__);
145 //cout << "read MED : mesh=" << mMEDfilename << endl;
148 mMesh->readSequentialMED(mMEDFileName, mMeshName);
152 ostream& operator<<(ostream& pOs, MeshDisPart& pM)
154 switch (pM.mToDoOnNextWrite)
156 case MeshDisPart::MULTIPR_UNDEFINED:
160 case MeshDisPart::MULTIPR_KEEP_AS_IT:
161 pOs << pM.mMeshName << " " << pM.mId << " " << pM.mPartName << " " << pM.mPath << " " << pM.mMEDFileName;
164 case MeshDisPart::MULTIPR_WRITE_MESH:
165 pOs << pM.mMeshName << " " << pM.mId << " " << pM.mPartName << " " << pM.mPath << " " << pM.mMEDFileName;
168 case MeshDisPart::MULTIPR_WRITE_PARTS:
169 pOs << pM.mMeshName << " " << pM.mId << " " << pM.mPartName << " " << pM.mPath << " " << pM.mMEDFileName << " SPLIT " << pM.mSplit;
172 default: throw IllegalStateException("", __FILE__, __LINE__);
179 //*****************************************************************************
180 // Class MeshDis implementation
181 //*****************************************************************************
195 void MeshDis::reset()
197 mMEDfilename[0] = '\0';
199 for (unsigned itPart = 0 ; itPart != mParts.size() ; itPart++)
201 MeshDisPart* part = mParts[itPart];
206 //mProgressCallback = NULL;
210 void MeshDis::addMesh(
211 MeshDisPart::OnNextWrite pToDoOnNextWrite,
212 const char* pMeshName,
214 const char* pPartName,
216 const char* pMEDFileName,
219 MeshDisPart* part = new MeshDisPart();
230 mParts.push_back(part);
234 void MeshDis::insertMesh(
235 MeshDisPart::OnNextWrite pToDoOnNextWrite,
236 const char* pMeshName,
238 const char* pPartName,
240 const char* pMEDFileName,
244 MeshDisPart* part = new MeshDisPart();
255 mParts.insert(mParts.begin() + pPosition, part);
257 // rename id of following parts
258 for (unsigned i = pPosition + 1 ; i < mParts.size() ; i++)
265 void MeshDis::removeParts(const char* pPrefixPartName)
267 if (pPrefixPartName == NULL) throw NullArgumentException("", __FILE__, __LINE__);
270 sprintf(strPrefix, "%s_", pPrefixPartName);
272 for (vector<MeshDisPart*>::iterator itPart = mParts.begin() ; itPart != mParts.end() ; itPart++)
274 MeshDisPart* currentPart = (*itPart);
276 // remove part which have the same name and all sub_parts
277 // e.g. if pPrefixPartName="PART_4" => remove "PART_4" and "PART_4_*", but not "PART41"
278 if ((strcmp(currentPart->getPartName(), pPrefixPartName) == 0) ||
279 startsWith(currentPart->getPartName(), strPrefix))
281 mParts.erase(itPart);
283 // decrement id of following parts
284 for (vector<MeshDisPart*>::iterator itPart2 = itPart ; itPart2 != mParts.end() ; itPart2++)
290 if (currentPart->mMEDFileName != NULL)
292 remove(currentPart->mMEDFileName);
301 MeshDisPart* MeshDis::findPart(const char* pPartName)
303 if (pPartName == NULL) throw NullArgumentException("", __FILE__, __LINE__);
305 MeshDisPart* part = NULL;
307 for (unsigned itPart = 0 ; itPart < mParts.size() ; itPart++)
309 MeshDisPart* currentPart = mParts[itPart];
311 if (strcmp(currentPart->getPartName(), pPartName) == 0)
323 vector<string> MeshDis::getMeshes() const
327 if (mParts.size() > 0)
329 MeshDisPart* part = mParts[0];
330 const char* meshName = part->getMeshName();
331 res.push_back(meshName);
338 vector<string> MeshDis::getFields() const
342 if (mParts.size() == 0)
347 // all the parts of the distributed MED file should have the same fields
348 // => just return the name of fields of the first part
349 switch (mParts[0]->mToDoOnNextWrite)
351 case MeshDisPart::MULTIPR_KEEP_AS_IT:
352 case MeshDisPart::MULTIPR_WRITE_PARTS:
354 vector<pair<string, int> > tmp = multipr::getListScalarFields(mParts[0]->getMEDFileName());
356 for (int i = 0 ; i < tmp.size() ; i++)
358 res.push_back(tmp[i].first);
363 case MeshDisPart::MULTIPR_WRITE_MESH:
364 return mParts[0]->mMesh->getNameScalarFields();
367 throw IllegalStateException("", __FILE__, __LINE__);
372 int MeshDis::getTimeStamps(const char* pFieldName) const
374 if (mParts.size() == 0)
376 // no parts in this distributed MED file => no fields => #iteration = 0
380 // all the parts of the distributed MED file should have the same fields
381 // => just return the number of iteration found in the field of the first part
382 switch (mParts[0]->mToDoOnNextWrite)
384 case MeshDisPart::MULTIPR_KEEP_AS_IT:
385 case MeshDisPart::MULTIPR_WRITE_PARTS:
387 vector<pair<string, int> > tmp = multipr::getListScalarFields(mParts[0]->getMEDFileName());
389 for (int i = 0 ; i < tmp.size() ; i++)
391 if (strcmp(tmp[i].first.c_str(), pFieldName) == 0)
393 return tmp[i].second;
397 // pFieldName not found in the list of fields
401 case MeshDisPart::MULTIPR_WRITE_MESH:
402 return mParts[0]->mMesh->getTimeStamps(pFieldName);
405 throw IllegalStateException("", __FILE__, __LINE__);
410 string MeshDis::getPartInfo(const char* pPartName)
412 MeshDisPart* part = findPart(pPartName);
417 sprintf(num, "%d", part->mId);
420 string(part->mMeshName) +
424 string(part->mPartName) +
426 string(part->mPath) +
428 string(part->mMEDFileName);
434 // part not found => return empty string
440 void MeshDis::splitPart(const char* pPartName, int pNbParts, int pPartitionner)
442 cout << "MULTIPR: MeshDis::splitPart()" << endl;
443 if (pPartName == NULL) throw NullArgumentException("", __FILE__, __LINE__);
444 if (pNbParts < 2) throw IllegalArgumentException("", __FILE__, __LINE__);
445 if ((pPartitionner != MULTIPR_METIS) && (pPartitionner != MULTIPR_SCOTCH)) throw IllegalArgumentException("should be 0=METIS or 1=SCOTCH", __FILE__, __LINE__);
447 cout << "MULTIPR: MeshDis::splitPart(): args OK" << endl;
448 //---------------------------------------------------------------------
449 // Find the MED file corresponding to the given part
450 //---------------------------------------------------------------------
451 MeshDisPart* part = findPart(pPartName);
455 throw IllegalArgumentException("part not found in this distributed MED file", __FILE__, __LINE__);
458 cout << "MULTIPR: MeshDis::splitPart(): find part OK" << endl;
460 //---------------------------------------------------------------------
461 // Load the sequential MED file
462 //---------------------------------------------------------------------
463 MEDSPLITTER::MESHCollection* collection;
464 collection = new MEDSPLITTER::MESHCollection(part->getMEDFileName(), part->getMeshName());
466 cout << "MULTIPR: MeshDis::splitPart(): MEDSPLITTER collection OK" << endl;
467 //---------------------------------------------------------------------
468 // Partition the group
469 //---------------------------------------------------------------------
470 MEDSPLITTER::Topology* topology;
471 if (pPartitionner == MULTIPR_METIS)
475 topology = collection->createPartition(pNbParts, MEDSPLITTER::Graph::METIS);
479 throw RuntimeException("MEDSPLITTER error: createPartition(), using METIS", __FILE__, __LINE__);
482 else if (pPartitionner == MULTIPR_SCOTCH)
486 cout << "MULTIPR: try to create partition using SCOTCH: #parts=" << pNbParts << endl;
487 topology = collection->createPartition(pNbParts, MEDSPLITTER::Graph::SCOTCH);
488 cout << "MULTIPR: assigned SCOTCH" << endl;
492 throw RuntimeException("MEDSPLITTER error: createPartition(), using SCOTCH", __FILE__, __LINE__);
497 throw IllegalStateException("unknown partitionner", __FILE__, __LINE__);
502 MEDSPLITTER::MESHCollection* newCollection = new MEDSPLITTER::MESHCollection(*collection, topology);
504 part->mToDoOnNextWrite = MeshDisPart::MULTIPR_WRITE_PARTS;
505 part->mSplit = pNbParts;
506 part->mOldCollection = collection;
507 part->mCollection = newCollection;
511 cout << "MEDSPLITTER error: new MESHCollection()" << endl;
512 throw RuntimeException("MEDSPLITTER error: new MESHCollection()", __FILE__, __LINE__);
517 void MeshDis::decimatePart(
518 const char* pPartName,
519 const char* pFieldName,
521 const char* pFilterName,
527 //---------------------------------------------------------------------
529 //---------------------------------------------------------------------
530 if (pPartName == NULL) throw NullArgumentException("partname should not be NULL", __FILE__, __LINE__);
531 if (pFieldName == NULL) throw NullArgumentException("fieldname should not be NULL", __FILE__, __LINE__);
532 if (pFieldIt < med_int(1)) throw IllegalArgumentException("invalid field iteration; should be >= 1", __FILE__, __LINE__);
533 if (pTMed < 0.0) throw IllegalArgumentException("med res.: threshold must be > 0", __FILE__, __LINE__);
534 if (pTMed >= pTLow) throw IllegalArgumentException("threshold for med res. must be < threshold for low res.", __FILE__, __LINE__);
535 if (pRadius <= med_float(0.0)) throw IllegalArgumentException("radius should be > 0", __FILE__, __LINE__);
536 if ((pBoxing < 1) || (pBoxing > 200)) throw IllegalArgumentException("boxing should be in [1..200]", __FILE__, __LINE__);
538 //---------------------------------------------------------------------
539 // Find the MED file corresponding to the given part
540 //---------------------------------------------------------------------
541 MeshDisPart* part = findPart(pPartName);
544 throw IllegalArgumentException("part not found in the given distributed MED file", __FILE__, __LINE__);
547 //---------------------------------------------------------------------
548 // Load the associated sequential MED file
549 //---------------------------------------------------------------------
550 if (part->mMesh == NULL)
555 Mesh* meshFull = part->mMesh;
556 cout << (*meshFull) << endl;
558 const char* originalFilename = part->getMEDFileName();
559 string strPrefix = removeExtension(originalFilename, ".med");
562 //cout << (*this) << endl;
564 //---------------------------------------------------------------------
565 // Decimates the given mesh
566 //---------------------------------------------------------------------
567 // arguments for decimation are passed as a string for genericity
569 char newPartName[MED_TAILLE_NOM + 1];
570 char newMEDFileName[256];
572 // *** create a new mesh = MEDIUM resolution ***
573 sprintf(argv, "%s %d %lf %lf %d", pFieldName, pFieldIt, pTMed, pRadius, pBoxing);
574 sprintf(newPartName, "%s_MED", pPartName);
575 sprintf(newMEDFileName, "%s_gradmoy-med-%s-%s.med",
577 realToString(pTMed).c_str(),
578 realToString(pRadius).c_str());
581 Mesh* meshMedium = meshFull->decimate(pFilterName, argv, part->getMeshName());
582 cout << (*meshMedium) << endl;
585 MeshDisPart::MULTIPR_WRITE_MESH,
595 // *** create a new mesh = LOW resolution ***
596 sprintf(argv, "%s %d %lf %lf %d", pFieldName, pFieldIt, pTLow, pRadius, pBoxing);
597 sprintf(newPartName, "%s_LOW", pPartName);
598 sprintf(newMEDFileName, "%s_gradmoy-low-%s-%s.med",
600 realToString(pTLow).c_str(),
601 realToString(pRadius).c_str());
604 Mesh* meshLow = meshFull->decimate(pFilterName, argv, part->getMeshName());
605 cout << (*meshLow) << endl;
608 MeshDisPart::MULTIPR_WRITE_MESH,
619 //cout << (*this) << endl;
623 string MeshDis::evalDecimationParams(
624 const char* pPartName,
625 const char* pFieldName,
627 const char* pFilterName,
628 const char* pFilterParams)
630 MeshDisPart* part = findPart(pPartName);
638 if (part->mMesh == NULL)
643 multipr::DecimationFilter* filter = multipr::DecimationFilter::create(pFilterName);
649 multipr::DecimationFilterGradAvg* filterGrad = dynamic_cast<multipr::DecimationFilterGradAvg*>(filter);
651 if (filterGrad != NULL)
655 int ret = sscanf(pFilterParams, "%d", &mode);
657 // mode 2 = GET RADIUS
658 if ((ret == 1) && (mode == 2))
660 double radius = part->mMesh->evalDefaultRadius(8);
662 sprintf(res, "%f", radius);
669 ret = sscanf(pFilterParams, "%d %f %d", &mode, &radius, &boxing);
671 // mode 1 = GET GRADIENT MIN, MAX and AVG
672 if ((ret == 3) && (mode == 1))
674 double gradMin = 0.1, gradAvg = 0.15, gradMax = 0.2;
676 filterGrad->getGradientInfo(
687 sprintf(res, "%f %f %f", gradMin, gradAvg, gradMax);
702 int MeshDis::computeNumParts()
706 for (unsigned itPart = 0 ; itPart < mParts.size() ; itPart++)
708 switch (mParts[itPart]->mToDoOnNextWrite)
710 case MeshDisPart::MULTIPR_KEEP_AS_IT:
711 case MeshDisPart::MULTIPR_WRITE_MESH:
715 case MeshDisPart::MULTIPR_WRITE_PARTS:
716 numParts += mParts[itPart]->mSplit;
719 default: throw IllegalStateException("", __FILE__, __LINE__);
727 void MeshDis::readDistributedMED(const char* pMEDfilename)
729 //cout << "DBG: readDistributedMED" << endl;
730 if (pMEDfilename == NULL) throw NullArgumentException("filename should not be NULL", __FILE__, __LINE__);
732 const int MAX_SIZEOF_LINE = 1024;
735 strcpy(mMEDfilename, pMEDfilename);
737 //---------------------------------------------------------------------
738 // Open master file (ASCII file)
739 //---------------------------------------------------------------------
740 ifstream fileMaster(mMEDfilename);
741 if (fileMaster.fail()) throw IOException("i/o error while opening MED master file", __FILE__, __LINE__);
743 //cout << "DBG: readDistributedMED: open" << endl;
745 //---------------------------------------------------------------------
747 //---------------------------------------------------------------------
748 char charbuffer[MAX_SIZEOF_LINE];
749 fileMaster.getline(charbuffer, MAX_SIZEOF_LINE);
750 if (fileMaster.fail()) throw IOException("i/o error while reading MED master file", __FILE__, __LINE__);
753 if ((charbuffer[0] != '#') ||
754 (charbuffer[1] != ' ') ||
755 (charbuffer[2] != 'M') ||
756 (charbuffer[3] != 'E') ||
757 (charbuffer[4] != 'D'))
758 throw IOException("not a valid distributed MED file", __FILE__, __LINE__);
760 while ((charbuffer[0] == '#') || (strlen(charbuffer) == 0))
762 fileMaster.getline(charbuffer, MAX_SIZEOF_LINE);
763 if (fileMaster.fail()) throw IOException("i/o error while reading MED master file", __FILE__, __LINE__);
766 // read number of parts
767 int nbParts = atoi(charbuffer);
768 //cout << "readDistributedMED: #parts=" << nbParts << endl;
770 //---------------------------------------------------------------------
771 // Read infos about sub-parts
772 //---------------------------------------------------------------------
773 char lMeshName[MED_TAILLE_NOM + 1];
775 char lPartName[MED_TAILLE_NOM + 1];
777 char lMEDFileName[256];
779 for (int i = 0 ; i < nbParts ; i++)
781 fileMaster.getline(charbuffer, MAX_SIZEOF_LINE);
782 if (fileMaster.fail()) throw IOException("i/o error while reading MED master file", __FILE__, __LINE__);
784 while ((charbuffer[0] == '#') || (strlen(charbuffer) == 0))
786 fileMaster.getline(charbuffer, MAX_SIZEOF_LINE);
787 if (fileMaster.fail()) throw IOException("i/o error while reading MED master file", __FILE__, __LINE__);
794 lMEDFileName[0] = '\0';
796 int ret = sscanf(charbuffer, "%s %d %s %s %s",
803 if (ret != 5) throw IOException("i/o error while reading MED master file; bad format", __FILE__, __LINE__);
805 //cout << "DBG: read: " << lMeshName << " " << lId << " " << lPartName << endl;
807 MeshDisPart::MULTIPR_KEEP_AS_IT,
816 //---------------------------------------------------------------------
818 //---------------------------------------------------------------------
820 if (fileMaster.fail()) throw IOException("i/o error while closing MED master file", __FILE__, __LINE__);
825 * Retrieves the output of MEDSPLITTER and convert it for MULTIPR.
827 int convertMedsplitterToMultipr(ofstream& pFileMaster, const char* pTmpFilename, int pId, MeshDisPart* pPart, string pDestPath)
829 MULTIPR_LOG("convert" << endl);
831 const int MAX_SIZEOF_LINE = 1024;
832 char charbuffer[MAX_SIZEOF_LINE];
834 // Open medsplitter master file (ASCII file)
835 ifstream fileMasterMedsplitter(pTmpFilename);
836 if (fileMasterMedsplitter.fail()) throw IOException("i/o error while opening MEDSPLITTER master file", __FILE__, __LINE__);
838 fileMasterMedsplitter.getline(charbuffer, MAX_SIZEOF_LINE);
839 if (fileMasterMedsplitter.fail()) throw IOException("i/o error while reading MEDSPLITTER master file", __FILE__, __LINE__);
841 while ((charbuffer[0] == '#') || (strlen(charbuffer) == 0))
843 fileMasterMedsplitter.getline(charbuffer, MAX_SIZEOF_LINE);
844 if (fileMasterMedsplitter.fail()) throw IOException("i/o error while reading MEDSPLITTER master file", __FILE__, __LINE__);
847 // read number of parts
848 int nbParts = atoi(charbuffer);
849 //cout << "nb parts=" << nbParts << endl;
851 char lMeshName[MED_TAILLE_NOM + 1];
853 char lPartName[MED_TAILLE_NOM + 1];
855 char lMEDFileName[256];
857 for (int i = 0 ; i < nbParts ; i++)
859 fileMasterMedsplitter.getline(charbuffer, MAX_SIZEOF_LINE);
860 if (fileMasterMedsplitter.fail()) throw IOException("", __FILE__, __LINE__);
862 // parses the current line
867 lMEDFileName[0] = '\0';
869 int ret = sscanf(charbuffer, "%s %d %s %s %s",
876 if (ret != 5) throw IOException("i/o error while reading MEDSPLITTER master file; bad format", __FILE__, __LINE__);
878 //cout << lMeshName << " " << (pId + i) << " " << pPart->getPartName() << "_" << (i + 1) << " " << lPath << " " << lMEDFileName << endl;
880 string strDestFilename = pDestPath + multipr::getFilenameWithoutPath(lMEDFileName);
881 if (strcmp(lMEDFileName, strDestFilename.c_str()) != 0)
883 multipr::copyFile(lMEDFileName, pDestPath.c_str());
884 strcpy(lMEDFileName, strDestFilename.c_str());
887 pFileMaster << lMeshName << " " << (pId + i) << " " << pPart->getPartName() << "_" << (i + 1) << " " << lPath << " " << lMEDFileName << endl;
890 fileMasterMedsplitter.close();
891 if (fileMasterMedsplitter.fail()) throw IOException("i/o error while closing MEDSPLITTER master file", __FILE__, __LINE__);
893 // remove master file generated by MEDSPLITTER
894 remove(pTmpFilename);
900 void MeshDis::writeDistributedMED(const char* pMEDfilenamePrefix)
902 if (pMEDfilenamePrefix == NULL) throw NullArgumentException("", __FILE__, __LINE__);
904 //---------------------------------------------------------------------
905 // Build master filename
906 //---------------------------------------------------------------------
907 string strPrefix = string(pMEDfilenamePrefix);
908 const char* strExtension = ".med";
909 string strMasterFilename;
911 // add suffix "_grains_maitre" iff it is not yet in the filename
912 if (strstr(pMEDfilenamePrefix, "_grains_maitre") == 0)
914 strMasterFilename= strPrefix + "_grains_maitre" + strExtension;
918 strMasterFilename = strPrefix + strExtension;
921 string strDestPath = multipr::getPath(strMasterFilename.c_str());
923 MULTIPR_LOG("Create master: " << strMasterFilename << endl);
924 strcpy(mMEDfilename, strMasterFilename.c_str());
926 //---------------------------------------------------------------------
927 // Create an ASCII master file for the resulting distributed mesh and write header
928 //---------------------------------------------------------------------
929 remove(strMasterFilename.c_str());
930 ofstream fileMaster(strMasterFilename.c_str());
932 if (fileMaster == 0) throw IOException("i/o error while creating MED master file", __FILE__, __LINE__);
934 fileMaster << "# MED file v2.3 - Master file created by MULTIPR v" << getVersion() << endl;
935 fileMaster << "#" << " " << endl;
937 fileMaster << computeNumParts() << endl;
938 if (fileMaster.fail()) throw IOException("i/o error while writing MED master file", __FILE__, __LINE__);
940 //---------------------------------------------------------------------
941 // Create a new MED file (v2.3)
942 //---------------------------------------------------------------------
945 if (gProgressCallback != NULL) gProgressCallback->start("Save mesh", mParts.size());
950 // for each sub-meshes
951 for (unsigned itPart = 0 ; itPart < mParts.size() ; itPart++)
953 switch (mParts[itPart]->mToDoOnNextWrite)
955 case MeshDisPart::MULTIPR_KEEP_AS_IT:
957 mParts[itPart]->mId = id;
960 // copy file in another directory?
961 string strSrcPath = multipr::getPath(mParts[itPart]->getMEDFileName());
962 if (strSrcPath != strDestPath)
964 cout << "Write: KEEP_AS_IT: copy file" << endl;
965 string strDestFilename = strDestPath + multipr::getFilenameWithoutPath(mParts[itPart]->getMEDFileName());
966 multipr::copyFile(mParts[itPart]->getMEDFileName(), strDestPath.c_str());
967 strcpy(mParts[itPart]->mMEDFileName, strDestFilename.c_str());
970 fileMaster << (*mParts[itPart]) << endl;
971 cout << (*mParts[itPart]) << endl;
975 case MeshDisPart::MULTIPR_WRITE_MESH:
977 if (strlen(mParts[itPart]->getMEDFileName()) == 0) throw IOException("MED filename is empty", __FILE__, __LINE__);
978 if (mParts[itPart]->mMesh == NULL) throw IllegalStateException("invalid mesh (shoult not be NULL)", __FILE__, __LINE__);
980 string strDestFilename = strDestPath + multipr::getFilenameWithoutPath(mParts[itPart]->getMEDFileName());
981 strcpy(mParts[itPart]->mMEDFileName, strDestFilename.c_str());
983 mParts[itPart]->mMesh->writeMED(mParts[itPart]->getMEDFileName());
984 mParts[itPart]->mId = id;
986 fileMaster << (*mParts[itPart]) << endl;
987 cout << (*mParts[itPart]) << endl;
991 case MeshDisPart::MULTIPR_WRITE_PARTS:
993 // split this part using medsplitter
994 if (mParts[itPart]->mOldCollection == NULL) throw IllegalStateException("", __FILE__, __LINE__);
995 string strPrefix = removeExtension(mParts[itPart]->getMEDFileName(), ".med");
996 char tmpFilename[256];
997 sprintf(tmpFilename, "%s_part", strPrefix.c_str());
998 mParts[itPart]->mCollection->write(tmpFilename);
999 mParts[itPart]->mCollection->castAllFields(*(mParts[itPart]->mOldCollection));
1000 int ret = convertMedsplitterToMultipr(fileMaster, tmpFilename, id, mParts[itPart], strDestPath);
1002 remove(mParts[itPart]->getMEDFileName());
1006 default: throw IllegalStateException("should not be there", __FILE__, __LINE__);
1009 if (gProgressCallback != NULL) gProgressCallback->moveOn();
1013 catch (RuntimeException& e)
1015 if (gProgressCallback != NULL) gProgressCallback->done();
1019 if (gProgressCallback != NULL) gProgressCallback->done();
1021 //---------------------------------------------------------------------
1022 // Close master file
1023 //---------------------------------------------------------------------
1025 if (fileMaster.fail()) throw IOException("i/o error while closing MED master file", __FILE__, __LINE__);
1029 ostream& operator<<(ostream& pOs, MeshDis& pM)
1031 pOs << "Mesh Dis.:" << endl;
1032 pOs << " Filename =|" << pM.mMEDfilename << "|" << endl;
1033 pOs << " #Sub-meshes=" << pM.mParts.size() << endl;
1035 for (unsigned itPart = 0 ; itPart < pM.mParts.size() ; itPart++)
1037 cout << " " << (itPart + 1) << ": " << (*(pM.mParts[itPart])) << endl;
1044 } // namespace multipr