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_Plot3DPL.hxx"
28 #include "VISU_CutPlanesPL.hxx"
29 #include "VISU_PipeLineUtils.hxx"
31 #include <vtkAppendPolyData.h>
32 #include <vtkCutter.h>
35 #include <vtkCellDataToPointData.h>
36 #include <vtkGeometryFilter.h>
37 #include <vtkContourFilter.h>
38 #include <vtkWarpScalar.h>
39 #include <vtkOutlineFilter.h>
42 //----------------------------------------------------------------------------
43 vtkStandardNewMacro(VISU_Plot3DPL);
46 //----------------------------------------------------------------------------
49 myCellDataToPointData(vtkCellDataToPointData::New()),
50 myAppendPolyData(vtkAppendPolyData::New()),
51 myGeometryFilter(vtkGeometryFilter::New()),
52 myContourFilter(vtkContourFilter::New()),
53 myWarpScalar(vtkWarpScalar::New()),
54 myOrientation(VISU_CutPlanesPL::YZ),
61 SetIsShrinkable(false);
62 SetIsFeatureEdgesAllowed(false);
64 myCellDataToPointData->Delete();
65 myAppendPolyData->Delete();
66 myGeometryFilter->Delete();
67 myContourFilter->Delete();
68 myWarpScalar->Delete();
70 myAngle[0] = myAngle[1] = myAngle[2] = 0.0;
72 SetNumberOfContours(32);
76 //----------------------------------------------------------------------------
82 //----------------------------------------------------------------------------
87 unsigned long int aTime = Superclass::GetMTime();
89 aTime = std::max(aTime, myCellDataToPointData->GetMTime());
90 aTime = std::max(aTime, myAppendPolyData->GetMTime());
91 aTime = std::max(aTime, myGeometryFilter->GetMTime());
92 aTime = std::max(aTime, myContourFilter->GetMTime());
93 aTime = std::max(aTime, myWarpScalar->GetMTime());
99 //----------------------------------------------------------------------------
102 ::DoShallowCopy(VISU_PipeLine *thePipeLine,
105 Superclass::DoShallowCopy(thePipeLine, theIsCopyInput);
107 if(VISU_Plot3DPL *aPipeLine = dynamic_cast<VISU_Plot3DPL*>(thePipeLine)){
108 SetOrientation (aPipeLine->GetPlaneOrientation(),
109 aPipeLine->GetRotateX(), aPipeLine->GetRotateY());
110 SetPlanePosition (aPipeLine->GetPlanePosition(),
111 aPipeLine->IsPositionRelative() );
112 SetScaleFactor( aPipeLine->GetScaleFactor() );
113 SetContourPrs( aPipeLine->GetIsContourPrs() );
114 SetNumberOfContours( aPipeLine->GetNumberOfContours() );
119 //----------------------------------------------------------------------------
120 VISU_CutPlanesPL::PlaneOrientation
122 ::GetOrientation(vtkDataSet* theDataSet)
124 theDataSet->Update();
126 vtkFloatingPointType aBounds[6];
127 theDataSet->GetBounds(aBounds);
128 vtkFloatingPointType aDelta[3] = {aBounds[1] - aBounds[0], aBounds[3] - aBounds[2], aBounds[5] - aBounds[4]};
130 if(aDelta[0] >= aDelta[1] && aDelta[0] >= aDelta[2])
131 if(aDelta[1] >= aDelta[2])
132 return VISU_CutPlanesPL::XY;
134 return VISU_CutPlanesPL::ZX;
136 if(aDelta[1] >= aDelta[0] && aDelta[1] >= aDelta[2])
137 if(aDelta[0] >= aDelta[2])
138 return VISU_CutPlanesPL::XY;
140 return VISU_CutPlanesPL::YZ;
142 if(aDelta[2] >= aDelta[0] && aDelta[2] >= aDelta[1])
143 if(aDelta[0] >= aDelta[1])
144 return VISU_CutPlanesPL::ZX;
146 return VISU_CutPlanesPL::YZ;
148 return VISU_CutPlanesPL::XY;
152 //----------------------------------------------------------------------------
155 ::GetScaleFactor( VISU_ColoredPL* theColoredPL,
156 vtkDataSet* theDataSet )
158 theDataSet->Update();
159 vtkFloatingPointType aLength = theDataSet->GetLength(); // diagonal length
161 vtkFloatingPointType aScalarRange[2];
162 theColoredPL->GetSourceRange(aScalarRange);
164 static vtkFloatingPointType EPS = 0.3;
165 vtkFloatingPointType aRange = aScalarRange[1];
167 return aLength / aRange * EPS;
173 //----------------------------------------------------------------------------
180 myOrientation = GetOrientation(GetMergedInput());
181 SetScaleFactor( GetScaleFactor( this, GetMergedInput() ) );
185 //----------------------------------------------------------------------------
190 return myAppendPolyData->GetOutput();
194 //----------------------------------------------------------------------------
199 vtkFloatingPointType aPlaneNormal[3];
200 vtkFloatingPointType anOrigin[3];
201 GetBasePlane( anOrigin, aPlaneNormal );
203 vtkPolyData* aPolyData = 0;
204 vtkCutter *aCutPlane = 0;
205 vtkDataSet* aDataSet = GetMergedInput();
207 if ( !IsPlanarInput() )
209 aCutPlane = vtkCutter::New();
210 aCutPlane->SetInput(aDataSet);
212 vtkPlane *aPlane = vtkPlane::New();
213 aPlane->SetOrigin(anOrigin);
214 aPlane->SetNormal(aPlaneNormal);
216 aCutPlane->SetCutFunction(aPlane);
219 aPolyData = aCutPlane->GetOutput();
223 if ( !aPolyData || aPolyData->GetNumberOfCells() == 0 ) {
224 myGeometryFilter->SetInput(aDataSet);
225 aPolyData = myGeometryFilter->GetOutput();
228 if ( !myIsContour ) // surface prs
230 if(VISU::IsDataOnCells(aPolyData)) {
231 myCellDataToPointData->SetInput(aPolyData);
232 myCellDataToPointData->PassCellDataOn();
233 myWarpScalar->SetInput(myCellDataToPointData->GetPolyDataOutput());
235 myWarpScalar->SetInput(aPolyData);
239 if(VISU::IsDataOnCells(aPolyData)) {
240 myCellDataToPointData->SetInput(aPolyData);
241 myCellDataToPointData->PassCellDataOn();
242 myContourFilter->SetInput(myCellDataToPointData->GetOutput());
244 myContourFilter->SetInput(aPolyData);
246 vtkFloatingPointType aScalarRange[2];
247 GetSourceRange(aScalarRange);
249 myContourFilter->GenerateValues(GetNumberOfContours(),aScalarRange);
250 myWarpScalar->SetInput(myContourFilter->GetOutput());
253 VISU_CutPlanesPL::ClearAppendPolyData(myAppendPolyData.GetPointer());
254 myAppendPolyData->AddInput(myWarpScalar->GetPolyDataOutput());
259 myWarpScalar->SetNormal(aPlaneNormal);
261 Superclass::Update();
265 //----------------------------------------------------------------------------
270 unsigned long int aSize = Superclass::GetMemorySize();
272 if(vtkDataObject* aDataObject = myGeometryFilter->GetInput())
273 aSize += aDataObject->GetActualMemorySize() * 1024;
275 if(myCellDataToPointData->GetInput())
276 if(vtkDataSet* aDataSet = myCellDataToPointData->GetOutput())
277 aSize += aDataSet->GetActualMemorySize() * 1024;
279 if(vtkDataObject* aDataObject = myContourFilter->GetInput())
280 aSize += aDataObject->GetActualMemorySize() * 1024;
282 if(vtkDataObject* aDataObject = myWarpScalar->GetInput())
283 aSize += aDataObject->GetActualMemorySize() * 1024;
285 int anEnd = myAppendPolyData->GetNumberOfInputConnections(0);
286 for(int anId = 0; anId < anEnd; anId++){
287 if(vtkDataObject* aDataObject = myAppendPolyData->GetInput(anId))
288 aSize += aDataObject->GetActualMemorySize() * 1024;
295 //----------------------------------------------------------------------------
298 ::SetNumberOfContours(int theNumber)
300 myContourFilter->SetNumberOfContours(theNumber);
304 //----------------------------------------------------------------------------
307 ::GetNumberOfContours()
309 return myContourFilter->GetNumberOfContours();
313 //----------------------------------------------------------------------------
316 ::SetScaleFactor(vtkFloatingPointType theScaleFactor)
318 myScaleFactor = theScaleFactor;
319 myWarpScalar->SetScaleFactor(theScaleFactor*myMapScaleFactor);
323 //----------------------------------------------------------------------------
328 return myScaleFactor;
332 //----------------------------------------------------------------------------
335 SetContourPrs(bool theIsContourPrs )
337 if(myIsContour == theIsContourPrs)
340 myIsContour = theIsContourPrs;
345 //----------------------------------------------------------------------------
354 //----------------------------------------------------------------------------
357 ::SetPlanePosition(vtkFloatingPointType thePosition,
360 bool anIsSameValue = VISU::CheckIsSameValue(myIsRelative, theIsRelative);
361 anIsSameValue &= (myPosition == thePosition);
365 myIsRelative = theIsRelative;
366 myPosition = thePosition;
371 //----------------------------------------------------------------------------
374 ::IsPositionRelative()
380 //----------------------------------------------------------------------------
381 VISU_CutPlanesPL::PlaneOrientation
383 ::GetPlaneOrientation()
385 return myOrientation;
389 //----------------------------------------------------------------------------
394 switch(myOrientation){
395 case VISU_CutPlanesPL::XY: return myAngle[0];
396 case VISU_CutPlanesPL::YZ: return myAngle[1];
397 case VISU_CutPlanesPL::ZX: return myAngle[2];
403 //----------------------------------------------------------------------------
407 switch(myOrientation){
408 case VISU_CutPlanesPL::XY: return myAngle[1];
409 case VISU_CutPlanesPL::YZ: return myAngle[2];
410 case VISU_CutPlanesPL::ZX: return myAngle[0];
416 //----------------------------------------------------------------------------
419 SetOrientation(VISU_CutPlanesPL::PlaneOrientation theOrientation,
420 vtkFloatingPointType theXAngle,
421 vtkFloatingPointType theYAngle)
423 bool anIsSameValue = VISU::CheckIsSameValue(GetRotateX(), theXAngle);
424 anIsSameValue &= VISU::CheckIsSameValue(GetRotateY(), theYAngle);
425 anIsSameValue &= (myOrientation == theOrientation);
429 switch(theOrientation){
430 case VISU_CutPlanesPL::XY: myAngle[0] = theXAngle; break;
431 case VISU_CutPlanesPL::YZ: myAngle[1] = theXAngle; break;
432 case VISU_CutPlanesPL::ZX: myAngle[2] = theXAngle; break;
435 switch(theOrientation){
436 case VISU_CutPlanesPL::XY: myAngle[1] = theYAngle; break;
437 case VISU_CutPlanesPL::YZ: myAngle[2] = theYAngle; break;
438 case VISU_CutPlanesPL::ZX: myAngle[0] = theYAngle; break;
441 myOrientation = theOrientation;
446 //----------------------------------------------------------------------------
454 //=======================================================================
455 //function : GetBasePlane
457 //=======================================================================
460 ::GetBasePlane(vtkFloatingPointType theOrigin[3],
461 vtkFloatingPointType theNormal[3],
462 bool theCenterOrigine )
464 VISU_CutPlanesPL::GetDir(theNormal,myAngle,myOrientation);
466 vtkFloatingPointType aPosition = myPosition;
467 vtkFloatingPointType aBounds[6], aBoundPrj[3];
470 GetInput()->GetBounds(aBounds);
471 VISU_CutPlanesPL::GetBoundProject(aBoundPrj,aBounds,theNormal);
472 aPosition = aBoundPrj[0] + aBoundPrj[2]*myPosition;
474 VISU::Mul(theNormal,aPosition,theOrigin);
476 if ( theCenterOrigine ) {
477 // move theOrigin to the center of aBounds projections to the plane
478 GetMergedInput()->GetBounds(aBounds);
479 vtkFloatingPointType boundPoints[8][3] = {
480 {aBounds[0],aBounds[2],aBounds[4]},
481 {aBounds[1],aBounds[2],aBounds[4]},
482 {aBounds[0],aBounds[3],aBounds[4]},
483 {aBounds[1],aBounds[3],aBounds[4]},
484 {aBounds[0],aBounds[2],aBounds[5]},
485 {aBounds[1],aBounds[2],aBounds[5]},
486 {aBounds[0],aBounds[3],aBounds[5]},
487 {aBounds[1],aBounds[3],aBounds[5]}};
488 vtkFloatingPointType newOrigin[3] = { 0,0,0 };
489 for(int i = 0; i < 8; i++) {
490 vtkFloatingPointType proj[3];
491 vtkPlane::ProjectPoint( boundPoints[i], theOrigin, theNormal, proj );
492 newOrigin[0] += proj[0];
493 newOrigin[1] += proj[1];
494 newOrigin[2] += proj[2];
496 theOrigin[0] = newOrigin[0] / 8.;
497 theOrigin[1] = newOrigin[1] / 8.;
498 theOrigin[2] = newOrigin[2] / 8.;
502 //=======================================================================
503 //function : GetMinMaxPosition
504 //purpose : return absolute position range
505 //=======================================================================
508 ::GetMinMaxPosition( vtkFloatingPointType& minPos,
509 vtkFloatingPointType& maxPos )
511 vtkFloatingPointType aBounds[6], aBoundPrj[3], aNormal[3];
512 VISU_CutPlanesPL::GetDir(aNormal,myAngle,myOrientation);
513 GetInput()->GetBounds(aBounds);
514 VISU_CutPlanesPL::GetBoundProject(aBoundPrj,aBounds,aNormal);
515 minPos = aBoundPrj[0];
516 maxPos = aBoundPrj[1];
519 //=======================================================================
520 //function : SetMapScale
522 //=======================================================================
526 ::SetMapScale(vtkFloatingPointType theMapScale)
528 myMapScaleFactor = theMapScale;
529 Superclass::SetMapScale(theMapScale);
532 vtkFloatingPointType aRange[2];
533 GetSourceRange(aRange);
534 vtkFloatingPointType aNewRange[] = { aRange[1] - theMapScale*(aRange[1]-aRange[0]), aRange[1] };
535 myContourFilter->GenerateValues(GetNumberOfContours(),aNewRange);
537 myWarpScalar->SetScaleFactor(myScaleFactor*theMapScale);