00001 #ifndef _Geom_MeshSpatialObject_cxx
00002 #define _Geom_MeshSpatialObject_cxx
00003 #include "Geom_MeshSpatialObject.h"
00004
00005 namespace mial
00006 {
00007
00008 template <class dType, int nDims,class MType, class VType >
00009 Geom_MeshSpatialObject<dType, nDims,MType,VType>
00010 ::Geom_MeshSpatialObject(dType p)
00011 {
00012 theMeshSpatialObject = MeshSpatialObjectType::New();
00013 theMesh = theMeshSpatialObject->GetMesh();
00014 writer = WriterType::New();
00015 m_IsInsidePrecision = p;
00016 }
00017
00018 template <class dType, int nDims,class MType, class VType >
00019 MType
00020 Geom_MeshSpatialObject<dType, nDims,MType,VType>
00021 ::getMatrixNodePositions()
00022 {
00023 this->mNodes.set_size(this->numNodes,nDims);
00024 this->updateMatrixNodePositions();
00025 return this->mNodes;
00026 }
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 template <class dType, int nDims,class MType, class VType >
00043 bool
00044 Geom_MeshSpatialObject<dType, nDims,MType,VType>
00045 ::setMatrixNodePositions(MatrixType pos, int * inds)
00046 {
00047 for(int i=0; i< sizeof(inds)/sizeof(int); i++)
00048 this->mNodes.set_row(i,pos.get_row(i));
00049 this->updateMeshNodePositions();
00050 return true;
00051 }
00052
00053 template <class dType, int nDims,class MType, class VType >
00054 bool
00055 Geom_MeshSpatialObject<dType, nDims,MType,VType>
00056 ::addNodes(MatrixType pos, VectorType classes)
00057 {
00058
00059 MatrixType tmp;
00060 tmp.set_size(this->numNodes+pos.rows(),nDims);
00061 VectorType tmpC;
00062 tmpC.set_size(this->numNodes+pos.rows());
00063
00064
00065 for(int i=0;i<this->numNodes;i++)
00066 {
00067 tmp.set_row(i,this->mNodes.get_row(i));
00068 tmpC(i) = this->nodeClass(i);
00069 }
00070
00071 for(int i=this->numNodes, c=0;i<this->numNodes+pos.rows();i++,c++)
00072 {
00073 tmp.set_row(i,pos.get_row(c));
00074 tmpC(i) = classes(c);
00075 }
00076
00077 this->numNodes +=pos.rows();
00078
00079 this->mNodes.set_size(this->numNodes,nDims);
00080 this->mNodes = tmp;
00081 this->nodeClass = tmpC;
00082
00083
00084 this->updateMeshNodePositions();
00085 return true;
00086 }
00087 template <class dType, int nDims,class MType, class VType >
00088 bool
00089 Geom_MeshSpatialObject<dType, nDims,MType,VType>
00090 ::setMatrixNodePositions(MatrixType pos)
00091 {
00092 this->mNodes = pos;
00093 this->updateMeshNodePositions();
00094 return true;
00095 }
00096
00097 template <class dType, int nDims,class MType, class VType >
00098 void
00099 Geom_MeshSpatialObject<dType, nDims,MType,VType>
00100 ::updateMatrixNodePositions()
00101 {
00102 typename MeshType::PointsContainer::Iterator pointIterator;
00103 pointIterator = theMesh->GetPoints()->Begin();
00104 typename MeshType::PointsContainer::Iterator end = theMesh->GetPoints()->End();
00105
00106 int count =0;
00107 this->numNodes =0;
00108
00109 while( pointIterator != end )
00110 { ++pointIterator;
00111 this->numNodes++;
00112 }
00113
00114
00115 pointIterator = theMesh->GetPoints()->Begin();
00116 this->mNodes.set_size(this->numNodes,nDims);
00117 while( pointIterator != end )
00118 {
00119 typename MeshType::PointType p = pointIterator.Value();
00120 for(int i=0;i<nDims;i++)
00121 {
00122 this->mNodes(count,i)=p[i];
00123 }
00124 ++pointIterator;
00125 count++;
00126 }
00127 }
00128
00129 template <class dType, int nDims,class MType, class VType >
00130 void
00131 Geom_MeshSpatialObject<dType, nDims,MType,VType>
00132 ::updateMeshNodePositions()
00133 {
00134
00135 PointType tmp;
00136 for(int count=0;count < this->numNodes; count++)
00137 {
00138 for(int i=0; i<nDims; i++)
00139 {
00140 tmp[i] = this->mNodes(count,i);
00141 }
00142 theMesh->SetPoint(count,tmp);
00143 }
00144 theMeshSpatialObject->SetMesh(theMesh);
00145 }
00146
00147 template <class dType, int nDims,class MType, class VType >
00148 void
00149 Geom_MeshSpatialObject<dType, nDims,MType,VType>
00150 ::updateMatrixConnections()
00151 {
00152 CellIterator cellIterator = theMesh->GetCells()->Begin();
00153 CellIterator cellEnd = theMesh->GetCells()->End();
00154
00155 cellIterator = theMesh->GetCells()->Begin();
00156 cellEnd = theMesh->GetCells()->End();
00157
00158 typename TriangleType::PointIdIterator pit;
00159
00160
00161
00162 this->mConnections.set_size(3*theMesh->GetNumberOfCells(),2);
00163 this->numConnections =0;
00164 while( cellIterator != cellEnd )
00165 {
00166 CellType * cell = cellIterator.Value();
00167 switch( cell->GetType() )
00168 {
00169 case CellType::TRIANGLE_CELL:
00170 {
00171 TriangleType * tri = dynamic_cast<TriangleType *>( cell );
00172 pit = tri->PointIdsBegin();
00173
00174
00175 mConnections(this->numConnections,0) = *(pit);
00176 mConnections(this->numConnections,1) = *(pit+1);
00177 this->numConnections++;
00178
00179 mConnections(this->numConnections,0) = *(pit+1);
00180 mConnections(this->numConnections,1) = *(pit+2);
00181 this->numConnections++;
00182
00183 mConnections(this->numConnections,0) = *(pit+2);
00184 mConnections(this->numConnections,1) = *(pit);
00185 this->numConnections++;
00186
00187 break;
00188 }
00189 }
00190 ++cellIterator;
00191 }
00192 }
00193
00194 template <class dType, int nDims,class MType, class VType >
00195 void
00196 Geom_MeshSpatialObject<dType, nDims,MType,VType>
00197 ::writeNodesToFile( std::string fileName )
00198 {
00199 std::ofstream out(fileName.c_str());
00200
00201 typename MeshType::PointsContainer::Iterator pointIterator;
00202 pointIterator = theMesh->GetPoints()->Begin();
00203 typename MeshType::PointsContainer::Iterator end = theMesh->GetPoints()->End();
00204 out << theMesh->GetNumberOfPoints() << std::endl;
00205 while( pointIterator != end )
00206 {
00207 typename MeshType::PointType p = pointIterator.Value();
00208 out << p << std::endl;
00209 ++pointIterator;
00210 }
00211 }
00212
00213 template <class dType, int nDims,class MType, class VType >
00214 void
00215 Geom_MeshSpatialObject<dType, nDims,MType,VType>
00216 ::writeObjectToFile(std::string fileName)
00217 {
00218 writer->SetInput( theMeshSpatialObject );
00219 writer->SetFileName( fileName.c_str() );
00220 writer->Update();
00221 }
00222
00223 template <class dType, int nDims,class MType, class VType >
00224 void
00225 Geom_MeshSpatialObject<dType, nDims,MType,VType>
00226 ::readNodesFromFile( std::string fileName )
00227 {
00228 std::ifstream in(fileName.c_str());
00229 int count = 0;
00230 int size =0;
00231 in >> size;
00232
00233 PointType tmp;
00234 while(count < size)
00235 {
00236 for(int i=0; i<nDims; i++)
00237 {
00238 in >> tmp[i];
00239 }
00240 theMesh->SetPoint(count,tmp);
00241 count++;
00242 }
00243 this->numNodes = theMesh->GetNumberOfPoints();
00244 theMeshSpatialObject->SetMesh(theMesh);
00245 updateMatrixNodePositions();
00246
00247
00248 this->nodesChange = true;
00249 }
00250
00251 template <class dType, int nDims,class MType, class VType >
00252 bool
00253 Geom_MeshSpatialObject<dType, nDims,MType,VType>
00254 ::readTopologyFromFile( std::string fileName )
00255 {
00256
00257
00258 typename ReaderType::Pointer reader = ReaderType::New();
00259 reader->SetFileName(fileName.c_str());
00260 reader->Update();
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300 MeshSpatialObjectType* t = dynamic_cast<MeshSpatialObjectType *> ( (reader->GetScene())->GetObjectById(0));
00301 theMeshSpatialObject->SetMesh( t->GetMesh());
00302 theMesh = theMeshSpatialObject->GetMesh();
00303
00304
00305
00306 updateMatrixNodePositions();
00307
00308
00309 updateMatrixConnections();
00310
00311
00312 this->topologyChange = true;
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341 return false;
00342 }
00343
00344 template < class dType, int nDims, class MType, class VType >
00345 typename itk::Image< unsigned char, nDims>::Pointer
00346 Geom_MeshSpatialObject< dType, nDims, MType, VType >
00347 ::generateBinaryImageFromTopology( typename Geom_MeshSpatialObject<dType,nDims,MType,VType>::BinaryImageType::SizeType size)
00348 {
00349
00350 typename BinaryImageType::Pointer image = BinaryImageType::New();
00351
00352 typedef itk::TriangleMeshToBinaryImageFilter< MeshType, BinaryImageType > meshToImageFilterType;
00353 typename meshToImageFilterType::Pointer meshToImageFilter = meshToImageFilterType::New();
00354
00355
00356
00357
00358
00359
00360
00361
00362 meshToImageFilter->SetSize( size );
00363
00364 meshToImageFilter->SetInput( theMeshSpatialObject->GetMesh() );
00365 image = meshToImageFilter->GetOutput();
00366 meshToImageFilter->Update();
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438 return image;
00439 }
00440
00441 template < class dType, int nDims, class MType, class VType >
00442 void
00443 Geom_MeshSpatialObject< dType, nDims, MType, VType >
00444 ::generateTopologyFromBinaryImage( BinaryImageTypePointer binaryInputImage )
00445 {
00446 typedef itk::BinaryMask3DMeshSource< BinaryImageType, MeshType > MeshSourceType;
00447 typename MeshSourceType::Pointer imgToMeshFilter = MeshSourceType::New();
00448
00449 imgToMeshFilter->SetInput( binaryInputImage );
00450
00451
00452 typedef itk::MinimumMaximumImageFilter< BinaryImageType > MinMaxFilterType;
00453 typename MinMaxFilterType::Pointer minMaxFilter = MinMaxFilterType::New();
00454 minMaxFilter->SetInput( binaryInputImage );
00455 minMaxFilter->Update();
00456
00457 imgToMeshFilter->SetObjectValue( minMaxFilter->GetMaximum() );
00458
00459 imgToMeshFilter->Update();
00460
00461 std::cout << "BinaryMask3DMeshSource update completed." << std::endl;
00462 theMesh = imgToMeshFilter->GetOutput();
00463
00464
00465
00466 typename MeshType::CellDataContainer::Pointer emptyCellDataContainer = MeshType::CellDataContainer::New();
00467 theMesh->SetCellData( emptyCellDataContainer );
00468 theMeshSpatialObject->SetMesh( theMesh );
00469 }
00470 template < class dType, int nDims, class MType, class VType >
00471 bool
00472 Geom_MeshSpatialObject< dType, nDims, MType, VType >
00473 ::isInside( VectorType p)
00474 {
00475
00476
00477
00478 CellIterator cellIterator = theMesh->GetCells()->Begin();
00479 CellIterator cellEnd = theMesh->GetCells()->End();
00480
00481 cellIterator = theMesh->GetCells()->Begin();
00482 cellEnd = theMesh->GetCells()->End();
00483
00484 TriangleType * tri;
00485 int pCount = 0;
00486 int nCount = 0;
00487 VectorType ray(nDims);
00488
00489
00490 ray.fill(0);
00491 ray(0)=1;
00492 ray(1)=0;
00493 ray(2)=0;
00494
00495 double minDist =0;
00496 CoordRepType closestPoint[nDims];
00497 CoordRepType position[nDims];
00498
00499 for(int i=0; i<nDims;i++)
00500 position[i] = p(i);
00501
00502 while( cellIterator != cellEnd )
00503 {
00504 CellType * cell = cellIterator.Value();
00505 if( cell->GetType() == CellType::TRIANGLE_CELL )
00506 {
00507 tri = dynamic_cast<TriangleType *>( cell );
00508 tri->EvaluatePosition(position,theMesh->GetPoints(),closestPoint,NULL,&minDist,NULL);
00509 if(abs(minDist) <= m_IsInsidePrecision)
00510 {
00511 return true;
00512 }else
00513 {
00514 if(intersectWithLine(ray,p,tri))
00515 pCount++;
00516 if(intersectWithLine(-ray,p,tri))
00517 nCount++;
00518 }
00519 }
00520 ++cellIterator;
00521 }
00522 return ( (pCount%2 !=0)&&(nCount%2!=0));
00523 }
00524
00525 template < class dType, int nDims, class MType, class VType >
00526 bool
00527 Geom_MeshSpatialObject< dType, nDims, MType, VType >
00528 ::intersectWithLine( VectorType L, VectorType P, TriangleType* tri)
00529 {
00530
00531 if(this->nodesChange)
00532 updateMatrixNodePositions();
00533
00534 typename TriangleType::PointIdIterator pit;
00535 pit = tri->PointIdsBegin();
00536
00537
00538 VectorType v1(nDims);
00539 VectorType v2(nDims);
00540 VectorType n(nDims);
00541 VectorType w(nDims);
00542 VectorType intersectionPoint(nDims);
00543
00544 v1 = this->mNodes.get_row(*(pit+1))-this->mNodes.get_row(*pit);
00545 v2 = this->mNodes.get_row(*(pit+2))-this->mNodes.get_row(*pit);
00546 n = vnl_cross_3d(v1,v2);
00547 n.normalize();
00548 L.normalize();
00549
00550
00551
00552
00553
00554 dType s;
00555 CoordRepType position[nDims];
00556 double minDist;
00557 CoordRepType closestPoint[nDims];
00558
00559 double t;
00560 t = dot_product(n,L);
00561 if( t != 0)
00562 {
00563 w = P - this->mNodes.get_row(*(pit));
00564 s = -dot_product(n,w)/dot_product(n,L);
00565 if(s>=0)
00566 {
00567 intersectionPoint = P+ s*L;
00568
00569 for(int i=0;i<nDims;i++)
00570 position[i] = intersectionPoint(i);
00571
00572
00573
00574
00575 tri->EvaluatePosition(position,theMesh->GetPoints(),closestPoint,NULL,&minDist,NULL);
00576
00577 if(abs(minDist) <= m_IsInsidePrecision)
00578 return true;
00579 else
00580 {
00581 return false;
00582 }
00583 }
00584 else
00585 return false;
00586 }
00587 else
00588 {
00589 return false;
00590 }
00591 }
00592
00593 template < class dType, int nDims, class MType, class VType >
00594 bool
00595 Geom_MeshSpatialObject< dType, nDims, MType, VType >
00596 ::addConnection(int start,int end)
00597 {
00598 MatrixType tmp;
00599 tmp.set_size(this->numConnections+1,2);
00600
00601
00602 for(int i=0;i<this->numConnections;i++)
00603 {
00604 tmp(i,0) = this->mConnections(i,0);
00605 tmp(i,1) = this->mConnections(i,1);
00606 }
00607 tmp(this->numConnections,0) = start;
00608 tmp(this->numConnections,1) = end;
00609
00610 this->numConnections++;
00611
00612 this->mConnections.set_size(this->numConnections,2);
00613 this->mConnections = tmp;
00614
00615 CellAutoPointer Lines;
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627 this->topologyChange = true;
00628
00629 return false;
00630 }
00631
00632 }
00633 #endif