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 vtkDataSet* aMergedInput = GetMergedInput();
160 if(VISU::IsQuadraticData(aMergedInput)) // Bug 0020123, note 0005343
161 throw std::runtime_error("Impossible to build presentation");
163 ClearAppendPolyData(myAppendPolyData);
166 if(!myVectorialField || !IsDeformed()){
167 SetMergeFilterInput(aMergedInput,aMergedInput);
171 if(VISU::IsDataOnCells(aMergedInput))
172 GetMapper()->SetScalarModeToUseCellData();
174 GetMapper()->SetScalarModeToUsePointData();
178 vtkFloatingPointType aDir[3];
183 vtkFloatingPointType aBounds[6];
185 vtkDataSet* aFilterOutput = GetMergeFilterOutput();
187 aFilterOutput->GetBounds(aBounds);
189 CutWithPlanes(myAppendPolyData,
200 SetWarpVectorInput(myAppendPolyData->GetOutput());
201 Superclass::Update();
205 //----------------------------------------------------------------------------
210 unsigned long int aSize = Superclass::GetMemorySize();
212 if(vtkDataSet* aDataSet = myAppendPolyData->GetOutput())
213 aSize += aDataSet->GetActualMemorySize() * 1024;
215 int anEnd = myAppendPolyData->GetNumberOfInputConnections(0);
216 for(int anId = 0; anId < anEnd; anId++)
217 if(vtkDataSet* aDataSet = myAppendPolyData->GetInput(anId))
218 aSize += aDataSet->GetActualMemorySize() * 1024;
224 //----------------------------------------------------------------------------
227 ::SetPartPosition(int theNum)
229 for(int i = 0; i < myNbParts; i++)
230 myPartPosition[i] = GetPartPosition(i,theNum);
235 ::ClearAppendPolyData(vtkAppendPolyData *theAppendPolyData)
237 theAppendPolyData->RemoveAllInputs();
241 //----------------------------------------------------------------------------
242 vtkFloatingPointType*
244 GetRx(vtkFloatingPointType theRx[3][3],
245 vtkFloatingPointType thaAng)
247 theRx[0][0] = 1.0; theRx[0][1] = 0.0; theRx[0][2] = 0.0;
248 theRx[1][0] = 0.0; theRx[1][1] = cos(thaAng); theRx[1][2] = -sin(thaAng);
249 theRx[2][0] = 0.0; theRx[2][1] = sin(thaAng); theRx[2][2] = cos(thaAng);
255 //----------------------------------------------------------------------------
256 vtkFloatingPointType*
258 ::GetRy(vtkFloatingPointType theRy[3][3],
259 vtkFloatingPointType thaAng)
261 theRy[0][0] = cos(thaAng); theRy[0][1] = 0.0; theRy[0][2] = sin(thaAng);
262 theRy[1][0] = 0.0; theRy[1][1] = 1.0; theRy[1][2] = 0.0;
263 theRy[2][0] = -sin(thaAng); theRy[2][1] = 0.0; theRy[2][2] = cos(thaAng);
268 //----------------------------------------------------------------------------
269 vtkFloatingPointType*
271 ::GetRz(vtkFloatingPointType theRz[3][3],
272 vtkFloatingPointType thaAng)
274 theRz[0][0] = cos(thaAng); theRz[0][1] = -sin(thaAng); theRz[0][2] = 0.0;
275 theRz[1][0] = sin(thaAng); theRz[1][1] = cos(thaAng); theRz[1][2] = 0.0;
276 theRz[2][0] = 0.0; theRz[2][1] = 0.0; theRz[2][2] = 1.0;
281 //----------------------------------------------------------------------------
284 ::CorrectPnt(vtkFloatingPointType thePnt[3],
285 const vtkFloatingPointType BoundPrj[6])
287 for(int i = 0, j = 0; i < 3; ++i, j=2*i){
288 if(thePnt[i] < BoundPrj[j]) thePnt[i] = BoundPrj[j];
289 if(thePnt[i] > BoundPrj[j+1]) thePnt[i] = BoundPrj[j+1];
294 //----------------------------------------------------------------------------
297 ::GetBoundProject(vtkFloatingPointType BoundPrj[3],
298 const vtkFloatingPointType BoundBox[6],
299 const vtkFloatingPointType Dir[3])
301 vtkFloatingPointType BoundPoints[8][3] = { {BoundBox[0],BoundBox[2],BoundBox[4]},
302 {BoundBox[1],BoundBox[2],BoundBox[4]},
303 {BoundBox[0],BoundBox[3],BoundBox[4]},
304 {BoundBox[1],BoundBox[3],BoundBox[4]},
305 {BoundBox[0],BoundBox[2],BoundBox[5]},
306 {BoundBox[1],BoundBox[2],BoundBox[5]},
307 {BoundBox[0],BoundBox[3],BoundBox[5]},
308 {BoundBox[1],BoundBox[3],BoundBox[5]}};
309 BoundPrj[0] = vtkMath::Dot(Dir,BoundPoints[0]), BoundPrj[1] = BoundPrj[0];
310 for(int i = 1; i < 8; i++){
311 vtkFloatingPointType tmp = vtkMath::Dot(Dir,BoundPoints[i]);
312 if(BoundPrj[1] < tmp) BoundPrj[1] = tmp;
313 if(BoundPrj[0] > tmp) BoundPrj[0] = tmp;
315 BoundPrj[2] = BoundPrj[1] - BoundPrj[0];
316 BoundPrj[1] = BoundPrj[0] + (1.0 - EPS)*BoundPrj[2];
317 BoundPrj[0] = BoundPrj[0] + EPS*BoundPrj[2];
318 BoundPrj[2] = BoundPrj[1] - BoundPrj[0];
322 //----------------------------------------------------------------------------
325 ::SetOrientation(const VISU_CutPlanesPL::PlaneOrientation& theOrient,
326 vtkFloatingPointType theXAng,
327 vtkFloatingPointType theYAng,
330 myBasePlane[theNum] = theOrient;
331 switch(myBasePlane[theNum]){
332 case XY: myAng[theNum][0] = theXAng; break;
333 case YZ: myAng[theNum][1] = theXAng; break;
334 case ZX: myAng[theNum][2] = theXAng; break;
336 switch(myBasePlane[theNum]){
337 case XY: myAng[theNum][1] = theYAng; break;
338 case YZ: myAng[theNum][2] = theYAng; break;
339 case ZX: myAng[theNum][0] = theYAng; break;
344 //----------------------------------------------------------------------------
345 const VISU_CutPlanesPL::PlaneOrientation&
347 ::GetPlaneOrientation(int theNum)
349 return myBasePlane[theNum];
354 ::GetRotateX(int theNum)
356 switch(myBasePlane[theNum]){
357 case XY: return myAng[theNum][0];
358 case YZ: return myAng[theNum][1];
359 case ZX: return myAng[theNum][2];
365 //----------------------------------------------------------------------------
368 ::GetRotateY(int theNum)
370 switch(myBasePlane[theNum]){
371 case XY: return myAng[theNum][1];
372 case YZ: return myAng[theNum][2];
373 case ZX: return myAng[theNum][0];
379 //----------------------------------------------------------------------------
382 ::GetDisplacement(int theNum)
384 return myDisplacement[theNum];
388 //----------------------------------------------------------------------------
391 ::SetDisplacement(vtkFloatingPointType theDisp,
394 if(VISU::CheckIsSameValue(myDisplacement[theNum], theDisp))
397 myDisplacement[theNum] = theDisp;
402 //----------------------------------------------------------------------------
405 ::SetNbParts(int theNbParts)
407 if(theNbParts > 0 && GetNbParts() != theNbParts){
408 myPartPosition.resize(theNbParts);
409 myPartCondition.resize(theNbParts, 1);
410 myNbParts = theNbParts;
416 //----------------------------------------------------------------------------
421 return myPartPosition.size();
425 //----------------------------------------------------------------------------
428 ::SetPartPosition(int thePartNumber,
429 vtkFloatingPointType thePartPosition)
431 if(thePartNumber >= myNbParts)
434 bool anIsSameValue = VISU::CheckIsSameValue(myPartPosition[thePartNumber], thePartPosition);
435 anIsSameValue &= VISU::CheckIsSameValue(myPartCondition[thePartNumber], 0);
439 myPartPosition[thePartNumber] = thePartPosition;
440 myPartCondition[thePartNumber] = 0;
445 //----------------------------------------------------------------------------
448 ::GetPartPosition(int thePartNumber,
451 if(thePartNumber >= myNbParts)
454 vtkFloatingPointType aPosition = myPartPosition[thePartNumber];
455 if(myPartCondition[thePartNumber]){
456 vtkFloatingPointType aDir[3], aBounds[6], aBoundPrj[3];
458 GetMergedInput()->GetBounds(aBounds);
460 GetMergeFilterOutput()->GetBounds(aBounds);
465 myBasePlane[theNum]);
467 GetBoundProject(aBoundPrj,
472 vtkFloatingPointType aDBoundPrj = aBoundPrj[2]/(myNbParts - 1);
473 vtkFloatingPointType aDisplacement = aDBoundPrj * myDisplacement[theNum];
474 vtkFloatingPointType aStartPosition = aBoundPrj[0] - 0.5*aDBoundPrj + aDisplacement;
475 aPosition = aStartPosition + thePartNumber*aDBoundPrj;
477 aPosition = aBoundPrj[0] + aBoundPrj[2]*myDisplacement[theNum];
484 //----------------------------------------------------------------------------
487 ::SetPartDefault(int thePartNumber)
489 if(thePartNumber >= myNbParts)
492 bool anIsSameValue = VISU::CheckIsSameValue(myPartPosition[thePartNumber], GetPartPosition(thePartNumber));
493 anIsSameValue &= VISU::CheckIsSameValue(myPartCondition[thePartNumber], 1);
497 myPartPosition[thePartNumber] = GetPartPosition(thePartNumber);
498 myPartCondition[thePartNumber] = 1;
503 //----------------------------------------------------------------------------
506 ::IsPartDefault(int thePartNumber)
508 if(thePartNumber >= myNbParts)
511 return myPartCondition[thePartNumber];
515 //----------------------------------------------------------------------------
518 ::GetDir(vtkFloatingPointType theDir[3],
519 const vtkFloatingPointType theAng[3],
520 const PlaneOrientation& theBasePlane)
523 vtkFloatingPointType aRx[3][3], aRy[3][3], aRz[3][3], aRotation[3][3];
524 switch(theBasePlane){
526 if(fabs(theAng[0]) > EPS) GetRx(aRx,theAng[0]); else vtkMath::Identity3x3(aRx);
527 if(fabs(theAng[1]) > EPS) GetRy(aRy,theAng[1]); else vtkMath::Identity3x3(aRy);
528 vtkMath::Multiply3x3(aRx,aRy,aRotation);
532 if(fabs(theAng[1]) > EPS) GetRy(aRy,theAng[1]); else vtkMath::Identity3x3(aRy);
533 if(fabs(theAng[2]) > EPS) GetRz(aRz,theAng[2]); else vtkMath::Identity3x3(aRz);
534 vtkMath::Multiply3x3(aRy,aRz,aRotation);
538 if(fabs(theAng[2]) > EPS) GetRz(aRz,theAng[2]); else vtkMath::Identity3x3(aRz);
539 if(fabs(theAng[0]) > EPS) GetRx(aRx,theAng[0]); else vtkMath::Identity3x3(aRx);
540 vtkMath::Multiply3x3(aRz,aRx,aRotation);
545 for(int i = 0; i < 3; i++)
546 theDir[i] = aRotation[i][iPlane];
550 //----------------------------------------------------------------------------
553 ::CutWithPlane(vtkAppendPolyData* theAppendPolyData,
554 vtkDataSet* theDataSet,
555 vtkFloatingPointType theDir[3],
556 vtkFloatingPointType theOrig[3])
558 vtkCutter *aCutPlane = vtkCutter::New();
559 aCutPlane->SetInput(theDataSet);
560 vtkPlane *aPlane = vtkPlane::New();
561 aPlane->SetOrigin(theOrig);
563 aPlane->SetNormal(theDir);
564 aCutPlane->SetCutFunction(aPlane);
566 theAppendPolyData->AddInput(aCutPlane->GetOutput());
571 //----------------------------------------------------------------------------
574 ::CutWithPlanes(vtkAppendPolyData* theAppendPolyData,
575 vtkDataSet* theDataSet,
577 vtkFloatingPointType theDir[3],
578 vtkFloatingPointType theBounds[6],
579 const std::vector<vtkFloatingPointType>& thePlanePosition,
580 const std::vector<int>& thePlaneCondition,
581 vtkFloatingPointType theDisplacement)
583 vtkFloatingPointType aBoundPrj[3], aOrig[3], aPosition;
584 GetBoundProject(aBoundPrj, theBounds, theDir);
586 vtkFloatingPointType aDBoundPrj = aBoundPrj[2]/(theNbPlanes - 1);
587 vtkFloatingPointType aDisplacement = aDBoundPrj*theDisplacement;
588 vtkFloatingPointType aStartPosition = aBoundPrj[0] - 0.5*aDBoundPrj + aDisplacement;
589 for (int i = 0; i < theNbPlanes; i++){
590 aPosition = aStartPosition + i*aDBoundPrj;
591 if(thePlaneCondition[i]){
592 aPosition = aStartPosition + i*aDBoundPrj;
594 aPosition = thePlanePosition[i];
595 VISU::Mul(theDir,aPosition,aOrig);
596 CutWithPlane(theAppendPolyData,theDataSet,theDir,aOrig);
599 if(thePlaneCondition[0])
600 aPosition = aBoundPrj[0] + aBoundPrj[2]*theDisplacement;
602 aPosition = thePlanePosition[0];
603 VISU::Mul(theDir,aPosition,aOrig);
604 CutWithPlane(theAppendPolyData,theDataSet,theDir,aOrig);
606 vtkPolyData *aPolyData = theAppendPolyData->GetOutput();
608 theAppendPolyData->Update();
612 //----------------------------------------------------------------------------
614 VISU_CutPlanesPL::SetVectorialField(VISU::PUnstructuredGridIDMapper theMapper)
616 if(myVectorialField == theMapper)
619 if(CheckCanDeformate(theMapper->GetOutput())){
620 myVectorialField = theMapper;
622 SetMergeFilterInput(GetMergedInput(),theMapper->GetOutput());
625 UseDeformation(false);
630 //----------------------------------------------------------------------------
631 VISU::PUnstructuredGridIDMapper VISU_CutPlanesPL::
634 return myVectorialField;
637 //----------------------------------------------------------------------------
638 void VISU_CutPlanesPL::SetMapScale(vtkFloatingPointType theMapScale){
639 Superclass::SetMapScale(theMapScale);
641 VISU_OptionalDeformationPL::SetMapScale(theMapScale);