]> SALOME platform Git repositories - modules/visu.git/blob - src/VISU_I/VISU_CutLinesBase_i.cc
Salome HOME
IPAL21489 Filter by Scalars... does not show visible elements for some presentations.
[modules/visu.git] / src / VISU_I / VISU_CutLinesBase_i.cc
1 //  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 //  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
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.
10 //
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.
15 //
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
19 //
20 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 //  File   : VISU_CutLinesBase_i.cc
23 //  Author : Oleg UVAROV
24 //  Module : VISU
25 //
26 #include "VISU_CutLinesBase_i.hh"
27 #include "VISU_Prs3dUtils.hh"
28 #include "VISU_Result_i.hh"
29
30 #include "VISU_Actor.h"
31 #include "VISU_CutLinesBasePL.hxx"
32 #include "VISU_Convertor.hxx"
33 #include "VISU_PipeLineUtils.hxx"
34
35 #include "SUIT_ResourceMgr.h"
36
37 #include <vtkAppendPolyData.h>
38
39 static vtkFloatingPointType EPS_machine = 1.0E-7;
40
41 #ifdef _DEBUG_
42 static int MYDEBUG = 0;
43 #else
44 static int MYDEBUG = 0;
45 #endif
46
47 using namespace std;
48
49 //---------------------------------------------------------------
50 VISU::CutLinesBase_i::
51 CutLinesBase_i(EPublishInStudyMode thePublishInStudyMode) :
52   ColoredPrs3d_i(thePublishInStudyMode),
53   ScalarMap_i(thePublishInStudyMode),
54   myUseAbsLength( false ),
55   myCutLinesBasePL(NULL)
56 {}
57
58
59 //---------------------------------------------------------------
60 void
61 VISU::CutLinesBase_i
62 ::SameAs(const Prs3d_i* theOrigin)
63 {
64   TSuperClass::SameAs(theOrigin);
65
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());
70   }
71 }
72
73
74 //---------------------------------------------------------------
75 /*! Copy map to /a myMapCurvesInverted.
76  * \param theCurves - map
77  */
78 void 
79 VISU::CutLinesBase_i
80 ::CopyCurvesInverted(const TCurvesInv& theCurves)
81 {
82   myMapCurvesInverted = theCurves;
83 }
84
85
86 //---------------------------------------------------------------
87 VISU::Storable* 
88 VISU::CutLinesBase_i
89 ::Create(const std::string& theMeshName, 
90          VISU::Entity theEntity,
91          const std::string& theFieldName, 
92          CORBA::Long theTimeStampNumber)
93 {
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);
98 }
99
100
101 //---------------------------------------------------------------
102 VISU::Storable* 
103 VISU::CutLinesBase_i
104 ::Restore(SALOMEDS::SObject_ptr theSObject,
105           const Storable::TRestoringMap& theMap)
106 {
107   if(!TSuperClass::Restore(theSObject, theMap))
108     return NULL;
109
110   SetNbLines(VISU::Storable::FindValue(theMap,"myNbLines").toInt());
111
112   SetUseAbsoluteLength(VISU::Storable::FindValue(theMap,"myUseAbsLength").toInt());
113
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);
120       else
121         SetCurveInverted(i,false);
122     }
123   } else {
124     for(int i = 0, iEnd = GetNbLines(); i < iEnd ; i++)
125       SetCurveInverted(i,false);
126   }
127       
128   return this;
129 }
130
131
132 //---------------------------------------------------------------
133 void
134 VISU::CutLinesBase_i
135 ::ToStream(std::ostringstream& theStr)
136 {
137   TSuperClass::ToStream(theStr);
138
139   Storable::DataToStream( theStr, "myNbLines",      GetNbLines() );
140
141   Storable::DataToStream( theStr, "myUseAbsLength", IsUseAbsoluteLength());
142
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());
148 }
149
150
151 //---------------------------------------------------------------
152 VISU::CutLinesBase_i
153 ::~CutLinesBase_i()
154 {
155   if(MYDEBUG) MESSAGE("CutLinesBase_i::~CutLinesBase_i()");
156 }
157
158
159 //---------------------------------------------------------------
160 void
161 VISU::CutLinesBase_i
162 ::SetNbLines(CORBA::Long theNb) 
163
164   VISU::TSetModified aModified(this);
165
166   ProcessVoidEvent(new TVoidMemFun1ArgEvent<VISU_CutLinesBasePL, int>
167                    (GetSpecificPL(), &VISU_CutLinesBasePL::SetNbParts, theNb));
168 }
169
170 //---------------------------------------------------------------
171 CORBA::Long
172 VISU::CutLinesBase_i
173 ::GetNbLines() 
174
175   return myCutLinesBasePL->GetNbParts();
176 }
177
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.
182  */
183 void
184 VISU::CutLinesBase_i
185 ::SetAllCurvesInverted(CORBA::Boolean theInvert)
186 {
187   for(int i=0; i < GetNbLines(); i++)
188     SetCurveInverted(i, theInvert);
189 }
190
191 //---------------------------------------------------------------
192 /*! Checks the orientation of all curves
193  * \retval TRUE - if all curves are inverted, else FALSE
194  */
195 CORBA::Boolean 
196 VISU::CutLinesBase_i
197 ::IsAllCurvesInverted()
198 {
199   for (int i=0; i<GetNbLines(); i++)
200     if (!IsCurveInverted(i)) return false;
201   return true;
202 }
203
204 //---------------------------------------------------------------
205 /*! Sets orientation of curve
206  * \param theCurveNumber - integer value, number of cut line.
207  * \param theInvert      - boolean value, TRUE or false.
208  */
209 void
210 VISU::CutLinesBase_i
211 ::SetCurveInverted(CORBA::Long theCurveNumber, CORBA::Boolean theInvert)
212 {
213   if(myMapCurvesInverted[theCurveNumber] == theInvert)
214     return;
215
216   VISU::TSetModified aModified(this);
217
218   myMapCurvesInverted[theCurveNumber] = theInvert;
219   myParamsTime.Modified();
220 }
221
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.
226  */
227 CORBA::Boolean
228 VISU::CutLinesBase_i
229 ::IsCurveInverted(CORBA::Long theCurveNumber)
230 {
231   return myMapCurvesInverted[theCurveNumber];
232 }
233
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.
237 */
238 void
239 VISU::CutLinesBase_i
240 ::SetUseAbsoluteLength(CORBA::Boolean theAbsLength)
241 {
242   if ( myUseAbsLength == theAbsLength )
243     return;
244
245   VISU::TSetModified aModified(this);
246
247   myUseAbsLength = theAbsLength;
248   myParamsTime.Modified();
249 }
250
251 //---------------------------------------------------------------
252 CORBA::Boolean
253 VISU::CutLinesBase_i
254 ::IsUseAbsoluteLength()
255 {
256   return myUseAbsLength;
257 }
258
259
260 //---------------------------------------------------------------
261 void
262 VISU::CutLinesBase_i
263 ::CreatePipeLine(VISU_PipeLine* thePipeLine)
264 {
265   /*if(!thePipeLine){
266     myCutLinesBasePL = VISU_CutLinesBasePL::New();
267     }else*/
268     myCutLinesBasePL = dynamic_cast<VISU_CutLinesBasePL*>(thePipeLine);
269
270   TSuperClass::CreatePipeLine(myCutLinesBasePL);
271 }
272
273
274 //---------------------------------------------------------------
275 void
276 VISU::CutLinesBase_i
277 ::BuildTableOfReal(SALOMEDS::SObject_var theSObject, bool theIsCutSegment)
278 {
279   try{
280     if(MYDEBUG) MESSAGE("CutPlanes_i::BuildTableOfReal");
281     Update();
282     SALOMEDS::GenericAttribute_var anAttr;
283     SALOMEDS::StudyBuilder_var aStudyBuilder = GetStudyDocument()->NewBuilder();
284     anAttr = aStudyBuilder->FindOrCreateAttribute(theSObject, "AttributeTableOfReal");
285     SALOMEDS::AttributeTableOfReal_var aTableOfReal = SALOMEDS::AttributeTableOfReal::_narrow(anAttr);
286     
287     typedef set<vtkFloatingPointType> TXCont;
288     typedef map<vtkFloatingPointType,vtkFloatingPointType> TXYMap;
289     typedef map<int,TXYMap> TXYMapCont;
290     typedef map<long,long> TLineIdCont;
291     
292     QString aTitle( GetScalarBarTitle().c_str() );
293     aTitle = aTitle.simplified();
294     aTableOfReal->SetTitle( aTitle.toLatin1().data() );
295     
296     int iLineEnd = myCutLinesBasePL->GetAppendPolyData()->GetNumberOfInputConnections(0);
297     if(MYDEBUG) MESSAGE("CutPlanes_i::BuildTableOfReal iLineEnd = "<<iLineEnd);
298     TXCont aXCont;
299     TXYMapCont aXYMapCont; 
300     TLineIdCont aLineIdCont;  // Define internal numeration of lines
301     const vtkFloatingPointType *aDirLn = myCutLinesBasePL->GetDirLn();
302     const vtkFloatingPointType *aBasePnt = myCutLinesBasePL->GetBasePnt();
303     const vtkFloatingPointType *aBoundPrjLn = myCutLinesBasePL->GetBoundPrjLn();
304     for(int iLine = 0, jLine = 0; iLine < iLineEnd; iLine++){
305       vtkDataSet *aDataSet = myCutLinesBasePL->GetAppendPolyData()->GetInput(iLine);
306       aDataSet->Update();
307       int aNbPoints = aDataSet->GetNumberOfPoints();
308       if(!aNbPoints) continue;
309       vtkPointData *aPointData = aDataSet->GetPointData();
310       vtkDataArray *aScalars = aPointData->GetScalars();
311       vtkCellDataToPointData *aFilter = NULL;
312       if(!aScalars) {
313         aFilter = vtkCellDataToPointData::New();
314         aFilter->SetInput(aDataSet);
315         aFilter->PassCellDataOn();
316         aDataSet = aFilter->GetOutput();
317         aDataSet->Update();
318       }
319       aPointData = aDataSet->GetPointData();
320       aScalars = aPointData->GetScalars();
321       if(!aScalars) continue;
322       if(MYDEBUG) MESSAGE("CutPlanes_i::BuildTableOfReal iLine = "<<iLine<<"; aNbPoints = "<<aNbPoints);
323       aLineIdCont[iLine] = jLine++;
324       TXYMap& aXYMap = aXYMapCont[iLine];
325       vtkFloatingPointType aPnt[3], aVect[3], aDist, aTopBnd, aDivide;
326       aTopBnd = aBoundPrjLn[2];
327       aDivide = aBoundPrjLn[2];
328       if( !IsUseAbsoluteLength() ){
329         aTopBnd = 1.0;
330       }
331       else aDivide = 1.0;
332
333       for(int i = 0; i < aNbPoints; i++){
334         aDataSet->GetPoint(i,aPnt);
335         for(int j = 0; j < 3; j++)
336           aVect[j] = aPnt[j] - aBasePnt[j];
337         //VISU::Sub(aPnt,aBasePnt,aVect);
338         if ( fabs(aBoundPrjLn[2]) < EPS_machine )
339           aDist = 0.5;
340         else
341         {
342           aDist = vtkMath::Dot(aVect,aDirLn)/aDivide; 
343           // the workaround
344           if(aDist < 0.0) aDist = 0.0; 
345           if(aDist > aTopBnd) aDist = aTopBnd;
346         }
347         aXYMap[aDist] = aScalars->GetTuple1(i);
348       }
349       if(aFilter)
350         aFilter->Delete();
351     }
352     if(aXYMapCont.size() == 0)
353       throw std::runtime_error("CutPlanes_i::BuildTableOfReal aXYMapCont.size() == 0 !!!");
354
355     {
356       // Invertion all curves in the table, which has inversion flag is TRUE (see \a myMapCurvesInverted)
357       for(int iLine=0; iLine < iLineEnd; iLine++){
358         if (!IsCurveInverted(iLine)) continue;
359         TXYMap aNewXYMap;
360         TXYMap& aXYMap = aXYMapCont[iLine];
361         TXYMap::const_iterator aXYMapIter = aXYMap.begin();
362         std::list<vtkFloatingPointType> XKeys;
363         for (;aXYMapIter != aXYMap.end() ; aXYMapIter++) XKeys.push_back(aXYMapIter->first);
364         XKeys.sort();
365         if (XKeys.size() > 1) {
366           vtkFloatingPointType a_first_indx = XKeys.front();
367           vtkFloatingPointType a_last_indx = XKeys.back();
368           if (a_first_indx > a_last_indx){
369             XKeys.reverse();
370             vtkFloatingPointType tmp = a_first_indx;
371             a_first_indx = a_last_indx;
372             a_last_indx = tmp;
373           }
374           std::list<vtkFloatingPointType>::const_iterator aIter = XKeys.begin();
375           for (int k=0;k<XKeys.size() && aIter != XKeys.end();k++,aIter++){
376             // Warning: value '1.0' come from workaround:
377             // see also aDist = vtkMath::Dot(aVect,aDirLn) / aBoundPrjLn[2];
378             // aDist >= 0 and aDist<=1.0
379             vtkFloatingPointType aTopBnd = aBoundPrjLn[2];
380             if( !IsUseAbsoluteLength() ){
381               aTopBnd = 1.0;
382             }
383             aNewXYMap[aTopBnd - *aIter] = aXYMap[*aIter];
384           }
385           TXYMap::const_iterator aNewXYMapIter = aNewXYMap.begin();
386           aXYMap.clear();
387           for (;aNewXYMapIter != aNewXYMap.end();aNewXYMapIter++) {
388             aXYMap[aNewXYMapIter->first] = aNewXYMapIter->second;
389           }
390         }
391       }
392     }
393     //Resorting of theXYMap
394     TXYMapCont::iterator aXYMapContIter = aXYMapCont.begin();
395     for(; aXYMapContIter != aXYMapCont.end(); aXYMapContIter++){
396       TXYMap& aXYMap = aXYMapContIter->second, aNewXYMap;
397       if(aXYMap.size() > 2){  
398         // Try to smooth the values of the line by applying linear approximation
399         TXYMap::const_iterator aXYMapIter[2] = {aXYMap.begin(), ++aXYMap.begin()};
400         aNewXYMap[aXYMapIter[0]->first] = aXYMapIter[0]->second;
401         aXCont.insert(aXYMapIter[0]->first);
402         for(; aXYMapIter[1] != aXYMap.end(); aXYMapIter[0]++, aXYMapIter[1]++){
403           vtkFloatingPointType aY[3] = {aXYMapIter[0]->second, aXYMapIter[1]->second, 0.0};
404           aY[2] = (aY[0] + aY[1])/2.0;
405           vtkFloatingPointType aX[3] = {aXYMapIter[0]->first, aXYMapIter[1]->first, 0.0};
406           aX[2] = (aX[0] + aX[1])/2.0;
407           aNewXYMap[aX[2]] = aY[2];
408           aXCont.insert(aX[2]);
409         }
410         aNewXYMap[aXYMapIter[0]->first] = aXYMapIter[0]->second;
411         aXCont.insert(aXYMapIter[0]->first);
412         aXYMap = aNewXYMap;
413       }else{
414         TXYMap::const_iterator aXYMapIter = aXYMap.begin();
415         for(; aXYMapIter != aXYMap.end(); aXYMapIter++)
416           aXCont.insert(aXYMapIter->first);
417       }
418     }
419     if(aXCont.size() == 0)
420       throw std::runtime_error("CutPlanes_i::BuildTableOfReal aXCont.size() == 0 !!!");
421     QString aString;
422     int iEnd = aXCont.size();
423     aTableOfReal->SetNbColumns(iEnd);
424     TXCont::const_iterator aXContIter = aXCont.begin();
425     vtkFloatingPointType aMinDist = *aXContIter;
426     aXContIter = aXCont.end();
427     aXContIter--;
428     vtkFloatingPointType aMaxDist = *aXContIter;
429     if(aMaxDist <= aMinDist)
430       throw std::runtime_error("CutPlanes_i::BuildTableOfReal aMaxDist <= aMinDist !!!");
431     aXContIter = aXCont.begin();
432     for(long i = 0; aXContIter != aXCont.end(); aXContIter++, i++){
433       vtkFloatingPointType aDist = *aXContIter; 
434       vtkFloatingPointType aXVal = aDist;
435       if(theIsCutSegment){
436         aXVal -= aMinDist;
437         if(!IsUseAbsoluteLength())
438           aXVal /= (aMaxDist - aMinDist);
439       }
440       aTableOfReal->PutValue(aXVal,1,i+1);
441       aString.sprintf("%d",i);
442       aTableOfReal->SetColumnTitle(i+1,(const char*)aString.toLatin1());
443       if(MYDEBUG) MESSAGE("CutPlanes_i::BuildTableOfReal aDist = "<<aDist<<" aXVal = "<<aXVal);
444       TXYMapCont::const_iterator aXYMapContIter = aXYMapCont.begin();
445       for(; aXYMapContIter != aXYMapCont.end(); aXYMapContIter++){
446         long iLine = aXYMapContIter->first;
447         long iLineId = aLineIdCont[iLine];
448         const TXYMap& aXYMap = aXYMapCont[iLine];
449         TXYMap::const_iterator aXYMapIter = aXYMap.find(aDist);
450         // Can we find some value that belong to the line and have the same X coordinate?
451         if(aXYMapIter == aXYMap.end()) continue;
452         vtkFloatingPointType aVal = aXYMapIter->second;
453         aTableOfReal->PutValue(aVal,iLineId+2,i+1);
454       }
455     }
456     {
457       aTableOfReal->SetRowTitle(1,"X");
458       aTableOfReal->SetRowUnit(1,"-");
459       QString aUnitName = GetField()->myUnitNames[0].c_str();
460       int aScalarMode = myCutLinesBasePL->GetScalarMode();
461       if(aScalarMode != 0) 
462         aUnitName = GetField()->myUnitNames[aScalarMode-1].c_str();
463       aUnitName = aUnitName.simplified();
464       if(aUnitName.isEmpty()) aUnitName = "-";
465       TXYMapCont::const_iterator aXYMapContIter = aXYMapCont.begin();
466       for(; aXYMapContIter != aXYMapCont.end(); aXYMapContIter++){
467         long iLine = aXYMapContIter->first;
468         long iLineId = aLineIdCont[iLine];
469         aString.sprintf("Y%d",iLine);
470         if(MYDEBUG) 
471           MESSAGE("CutPlanes_i::BuildTableOfReal - SetRowTitle("<<iLineId+2<<",'"<<(const char*)aString.toLatin1()<<"')");
472         aTableOfReal->SetRowTitle(iLineId+2,(const char*)aString.toLatin1());
473         aTableOfReal->SetRowUnit(iLineId+2,(const char*)aUnitName.toLatin1());
474       }
475     }
476   }catch(std::exception& exc){
477     INFOS("Follow exception was occured :\n"<<exc.what());
478   }catch (...){
479     INFOS("Unknown exception was occured !!!");
480   }
481 }