1 // Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : VISU_CutLinesBase_i.cc
23 // Author : Oleg UVAROV
26 #include "VISU_CutLinesBase_i.hh"
27 #include "VISU_Prs3dUtils.hh"
28 #include "VISU_Result_i.hh"
30 #include "VISU_Actor.h"
31 #include "VISU_CutLinesBasePL.hxx"
32 #include "VISU_Convertor.hxx"
33 #include "VISU_PipeLineUtils.hxx"
35 #include "SUIT_ResourceMgr.h"
37 #include <vtkAppendPolyData.h>
39 static vtkFloatingPointType EPS_machine = 1.0E-7;
42 static int MYDEBUG = 0;
44 static int MYDEBUG = 0;
49 //---------------------------------------------------------------
50 VISU::CutLinesBase_i::
51 CutLinesBase_i(EPublishInStudyMode thePublishInStudyMode) :
52 ColoredPrs3d_i(thePublishInStudyMode),
53 ScalarMap_i(thePublishInStudyMode),
54 myUseAbsLength( false ),
55 myCutLinesBasePL(NULL)
59 //---------------------------------------------------------------
62 ::SameAs(const Prs3d_i* theOrigin)
64 TSuperClass::SameAs(theOrigin);
66 if(const CutLinesBase_i* aPrs3d = dynamic_cast<const CutLinesBase_i*>(theOrigin)){
67 CutLinesBase_i* anOrigin = const_cast<CutLinesBase_i*>(aPrs3d);
68 myUseAbsLength = anOrigin->IsUseAbsoluteLength();
69 CopyCurvesInverted(anOrigin->GetCurvesInverted());
74 //---------------------------------------------------------------
75 /*! Copy map to /a myMapCurvesInverted.
76 * \param theCurves - map
80 ::CopyCurvesInverted(const TCurvesInv& theCurves)
82 myMapCurvesInverted = theCurves;
86 //---------------------------------------------------------------
89 ::Create(const std::string& theMeshName,
90 VISU::Entity theEntity,
91 const std::string& theFieldName,
92 CORBA::Long theTimeStampNumber)
94 SUIT_ResourceMgr* aResourceMgr = VISU::GetResourceMgr();
95 SetUseAbsoluteLength( aResourceMgr->booleanValue( "VISU", "use_absolute_length", false ) );
96 SetAllCurvesInverted( aResourceMgr->booleanValue( "VISU", "invert_all_curves", false ) );
97 return TSuperClass::Create(theMeshName,theEntity,theFieldName,theTimeStampNumber);
101 //---------------------------------------------------------------
104 ::Restore(SALOMEDS::SObject_ptr theSObject,
105 const Storable::TRestoringMap& theMap)
107 if(!TSuperClass::Restore(theSObject, theMap))
110 SetNbLines(VISU::Storable::FindValue(theMap,"myNbLines").toInt());
112 SetUseAbsoluteLength(VISU::Storable::FindValue(theMap,"myUseAbsLength").toInt());
114 // Restoring the map - \a myMapCurvesInverted
115 QStringList aMapCurvesInverted = VISU::Storable::FindValue(theMap,"myMapCurvesInverted").split("|",QString::SkipEmptyParts );
116 if (aMapCurvesInverted.count() == GetNbLines()){
117 for(int i = 0, iEnd = GetNbLines(); i < iEnd ; i++){
118 if(aMapCurvesInverted[i].toInt())
119 SetCurveInverted(i,true);
121 SetCurveInverted(i,false);
124 for(int i = 0, iEnd = GetNbLines(); i < iEnd ; i++)
125 SetCurveInverted(i,false);
132 //---------------------------------------------------------------
135 ::ToStream(std::ostringstream& theStr)
137 TSuperClass::ToStream(theStr);
139 Storable::DataToStream( theStr, "myNbLines", GetNbLines() );
141 Storable::DataToStream( theStr, "myUseAbsLength", IsUseAbsoluteLength());
143 // Storing the map - \a myMapCurvesInverted
144 QString aStrCurvesInverted;
145 for(int i = 0, iEnd = GetNbLines(); i < iEnd; i++)
146 aStrCurvesInverted.append(QString::number(IsCurveInverted(i)) + "|");
147 Storable::DataToStream( theStr, "myMapCurvesInverted", (const char*)aStrCurvesInverted.toLatin1());
151 //---------------------------------------------------------------
155 if(MYDEBUG) MESSAGE("CutLinesBase_i::~CutLinesBase_i()");
159 //---------------------------------------------------------------
162 ::SetNbLines(CORBA::Long theNb)
164 VISU::TSetModified aModified(this);
166 ProcessVoidEvent(new TVoidMemFun1ArgEvent<VISU_CutLinesBasePL, int>
167 (GetSpecificPL(), &VISU_CutLinesBasePL::SetNbParts, theNb));
170 //---------------------------------------------------------------
175 return myCutLinesBasePL->GetNbParts();
178 //---------------------------------------------------------------
179 /*! Invert all curves of corresponding table
180 * see void VISU::CutLinesBase_i::SetCurveInverted(CORBA::Long theCurveNumber,CORBA::Boolean theInvert)
181 * \param theInvert - Invert all curves, if value is TRUE, else not.
185 ::SetAllCurvesInverted(CORBA::Boolean theInvert)
187 for(int i=0; i < GetNbLines(); i++)
188 SetCurveInverted(i, theInvert);
191 //---------------------------------------------------------------
192 /*! Checks the orientation of all curves
193 * \retval TRUE - if all curves are inverted, else FALSE
197 ::IsAllCurvesInverted()
199 for (int i=0; i<GetNbLines(); i++)
200 if (!IsCurveInverted(i)) return false;
204 //---------------------------------------------------------------
205 /*! Sets orientation of curve
206 * \param theCurveNumber - integer value, number of cut line.
207 * \param theInvert - boolean value, TRUE or false.
211 ::SetCurveInverted(CORBA::Long theCurveNumber, CORBA::Boolean theInvert)
213 if(myMapCurvesInverted[theCurveNumber] == theInvert)
216 VISU::TSetModified aModified(this);
218 myMapCurvesInverted[theCurveNumber] = theInvert;
219 myParamsTime.Modified();
222 //---------------------------------------------------------------
223 /*! Checks orientation of curve.
224 * \param theCurveNumber - integer value, number of cut line.
225 * \retval TRUE - if line in the table is inverted, else FALSE.
229 ::IsCurveInverted(CORBA::Long theCurveNumber)
231 return myMapCurvesInverted[theCurveNumber];
234 //---------------------------------------------------------------
235 /*! It control the way the length of cutlines is shown: using aboslute or relative values
236 * \param theAbsLength - boolean value, TRUE or false.
240 ::SetUseAbsoluteLength(CORBA::Boolean theAbsLength)
242 if ( myUseAbsLength == theAbsLength )
245 VISU::TSetModified aModified(this);
247 myUseAbsLength = theAbsLength;
248 myParamsTime.Modified();
251 //---------------------------------------------------------------
254 ::IsUseAbsoluteLength()
256 return myUseAbsLength;
260 //---------------------------------------------------------------
263 ::CreatePipeLine(VISU_PipeLine* thePipeLine)
265 // temporarily commented (see note 0006576 of the external issue 0020468)
266 //myCutLinesBasePL = dynamic_cast<VISU_CutLinesBasePL*>(thePipeLine);
267 myCutLinesBasePL = (VISU_CutLinesBasePL*)thePipeLine;
269 TSuperClass::CreatePipeLine(myCutLinesBasePL);
273 //---------------------------------------------------------------
276 ::BuildTableOfReal(SALOMEDS::SObject_var theSObject, bool theIsCutSegment)
279 if(MYDEBUG) MESSAGE("CutPlanes_i::BuildTableOfReal");
281 SALOMEDS::GenericAttribute_var anAttr;
282 SALOMEDS::StudyBuilder_var aStudyBuilder = GetStudyDocument()->NewBuilder();
283 anAttr = aStudyBuilder->FindOrCreateAttribute(theSObject, "AttributeTableOfReal");
284 SALOMEDS::AttributeTableOfReal_var aTableOfReal = SALOMEDS::AttributeTableOfReal::_narrow(anAttr);
286 typedef set<vtkFloatingPointType> TXCont;
287 typedef map<vtkFloatingPointType,vtkFloatingPointType> TXYMap;
288 typedef map<int,TXYMap> TXYMapCont;
289 typedef map<long,long> TLineIdCont;
291 QString aTitle( GetScalarBarTitle().c_str() );
292 aTitle = aTitle.simplified();
293 aTableOfReal->SetTitle( aTitle.toLatin1().data() );
295 int iLineEnd = myCutLinesBasePL->GetAppendPolyData()->GetNumberOfInputConnections(0);
296 if(MYDEBUG) MESSAGE("CutPlanes_i::BuildTableOfReal iLineEnd = "<<iLineEnd);
298 TXYMapCont aXYMapCont;
299 TLineIdCont aLineIdCont; // Define internal numeration of lines
300 const vtkFloatingPointType *aDirLn = myCutLinesBasePL->GetDirLn();
301 const vtkFloatingPointType *aBasePnt = myCutLinesBasePL->GetBasePnt();
302 const vtkFloatingPointType *aBoundPrjLn = myCutLinesBasePL->GetBoundPrjLn();
303 for(int iLine = 0, jLine = 0; iLine < iLineEnd; iLine++){
304 vtkDataSet *aDataSet = myCutLinesBasePL->GetAppendPolyData()->GetInput(iLine);
306 int aNbPoints = aDataSet->GetNumberOfPoints();
307 if(!aNbPoints) continue;
308 vtkPointData *aPointData = aDataSet->GetPointData();
309 vtkDataArray *aScalars = aPointData->GetScalars();
310 vtkCellDataToPointData *aFilter = NULL;
312 aFilter = vtkCellDataToPointData::New();
313 aFilter->SetInput(aDataSet);
314 aFilter->PassCellDataOn();
315 aDataSet = aFilter->GetOutput();
318 aPointData = aDataSet->GetPointData();
319 aScalars = aPointData->GetScalars();
320 if(!aScalars) continue;
321 if(MYDEBUG) MESSAGE("CutPlanes_i::BuildTableOfReal iLine = "<<iLine<<"; aNbPoints = "<<aNbPoints);
322 aLineIdCont[iLine] = jLine++;
323 TXYMap& aXYMap = aXYMapCont[iLine];
324 vtkFloatingPointType aPnt[3], aVect[3], aDist, aTopBnd, aDivide;
325 aTopBnd = aBoundPrjLn[2];
326 aDivide = aBoundPrjLn[2];
327 if( !IsUseAbsoluteLength() ){
332 for(int i = 0; i < aNbPoints; i++){
333 aDataSet->GetPoint(i,aPnt);
334 for(int j = 0; j < 3; j++)
335 aVect[j] = aPnt[j] - aBasePnt[j];
336 //VISU::Sub(aPnt,aBasePnt,aVect);
337 if ( fabs(aBoundPrjLn[2]) < EPS_machine )
341 aDist = vtkMath::Dot(aVect,aDirLn)/aDivide;
343 if(aDist < 0.0) aDist = 0.0;
344 if(aDist > aTopBnd) aDist = aTopBnd;
346 aXYMap[aDist] = aScalars->GetTuple1(i);
351 if(aXYMapCont.size() == 0)
352 throw std::runtime_error("CutPlanes_i::BuildTableOfReal aXYMapCont.size() == 0 !!!");
355 // Invertion all curves in the table, which has inversion flag is TRUE (see \a myMapCurvesInverted)
356 for(int iLine=0; iLine < iLineEnd; iLine++){
357 if (!IsCurveInverted(iLine)) continue;
359 TXYMap& aXYMap = aXYMapCont[iLine];
360 TXYMap::const_iterator aXYMapIter = aXYMap.begin();
361 std::list<vtkFloatingPointType> XKeys;
362 for (;aXYMapIter != aXYMap.end() ; aXYMapIter++) XKeys.push_back(aXYMapIter->first);
364 if (XKeys.size() > 1) {
365 vtkFloatingPointType a_first_indx = XKeys.front();
366 vtkFloatingPointType a_last_indx = XKeys.back();
367 if (a_first_indx > a_last_indx){
369 vtkFloatingPointType tmp = a_first_indx;
370 a_first_indx = a_last_indx;
373 std::list<vtkFloatingPointType>::const_iterator aIter = XKeys.begin();
374 for (int k=0;k<XKeys.size() && aIter != XKeys.end();k++,aIter++){
375 // Warning: value '1.0' come from workaround:
376 // see also aDist = vtkMath::Dot(aVect,aDirLn) / aBoundPrjLn[2];
377 // aDist >= 0 and aDist<=1.0
378 vtkFloatingPointType aTopBnd = aBoundPrjLn[2];
379 if( !IsUseAbsoluteLength() ){
382 aNewXYMap[aTopBnd - *aIter] = aXYMap[*aIter];
384 TXYMap::const_iterator aNewXYMapIter = aNewXYMap.begin();
386 for (;aNewXYMapIter != aNewXYMap.end();aNewXYMapIter++) {
387 aXYMap[aNewXYMapIter->first] = aNewXYMapIter->second;
392 //Resorting of theXYMap
393 TXYMapCont::iterator aXYMapContIter = aXYMapCont.begin();
394 for(; aXYMapContIter != aXYMapCont.end(); aXYMapContIter++){
395 TXYMap& aXYMap = aXYMapContIter->second, aNewXYMap;
396 if(aXYMap.size() > 2){
397 // Try to smooth the values of the line by applying linear approximation
398 TXYMap::const_iterator aXYMapIter[2] = {aXYMap.begin(), ++aXYMap.begin()};
399 aNewXYMap[aXYMapIter[0]->first] = aXYMapIter[0]->second;
400 aXCont.insert(aXYMapIter[0]->first);
401 for(; aXYMapIter[1] != aXYMap.end(); aXYMapIter[0]++, aXYMapIter[1]++){
402 vtkFloatingPointType aY[3] = {aXYMapIter[0]->second, aXYMapIter[1]->second, 0.0};
403 aY[2] = (aY[0] + aY[1])/2.0;
404 vtkFloatingPointType aX[3] = {aXYMapIter[0]->first, aXYMapIter[1]->first, 0.0};
405 aX[2] = (aX[0] + aX[1])/2.0;
406 aNewXYMap[aX[2]] = aY[2];
407 aXCont.insert(aX[2]);
409 aNewXYMap[aXYMapIter[0]->first] = aXYMapIter[0]->second;
410 aXCont.insert(aXYMapIter[0]->first);
413 TXYMap::const_iterator aXYMapIter = aXYMap.begin();
414 for(; aXYMapIter != aXYMap.end(); aXYMapIter++)
415 aXCont.insert(aXYMapIter->first);
418 if(aXCont.size() == 0)
419 throw std::runtime_error("CutPlanes_i::BuildTableOfReal aXCont.size() == 0 !!!");
421 int iEnd = aXCont.size();
422 aTableOfReal->SetNbColumns(iEnd);
423 TXCont::const_iterator aXContIter = aXCont.begin();
424 vtkFloatingPointType aMinDist = *aXContIter;
425 aXContIter = aXCont.end();
427 vtkFloatingPointType aMaxDist = *aXContIter;
428 if(aMaxDist <= aMinDist)
429 throw std::runtime_error("CutPlanes_i::BuildTableOfReal aMaxDist <= aMinDist !!!");
430 aXContIter = aXCont.begin();
431 for(long i = 0; aXContIter != aXCont.end(); aXContIter++, i++){
432 vtkFloatingPointType aDist = *aXContIter;
433 vtkFloatingPointType aXVal = aDist;
436 if(!IsUseAbsoluteLength())
437 aXVal /= (aMaxDist - aMinDist);
439 aTableOfReal->PutValue(aXVal,1,i+1);
440 aString.sprintf("%d",i);
441 aTableOfReal->SetColumnTitle(i+1,(const char*)aString.toLatin1());
442 if(MYDEBUG) MESSAGE("CutPlanes_i::BuildTableOfReal aDist = "<<aDist<<" aXVal = "<<aXVal);
443 TXYMapCont::const_iterator aXYMapContIter = aXYMapCont.begin();
444 for(; aXYMapContIter != aXYMapCont.end(); aXYMapContIter++){
445 long iLine = aXYMapContIter->first;
446 long iLineId = aLineIdCont[iLine];
447 const TXYMap& aXYMap = aXYMapCont[iLine];
448 TXYMap::const_iterator aXYMapIter = aXYMap.find(aDist);
449 // Can we find some value that belong to the line and have the same X coordinate?
450 if(aXYMapIter == aXYMap.end()) continue;
451 vtkFloatingPointType aVal = aXYMapIter->second;
452 aTableOfReal->PutValue(aVal,iLineId+2,i+1);
456 aTableOfReal->SetRowTitle(1,"X");
457 aTableOfReal->SetRowUnit(1,"-");
458 QString aUnitName = GetField()->myUnitNames[0].c_str();
459 int aScalarMode = myCutLinesBasePL->GetScalarMode();
461 aUnitName = GetField()->myUnitNames[aScalarMode-1].c_str();
462 aUnitName = aUnitName.simplified();
463 if(aUnitName.isEmpty()) aUnitName = "-";
464 TXYMapCont::const_iterator aXYMapContIter = aXYMapCont.begin();
465 for(; aXYMapContIter != aXYMapCont.end(); aXYMapContIter++){
466 long iLine = aXYMapContIter->first;
467 long iLineId = aLineIdCont[iLine];
468 aString.sprintf("Y%d",iLine);
470 MESSAGE("CutPlanes_i::BuildTableOfReal - SetRowTitle("<<iLineId+2<<",'"<<(const char*)aString.toLatin1()<<"')");
471 aTableOfReal->SetRowTitle(iLineId+2,(const char*)aString.toLatin1());
472 aTableOfReal->SetRowUnit(iLineId+2,(const char*)aUnitName.toLatin1());
475 }catch(std::exception& exc){
476 INFOS("Follow exception was occured :\n"<<exc.what());
478 INFOS("Unknown exception was occured !!!");