Salome HOME
e4017fa5b222fd4f5c46fbaa70517bb6d22b2716
[modules/visu.git] / src / VISU_I / VISU_CutLines_i.cc
1 //  VISU OBJECT : interactive object for VISU entities implementation
2 //
3 //  Copyright (C) 2003  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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
21 //
22 //
23 //  File   : VISU_PrsObject_i.cxx
24 //  Author : Alexey PETROV
25 //  Module : VISU
26
27 #include "VISU_CutLinesPL.hxx"
28 #include "VISU_Result_i.hh"
29 #include "VISU_CutLines_i.hh"
30 #include "VISU_Actor.h"
31
32 #include "VISU_PipeLineUtils.hxx"
33
34 #include <vtkAppendPolyData.h>
35
36 using namespace VISU;
37 using namespace std;
38
39 #ifdef _DEBUG_
40 static int MYDEBUG = 0;
41 static int MYDEBUGWITHFILES = 0;
42 #else
43 static int MYDEBUG = 0;
44 static int MYDEBUGWITHFILES = 0;
45 #endif
46
47 int VISU::CutLines_i::IsPossible(Result_i* theResult, const char* theMeshName, VISU::Entity theEntity, 
48                                  const char* theFieldName, int theIteration, int isMemoryCheck)
49 {
50   return VISU::ScalarMap_i::IsPossible(theResult,theMeshName,theEntity,theFieldName,theIteration,isMemoryCheck);
51 }
52
53 int VISU::CutLines_i::myNbPresent = 0;
54 QString VISU::CutLines_i::GenerateName() { return VISU::GenerateName("CutLines",myNbPresent++);}
55
56 const string VISU::CutLines_i::myComment = "CUTLINES";
57 const char* VISU::CutLines_i::GetComment() const { return myComment.c_str();}
58
59
60 VISU::CutLines_i::CutLines_i(Result_i* theResult, bool theAddToStudy, SALOMEDS::SObject_ptr theSObject) :
61        PrsObject_i(theResult->GetStudyDocument()), 
62        Prs3d_i(theResult,theSObject),
63        ScalarMap_i(theResult,theAddToStudy,theSObject)
64 {
65   myCutLinesPL = NULL;
66 }
67
68
69
70 void VISU::CutLines_i::SameAs(const CutLines_i* theOrigin){
71   CutLines_i* aCutLines = const_cast<CutLines_i*>(theOrigin);
72   VISU::ScalarMap_i::SameAs(theOrigin);
73 }
74
75
76 VISU::Storable* VISU::CutLines_i::Create(const char* theMeshName, VISU::Entity theEntity, 
77                                          const char* theFieldName, int theIteration)
78 {
79   return ScalarMap_i::Create(theMeshName,theEntity,theFieldName,theIteration);
80 }
81
82
83 VISU::Storable* VISU::CutLines_i::Restore(const Storable::TRestoringMap& theMap)
84      throw(std::logic_error&)
85 {
86   DoHook();
87   SetNbLines(VISU::Storable::FindValue(theMap,"myNbLines").toInt());
88   SetDisplacement(VISU::Storable::FindValue(theMap,"myDisplacement[0]").toDouble());
89   SetDisplacement2(VISU::Storable::FindValue(theMap,"myDisplacement[1]").toDouble());
90   SetOrientation(CutPlanes::Orientation(VISU::Storable::FindValue(theMap,"myBasePlane[0]").toInt()),
91                  Storable::FindValue(theMap,"aRot[0][0]").toDouble(),
92                  Storable::FindValue(theMap,"aRot[0][1]").toDouble());
93   SetOrientation2(CutPlanes::Orientation(VISU::Storable::FindValue(theMap,"myBasePlane[1]").toInt()),
94                   Storable::FindValue(theMap,"aRot[1][0]").toDouble(),
95                   Storable::FindValue(theMap,"aRot[1][1]").toDouble());
96   if (VISU::Storable::FindValue(theMap,"myBasePlaneCondition").toInt())
97     SetDefault();
98   else
99     SetBasePlanePosition(VISU::Storable::FindValue(theMap,"myBasePlanePosition").toDouble());
100   
101   QStringList aPosList = QStringList::split("|",VISU::Storable::FindValue(theMap,"myLinePosition") );
102   QStringList aCondList = QStringList::split("|",VISU::Storable::FindValue(theMap,"myLineCondition") );
103   for(int i = 0, iEnd = GetNbLines(); i < iEnd; i++)
104     if(aCondList[i].toInt() == 0)
105       SetLinePosition(i,aPosList[i].toDouble());
106
107   return ScalarMap_i::Restore(theMap);
108 }
109
110
111 void VISU::CutLines_i::ToStream(std::ostringstream& theStr){
112   ScalarMap_i::ToStream(theStr);
113
114   int aNbLines = GetNbLines();
115   
116   Storable::DataToStream( theStr, "myNbLines",         aNbLines );
117   Storable::DataToStream( theStr, "myDisplacement[0]", GetDisplacement() );
118   Storable::DataToStream( theStr, "myDisplacement[1]", GetDisplacement2() );
119   Storable::DataToStream( theStr, "myBasePlane[0]",    int(GetOrientationType()) );
120   Storable::DataToStream( theStr, "myBasePlane[1]",    int(GetOrientationType2()) );
121   Storable::DataToStream( theStr, "aRot[0][0]",        GetRotateX() );
122   Storable::DataToStream( theStr, "aRot[0][1]",        GetRotateY() );
123   Storable::DataToStream( theStr, "aRot[1][0]",        GetRotateX2() );
124   Storable::DataToStream( theStr, "aRot[1][1]",        GetRotateY2() );
125   Storable::DataToStream( theStr, "myBasePlanePosition", GetBasePlanePosition() );
126   Storable::DataToStream( theStr, "myBasePlaneCondition", IsDefault() );
127
128   QString aStrPos, aStrCon;
129   for(int i = 0, iEnd = GetNbLines(); i < iEnd; i++){
130     aStrPos.append(QString::number(GetLinePosition(i)) + "|");
131     aStrCon.append(QString::number(IsDefaultPosition(i)) + "|");
132   }
133   Storable::DataToStream( theStr, "myLinePosition",  aStrPos.latin1());
134   Storable::DataToStream( theStr, "myLineCondition", aStrCon.latin1());
135 }
136
137 VISU::CutLines_i::~CutLines_i(){
138   if(MYDEBUG) MESSAGE("CutLines_i::~CutLines_i()");
139 }
140
141
142 void VISU::CutLines_i::SetOrientation(VISU::CutPlanes::Orientation theOrient,
143                                       CORBA::Double theXAngle, CORBA::Double theYAngle)
144 {
145   myCutLinesPL->SetOrientation(VISU_CutPlanesPL::PlaneOrientation(theOrient),
146                                theXAngle,theYAngle);
147 }
148 void VISU::CutLines_i::SetOrientation2(VISU::CutPlanes::Orientation theOrient,
149                                        CORBA::Double theXAngle, CORBA::Double theYAngle)
150 {
151   myCutLinesPL->SetOrientation(VISU_CutPlanesPL::PlaneOrientation(theOrient),
152                                theXAngle,theYAngle,1);
153 }
154
155 VISU::CutPlanes::Orientation VISU::CutLines_i::GetOrientationType() { 
156   return VISU::CutPlanes::Orientation(myCutLinesPL->GetPlaneOrientation());
157 }
158 VISU::CutPlanes::Orientation VISU::CutLines_i::GetOrientationType2() { 
159   return VISU::CutPlanes::Orientation(myCutLinesPL->GetPlaneOrientation(1));
160 }
161
162 CORBA::Double VISU::CutLines_i::GetRotateX(){
163   return myCutLinesPL->GetRotateX();
164 }
165 CORBA::Double VISU::CutLines_i::GetRotateY(){
166   return myCutLinesPL->GetRotateY();
167 }
168
169 CORBA::Double VISU::CutLines_i::GetRotateX2(){
170   return myCutLinesPL->GetRotateX(1);
171 }
172 CORBA::Double VISU::CutLines_i::GetRotateY2(){
173   return myCutLinesPL->GetRotateY(1);
174 }
175
176
177 void VISU::CutLines_i::SetDisplacement(CORBA::Double theDisp) { 
178   myCutLinesPL->SetDisplacement(theDisp);
179 }
180 void VISU::CutLines_i::SetDisplacement2(CORBA::Double theDisp) { 
181   myCutLinesPL->SetDisplacement(theDisp,1);
182 }
183
184 CORBA::Double VISU::CutLines_i::GetDisplacement() { 
185   return myCutLinesPL->GetDisplacement();
186 }
187 CORBA::Double VISU::CutLines_i::GetDisplacement2() { 
188   return myCutLinesPL->GetDisplacement(1);
189 }
190
191
192 void VISU::CutLines_i::SetBasePlanePosition(CORBA::Double thePlanePosition){
193   myCutLinesPL->SetPosition(thePlanePosition);
194 }
195
196 CORBA::Double VISU::CutLines_i::GetBasePlanePosition(){ 
197   return myCutLinesPL->GetPosition();
198 }
199
200 void VISU::CutLines_i::SetLinePosition(CORBA::Long thePlaneNumber, CORBA::Double thePlanePosition){
201   myCutLinesPL->SetPartPosition(thePlaneNumber,thePlanePosition);
202 }
203
204 CORBA::Double VISU::CutLines_i::GetLinePosition(CORBA::Long thePlaneNumber){ 
205   return myCutLinesPL->GetPartPosition(thePlaneNumber,1);
206 }
207
208
209 void VISU::CutLines_i::SetDefault(){
210   myCutLinesPL->SetDefault();
211 }
212
213 CORBA::Boolean VISU::CutLines_i::IsDefault(){ 
214   return myCutLinesPL->IsDefault();
215 }
216
217 void VISU::CutLines_i::SetDefaultPosition(CORBA::Long thePlaneNumber){
218   myCutLinesPL->SetPartDefault(thePlaneNumber);
219 }
220
221 CORBA::Boolean VISU::CutLines_i::IsDefaultPosition(CORBA::Long thePlaneNumber){ 
222   return myCutLinesPL->IsPartDefault(thePlaneNumber);
223 }
224
225
226 void VISU::CutLines_i::SetNbLines(CORBA::Long theNb) { 
227   myCutLinesPL->SetNbParts(theNb);
228 }
229 CORBA::Long VISU::CutLines_i::GetNbLines() { 
230   return myCutLinesPL->GetNbParts();
231 }
232
233
234 void VISU::CutLines_i::DoHook(){
235   if(!myPipeLine) myPipeLine = VISU_CutLinesPL::New();
236   myCutLinesPL = dynamic_cast<VISU_CutLinesPL*>(myPipeLine);
237
238   ScalarMap_i::DoHook();
239 }
240
241 void VISU::CutLines_i::BuildTableOfReal(SALOMEDS::SObject_ptr theSObject){
242   try{
243     if(MYDEBUG) MESSAGE("CutPlanes_i::BuildTableOfReal");
244     Update();
245     SALOMEDS::GenericAttribute_var anAttr;
246     SALOMEDS::StudyBuilder_var aStudyBuilder = myStudy->NewBuilder();
247     anAttr = aStudyBuilder->FindOrCreateAttribute(theSObject, "AttributeTableOfReal");
248     SALOMEDS::AttributeTableOfReal_var aTableOfReal = SALOMEDS::AttributeTableOfReal::_narrow(anAttr);
249     
250     typedef set<float> TXCont;
251     typedef map<float,float> TXYMap;
252     typedef map<int,TXYMap> TXYMapCont;
253     typedef map<long,long> TLineIdCont;
254     
255     const VISU::TField::TValField& aValField = myField->myValField;
256     const VISU::TField::TValForTime& aValForTime = aValField.find((int)myIteration)->second;
257     const VISU::TField::TTime& aTime = aValForTime.myTime;
258     QString aTitle;
259     //aTitle.sprintf("%s %s",myTitle.c_str(),aTime.second.c_str());
260     aTitle.sprintf("%s",myTitle.c_str());
261     aTitle = aTitle.simplifyWhiteSpace();
262     aTableOfReal->SetTitle(aTitle.latin1());
263     
264     int iLineEnd = myCutLinesPL->GetAppendPolyData()->GetNumberOfInputs();
265     if(MYDEBUG) MESSAGE("CutPlanes_i::BuildTableOfReal iLineEnd = "<<iLineEnd);
266     TXCont aXCont;
267     TXYMapCont aXYMapCont; 
268     TLineIdCont aLineIdCont;  // Define internal numeration of lines
269     const float *aDirLn = myCutLinesPL->GetDirLn();
270     const float *aBasePnt = myCutLinesPL->GetBasePnt();
271     const float *aBoundPrjLn = myCutLinesPL->GetBoundPrjLn();
272     for(int iLine = 0, jLine = 0; iLine < iLineEnd; iLine++){
273       vtkDataSet *aDataSet = myCutLinesPL->GetAppendPolyData()->GetInput(iLine);
274       aDataSet->Update();
275       int aNbPoints = aDataSet->GetNumberOfPoints();
276       if(!aNbPoints) continue;
277       vtkPointData *aPointData = aDataSet->GetPointData();
278       vtkDataArray *aScalars = aPointData->GetScalars();
279       vtkCellDataToPointData *aFilter = NULL;
280       if(!aScalars) {
281         aFilter = vtkCellDataToPointData::New();
282         aFilter->SetInput(aDataSet);
283         aFilter->PassCellDataOn();
284         aDataSet = aFilter->GetOutput();
285         aDataSet->Update();
286       }
287       aPointData = aDataSet->GetPointData();
288       aScalars = aPointData->GetScalars();
289       if(!aScalars) continue;
290       if(MYDEBUG) MESSAGE("CutPlanes_i::BuildTableOfReal iLine = "<<iLine<<"; aNbPoints = "<<aNbPoints);
291       aLineIdCont[iLine] = jLine++;
292       TXYMap& aXYMap = aXYMapCont[iLine];
293       float aPnt[3], aVect[3], aDist;
294       for(int i = 0; i < aNbPoints; i++){
295         aDataSet->GetPoint(i,aPnt);
296         Sub(aPnt,aBasePnt,aVect);
297         aDist = vtkMath::Dot(aVect,aDirLn) / aBoundPrjLn[2];
298         // the workaround
299         if(aDist < 0.0) aDist = 0.0; 
300         if(aDist > 1.0) aDist = 1.0;
301         aXYMap[aDist] = aScalars->GetTuple1(i);
302       }
303       if(aFilter){
304         aFilter->UnRegisterAllOutputs();
305         aFilter->Delete();
306       }
307     }
308     if(aXYMapCont.size() == 0)
309       throw std::runtime_error("CutPlanes_i::BuildTableOfReal aXYMapCont.size() == 0 !!!");
310     //Resorting of theXYMap
311     TXYMapCont::iterator aXYMapContIter = aXYMapCont.begin();
312     for(; aXYMapContIter != aXYMapCont.end(); aXYMapContIter++){
313       TXYMap& aXYMap = aXYMapContIter->second, aNewXYMap;
314       if(aXYMap.size() > 2){  
315         // Try to smooth the values of the line by applying linear approximation
316         TXYMap::const_iterator aXYMapIter[2] = {aXYMap.begin(), ++aXYMap.begin()};
317         aNewXYMap[aXYMapIter[0]->first] = aXYMapIter[0]->second;
318         aXCont.insert(aXYMapIter[0]->first);
319         for(; aXYMapIter[1] != aXYMap.end(); aXYMapIter[0]++, aXYMapIter[1]++){
320           float aY[3] = {aXYMapIter[0]->second, aXYMapIter[1]->second, 0.0};
321           aY[2] = (aY[0] + aY[1])/2.0;
322           float aX[3] = {aXYMapIter[0]->first, aXYMapIter[1]->first, 0.0};
323           aX[2] = (aX[0] + aX[1])/2.0;
324           aNewXYMap[aX[2]] = aY[2];
325           aXCont.insert(aX[2]);
326         }
327         aNewXYMap[aXYMapIter[0]->first] = aXYMapIter[0]->second;
328         aXCont.insert(aXYMapIter[0]->first);
329         aXYMap = aNewXYMap;
330       }else{
331         TXYMap::const_iterator aXYMapIter = aXYMap.begin();
332         for(; aXYMapIter != aXYMap.end(); aXYMapIter++)
333           aXCont.insert(aXYMapIter->first);
334       }
335     }
336     if(aXCont.size() == 0)
337       throw std::runtime_error("CutPlanes_i::BuildTableOfReal aXCont.size() == 0 !!!");
338     QString aString;
339     int iEnd = aXCont.size();
340     aTableOfReal->SetNbColumns(iEnd);
341     TXCont::const_iterator aXContIter = aXCont.begin();
342     for(long i = 0; aXContIter != aXCont.end(); aXContIter++, i++){
343       float aDist = *aXContIter; 
344       aTableOfReal->PutValue(aDist,1,i+1);
345       aString.sprintf("%d",i);
346       aTableOfReal->SetColumnTitle(i+1,aString.latin1());
347       if(MYDEBUG) MESSAGE("CutPlanes_i::BuildTableOfReal aDist = "<<aDist);
348       TXYMapCont::const_iterator aXYMapContIter = aXYMapCont.begin();
349       for(; aXYMapContIter != aXYMapCont.end(); aXYMapContIter++){
350         long iLine = aXYMapContIter->first;
351         long iLineId = aLineIdCont[iLine];
352         const TXYMap& aXYMap = aXYMapCont[iLine];
353         TXYMap::const_iterator aXYMapIter = aXYMap.find(aDist);
354         // Can we find some value that belong to the line and have the same X coordinate?
355         if(aXYMapIter == aXYMap.end()) continue;
356         float aVal = aXYMapIter->second;
357         aTableOfReal->PutValue(aVal,iLineId+2,i+1);
358       }
359     }
360     {
361       aTableOfReal->SetRowTitle(1,"X");
362       aTableOfReal->SetRowUnit(1,"-");
363       QString aUnitName = myField->myUnitNames[0].c_str();
364       int aScalarMode = myCutLinesPL->GetScalarMode();
365       if(aScalarMode != 0) 
366         aUnitName = myField->myUnitNames[aScalarMode-1].c_str();
367       aUnitName = aUnitName.simplifyWhiteSpace();
368       if(aUnitName.isEmpty()) aUnitName = "-";
369       TXYMapCont::const_iterator aXYMapContIter = aXYMapCont.begin();
370       for(; aXYMapContIter != aXYMapCont.end(); aXYMapContIter++){
371         long iLine = aXYMapContIter->first;
372         long iLineId = aLineIdCont[iLine];
373         aString.sprintf("Y%d",iLine);
374         if(MYDEBUG) 
375           MESSAGE("CutPlanes_i::BuildTableOfReal - SetRowTitle("<<iLineId+2<<",'"<<aString<<"')");
376         aTableOfReal->SetRowTitle(iLineId+2,aString.latin1());
377         aTableOfReal->SetRowUnit(iLineId+2,aUnitName.latin1());
378       }
379     }
380   }catch(std::runtime_error& exc){
381     INFOS("Follow exception was accured :\n"<<exc.what());
382   }catch (...){
383     INFOS("Unknown exception was accured !!!");
384   }
385 }