]> SALOME platform Git repositories - modules/visu.git/blob - src/PIPELINE/VISU_CutSegmentPL.cxx
Salome HOME
9a88480499207ed4213d020d1b5e5e14f7dfcd1e
[modules/visu.git] / src / PIPELINE / VISU_CutSegmentPL.cxx
1 //  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 //  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
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.
10 //
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.
15 //
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
19 //
20 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 // File:    VISU_CutSegmentPL.hxx
23 // Author:  Oleg UVAROV
24 // Module : VISU
25 //
26 #include "VISU_CutSegmentPL.hxx"
27 #include "VISU_PipeLineUtils.hxx"
28
29 #include <vtkAppendPolyData.h>
30
31 //----------------------------------------------------------------------------
32 vtkStandardNewMacro(VISU_CutSegmentPL);
33
34
35 //----------------------------------------------------------------------------
36 VISU_CutSegmentPL
37 ::VISU_CutSegmentPL()
38 {
39 }
40
41 //----------------------------------------------------------------------------
42 void
43 VISU_CutSegmentPL
44 ::DoShallowCopy(VISU_PipeLine *thePipeLine,
45                 bool theIsCopyInput)
46 {
47   Superclass::DoShallowCopy(thePipeLine, theIsCopyInput);
48
49   if(VISU_CutSegmentPL *aPipeLine = dynamic_cast<VISU_CutSegmentPL*>(thePipeLine)){
50     vtkFloatingPointType x, y, z;
51     aPipeLine->GetPoint1(x, y, z);
52     SetPoint1(x, y, z);
53     aPipeLine->GetPoint2(x, y, z);
54     SetPoint2(x, y, z);
55   }
56 }
57
58 //----------------------------------------------------------------------------
59 void
60 VISU_CutSegmentPL
61 ::Init()
62 {
63   Superclass::Init();
64
65   vtkFloatingPointType aBounds[6];
66   GetMergedInput()->GetBounds(aBounds);
67
68   for( int i = 0; i < 3; i++ ) {
69     vtkFloatingPointType min = aBounds[ 2*i ];
70     vtkFloatingPointType max = aBounds[ 2*i+1 ];
71     myPoint1[ i ] = i == 1 ? min : ( min + max ) / 2;
72     myPoint2[ i ] = i == 1 ? max : ( min + max ) / 2;
73   }
74 }
75
76 //----------------------------------------------------------------------------
77 void
78 VISU_CutSegmentPL
79 ::SetPoint1(vtkFloatingPointType theX,
80             vtkFloatingPointType theY,
81             vtkFloatingPointType theZ )
82 {
83   myPoint1[0] = theX;
84   myPoint1[1] = theY;
85   myPoint1[2] = theZ;
86 }
87
88 //----------------------------------------------------------------------------
89 void
90 VISU_CutSegmentPL
91 ::GetPoint1(vtkFloatingPointType& theX,
92             vtkFloatingPointType& theY,
93             vtkFloatingPointType& theZ )
94 {
95   theX = myPoint1[0];
96   theY = myPoint1[1];
97   theZ = myPoint1[2];
98 }
99
100 //----------------------------------------------------------------------------
101 void
102 VISU_CutSegmentPL
103 ::SetPoint2(vtkFloatingPointType theX,
104             vtkFloatingPointType theY,
105             vtkFloatingPointType theZ )
106 {
107   myPoint2[0] = theX;
108   myPoint2[1] = theY;
109   myPoint2[2] = theZ;
110 }
111
112 //----------------------------------------------------------------------------
113 void
114 VISU_CutSegmentPL
115 ::GetPoint2(vtkFloatingPointType& theX,
116             vtkFloatingPointType& theY,
117             vtkFloatingPointType& theZ )
118 {
119   theX = myPoint2[0];
120   theY = myPoint2[1];
121   theZ = myPoint2[2];
122 }
123
124 //----------------------------------------------------------------------------
125 vtkDataSet* 
126 VISU_CutSegmentPL
127 ::InsertCustomPL()
128 {
129   return myAppendPolyData->GetOutput();
130 }
131
132 //----------------------------------------------------------------------------
133 void
134 VISU_CutSegmentPL
135 ::Update()
136 {
137   vtkDataSet* aMergedInput = GetMergedInput();
138   if(VISU::IsQuadraticData(aMergedInput)) // Bug 0020123, note 0005343
139     throw std::runtime_error("Impossible to build presentation");
140
141   vtkFloatingPointType aVector12[3], aVector21[3];
142   VISU::Sub( myPoint2, myPoint1, aVector12 );
143   VISU::Sub( myPoint1, myPoint2, aVector21 );
144
145   double aPrecision = 1.0 / VTK_LARGE_FLOAT;
146   double aNorm = vtkMath::Normalize( aVector12 );
147   if( aNorm < aPrecision )
148     return;
149
150   // compute two vectors which are orthogonal to the line between the input points
151   // these vectors could be used as normals of two planes, intersected exactly at this line
152   // origin of these planes should be places at one of the input points
153   vtkFloatingPointType aVector1[3], aVector2[3];
154   vtkMath::Perpendiculars( aVector12, aVector1, aVector2, 0 );
155
156   ClearAppendPolyData(myAppendPolyData);
157
158   SetPartPosition(1);
159
160   vtkFloatingPointType aBounds[6];
161   GetMergedInput()->GetBounds(aBounds);
162
163   // check if the input is planar -  in this case one cut plane will be enough
164   // (besides, the second cut corrupts the resulting output, splitting it to points)
165   bool isPlanar = true;
166   vtkFloatingPointType aNormal[3] = { 0.0, 0.0, 0.0 };
167   if( fabs( aBounds[0] - aBounds[1] ) < aPrecision )
168     aNormal[0] = 1.0;
169   else if( fabs( aBounds[2] - aBounds[3] ) < aPrecision )
170     aNormal[1] = 1.0;
171   else if( fabs( aBounds[4] - aBounds[5] ) < aPrecision )
172     aNormal[2] = 1.0;
173   else
174     isPlanar = false;
175
176   if( isPlanar ) {
177     // choose a vector which is not collinear with normal of the plane
178     vtkFloatingPointType aCross[3];
179     vtkMath::Cross( aVector1, aNormal, aCross );
180     bool isFirst = vtkMath::Norm( aCross ) > aPrecision;
181     VISU_CutPlanesPL::CutWithPlane(myAppendPolyData, GetMergedInput(), isFirst ? aVector1 : aVector2, myPoint1);
182     myAppendPolyData->Update();
183   }
184   else {
185     vtkAppendPolyData *anAppendPolyData = vtkAppendPolyData::New();
186
187     VISU_CutPlanesPL::CutWithPlane(anAppendPolyData, GetMergedInput(), aVector1, myPoint1);
188     vtkDataSet *aDataSet = anAppendPolyData->GetOutput();
189     aDataSet->Update();
190
191     VISU_CutPlanesPL::CutWithPlane(myAppendPolyData, aDataSet, aVector2, myPoint1);
192     myAppendPolyData->Update();
193
194     anAppendPolyData->Delete();
195   }
196
197   // calculate values for building of table
198   for (int i = 0; i<3 ; i++) {
199     myRealDirLn[i] = myDirLn[i] = aVector12[i];
200     if(myDirLn[i] < 0.0) 
201       myDirLn[i] = -1.0*myDirLn[i]; //enk:: correction of bug Bug PAL10401
202   }
203
204   GetBoundProject(myBoundPrjLn, 
205                   aBounds, 
206                   myDirLn);
207
208   VISU::Mul(myDirLn,
209             myBoundPrjLn[0],
210             myBasePnt);
211   
212   CorrectPnt(myBasePnt,
213              aBounds);
214
215   VISU_ScalarMapPL::Update();
216 }