1 // VISU OBJECT : interactive object for VISU entities implementation
3 // Copyright (C) 2003 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
23 // File : VISU_PrsObject_i.cxx
24 // Author : Alexey PETROV
27 #include "VISU_CutLines_i.hh"
28 #include "VISU_Result_i.hh"
30 #include "VISU_Actor.h"
31 #include "VISU_CutLinesPL.hxx"
32 #include "VISU_Convertor.hxx"
33 #include "VISU_PipeLineUtils.hxx"
35 #include "SUIT_ResourceMgr.h"
37 #include <vtkAppendPolyData.h>
42 static vtkFloatingPointType EPS_machine = 1.0E-7;
45 static int MYDEBUG = 0;
47 static int MYDEBUG = 0;
50 int VISU::CutLines_i::IsPossible(Result_i* theResult, const char* theMeshName, VISU::Entity theEntity,
51 const char* theFieldName, int theIteration, int isMemoryCheck)
53 return VISU::ScalarMap_i::IsPossible(theResult,theMeshName,theEntity,theFieldName,theIteration,isMemoryCheck);
56 int VISU::CutLines_i::myNbPresent = 0;
57 QString VISU::CutLines_i::GenerateName() { return VISU::GenerateName("CutLines",myNbPresent++);}
59 const string VISU::CutLines_i::myComment = "CUTLINES";
60 const char* VISU::CutLines_i::GetComment() const { return myComment.c_str();}
64 CutLines_i(Result_i* theResult,
66 PrsObject_i(theResult->GetStudyDocument()),
67 Prs3d_i(theResult,theAddToStudy),
68 ColoredPrs3d_i(theResult,theAddToStudy),
69 ScalarMap_i(theResult,theAddToStudy),
75 CutLines_i(Result_i* theResult,
76 SALOMEDS::SObject_ptr theSObject) :
77 PrsObject_i(theResult->GetStudyDocument()),
78 Prs3d_i(theResult,theSObject),
79 ColoredPrs3d_i(theResult,theSObject),
80 ScalarMap_i(theResult,theSObject),
86 /*! Copy map to /a myMapCurvesInverted.
87 * \param theCurves - map
89 void VISU::CutLines_i::CopyCurvesInverted(const TCurvesInv& theCurves){
90 myMapCurvesInverted = theCurves;
93 VISU::Storable* VISU::CutLines_i::Create(const char* theMeshName, VISU::Entity theEntity,
94 const char* theFieldName, int theIteration)
96 return ScalarMap_i::Create(theMeshName,theEntity,theFieldName,theIteration);
100 VISU::Storable* VISU::CutLines_i::Restore(const Storable::TRestoringMap& theMap)
102 TSuperClass::Restore(theMap);
104 SetNbLines(VISU::Storable::FindValue(theMap,"myNbLines").toInt());
105 SetDisplacement(VISU::Storable::FindValue(theMap,"myDisplacement[0]").toDouble());
106 SetDisplacement2(VISU::Storable::FindValue(theMap,"myDisplacement[1]").toDouble());
107 SetOrientation(CutPlanes::Orientation(VISU::Storable::FindValue(theMap,"myBasePlane[0]").toInt()),
108 Storable::FindValue(theMap,"aRot[0][0]").toDouble(),
109 Storable::FindValue(theMap,"aRot[0][1]").toDouble());
110 SetOrientation2(CutPlanes::Orientation(VISU::Storable::FindValue(theMap,"myBasePlane[1]").toInt()),
111 Storable::FindValue(theMap,"aRot[1][0]").toDouble(),
112 Storable::FindValue(theMap,"aRot[1][1]").toDouble());
113 if (VISU::Storable::FindValue(theMap,"myBasePlaneCondition").toInt())
116 SetBasePlanePosition(VISU::Storable::FindValue(theMap,"myBasePlanePosition").toDouble());
118 QStringList aPosList = QStringList::split("|",VISU::Storable::FindValue(theMap,"myLinePosition") );
119 QStringList aCondList = QStringList::split("|",VISU::Storable::FindValue(theMap,"myLineCondition") );
120 for(int i = 0, iEnd = GetNbLines(); i < iEnd; i++)
121 if(aCondList[i].toInt() == 0)
122 SetLinePosition(i,aPosList[i].toDouble());
124 // Restoring the map - \a myMapCurvesInverted
125 QStringList aMapCurvesInverted = QStringList::split("|",VISU::Storable::FindValue(theMap,"myMapCurvesInverted") );
126 if (aMapCurvesInverted.count() == GetNbLines()){
127 for(int i = 0, iEnd = GetNbLines(); i < iEnd ; i++){
128 if(aMapCurvesInverted[i].toInt())
129 SetCurveInverted(i,true);
131 SetCurveInverted(i,false);
134 for(int i = 0, iEnd = GetNbLines(); i < iEnd ; i++)
135 SetCurveInverted(i,false);
142 void VISU::CutLines_i::ToStream(std::ostringstream& theStr){
143 ScalarMap_i::ToStream(theStr);
145 int aNbLines = GetNbLines();
147 Storable::DataToStream( theStr, "myNbLines", aNbLines );
148 Storable::DataToStream( theStr, "myDisplacement[0]", GetDisplacement() );
149 Storable::DataToStream( theStr, "myDisplacement[1]", GetDisplacement2() );
150 Storable::DataToStream( theStr, "myBasePlane[0]", int(GetOrientationType()) );
151 Storable::DataToStream( theStr, "myBasePlane[1]", int(GetOrientationType2()) );
152 Storable::DataToStream( theStr, "aRot[0][0]", GetRotateX() );
153 Storable::DataToStream( theStr, "aRot[0][1]", GetRotateY() );
154 Storable::DataToStream( theStr, "aRot[1][0]", GetRotateX2() );
155 Storable::DataToStream( theStr, "aRot[1][1]", GetRotateY2() );
156 Storable::DataToStream( theStr, "myBasePlanePosition", GetBasePlanePosition() );
157 Storable::DataToStream( theStr, "myBasePlaneCondition", IsDefault() );
159 QString aStrPos, aStrCon;
160 for(int i = 0, iEnd = GetNbLines(); i < iEnd; i++){
161 aStrPos.append(QString::number(GetLinePosition(i)) + "|");
162 aStrCon.append(QString::number(IsDefaultPosition(i)) + "|");
164 Storable::DataToStream( theStr, "myLinePosition", aStrPos.latin1());
165 Storable::DataToStream( theStr, "myLineCondition", aStrCon.latin1());
167 // Storing the map - \a myMapCurvesInverted
168 QString aStrCurvesInverted;
169 for(int i = 0, iEnd = GetNbLines(); i < iEnd; i++)
170 aStrCurvesInverted.append(QString::number(IsCurveInverted(i)) + "|");
171 Storable::DataToStream( theStr, "myMapCurvesInverted", aStrCurvesInverted.latin1());
174 VISU::CutLines_i::~CutLines_i(){
175 if(MYDEBUG) MESSAGE("CutLines_i::~CutLines_i()");
179 void VISU::CutLines_i::SetOrientation(VISU::CutPlanes::Orientation theOrient,
180 CORBA::Double theXAngle, CORBA::Double theYAngle)
182 myCutLinesPL->SetOrientation(VISU_CutPlanesPL::PlaneOrientation(theOrient),
183 theXAngle,theYAngle);
185 void VISU::CutLines_i::SetOrientation2(VISU::CutPlanes::Orientation theOrient,
186 CORBA::Double theXAngle, CORBA::Double theYAngle)
188 myCutLinesPL->SetOrientation(VISU_CutPlanesPL::PlaneOrientation(theOrient),
189 theXAngle,theYAngle,1);
192 VISU::CutPlanes::Orientation VISU::CutLines_i::GetOrientationType() {
193 return VISU::CutPlanes::Orientation(myCutLinesPL->GetPlaneOrientation());
195 VISU::CutPlanes::Orientation VISU::CutLines_i::GetOrientationType2() {
196 return VISU::CutPlanes::Orientation(myCutLinesPL->GetPlaneOrientation(1));
199 CORBA::Double VISU::CutLines_i::GetRotateX(){
200 return myCutLinesPL->GetRotateX();
202 CORBA::Double VISU::CutLines_i::GetRotateY(){
203 return myCutLinesPL->GetRotateY();
206 CORBA::Double VISU::CutLines_i::GetRotateX2(){
207 return myCutLinesPL->GetRotateX(1);
209 CORBA::Double VISU::CutLines_i::GetRotateY2(){
210 return myCutLinesPL->GetRotateY(1);
214 void VISU::CutLines_i::SetDisplacement(CORBA::Double theDisp) {
215 myCutLinesPL->SetDisplacement(theDisp);
217 void VISU::CutLines_i::SetDisplacement2(CORBA::Double theDisp) {
218 myCutLinesPL->SetDisplacement(theDisp,1);
221 CORBA::Double VISU::CutLines_i::GetDisplacement() {
222 return myCutLinesPL->GetDisplacement();
224 CORBA::Double VISU::CutLines_i::GetDisplacement2() {
225 return myCutLinesPL->GetDisplacement(1);
229 void VISU::CutLines_i::SetBasePlanePosition(CORBA::Double thePlanePosition){
230 myCutLinesPL->SetPosition(thePlanePosition);
233 CORBA::Double VISU::CutLines_i::GetBasePlanePosition(){
234 return myCutLinesPL->GetPosition();
237 void VISU::CutLines_i::SetLinePosition(CORBA::Long thePlaneNumber, CORBA::Double thePlanePosition){
238 myCutLinesPL->SetPartPosition(thePlaneNumber,thePlanePosition);
241 CORBA::Double VISU::CutLines_i::GetLinePosition(CORBA::Long thePlaneNumber){
242 return myCutLinesPL->GetPartPosition(thePlaneNumber,1);
246 void VISU::CutLines_i::SetDefault(){
247 myCutLinesPL->SetDefault();
250 CORBA::Boolean VISU::CutLines_i::IsDefault(){
251 return myCutLinesPL->IsDefault();
254 void VISU::CutLines_i::SetDefaultPosition(CORBA::Long thePlaneNumber){
255 myCutLinesPL->SetPartDefault(thePlaneNumber);
258 CORBA::Boolean VISU::CutLines_i::IsDefaultPosition(CORBA::Long thePlaneNumber){
259 return myCutLinesPL->IsPartDefault(thePlaneNumber);
262 /*! Invert all curves of corresponding table
263 * see void VISU::CutLines_i::SetCurveInverted(CORBA::Long theCurveNumber,CORBA::Boolean theInvert)
264 * \param theInvert - Invert all curves, if value is TRUE, else not.
266 void VISU::CutLines_i::SetAllCurvesInverted(CORBA::Boolean theInvert){
267 for (int i=0; i<GetNbLines(); i++) SetCurveInverted(i,theInvert);
270 /*! Checks the orientation of all curves
271 * \retval TRUE - if all curves are inverted, else FALSE
273 CORBA::Boolean VISU::CutLines_i::IsAllCurvesInverted(){
274 for (int i=0; i<GetNbLines(); i++)
275 if (!IsCurveInverted(i)) return false;
279 /*! Sets orientation of curve
280 * \param theCurveNumber - integer value, number of cut line.
281 * \param theInvert - boolean value, TRUE or false.
283 void VISU::CutLines_i::SetCurveInverted(CORBA::Long theCurveNumber,CORBA::Boolean theInvert){
284 myMapCurvesInverted[theCurveNumber] = theInvert;
287 /*! Checks orientation of curve.
288 * \param theCurveNumber - integer value, number of cut line.
289 * \retval TRUE - if line in the table is inverted, else FALSE.
291 CORBA::Boolean VISU::CutLines_i::IsCurveInverted(CORBA::Long theCurveNumber){
292 return myMapCurvesInverted[theCurveNumber];
295 void VISU::CutLines_i::SetNbLines(CORBA::Long theNb) {
296 myCutLinesPL->SetNbParts(theNb);
298 CORBA::Long VISU::CutLines_i::GetNbLines() {
299 return myCutLinesPL->GetNbParts();
303 void VISU::CutLines_i::DoHook(){
304 if(!myPipeLine) myPipeLine = VISU_CutLinesPL::New();
305 myCutLinesPL = dynamic_cast<VISU_CutLinesPL*>(myPipeLine);
307 ScalarMap_i::DoHook();
312 ::CreateActor(const Handle(SALOME_InteractiveObject)& theIO)
314 if(VISU_Actor* anActor = ScalarMap_i::CreateActor(theIO)){
315 anActor->SetVTKMapping(true);
316 SUIT_ResourceMgr* aResourceMgr = VISU::GetResourceMgr();
317 int aDispMode = aResourceMgr->integerValue("VISU" , "cut_lines_represent", 2);
318 anActor->SetRepresentation(aDispMode);
324 void VISU::CutLines_i::BuildTableOfReal(SALOMEDS::SObject_ptr theSObject){
326 if(MYDEBUG) MESSAGE("CutPlanes_i::BuildTableOfReal");
328 SALOMEDS::GenericAttribute_var anAttr;
329 SALOMEDS::StudyBuilder_var aStudyBuilder = myStudy->NewBuilder();
330 anAttr = aStudyBuilder->FindOrCreateAttribute(theSObject, "AttributeTableOfReal");
331 SALOMEDS::AttributeTableOfReal_var aTableOfReal = SALOMEDS::AttributeTableOfReal::_narrow(anAttr);
333 typedef set<vtkFloatingPointType> TXCont;
334 typedef map<vtkFloatingPointType,vtkFloatingPointType> TXYMap;
335 typedef map<int,TXYMap> TXYMapCont;
336 typedef map<long,long> TLineIdCont;
339 aTitle.sprintf("%s",myTitle.c_str());
340 aTitle = aTitle.simplifyWhiteSpace();
341 aTableOfReal->SetTitle(aTitle.latin1());
343 int iLineEnd = myCutLinesPL->GetAppendPolyData()->GetNumberOfInputs();
344 if(MYDEBUG) MESSAGE("CutPlanes_i::BuildTableOfReal iLineEnd = "<<iLineEnd);
346 TXYMapCont aXYMapCont;
347 TLineIdCont aLineIdCont; // Define internal numeration of lines
348 const vtkFloatingPointType *aDirLn = myCutLinesPL->GetDirLn();
349 const vtkFloatingPointType *aBasePnt = myCutLinesPL->GetBasePnt();
350 const vtkFloatingPointType *aBoundPrjLn = myCutLinesPL->GetBoundPrjLn();
351 for(int iLine = 0, jLine = 0; iLine < iLineEnd; iLine++){
352 vtkDataSet *aDataSet = myCutLinesPL->GetAppendPolyData()->GetInput(iLine);
354 int aNbPoints = aDataSet->GetNumberOfPoints();
355 if(!aNbPoints) continue;
356 vtkPointData *aPointData = aDataSet->GetPointData();
357 vtkDataArray *aScalars = aPointData->GetScalars();
358 vtkCellDataToPointData *aFilter = NULL;
360 aFilter = vtkCellDataToPointData::New();
361 aFilter->SetInput(aDataSet);
362 aFilter->PassCellDataOn();
363 aDataSet = aFilter->GetOutput();
366 aPointData = aDataSet->GetPointData();
367 aScalars = aPointData->GetScalars();
368 if(!aScalars) continue;
369 if(MYDEBUG) MESSAGE("CutPlanes_i::BuildTableOfReal iLine = "<<iLine<<"; aNbPoints = "<<aNbPoints);
370 aLineIdCont[iLine] = jLine++;
371 TXYMap& aXYMap = aXYMapCont[iLine];
372 vtkFloatingPointType aPnt[3], aVect[3], aDist;
373 for(int i = 0; i < aNbPoints; i++){
374 aDataSet->GetPoint(i,aPnt);
375 Sub(aPnt,aBasePnt,aVect);
376 if ( fabs(aBoundPrjLn[2]) < EPS_machine )
380 aDist = vtkMath::Dot(aVect,aDirLn) / aBoundPrjLn[2];
382 if(aDist < 0.0) aDist = 0.0;
383 if(aDist > 1.0) aDist = 1.0;
385 aXYMap[aDist] = aScalars->GetTuple1(i);
388 aFilter->UnRegisterAllOutputs();
392 if(aXYMapCont.size() == 0)
393 throw std::runtime_error("CutPlanes_i::BuildTableOfReal aXYMapCont.size() == 0 !!!");
396 // Invertion all curves in the table, which has inversion flag is TRUE (see \a myMapCurvesInverted)
397 for(int iLine=0; iLine < iLineEnd; iLine++){
398 if (!IsCurveInverted(iLine)) continue;
400 TXYMap& aXYMap = aXYMapCont[iLine];
401 TXYMap::const_iterator aXYMapIter = aXYMap.begin();
402 std::list<vtkFloatingPointType> XKeys;
403 for (;aXYMapIter != aXYMap.end() ; aXYMapIter++) XKeys.push_back(aXYMapIter->first);
405 if (XKeys.size() > 1) {
406 vtkFloatingPointType a_first_indx = XKeys.front();
407 vtkFloatingPointType a_last_indx = XKeys.back();
408 if (a_first_indx > a_last_indx){
410 vtkFloatingPointType tmp = a_first_indx;
411 a_first_indx = a_last_indx;
414 std::list<vtkFloatingPointType>::const_iterator aIter = XKeys.begin();
415 for (int k=0;k<XKeys.size() and aIter != XKeys.end();k++,aIter++){
416 // Warning: value '1.0' come from workaround:
417 // see also aDist = vtkMath::Dot(aVect,aDirLn) / aBoundPrjLn[2];
418 // aDist >= 0 and aDist<=1.0
419 aNewXYMap[1.0 - *aIter] = aXYMap[*aIter];
421 TXYMap::const_iterator aNewXYMapIter = aNewXYMap.begin();
423 for (;aNewXYMapIter != aNewXYMap.end();aNewXYMapIter++) {
424 aXYMap[aNewXYMapIter->first] = aNewXYMapIter->second;
429 //Resorting of theXYMap
430 TXYMapCont::iterator aXYMapContIter = aXYMapCont.begin();
431 for(; aXYMapContIter != aXYMapCont.end(); aXYMapContIter++){
432 TXYMap& aXYMap = aXYMapContIter->second, aNewXYMap;
433 if(aXYMap.size() > 2){
434 // Try to smooth the values of the line by applying linear approximation
435 TXYMap::const_iterator aXYMapIter[2] = {aXYMap.begin(), ++aXYMap.begin()};
436 aNewXYMap[aXYMapIter[0]->first] = aXYMapIter[0]->second;
437 aXCont.insert(aXYMapIter[0]->first);
438 for(; aXYMapIter[1] != aXYMap.end(); aXYMapIter[0]++, aXYMapIter[1]++){
439 vtkFloatingPointType aY[3] = {aXYMapIter[0]->second, aXYMapIter[1]->second, 0.0};
440 aY[2] = (aY[0] + aY[1])/2.0;
441 vtkFloatingPointType aX[3] = {aXYMapIter[0]->first, aXYMapIter[1]->first, 0.0};
442 aX[2] = (aX[0] + aX[1])/2.0;
443 aNewXYMap[aX[2]] = aY[2];
444 aXCont.insert(aX[2]);
446 aNewXYMap[aXYMapIter[0]->first] = aXYMapIter[0]->second;
447 aXCont.insert(aXYMapIter[0]->first);
450 TXYMap::const_iterator aXYMapIter = aXYMap.begin();
451 for(; aXYMapIter != aXYMap.end(); aXYMapIter++)
452 aXCont.insert(aXYMapIter->first);
455 if(aXCont.size() == 0)
456 throw std::runtime_error("CutPlanes_i::BuildTableOfReal aXCont.size() == 0 !!!");
458 int iEnd = aXCont.size();
459 aTableOfReal->SetNbColumns(iEnd);
460 TXCont::const_iterator aXContIter = aXCont.begin();
461 for(long i = 0; aXContIter != aXCont.end(); aXContIter++, i++){
462 vtkFloatingPointType aDist = *aXContIter;
463 aTableOfReal->PutValue(aDist,1,i+1);
464 aString.sprintf("%d",i);
465 aTableOfReal->SetColumnTitle(i+1,aString.latin1());
466 if(MYDEBUG) MESSAGE("CutPlanes_i::BuildTableOfReal aDist = "<<aDist);
467 TXYMapCont::const_iterator aXYMapContIter = aXYMapCont.begin();
468 for(; aXYMapContIter != aXYMapCont.end(); aXYMapContIter++){
469 long iLine = aXYMapContIter->first;
470 long iLineId = aLineIdCont[iLine];
471 const TXYMap& aXYMap = aXYMapCont[iLine];
472 TXYMap::const_iterator aXYMapIter = aXYMap.find(aDist);
473 // Can we find some value that belong to the line and have the same X coordinate?
474 if(aXYMapIter == aXYMap.end()) continue;
475 vtkFloatingPointType aVal = aXYMapIter->second;
476 aTableOfReal->PutValue(aVal,iLineId+2,i+1);
480 aTableOfReal->SetRowTitle(1,"X");
481 aTableOfReal->SetRowUnit(1,"-");
482 QString aUnitName = myField->myUnitNames[0].c_str();
483 int aScalarMode = myCutLinesPL->GetScalarMode();
485 aUnitName = myField->myUnitNames[aScalarMode-1].c_str();
486 aUnitName = aUnitName.simplifyWhiteSpace();
487 if(aUnitName.isEmpty()) aUnitName = "-";
488 TXYMapCont::const_iterator aXYMapContIter = aXYMapCont.begin();
489 for(; aXYMapContIter != aXYMapCont.end(); aXYMapContIter++){
490 long iLine = aXYMapContIter->first;
491 long iLineId = aLineIdCont[iLine];
492 aString.sprintf("Y%d",iLine);
494 MESSAGE("CutPlanes_i::BuildTableOfReal - SetRowTitle("<<iLineId+2<<",'"<<aString<<"')");
495 aTableOfReal->SetRowTitle(iLineId+2,aString.latin1());
496 aTableOfReal->SetRowUnit(iLineId+2,aUnitName.latin1());
499 }catch(std::exception& exc){
500 INFOS("Follow exception was occured :\n"<<exc.what());
502 INFOS("Unknown exception was occured !!!");