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