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 // VISU OBJECT : interactive object for VISU entities implementation
23 // File: VISU_PipeLine.cxx
24 // Author: Alexey PETROV
27 #include "VISU_CutPlanesPL.hxx"
28 #include "VISU_FieldTransform.hxx"
29 #include "VISU_PipeLineUtils.hxx"
30 #include "VTKViewer_GeometryFilter.h"
31 #include "VISU_MapperHolder.hxx"
32 #include "VISU_DeformationPL.hxx"
34 #include <vtkAppendPolyData.h>
35 #include <vtkCutter.h>
38 //#include <vtkUnstructuredGrid.h>
40 static vtkFloatingPointType EPS = 1.0E-3;
43 static int MYDEBUG = 0;
45 static int MYDEBUG = 0;
49 //----------------------------------------------------------------------------
50 vtkStandardNewMacro(VISU_CutPlanesPL);
53 //----------------------------------------------------------------------------
56 VISU_OptionalDeformationPL()
58 if(MYDEBUG) MESSAGE("VISU_CutPlanesPL()::VISU_CutPlanesPL() - "<<this);
60 SetIsShrinkable(false);
61 SetIsFeatureEdgesAllowed(false);
63 SetElnoDisassembleState( true );
65 myAppendPolyData = vtkAppendPolyData::New();
72 myDisplacement[0] = myDisplacement[1] = 0.5;
74 myAng[0][0] = myAng[0][1] = myAng[0][2] = 0.0;
75 myAng[1][0] = myAng[1][1] = myAng[1][2] = 0.0;
76 UseDeformation(false);
80 //----------------------------------------------------------------------------
84 if(MYDEBUG) MESSAGE("VISU_CutPlanesPL()::~VISU_CutPlanesPL() - "<<this);
85 myAppendPolyData->Delete();
86 myAppendPolyData = NULL;
90 //----------------------------------------------------------------------------
95 unsigned long int aTime = Superclass::GetMTime();
98 aTime = std::max(aTime, VISU_OptionalDeformationPL::GetMTime());
101 aTime = std::max(aTime, myAppendPolyData->GetMTime());
107 //----------------------------------------------------------------------------
110 ::DoShallowCopy(VISU_PipeLine *thePipeLine,
113 Superclass::DoShallowCopy(thePipeLine, theIsCopyInput);
115 if(VISU_CutPlanesPL *aPipeLine = dynamic_cast<VISU_CutPlanesPL*>(thePipeLine)){
117 SetOrientation(aPipeLine->GetPlaneOrientation(),
118 aPipeLine->GetRotateX(),
119 aPipeLine->GetRotateY());
121 SetDisplacement(aPipeLine->GetDisplacement());
123 SetNbParts(aPipeLine->GetNbParts());
124 for (int i = 0, iEnd = GetNbParts(); i < iEnd; i++)
125 if(!aPipeLine->IsPartDefault(i))
126 SetPartPosition(i, aPipeLine->GetPartPosition(i));
131 //----------------------------------------------------------------------------
139 myDisplacement[0] = 0.5;
140 myAng[0][0] = myAng[0][1] = myAng[0][2] = 0.0;
141 SetScale(VISU_DeformationPL::GetDefaultScaleFactor(this));
145 //----------------------------------------------------------------------------
150 return GetWarpVectorOutput();
154 //----------------------------------------------------------------------------
159 ClearAppendPolyData(myAppendPolyData);
162 if(!myVectorialField || !IsDeformed()){
163 SetMergeFilterInput(GetMergedInput(),GetMergedInput());
167 if(VISU::IsDataOnCells(GetMergedInput()))
168 GetMapper()->SetScalarModeToUseCellData();
170 GetMapper()->SetScalarModeToUsePointData();
174 vtkFloatingPointType aDir[3];
179 vtkFloatingPointType aBounds[6];
181 vtkDataSet* aFilterOutput = GetMergeFilterOutput();
183 aFilterOutput->GetBounds(aBounds);
185 CutWithPlanes(myAppendPolyData,
196 SetWarpVectorInput(myAppendPolyData->GetOutput());
197 Superclass::Update();
201 //----------------------------------------------------------------------------
206 unsigned long int aSize = Superclass::GetMemorySize();
208 if(vtkDataSet* aDataSet = myAppendPolyData->GetOutput())
209 aSize += aDataSet->GetActualMemorySize() * 1024;
211 int anEnd = myAppendPolyData->GetNumberOfInputConnections(0);
212 for(int anId = 0; anId < anEnd; anId++)
213 if(vtkDataSet* aDataSet = myAppendPolyData->GetInput(anId))
214 aSize += aDataSet->GetActualMemorySize() * 1024;
220 //----------------------------------------------------------------------------
223 ::SetPartPosition(int theNum)
225 for(int i = 0; i < myNbParts; i++)
226 myPartPosition[i] = GetPartPosition(i,theNum);
231 ::ClearAppendPolyData(vtkAppendPolyData *theAppendPolyData)
233 theAppendPolyData->RemoveAllInputs();
237 //----------------------------------------------------------------------------
238 vtkFloatingPointType*
240 GetRx(vtkFloatingPointType theRx[3][3],
241 vtkFloatingPointType thaAng)
243 theRx[0][0] = 1.0; theRx[0][1] = 0.0; theRx[0][2] = 0.0;
244 theRx[1][0] = 0.0; theRx[1][1] = cos(thaAng); theRx[1][2] = -sin(thaAng);
245 theRx[2][0] = 0.0; theRx[2][1] = sin(thaAng); theRx[2][2] = cos(thaAng);
251 //----------------------------------------------------------------------------
252 vtkFloatingPointType*
254 ::GetRy(vtkFloatingPointType theRy[3][3],
255 vtkFloatingPointType thaAng)
257 theRy[0][0] = cos(thaAng); theRy[0][1] = 0.0; theRy[0][2] = sin(thaAng);
258 theRy[1][0] = 0.0; theRy[1][1] = 1.0; theRy[1][2] = 0.0;
259 theRy[2][0] = -sin(thaAng); theRy[2][1] = 0.0; theRy[2][2] = cos(thaAng);
264 //----------------------------------------------------------------------------
265 vtkFloatingPointType*
267 ::GetRz(vtkFloatingPointType theRz[3][3],
268 vtkFloatingPointType thaAng)
270 theRz[0][0] = cos(thaAng); theRz[0][1] = -sin(thaAng); theRz[0][2] = 0.0;
271 theRz[1][0] = sin(thaAng); theRz[1][1] = cos(thaAng); theRz[1][2] = 0.0;
272 theRz[2][0] = 0.0; theRz[2][1] = 0.0; theRz[2][2] = 1.0;
277 //----------------------------------------------------------------------------
280 ::CorrectPnt(vtkFloatingPointType thePnt[3],
281 const vtkFloatingPointType BoundPrj[6])
283 for(int i = 0, j = 0; i < 3; ++i, j=2*i){
284 if(thePnt[i] < BoundPrj[j]) thePnt[i] = BoundPrj[j];
285 if(thePnt[i] > BoundPrj[j+1]) thePnt[i] = BoundPrj[j+1];
290 //----------------------------------------------------------------------------
293 ::GetBoundProject(vtkFloatingPointType BoundPrj[3],
294 const vtkFloatingPointType BoundBox[6],
295 const vtkFloatingPointType Dir[3])
297 vtkFloatingPointType BoundPoints[8][3] = { {BoundBox[0],BoundBox[2],BoundBox[4]},
298 {BoundBox[1],BoundBox[2],BoundBox[4]},
299 {BoundBox[0],BoundBox[3],BoundBox[4]},
300 {BoundBox[1],BoundBox[3],BoundBox[4]},
301 {BoundBox[0],BoundBox[2],BoundBox[5]},
302 {BoundBox[1],BoundBox[2],BoundBox[5]},
303 {BoundBox[0],BoundBox[3],BoundBox[5]},
304 {BoundBox[1],BoundBox[3],BoundBox[5]}};
305 BoundPrj[0] = vtkMath::Dot(Dir,BoundPoints[0]), BoundPrj[1] = BoundPrj[0];
306 for(int i = 1; i < 8; i++){
307 vtkFloatingPointType tmp = vtkMath::Dot(Dir,BoundPoints[i]);
308 if(BoundPrj[1] < tmp) BoundPrj[1] = tmp;
309 if(BoundPrj[0] > tmp) BoundPrj[0] = tmp;
311 BoundPrj[2] = BoundPrj[1] - BoundPrj[0];
312 BoundPrj[1] = BoundPrj[0] + (1.0 - EPS)*BoundPrj[2];
313 BoundPrj[0] = BoundPrj[0] + EPS*BoundPrj[2];
314 BoundPrj[2] = BoundPrj[1] - BoundPrj[0];
318 //----------------------------------------------------------------------------
321 ::SetOrientation(const VISU_CutPlanesPL::PlaneOrientation& theOrient,
322 vtkFloatingPointType theXAng,
323 vtkFloatingPointType theYAng,
326 myBasePlane[theNum] = theOrient;
327 switch(myBasePlane[theNum]){
328 case XY: myAng[theNum][0] = theXAng; break;
329 case YZ: myAng[theNum][1] = theXAng; break;
330 case ZX: myAng[theNum][2] = theXAng; break;
332 switch(myBasePlane[theNum]){
333 case XY: myAng[theNum][1] = theYAng; break;
334 case YZ: myAng[theNum][2] = theYAng; break;
335 case ZX: myAng[theNum][0] = theYAng; break;
340 //----------------------------------------------------------------------------
341 const VISU_CutPlanesPL::PlaneOrientation&
343 ::GetPlaneOrientation(int theNum)
345 return myBasePlane[theNum];
350 ::GetRotateX(int theNum)
352 switch(myBasePlane[theNum]){
353 case XY: return myAng[theNum][0];
354 case YZ: return myAng[theNum][1];
355 case ZX: return myAng[theNum][2];
361 //----------------------------------------------------------------------------
364 ::GetRotateY(int theNum)
366 switch(myBasePlane[theNum]){
367 case XY: return myAng[theNum][1];
368 case YZ: return myAng[theNum][2];
369 case ZX: return myAng[theNum][0];
375 //----------------------------------------------------------------------------
378 ::GetDisplacement(int theNum)
380 return myDisplacement[theNum];
384 //----------------------------------------------------------------------------
387 ::SetDisplacement(vtkFloatingPointType theDisp,
390 if(VISU::CheckIsSameValue(myDisplacement[theNum], theDisp))
393 myDisplacement[theNum] = theDisp;
398 //----------------------------------------------------------------------------
401 ::SetNbParts(int theNbParts)
403 if(theNbParts > 0 && GetNbParts() != theNbParts){
404 myPartPosition.resize(theNbParts);
405 myPartCondition.resize(theNbParts, 1);
406 myNbParts = theNbParts;
412 //----------------------------------------------------------------------------
417 return myPartPosition.size();
421 //----------------------------------------------------------------------------
424 ::SetPartPosition(int thePartNumber,
425 vtkFloatingPointType thePartPosition)
427 if(thePartNumber >= myNbParts)
430 bool anIsSameValue = VISU::CheckIsSameValue(myPartPosition[thePartNumber], thePartPosition);
431 anIsSameValue &= VISU::CheckIsSameValue(myPartCondition[thePartNumber], 0);
435 myPartPosition[thePartNumber] = thePartPosition;
436 myPartCondition[thePartNumber] = 0;
441 //----------------------------------------------------------------------------
444 ::GetPartPosition(int thePartNumber,
447 if(thePartNumber >= myNbParts)
450 vtkFloatingPointType aPosition = myPartPosition[thePartNumber];
451 if(myPartCondition[thePartNumber]){
452 vtkFloatingPointType aDir[3], aBounds[6], aBoundPrj[3];
454 GetMergedInput()->GetBounds(aBounds);
456 GetMergeFilterOutput()->GetBounds(aBounds);
461 myBasePlane[theNum]);
463 GetBoundProject(aBoundPrj,
468 vtkFloatingPointType aDBoundPrj = aBoundPrj[2]/(myNbParts - 1);
469 vtkFloatingPointType aDisplacement = aDBoundPrj * myDisplacement[theNum];
470 vtkFloatingPointType aStartPosition = aBoundPrj[0] - 0.5*aDBoundPrj + aDisplacement;
471 aPosition = aStartPosition + thePartNumber*aDBoundPrj;
473 aPosition = aBoundPrj[0] + aBoundPrj[2]*myDisplacement[theNum];
480 //----------------------------------------------------------------------------
483 ::SetPartDefault(int thePartNumber)
485 if(thePartNumber >= myNbParts)
488 bool anIsSameValue = VISU::CheckIsSameValue(myPartPosition[thePartNumber], GetPartPosition(thePartNumber));
489 anIsSameValue &= VISU::CheckIsSameValue(myPartCondition[thePartNumber], 1);
493 myPartPosition[thePartNumber] = GetPartPosition(thePartNumber);
494 myPartCondition[thePartNumber] = 1;
499 //----------------------------------------------------------------------------
502 ::IsPartDefault(int thePartNumber)
504 if(thePartNumber >= myNbParts)
507 return myPartCondition[thePartNumber];
511 //----------------------------------------------------------------------------
514 ::GetDir(vtkFloatingPointType theDir[3],
515 const vtkFloatingPointType theAng[3],
516 const PlaneOrientation& theBasePlane)
519 vtkFloatingPointType aRx[3][3], aRy[3][3], aRz[3][3], aRotation[3][3];
520 switch(theBasePlane){
522 if(fabs(theAng[0]) > EPS) GetRx(aRx,theAng[0]); else vtkMath::Identity3x3(aRx);
523 if(fabs(theAng[1]) > EPS) GetRy(aRy,theAng[1]); else vtkMath::Identity3x3(aRy);
524 vtkMath::Multiply3x3(aRx,aRy,aRotation);
528 if(fabs(theAng[1]) > EPS) GetRy(aRy,theAng[1]); else vtkMath::Identity3x3(aRy);
529 if(fabs(theAng[2]) > EPS) GetRz(aRz,theAng[2]); else vtkMath::Identity3x3(aRz);
530 vtkMath::Multiply3x3(aRy,aRz,aRotation);
534 if(fabs(theAng[2]) > EPS) GetRz(aRz,theAng[2]); else vtkMath::Identity3x3(aRz);
535 if(fabs(theAng[0]) > EPS) GetRx(aRx,theAng[0]); else vtkMath::Identity3x3(aRx);
536 vtkMath::Multiply3x3(aRz,aRx,aRotation);
541 for(int i = 0; i < 3; i++)
542 theDir[i] = aRotation[i][iPlane];
546 //----------------------------------------------------------------------------
549 ::CutWithPlane(vtkAppendPolyData* theAppendPolyData,
550 vtkDataSet* theDataSet,
551 vtkFloatingPointType theDir[3],
552 vtkFloatingPointType theOrig[3])
554 vtkCutter *aCutPlane = vtkCutter::New();
555 aCutPlane->SetInput(theDataSet);
556 vtkPlane *aPlane = vtkPlane::New();
557 aPlane->SetOrigin(theOrig);
559 aPlane->SetNormal(theDir);
560 aCutPlane->SetCutFunction(aPlane);
562 theAppendPolyData->AddInput(aCutPlane->GetOutput());
567 //----------------------------------------------------------------------------
570 ::CutWithPlanes(vtkAppendPolyData* theAppendPolyData,
571 vtkDataSet* theDataSet,
573 vtkFloatingPointType theDir[3],
574 vtkFloatingPointType theBounds[6],
575 const std::vector<vtkFloatingPointType>& thePlanePosition,
576 const std::vector<int>& thePlaneCondition,
577 vtkFloatingPointType theDisplacement)
579 vtkFloatingPointType aBoundPrj[3], aOrig[3], aPosition;
580 GetBoundProject(aBoundPrj, theBounds, theDir);
582 vtkFloatingPointType aDBoundPrj = aBoundPrj[2]/(theNbPlanes - 1);
583 vtkFloatingPointType aDisplacement = aDBoundPrj*theDisplacement;
584 vtkFloatingPointType aStartPosition = aBoundPrj[0] - 0.5*aDBoundPrj + aDisplacement;
585 for (int i = 0; i < theNbPlanes; i++){
586 aPosition = aStartPosition + i*aDBoundPrj;
587 if(thePlaneCondition[i]){
588 aPosition = aStartPosition + i*aDBoundPrj;
590 aPosition = thePlanePosition[i];
591 VISU::Mul(theDir,aPosition,aOrig);
592 CutWithPlane(theAppendPolyData,theDataSet,theDir,aOrig);
595 if(thePlaneCondition[0])
596 aPosition = aBoundPrj[0] + aBoundPrj[2]*theDisplacement;
598 aPosition = thePlanePosition[0];
599 VISU::Mul(theDir,aPosition,aOrig);
600 CutWithPlane(theAppendPolyData,theDataSet,theDir,aOrig);
602 vtkPolyData *aPolyData = theAppendPolyData->GetOutput();
604 theAppendPolyData->Update();
608 //----------------------------------------------------------------------------
610 VISU_CutPlanesPL::SetVectorialField(VISU::PUnstructuredGridIDMapper theMapper)
612 if(myVectorialField == theMapper)
615 if(CheckCanDeformate(theMapper->GetOutput())){
616 myVectorialField = theMapper;
618 SetMergeFilterInput(GetMergedInput(),theMapper->GetOutput());
621 UseDeformation(false);
626 //----------------------------------------------------------------------------
627 VISU::PUnstructuredGridIDMapper VISU_CutPlanesPL::
630 return myVectorialField;
633 //----------------------------------------------------------------------------
634 void VISU_CutPlanesPL::SetMapScale(vtkFloatingPointType theMapScale){
635 Superclass::SetMapScale(theMapScale);
637 VISU_OptionalDeformationPL::SetMapScale(theMapScale);