#include "SALOMEDSClient_AttributeComment.hxx"
#include "SALOMEDSClient_AttributeName.hxx"
+#include "CASCatch.hxx"
#include <qpixmap.h>
#include <qimage.h>
#include <qstrlist.h>
+#include <qdir.h>
using namespace std;
if (!CORBA::is_nil(theView3D)) {
VISU::View3D_i* pView = dynamic_cast<VISU::View3D_i*>(GetServant(theView3D).in());
SUIT_ViewWindow* aVW = pView->GetViewWindow();
- myView = VISU::GetViewWindow(aVW);
+ myView = dynamic_cast<SVTK_ViewWindow*>(aVW);
connect( myView, SIGNAL( destroyed() ), this, SLOT( onViewDeleted() ) );
}
- myMaxVal = 0;
- myMinVal = 0;
+ myTimeMinVal = 0;
+ myTimeMaxVal = 0;
myTimeMin = 0;
myTimeMax = 0;
myLastError = "";
myCycling = false;
myAnimEntry = "";
+
+ myDumpPath = "";
+ myAVIMaker = "jpeg2yuv";
}
for (int i = 0; i < getNbFields(); i++) {
clearData(myFieldsLst[i]);
}
+
+ /* Terminates the execution of the thread.
+ * The thread may or may not be terminated immediately,
+ * depending on the operating system's scheduling policies.
+ *
+ * Use QThread::wait() after terminate() for synchronous termination.
+ *
+ * When the thread is terminated, all threads waiting for the the thread to finish will be woken up.
+ *
+ * Warning: This function is dangerous, and its use is discouraged.
+ * The thread can be terminated at any point in its code path.
+ * Threads can be terminated while modifying data.
+ * There is no chance for the thread to cleanup after itself,
+ * unlock any held mutexes, etc. In short, use this function only if absolutely necessary.
+ */
+ myDumpPath = "";
+ QThread::wait(100);
+ QThread::terminate();
+ QThread::wait(400);
}
FieldData& theData,
VISU::Result_i* theResult,
bool theIsRangeDefined,
- CORBA::Double theMinVal,
- CORBA::Double theMaxVal)
+ CORBA::Double theTimeMin,
+ CORBA::Double theTimeMax)
{
double aMin = VTK_LARGE_FLOAT, aMax = -VTK_LARGE_FLOAT;
+
_PTR(ChildIterator) anIter = theStudy->NewChildIterator(theData.myField);
anIter->Next(); // First is reference on support
theData.myTiming[aFrameId] = VISU_TimeAnimation::getTimeValue(aTimeStamp);
if (theIsRangeDefined) {
- if (theData.myTiming[aFrameId] < theMinVal)
+ if (theData.myTiming[aFrameId] < theTimeMin)
continue;
- if (theData.myTiming[aFrameId] > theMaxVal)
+ if (theData.myTiming[aFrameId] > theTimeMax)
break;
}
QString aFieldName = VISU::Storable::FindValue(aTimeMap,"myFieldName");
int aTimeStampId = VISU::Storable::FindValue(aTimeMap,"myTimeStampId").toInt();
+ bool anIsCreated = false;
TPrs3d* aPresent = new TPrs3d(theResult, false);
- aPresent->Create(aMeshName.latin1(), anEntity,
- aFieldName.latin1(), aTimeStampId);
- theData.myPrs[aFrameId++] = aPresent;
-
- aMin = std::min(aPresent->GetMin(),aMin);
- aMax = std::min(aPresent->GetMax(),aMax);
+ CASCatch_TRY{
+ try{
+ if(aPresent->Create(aMeshName.latin1(),anEntity,aFieldName.latin1(),aTimeStampId)){
+ anIsCreated = true;
+ theData.myPrs[aFrameId++] = aPresent;
+ aMin = std::min(aPresent->GetMin(), aMin);
+ aMax = std::max(aPresent->GetMax(), aMax);
+ }
+ }catch(std::exception& exc){
+ INFOS("Follow exception was occured :\n"<<exc.what());
+ }catch(...){
+ INFOS("Unknown exception was occured!");
+ }
+ }CASCatch_CATCH(Standard_Failure) {
+ Handle(Standard_Failure) aFail = Standard_Failure::Caught();
+ INFOS("Follow signal was occured :\n"<<aFail->GetMessageString());
+ }
+ if(!anIsCreated)
+ aPresent->_remove_ref();
}
theData.myNbFrames = aFrameId;
using namespace VISU;
switch (aData.myPrsType) {
case VISU::TSCALARMAP: // ScalarMap
- GeneratePresentations<ScalarMap_i>(myStudy,aData,aResult,isRangeDefined(),myMinVal,myMaxVal);
+ GeneratePresentations<ScalarMap_i>(myStudy,
+ aData,
+ aResult,
+ isRangeDefined(),
+ myTimeMinVal,
+ myTimeMaxVal);
break;
case VISU::TISOSURFACE: // Iso Surfaces
- GeneratePresentations<IsoSurfaces_i>(myStudy,aData,aResult,isRangeDefined(),myMinVal,myMaxVal);
+ GeneratePresentations<IsoSurfaces_i>(myStudy,
+ aData,
+ aResult,
+ isRangeDefined(),
+ myTimeMinVal,
+ myTimeMaxVal);
break;
case VISU::TCUTPLANES: // Cut Planes
- GeneratePresentations<CutPlanes_i>(myStudy,aData,aResult,isRangeDefined(),myMinVal,myMaxVal);
+ GeneratePresentations<CutPlanes_i>(myStudy,
+ aData,
+ aResult,
+ isRangeDefined(),
+ myTimeMinVal,
+ myTimeMaxVal);
+ break;
+ case VISU::TCUTLINES: // Cut Lines
+ GeneratePresentations<CutLines_i>(myStudy,
+ aData,
+ aResult,
+ isRangeDefined(),
+ myTimeMinVal,
+ myTimeMaxVal);
break;
case VISU::TPLOT3D: // Plot3d
- GeneratePresentations<Plot3D_i>(myStudy,aData,aResult,isRangeDefined(),myMinVal,myMaxVal);
+ GeneratePresentations<Plot3D_i>(myStudy,
+ aData,
+ aResult,
+ isRangeDefined(),
+ myTimeMinVal,
+ myTimeMaxVal);
break;
case VISU::TDEFORMEDSHAPE: // Deformed Shape
- GeneratePresentations<DeformedShape_i>(myStudy,aData,aResult,isRangeDefined(),myMinVal,myMaxVal);
+ GeneratePresentations<DeformedShape_i>(myStudy,
+ aData,
+ aResult,
+ isRangeDefined(),
+ myTimeMinVal,
+ myTimeMaxVal);
break;
case VISU::TVECTORS: // Vectors
- GeneratePresentations<Vectors_i>(myStudy,aData,aResult,isRangeDefined(),myMinVal,myMaxVal);
+ GeneratePresentations<Vectors_i>(myStudy,
+ aData,
+ aResult,
+ isRangeDefined(),
+ myTimeMinVal,
+ myTimeMaxVal);
break;
case VISU::TSTREAMLINES: // Stream Lines
- GeneratePresentations<StreamLines_i>(myStudy,aData,aResult,isRangeDefined(),myMinVal,myMaxVal);
+ GeneratePresentations<StreamLines_i>(myStudy,
+ aData,
+ aResult,
+ isRangeDefined(),
+ myTimeMinVal,
+ myTimeMaxVal);
break;
case VISU::TGAUSSPOINTS: // Gauss Points
- GeneratePresentations<GaussPoints_i>(myStudy,aData,aResult,isRangeDefined(),myMinVal,myMaxVal);
+ GeneratePresentations<GaussPoints_i>(myStudy,
+ aData,
+ aResult,
+ isRangeDefined(),
+ myTimeMinVal,
+ myTimeMaxVal);
break;
case VISU::TSCALARMAPONDEFORMEDSHAPE: // Scalar map on deformed shape
- GeneratePresentations<ScalarMapOnDeformedShape_i>(myStudy,aData,aResult,isRangeDefined(),myMinVal,myMaxVal);
+ GeneratePresentations<ScalarMapOnDeformedShape_i>(myStudy,
+ aData,
+ aResult,
+ isRangeDefined(),
+ myTimeMinVal,
+ myTimeMaxVal);
break;
default:
MESSAGE("Not implemented for this presentation type: " << aData.myPrsType);
double aOneVal = 1;
if (myFieldsLst[0].myNbFrames > 2)
aOneVal = myFieldsLst[0].myTiming[1] - myFieldsLst[0].myTiming[0];
+ myFileIndex = 0;
+ int aNbFiles = 0;
+ QValueList<int> anIndexList;
+
qApp->lock();
while (myIsActive) {
emit frameChanged(myFrame, myFieldsLst[0].myTiming[myFrame]);
+ if(!(myFieldsLst[0].myField))
+ break;
for (int i = 0; i < getNbFields(); i++) {
FieldData& aData = myFieldsLst[i];
if (myFrame > 0) {
}
}
int delay = (int)(1000. * k / mySpeed);
+ isDumping = !myDumpPath.isEmpty();
if (delay < 1 && isDumping) {
// We must unlock mutex for some time before grabbing to allow view updating
delay = 1;
if (isDumping) {
// We must unlock mutex for some time before grabbing to allow view updating
qApp->unlock();
- msleep(100);
+ msleep(delay);
qApp->lock();
+ if(!(myFieldsLst[0].myField)) // break, if field was deleted.
+ break;
+ if (myDumpFormat.compare("AVI") != 0) {
+ QString aFile(myDumpPath);
+ QString aName = QString("%1").arg(myFieldsLst[0].myTiming[myFrame]);
+ int aPos = -1;
+ while ((aPos = aName.find(".")) > -1 )
+ aName.replace(aPos, 1, "_");
+ aFile += aName;
+ aFile += ".";
+ aFile += myDumpFormat.lower();
+ myView->dumpViewToFormat(aFile,myDumpFormat);
+ } else {
+ QFileInfo aFileInfo(myDumpPath);
+ QString aDirPath = aFileInfo.dirPath(true);
+ QString aBaseName = aFileInfo.fileName();
+
+ switch (myFrame) {
+ case 0:
+ break;
+ case 1:
+ myFileIndex += 5;
+ break;
+ default:
+ if (myProportional) {
+ double p = (myFieldsLst[0].myTiming[myFrame] -
+ myFieldsLst[0].myTiming[myFrame-1]) / aOneVal;
+ myFileIndex += (long) (5*p);
+ } else {
+ myFileIndex += 5;
+ }
+ }
- QPixmap px = QPixmap::grabWindow(myView->winId());
- QString aFile(myDumpPath);
- QString aName = QString("%1").arg(myFieldsLst[0].myTiming[myFrame]);
- int aPos = -1;
- while ((aPos = aName.find(".")) > -1 )
- aName.replace(aPos, 1, "_");
- aFile += aName;
- aFile += ".";
- aFile += myDumpFormat.lower();
- px.save(aFile, myDumpFormat);
+ QString aFile = aDirPath + QDir::separator() + aBaseName;
+ aFile += "_";
+ aFile += QString("%1").arg(myFileIndex).rightJustify(8, '0');
+ aFile += ".jpeg";
+
+ /* check image size is divisable 16
+ myView->dumpViewToFormat(aFile,"JPEG");
+ */
+ SUIT_ViewWindow* aView = myView;
+ QImage img = aView->dumpView();
+ if (!img.isNull()) {
+ int width = img.width(); width = (width/16)*16;
+ int height = img.height(); height = (height/16)*16;
+ QImage copy = img.copy(0, 0, width, height);
+ if (copy.save(aFile, "JPEG")) {
+ anIndexList.append(myFileIndex);
+ aNbFiles++;
+ }
+ }
+ }
}
if (!myIsActive) break;
myFrame = 0;
}
}
+
+ // make AVI file if need
+ if (isDumping && myDumpFormat.compare("AVI") == 0) {
+ double aFPS = 17.3 * mySpeed;
+
+ QFileInfo aFileInfo(myDumpPath);
+ QString aDirPath = aFileInfo.dirPath(true);
+ QString aBaseName = aFileInfo.fileName();
+
+ // add missing files
+ if (anIndexList.count() > 1) {
+ QString aFFile = aDirPath + QDir::separator() + aBaseName;
+ aFFile += QString("_%1.jpeg");
+ int aStartIndex = anIndexList[0], anEndIndex;
+ for (int i = 1; i < anIndexList.count(); i++) {
+ anEndIndex = anIndexList[i];
+ QString aCurFile = aFFile.arg(QString::number(aStartIndex).rightJustify(8, '0'));
+ QStringList aCommands;
+ for (int j = aStartIndex+1; j < anEndIndex; j++) {
+ QString aFile = aFFile.arg(QString::number(j).rightJustify(8, '0'));
+ aCommands.append(QString("ln -s %1 %2").arg(aCurFile).arg(aFile));
+ }
+ system(aCommands.join(" ; \\\n").latin1());
+ aStartIndex = anEndIndex;
+ }
+ }
+
+ // make AVI file
+ QString aPattern = aDirPath + QDir::separator() + aBaseName;
+ aPattern += "_\%08d.jpeg";
+
+ QString aCmd = myAVIMaker;
+ aCmd += " -I p";
+ aCmd += " -v 0";
+ aCmd += QString(" -f %1").arg(aFPS);
+ // aCmd += QString(" -n %1").arg(aNbFiles);
+ aCmd += QString(" -n %1").arg(myFileIndex+1);
+ aCmd += QString(" -j %1").arg(aPattern);
+ aCmd += " | yuv2lav";
+ aCmd += QString(" -o %1").arg(myDumpPath);
+ system(aCmd.latin1());
+
+ // remove temporary jpeg files
+ aCmd = "( ";
+ aCmd += QString("cd %1").arg(aDirPath);
+ aCmd += "; ls";
+ aCmd += QString(" | egrep '%1_[0-9]*.jpeg'").arg(aBaseName);
+ aCmd += " | xargs rm";
+ aCmd += " )";
+ system(aCmd.latin1());
+ }
+
emit stopped();
qApp->unlock();
QThread::exit();
{
myDumpFormat = theFormat;
QStrList aDumpFormats = QImageIO::outputFormats();
- if (myDumpFormat.isEmpty() || aDumpFormats.find(theFormat) < 0) {
+ if (myDumpFormat.isEmpty() ||
+ (aDumpFormats.find(theFormat) < 0 && myDumpFormat.compare("AVI") != 0)) {
if (aDumpFormats.find("JPEG"))
myDumpFormat = "JPEG";
else
return myDumpFormat.latin1();
}
+//------------------------------------------------------------------------
+bool VISU_TimeAnimation::checkAVIMaker() const
+{
+ QStrList aDumpFormats = QImageIO::outputFormats();
+ if (aDumpFormats.find("JPEG") < 0) return false;
+
+ QString aCmd("which ");
+ aCmd += myAVIMaker;
+ aCmd += " >& /dev/null";
+ int iErr = system(aCmd.latin1());
+ return (iErr == 0);
+}
+
//************************************************************************
int VISU_TimeAnimation::myNBAnimations = 0;
QString VISU_TimeAnimation::GenerateName()
case VISU::TCUTPLANES:
aPrsCmt = VISU::CutPlanes_i::myComment;
break;
+ case VISU::TCUTLINES:
+ aPrsCmt = VISU::CutLines_i::myComment;
+ break;
case VISU::TPLOT3D:
aPrsCmt = VISU::Plot3D_i::myComment;
break;
std::string aSComponentEntry = aSComponent->GetID();
QString aComment;
- aComment.sprintf("myComment=ANIMATION;myType=%d;myMinVal=%g;myMaxVal=%g",
- VISU::TANIMATION,myMinVal,myMaxVal);
+ aComment.sprintf("myComment=ANIMATION;myType=%d;myTimeMinVal=%g;myTimeMaxVal=%g",
+ VISU::TANIMATION,myTimeMinVal,myTimeMaxVal);
string anEntry = VISU::CreateAttributes(myStudy,aSComponentEntry.c_str(),"","",
GenerateName(),"",aComment,true);
std::string aSComponentEntry = aSComponent->GetID();
QString aComment;
- aComment.sprintf("myComment=ANIMATION;myType=%d;myMinVal=%g;myMaxVal=%g",
- VISU::TANIMATION,myMinVal,myMaxVal);
+ aComment.sprintf("myComment=ANIMATION;myType=%d;myTimeMinVal=%g;myTimeMaxVal=%g",
+ VISU::TANIMATION,myTimeMinVal,myTimeMaxVal);
_PTR(GenericAttribute) anAttr;
anAttr = aStudyBuilder->FindOrCreateAttribute(aAnimSObject, "AttributeComment");
VISU::Storable::StrToMap(strIn,aMap);
bool isExist;
- myMinVal = VISU::Storable::FindValue(aMap,"myMinVal",&isExist).toDouble();
- myMaxVal = VISU::Storable::FindValue(aMap,"myMaxVal",&isExist).toDouble();
+ myTimeMinVal = VISU::Storable::FindValue(aMap,"myTimeMinVal",&isExist).toDouble();
+ myTimeMaxVal = VISU::Storable::FindValue(aMap,"myTimeMaxVal",&isExist).toDouble();
_PTR(ChildIterator) anIter = myStudy->NewChildIterator(aAnimSObject);
for (anIter->Init(); anIter->More(); anIter->Next()) {
aData.myPrsType = VISU::TISOSURFACE;
else if (strName == VISU::CutPlanes_i::myComment.c_str())
aData.myPrsType = VISU::TCUTPLANES;
+ else if (strName == VISU::CutLines_i::myComment.c_str())
+ aData.myPrsType = VISU::TCUTLINES;
else if (strName == VISU::Plot3D_i::myComment.c_str())
aData.myPrsType = VISU::TPLOT3D;
else if (strName == VISU::DeformedShape_i::myComment.c_str())
aData.myPrs[0]->GetOffset(aData.myOffset);
for (int i = 1; i < aData.myNbFrames; i++) {
//jfa 03.08.2005:aData.myPrs[i]->SameAs(aData.myPrs[0]);
- //enk 06.02.2006:aData.myPrs[i]->SameAsParams(aData.myPrs[0]);//jfa 03.08.2005
- aData.myPrs[i]->SameAsParams(aData.myPrs[i-1]);//enk 06.02.2006: initializing from previous presentation
+ aData.myPrs[i]->SameAsParams(aData.myPrs[0]);//jfa 03.08.2005
}
}
string aStr = aAnimSObject->GetID();