1 // Copyright (C) 2007-2012 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
23 // VISU OBJECT : interactive object for VISU entities implementation
24 // File: VISU_PipeLine.cxx
25 // Author: Alexey PETROV
28 #include "VISU_CutPlanesPL.hxx"
29 #include "VISU_FieldTransform.hxx"
30 #include "VISU_PipeLineUtils.hxx"
31 #include "VTKViewer_GeometryFilter.h"
32 #include "VISU_MapperHolder.hxx"
33 #include "VISU_DeformationPL.hxx"
35 #include <vtkAppendPolyData.h>
36 #include <vtkEDFCutter.h>
39 //#include <vtkUnstructuredGrid.h>
41 static vtkFloatingPointType EPS = 1.0E-3;
44 static int MYDEBUG = 0;
46 static int MYDEBUG = 0;
50 //----------------------------------------------------------------------------
51 vtkStandardNewMacro(VISU_CutPlanesPL);
54 //----------------------------------------------------------------------------
57 VISU_OptionalDeformationPL()
59 if(MYDEBUG) MESSAGE("VISU_CutPlanesPL()::VISU_CutPlanesPL() - "<<this);
61 SetIsShrinkable(false);
62 SetIsFeatureEdgesAllowed(false);
64 SetElnoDisassembleState( true );
66 myAppendPolyData = vtkAppendPolyData::New();
73 myDisplacement[0] = myDisplacement[1] = 0.5;
75 myAng[0][0] = myAng[0][1] = myAng[0][2] = 0.0;
76 myAng[1][0] = myAng[1][1] = myAng[1][2] = 0.0;
77 UseDeformation(false);
81 //----------------------------------------------------------------------------
85 if(MYDEBUG) MESSAGE("VISU_CutPlanesPL()::~VISU_CutPlanesPL() - "<<this);
86 myAppendPolyData->Delete();
87 myAppendPolyData = NULL;
91 //----------------------------------------------------------------------------
96 unsigned long int aTime = Superclass::GetMTime();
99 aTime = std::max(aTime, VISU_OptionalDeformationPL::GetMTime());
102 aTime = std::max(aTime, myAppendPolyData->GetMTime());
108 //----------------------------------------------------------------------------
111 ::DoShallowCopy(VISU_PipeLine *thePipeLine,
114 Superclass::DoShallowCopy(thePipeLine, theIsCopyInput);
116 if(VISU_CutPlanesPL *aPipeLine = dynamic_cast<VISU_CutPlanesPL*>(thePipeLine)){
118 SetOrientation(aPipeLine->GetPlaneOrientation(),
119 aPipeLine->GetRotateX(),
120 aPipeLine->GetRotateY());
122 SetDisplacement(aPipeLine->GetDisplacement());
124 SetNbParts(aPipeLine->GetNbParts());
125 for (int i = 0, iEnd = GetNbParts(); i < iEnd; i++) {
126 if(!aPipeLine->IsPartDefault(i))
127 SetPartPosition(i, aPipeLine->GetPartPosition(i));
135 //----------------------------------------------------------------------------
143 myDisplacement[0] = 0.5;
144 myAng[0][0] = myAng[0][1] = myAng[0][2] = 0.0;
145 SetScale(VISU_DeformationPL::GetDefaultScaleFactor(this));
149 //----------------------------------------------------------------------------
154 return GetWarpVectorOutput();
158 //----------------------------------------------------------------------------
163 vtkDataSet* aMergedInput = GetMergedInput();
164 if(VISU::IsQuadraticData(aMergedInput)) // Bug 0020123, note 0005343
165 throw std::runtime_error("Impossible to build presentation");
167 ClearAppendPolyData(myAppendPolyData);
170 if(!myVectorialField || !IsDeformed()){
171 SetMergeFilterInput(aMergedInput,aMergedInput);
175 if(VISU::IsDataOnCells(aMergedInput))
176 GetMapper()->SetScalarModeToUseCellData();
178 GetMapper()->SetScalarModeToUsePointData();
182 vtkFloatingPointType aDir[3];
187 vtkFloatingPointType aBounds[6];
189 vtkDataSet* aFilterOutput = GetMergeFilterOutput();
191 aFilterOutput->GetBounds(aBounds);
193 CutWithPlanes(myAppendPolyData,
204 SetWarpVectorInput(myAppendPolyData->GetOutput());
205 Superclass::Update();
209 //----------------------------------------------------------------------------
214 unsigned long int aSize = Superclass::GetMemorySize();
216 if(vtkDataSet* aDataSet = myAppendPolyData->GetOutput())
217 aSize += aDataSet->GetActualMemorySize() * 1024;
219 int anEnd = myAppendPolyData->GetNumberOfInputConnections(0);
220 for(int anId = 0; anId < anEnd; anId++)
221 if(vtkDataSet* aDataSet = myAppendPolyData->GetInput(anId))
222 aSize += aDataSet->GetActualMemorySize() * 1024;
228 //----------------------------------------------------------------------------
231 ::SetPartPosition(int theNum)
233 for(int i = 0; i < myNbParts; i++)
234 myPartPosition[i] = GetPartPosition(i,theNum);
239 ::ClearAppendPolyData(vtkAppendPolyData *theAppendPolyData)
241 theAppendPolyData->RemoveAllInputs();
245 //----------------------------------------------------------------------------
246 vtkFloatingPointType*
248 GetRx(vtkFloatingPointType theRx[3][3],
249 vtkFloatingPointType thaAng)
251 theRx[0][0] = 1.0; theRx[0][1] = 0.0; theRx[0][2] = 0.0;
252 theRx[1][0] = 0.0; theRx[1][1] = cos(thaAng); theRx[1][2] = -sin(thaAng);
253 theRx[2][0] = 0.0; theRx[2][1] = sin(thaAng); theRx[2][2] = cos(thaAng);
259 //----------------------------------------------------------------------------
260 vtkFloatingPointType*
262 ::GetRy(vtkFloatingPointType theRy[3][3],
263 vtkFloatingPointType thaAng)
265 theRy[0][0] = cos(thaAng); theRy[0][1] = 0.0; theRy[0][2] = sin(thaAng);
266 theRy[1][0] = 0.0; theRy[1][1] = 1.0; theRy[1][2] = 0.0;
267 theRy[2][0] = -sin(thaAng); theRy[2][1] = 0.0; theRy[2][2] = cos(thaAng);
272 //----------------------------------------------------------------------------
273 vtkFloatingPointType*
275 ::GetRz(vtkFloatingPointType theRz[3][3],
276 vtkFloatingPointType thaAng)
278 theRz[0][0] = cos(thaAng); theRz[0][1] = -sin(thaAng); theRz[0][2] = 0.0;
279 theRz[1][0] = sin(thaAng); theRz[1][1] = cos(thaAng); theRz[1][2] = 0.0;
280 theRz[2][0] = 0.0; theRz[2][1] = 0.0; theRz[2][2] = 1.0;
285 //----------------------------------------------------------------------------
288 ::CorrectPnt(vtkFloatingPointType thePnt[3],
289 const vtkFloatingPointType BoundPrj[6])
291 for(int i = 0, j = 0; i < 3; ++i, j=2*i){
292 if(thePnt[i] < BoundPrj[j]) thePnt[i] = BoundPrj[j];
293 if(thePnt[i] > BoundPrj[j+1]) thePnt[i] = BoundPrj[j+1];
298 //----------------------------------------------------------------------------
301 ::GetBoundProject(vtkFloatingPointType BoundPrj[3],
302 const vtkFloatingPointType BoundBox[6],
303 const vtkFloatingPointType Dir[3])
305 vtkFloatingPointType BoundPoints[8][3] = { {BoundBox[0],BoundBox[2],BoundBox[4]},
306 {BoundBox[1],BoundBox[2],BoundBox[4]},
307 {BoundBox[0],BoundBox[3],BoundBox[4]},
308 {BoundBox[1],BoundBox[3],BoundBox[4]},
309 {BoundBox[0],BoundBox[2],BoundBox[5]},
310 {BoundBox[1],BoundBox[2],BoundBox[5]},
311 {BoundBox[0],BoundBox[3],BoundBox[5]},
312 {BoundBox[1],BoundBox[3],BoundBox[5]}};
313 BoundPrj[0] = vtkMath::Dot(Dir,BoundPoints[0]), BoundPrj[1] = BoundPrj[0];
314 for(int i = 1; i < 8; i++){
315 vtkFloatingPointType tmp = vtkMath::Dot(Dir,BoundPoints[i]);
316 if(BoundPrj[1] < tmp) BoundPrj[1] = tmp;
317 if(BoundPrj[0] > tmp) BoundPrj[0] = tmp;
319 BoundPrj[2] = BoundPrj[1] - BoundPrj[0];
320 BoundPrj[1] = BoundPrj[0] + (1.0 - EPS)*BoundPrj[2];
321 BoundPrj[0] = BoundPrj[0] + EPS*BoundPrj[2];
322 BoundPrj[2] = BoundPrj[1] - BoundPrj[0];
326 //----------------------------------------------------------------------------
329 ::SetOrientation(const VISU_CutPlanesPL::PlaneOrientation& theOrient,
330 vtkFloatingPointType theXAng,
331 vtkFloatingPointType theYAng,
334 myBasePlane[theNum] = theOrient;
335 switch(myBasePlane[theNum]){
336 case XY: myAng[theNum][0] = theXAng; break;
337 case YZ: myAng[theNum][1] = theXAng; break;
338 case ZX: myAng[theNum][2] = theXAng; break;
340 switch(myBasePlane[theNum]){
341 case XY: myAng[theNum][1] = theYAng; break;
342 case YZ: myAng[theNum][2] = theYAng; break;
343 case ZX: myAng[theNum][0] = theYAng; break;
348 //----------------------------------------------------------------------------
349 const VISU_CutPlanesPL::PlaneOrientation&
351 ::GetPlaneOrientation(int theNum)
353 return myBasePlane[theNum];
358 ::GetRotateX(int theNum)
360 switch(myBasePlane[theNum]){
361 case XY: return myAng[theNum][0];
362 case YZ: return myAng[theNum][1];
363 case ZX: return myAng[theNum][2];
369 //----------------------------------------------------------------------------
372 ::GetRotateY(int theNum)
374 switch(myBasePlane[theNum]){
375 case XY: return myAng[theNum][1];
376 case YZ: return myAng[theNum][2];
377 case ZX: return myAng[theNum][0];
383 //----------------------------------------------------------------------------
386 ::GetDisplacement(int theNum)
388 return myDisplacement[theNum];
392 //----------------------------------------------------------------------------
395 ::SetDisplacement(vtkFloatingPointType theDisp,
398 if(VISU::CheckIsSameValue(myDisplacement[theNum], theDisp))
401 myDisplacement[theNum] = theDisp;
406 //----------------------------------------------------------------------------
409 ::SetNbParts(int theNbParts)
411 if(theNbParts > 0 && GetNbParts() != theNbParts){
412 myPartPosition.resize(theNbParts);
413 myPartCondition.resize(theNbParts, 1);
414 myNbParts = theNbParts;
420 //----------------------------------------------------------------------------
425 return myPartPosition.size();
429 //----------------------------------------------------------------------------
432 ::SetPartPosition(int thePartNumber,
433 vtkFloatingPointType thePartPosition)
435 if(thePartNumber >= myNbParts)
438 bool anIsSameValue = VISU::CheckIsSameValue(myPartPosition[thePartNumber], thePartPosition);
439 anIsSameValue &= VISU::CheckIsSameValue(myPartCondition[thePartNumber], 0);
443 myPartPosition[thePartNumber] = thePartPosition;
444 myPartCondition[thePartNumber] = 0;
449 //----------------------------------------------------------------------------
452 ::GetPartPosition(int thePartNumber,
455 if(thePartNumber >= myNbParts)
458 vtkFloatingPointType aPosition = myPartPosition[thePartNumber];
459 if(myPartCondition[thePartNumber]){
460 vtkFloatingPointType aDir[3], aBounds[6], aBoundPrj[3];
462 GetMergedInput()->GetBounds(aBounds);
464 GetMergeFilterOutput()->GetBounds(aBounds);
469 myBasePlane[theNum]);
471 GetBoundProject(aBoundPrj,
476 vtkFloatingPointType aDBoundPrj = aBoundPrj[2]/(myNbParts - 1);
477 vtkFloatingPointType aDisplacement = aDBoundPrj * myDisplacement[theNum];
478 vtkFloatingPointType aStartPosition = aBoundPrj[0] - 0.5*aDBoundPrj + aDisplacement;
479 aPosition = aStartPosition + thePartNumber*aDBoundPrj;
481 aPosition = aBoundPrj[0] + aBoundPrj[2]*myDisplacement[theNum];
488 //----------------------------------------------------------------------------
491 ::SetPartDefault(int thePartNumber)
493 if(thePartNumber >= myNbParts)
496 bool anIsSameValue = VISU::CheckIsSameValue(myPartPosition[thePartNumber], GetPartPosition(thePartNumber));
497 anIsSameValue &= VISU::CheckIsSameValue(myPartCondition[thePartNumber], 1);
501 myPartPosition[thePartNumber] = GetPartPosition(thePartNumber);
502 myPartCondition[thePartNumber] = 1;
507 //----------------------------------------------------------------------------
510 ::IsPartDefault(int thePartNumber)
512 if(thePartNumber >= myNbParts)
515 return myPartCondition[thePartNumber];
519 //----------------------------------------------------------------------------
522 ::GetDir(vtkFloatingPointType theDir[3],
523 const vtkFloatingPointType theAng[3],
524 const PlaneOrientation& theBasePlane)
527 vtkFloatingPointType aRx[3][3], aRy[3][3], aRz[3][3], aRotation[3][3];
528 switch(theBasePlane){
530 if(fabs(theAng[0]) > EPS) GetRx(aRx,theAng[0]); else vtkMath::Identity3x3(aRx);
531 if(fabs(theAng[1]) > EPS) GetRy(aRy,theAng[1]); else vtkMath::Identity3x3(aRy);
532 vtkMath::Multiply3x3(aRx,aRy,aRotation);
536 if(fabs(theAng[1]) > EPS) GetRy(aRy,theAng[1]); else vtkMath::Identity3x3(aRy);
537 if(fabs(theAng[2]) > EPS) GetRz(aRz,theAng[2]); else vtkMath::Identity3x3(aRz);
538 vtkMath::Multiply3x3(aRy,aRz,aRotation);
542 if(fabs(theAng[2]) > EPS) GetRz(aRz,theAng[2]); else vtkMath::Identity3x3(aRz);
543 if(fabs(theAng[0]) > EPS) GetRx(aRx,theAng[0]); else vtkMath::Identity3x3(aRx);
544 vtkMath::Multiply3x3(aRz,aRx,aRotation);
549 for(int i = 0; i < 3; i++)
550 theDir[i] = aRotation[i][iPlane];
554 //----------------------------------------------------------------------------
557 ::CutWithPlane(vtkAppendPolyData* theAppendPolyData,
558 vtkDataSet* theDataSet,
559 vtkFloatingPointType theDir[3],
560 vtkFloatingPointType theOrig[3])
562 vtkEDFCutter *aCutPlane = vtkEDFCutter::New();
563 aCutPlane->SetInput(theDataSet);
564 vtkPlane *aPlane = vtkPlane::New();
565 aPlane->SetOrigin(theOrig);
567 aPlane->SetNormal(theDir);
568 aCutPlane->SetCutFunction(aPlane);
570 theAppendPolyData->AddInput(aCutPlane->GetOutput());
575 //----------------------------------------------------------------------------
578 ::CutWithPlanes(vtkAppendPolyData* theAppendPolyData,
579 vtkDataSet* theDataSet,
581 vtkFloatingPointType theDir[3],
582 vtkFloatingPointType theBounds[6],
583 const std::vector<vtkFloatingPointType>& thePlanePosition,
584 const std::vector<int>& thePlaneCondition,
585 vtkFloatingPointType theDisplacement)
587 vtkFloatingPointType aBoundPrj[3], aOrig[3], aPosition;
588 GetBoundProject(aBoundPrj, theBounds, theDir);
590 vtkFloatingPointType aDBoundPrj = aBoundPrj[2]/(theNbPlanes - 1);
591 vtkFloatingPointType aDisplacement = aDBoundPrj*theDisplacement;
592 vtkFloatingPointType aStartPosition = aBoundPrj[0] - 0.5*aDBoundPrj + aDisplacement;
593 for (int i = 0; i < theNbPlanes; i++){
594 aPosition = aStartPosition + i*aDBoundPrj;
595 if(thePlaneCondition[i]){
596 aPosition = aStartPosition + i*aDBoundPrj;
598 aPosition = thePlanePosition[i];
599 VISU::Mul(theDir,aPosition,aOrig);
600 CutWithPlane(theAppendPolyData,theDataSet,theDir,aOrig);
603 if(thePlaneCondition[0])
604 aPosition = aBoundPrj[0] + aBoundPrj[2]*theDisplacement;
606 aPosition = thePlanePosition[0];
607 VISU::Mul(theDir,aPosition,aOrig);
608 CutWithPlane(theAppendPolyData,theDataSet,theDir,aOrig);
610 vtkPolyData *aPolyData = theAppendPolyData->GetOutput();
612 theAppendPolyData->Update();
616 //----------------------------------------------------------------------------
618 VISU_CutPlanesPL::SetVectorialField(VISU::PUnstructuredGridIDMapper theMapper)
620 if(myVectorialField == theMapper)
623 if(CheckCanDeformate(theMapper->GetOutput())){
624 myVectorialField = theMapper;
626 SetMergeFilterInput(GetMergedInput(),theMapper->GetOutput());
629 UseDeformation(false);
634 //----------------------------------------------------------------------------
635 VISU::PUnstructuredGridIDMapper VISU_CutPlanesPL::
638 return myVectorialField;
641 //----------------------------------------------------------------------------
642 void VISU_CutPlanesPL::SetMapScale(vtkFloatingPointType theMapScale){
643 Superclass::SetMapScale(theMapScale);
645 VISU_OptionalDeformationPL::SetMapScale(theMapScale);