00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "UtilVtk3DGeometriSelection.h"
00020
00021 #include <vtkPolyData.h>
00022 #include <vtkCell.h>
00023 #include <vtkCellLocator.h>
00024 #include <vtkPointData.h>
00025
00026 #include <vector>
00027 #include "matrix.h"
00028
00029
00030
00031
00032
00033 UtilVtk3DGeometriSelection::UtilVtk3DGeometriSelection()
00034 {
00035 _width = 0;
00036 _height = 0;
00037 _depth = 0;
00038 _mCubes = NULL;
00039 }
00040
00041 UtilVtk3DGeometriSelection::~UtilVtk3DGeometriSelection()
00042 {
00043 }
00044
00045 void UtilVtk3DGeometriSelection::SetDimentions(int w,int h,int d)
00046 {
00047 _width = w;
00048 _height = h;
00049 _depth = d;
00050 }
00051
00052 void UtilVtk3DGeometriSelection::SetMarchingCube(vtkMarchingCubes *mCubes)
00053 {
00054 _mCubes = mCubes;
00055 }
00056
00057 bool UtilVtk3DGeometriSelection::FindCubePointsFromPoints( double* pO, double* pF, double* pickPoint, double* cameraPos )
00058 {
00059 gtm::TVector< double > p1( 3 ), p2( 3 ), p3( 3 ), p4( 3 ), p5( 3 ), p6( 3 );
00060 gtm::TVector< double > c( 3 );
00061 gtm::TVector< double >* swp;
00062 gtm::TVector< double > tpO( pO, 3, false ), tpF( pF, 3, false );
00063 std::vector< gtm::TVector< double >* > points;
00064 double x1[ 3 ], x2[ 3 ], x3[ 3 ], d1, d2;
00065 int i, j;
00066
00067
00068 x1[ 0 ] = 0; x1[ 1 ] = _height; x1[ 2 ] = 0;
00069 x2[ 0 ] = 0; x2[ 1 ] = 0; x2[ 2 ] = 0;
00070 x3[ 0 ] = 0; x3[ 1 ] = 0; x3[ 2 ] = _depth;
00071 if( this->IntersectPlaneWithLine( p1.GetAnsiRef( ), x1, x2, x3, cameraPos, pickPoint ) )
00072 points.push_back( &p1 );
00073
00074
00075 x1[ 0 ] = 0; x1[ 1 ] = _height; x1[ 2 ] = _depth;
00076 x2[ 0 ] = 0; x2[ 1 ] = 0; x2[ 2 ] = _depth;
00077 x3[ 0 ] = _width; x3[ 1 ] = 0; x3[ 2 ] = _depth;
00078 if( this->IntersectPlaneWithLine( p2.GetAnsiRef( ), x1, x2, x3, cameraPos, pickPoint ) )
00079 points.push_back( &p2 );
00080
00081
00082 x1[ 0 ] = 0; x1[ 1 ] = 0; x1[ 2 ] = _depth;
00083 x2[ 0 ] = 0; x2[ 1 ] = 0; x2[ 2 ] = 0;
00084 x3[ 0 ] = _width; x3[ 1 ] = 0; x3[ 2 ] = 0;
00085 if( this->IntersectPlaneWithLine( p3.GetAnsiRef( ), x1, x2, x3, cameraPos, pickPoint ) )
00086 points.push_back( &p3 );
00087
00088
00089 x1[ 0 ] = _width; x1[ 1 ] = _height; x1[ 2 ] = _depth;
00090 x2[ 0 ] = _width; x2[ 1 ] = 0; x2[ 2 ] = _depth;
00091 x3[ 0 ] = _width; x3[ 1 ] = 0; x3[ 2 ] = 0;
00092 if( this->IntersectPlaneWithLine( p4.GetAnsiRef( ), x1, x2, x3, cameraPos, pickPoint ) )
00093 points.push_back( &p4 );
00094
00095
00096 x1[ 0 ] = _width; x1[ 1 ] = 0; x1[ 2 ] = 0;
00097 x2[ 0 ] = 0; x2[ 1 ] = 0; x2[ 2 ] = 0;
00098 x3[ 0 ] = 0; x3[ 1 ] = _height; x3[ 2 ] = 0;
00099 if( this->IntersectPlaneWithLine( p5.GetAnsiRef( ), x1, x2, x3, cameraPos, pickPoint ) )
00100 points.push_back( &p5 );
00101
00102
00103 x1[ 0 ] = 0; x1[ 1 ] = _height; x1[ 2 ] = 0;
00104 x2[ 0 ] = 0; x2[ 1 ] = _height; x2[ 2 ] = _depth;
00105 x3[ 0 ] = _width; x3[ 1 ] = _height; x3[ 2 ] = _depth;
00106 if( this->IntersectPlaneWithLine( p6.GetAnsiRef( ), x1, x2, x3, cameraPos, pickPoint ) )
00107 points.push_back( &p6 );
00108
00109 if( points.size( ) >= 2 ) {
00110
00111 c( 0 ) = ( double )_width / 2.0;
00112 c( 1 ) = ( double )_height / 2.0;
00113 c( 2 ) = ( double )_depth / 2.0;
00114
00115
00116 for( i = 0; i <(int) (points.size( )); i++ ) {
00117 for( j = 0; j < (int)(points.size( )) - 1; j++ ) {
00118
00119 d1 = ( c - *points[ j ] ).GetNorm( );
00120 d2 = ( c - *points[ j + 1 ] ).GetNorm( );
00121 if( d2 < d1 ) {
00122
00123 swp = points[ j ];
00124 points[ j ] = points[ j + 1 ];
00125 points[ j + 1 ] = swp;
00126
00127 }
00128
00129 }
00130
00131 }
00132
00133
00134 c = cameraPos;
00135 d1 = ( c - *points[ 0 ] ).GetNorm( );
00136 d2 = ( c - *points[ 1 ] ).GetNorm( );
00137 tpO = ( d1 < d2 )? *points[ 0 ]: *points[ 1 ];
00138 tpF = ( d1 > d2 )? *points[ 0 ]: *points[ 1 ];
00139 return( true );
00140
00141 } else return( false );
00142
00143 }
00144
00145 bool UtilVtk3DGeometriSelection::GetPointAndNormalIntersection( double* p, double* n, double* pO, double* pF )
00146 {
00147 gtm::TVector< double > n1( 3 ), n2( 3 ), n3( 3 );
00148
00149
00150
00151 vtkIdType cellId;
00152
00153 int subId, returnVal;
00154
00155 double t, pcoords[ 3 ], x[ 3 ];
00156 double fpO[ 3 ], fpF[ 3 ];
00157 double p1[ 3 ], p2[ 3 ], p3[ 3 ];
00158 vtkPolyData* data = _mCubes->GetOutput( );
00159 vtkCellLocator* locator = vtkCellLocator::New( );
00160
00161 locator->SetDataSet( data );
00162 locator->Initialize( );
00163 locator->Update( );
00164
00165 fpO[ 0 ] = pO[ 0 ]; fpO[ 1 ] = pO[ 1 ]; fpO[ 2 ] = pO[ 2 ];
00166 fpF[ 0 ] = pF[ 0 ]; fpF[ 1 ] = pF[ 1 ]; fpF[ 2 ] = pF[ 2 ];
00167 returnVal = locator->IntersectWithLine( fpO, fpF, 0.1, t, x, pcoords, subId, cellId );
00168 locator->Delete( );
00169
00170 if( returnVal )
00171 {
00172 vtkCell* cell = data->GetCell( cellId );
00173 vtkPoints* points = cell->GetPoints( );
00174
00175 data->GetPointData( )->GetNormals( )->GetTuple( cell->GetPointIds( )->GetId( 0 ), n1.GetAnsiRef( ) );
00176 data->GetPointData( )->GetNormals( )->GetTuple( cell->GetPointIds( )->GetId( 1 ), n2.GetAnsiRef( ) );
00177 data->GetPointData( )->GetNormals( )->GetTuple( cell->GetPointIds( )->GetId( 2 ), n3.GetAnsiRef( ) );
00178
00179 n1 += n2 + n3;
00180 n1 *= ( 1.0 / 3.0 );
00181 n1.Normalize( );
00182 n[ 0 ] = n1( 0 ); n[ 1 ] = n1( 1 ); n[ 2 ] = n1( 2 );
00183
00184 points->GetPoint( 0, p1 );
00185 points->GetPoint( 1, p2 );
00186 points->GetPoint( 2, p3 );
00187 this->IntersectPlaneWithLine( p, p1, p2, p3, pO, pF );
00188 return( true );
00189 } else return( false );
00190
00191 }
00192
00193
00194 bool UtilVtk3DGeometriSelection::IntersectPlaneWithLine( double* p, double* x1, double* x2, double* x3, double* x4, double* x5 )
00195 {
00196 gtm::TVector< double > vx1( 3 ), vx2( 3 ), vx3( 3 );
00197 gtm::TVector< double > vx4( 3 ), vx5( 3 ), vx6( p, 3, false );
00198 gtm::TMatrix< double > mU( 4, 4 ), mD( 4, 4 );
00199 double t;
00200 bool ret;
00201
00202 vx1 = x1;
00203 vx2 = x2;
00204 vx3 = x3;
00205 vx4 = x4;
00206 vx5 = x5;
00207 vx6 = vx5 - vx4;
00208
00209 mD( 0, 0 ) = mU( 0, 0 ) = 1;
00210 mD( 0, 1 ) = mU( 0, 1 ) = vx1( 0 );
00211 mD( 0, 2 ) = mU( 0, 2 ) = vx1( 1 );
00212 mD( 0, 3 ) = mU( 0, 3 ) = vx1( 2 );
00213 mD( 1, 0 ) = mU( 1, 0 ) = 1;
00214 mD( 1, 1 ) = mU( 1, 1 ) = vx2( 0 );
00215 mD( 1, 2 ) = mU( 1, 2 ) = vx2( 1 );
00216 mD( 1, 3 ) = mU( 1, 3 ) = vx2( 2 );
00217 mD( 2, 0 ) = mU( 2, 0 ) = 1;
00218 mD( 2, 1 ) = mU( 2, 1 ) = vx3( 0 );
00219 mD( 2, 2 ) = mU( 2, 2 ) = vx3( 1 );
00220 mD( 2, 3 ) = mU( 2, 3 ) = vx3( 2 );
00221 mU( 3, 0 ) = 1;
00222 mU( 3, 1 ) = vx4( 0 );
00223 mU( 3, 2 ) = vx4( 1 );
00224 mU( 3, 3 ) = vx4( 2 );
00225 mD( 3, 0 ) = 0;
00226 mD( 3, 1 ) = vx6( 0 );
00227 mD( 3, 2 ) = vx6( 1 );
00228 mD( 3, 3 ) = vx6( 2 );
00229
00230 ret = ( mD.Det( ) != 0 );
00231 if( ret ) {
00232
00233 t = mU.Det( ) / mD.Det( );
00234 vx6 = ( ( vx4 - vx5 ) * t ) + vx4;
00235
00236 }
00237 return( ret );
00238
00239 }
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249 void UtilVtk3DGeometriSelection::IntersectionPlaneAndLine(double *pResult,double *n,double *p,double *pA,double *pB)
00250 {
00251 double u,A,B,D;
00252 D = - (n[0]*p[0] + n[1]*p[1] + n[2]*p[2]) ;
00253 A= n[0]*pA[0] + n[1]*pA[1] + n[2]*pA[2] + D;
00254 B= n[0]*(pA[0]-pB[0]) + n[1]*(pA[1]-pB[1]) + n[2]*(pA[2]-pB[2]);
00255 if (B!=0)
00256 {
00257 u = A / B ;
00258 } else {
00259 u=-1;
00260 }
00261 pResult[0] = pA[0] + u*(pB[0] - pA[0]);
00262 pResult[1] = pA[1] + u*(pB[1] - pA[1]);
00263 pResult[2] = pA[2] + u*(pB[2] - pA[2]);
00264 }
00265
00266
00267
00268
00269
00270 double UtilVtk3DGeometriSelection::DistanceMinPointToLine(double *p,double *pA, double *pB)
00271 {
00272 double pResult[3];
00273 double normalToPlane[3];
00274 normalToPlane[0]=pA[0]-pB[0];
00275 normalToPlane[1]=pA[1]-pB[1];
00276 normalToPlane[2]=pA[2]-pB[2];
00277 IntersectionPlaneAndLine(pResult,normalToPlane,p,pA,pB);
00278
00279 double dx = p[0]-pResult[0];
00280 double dy = p[1]-pResult[1];
00281 double dz = p[2]-pResult[2];
00282
00283 double result=sqrt( dx*dx + dy*dy + dz*dz );
00284
00285 return result;
00286 }
00287
00288
00289
00290