C:/cmcintos/defOrgs/examples/vesselCrawler/source/Beh_Growing.cxx

00001 #ifndef _Beh_Growing_txx
00002 #define _Beh_Growing_txx
00003 
00004 #include "Beh_Growing.h"
00005 #include "vnl_cross.h"
00006 #include "vnl_math.h"
00007 #include "algo\vnl_matrix_inverse.h"
00008 #define PI 3.14159265
00009 
00010 namespace mial {
00011 
00012         template<class Type,class CrawlerPhysType>
00013         Beh_Growing<Type,CrawlerPhysType>::Beh_Growing()
00014                 :Behavior<Type,3>("Beh_Growing"), nDims(3)
00015         {
00016                 //Default constructor
00017         }
00018         template<class Type,class CrawlerPhysType>
00019         bool Beh_Growing<Type,CrawlerPhysType>::run(typename Behavior<Type,3>::behaviorIn * i, std::stringstream *s)
00020         {
00021                 //function [pointsXYZ,newAxis] = growTo(nodesXYZ,newAxis,pointXYZ,nodeNum,bifFound,radius,numNodesPerLayer,growDistance);
00022                 behaviorIn * in;
00023                 if(i != NULL)
00024                         in = (reinterpret_cast<behaviorIn *>(i)); //Typecast the input to its desired form
00025                 else
00026                 {
00027                         Error e;
00028                         e.msg = "Stream call not supported";
00029                         e.name = "Beh_Growing";
00030                         throw e;
00031                 }
00032                 //Get the new set of nodes
00033                 MatrixType newNodes = growTo(in);
00034 
00035                 VectorType classes(in->vesselGeom->getNumNodesPerLayer());
00036                 classes.fill(1);//Boundary nodes
00037                 classes(0) = 0;//Medial nodes
00038                 in->vesselGeom->addLayer(newNodes,classes);
00039                 
00040                 //Set springs rest.
00041                 //TODO get params from gui
00042                 int springsKDef = 3;
00043                 VectorType acSprings = in->vesselGeom->getActiveSprings(-1);
00044                 VectorType vals = acSprings;
00045                 vals.fill(springsKDef);
00046                 (reinterpret_cast<CrawlerPhysType *>(physLayer))->setSpringsK(acSprings,vals);
00047 
00048                 acSprings = in->vesselGeom->getActiveSprings(1);
00049                 vals = acSprings;
00050                 vals.fill(0.5*springsKDef);
00051                 (reinterpret_cast<CrawlerPhysType *>(physLayer))->setSpringsK(acSprings,vals);
00052         }
00053         template<class Type,class CrawlerPhysType>
00054         typename Beh_Growing<Type,CrawlerPhysType>::MatrixType Beh_Growing<Type,CrawlerPhysType>::growTo(behaviorIn* in)
00055         {
00056                 //TODO test/clean
00057 
00058                 int numNodesPerLayer = in->vesselGeom->getNumNodesPerLayer();
00059                 int nodeNum = in->vesselGeom->getNumNodes() - numNodesPerLayer;//0-based indexing so no +1;
00060 
00061                 MatrixType points(numNodesPerLayer,nDims);
00062                 points.fill(0);
00063                 Type theta                      = 0;
00064                 for(int i=0; i<numNodesPerLayer;i++)
00065                 {
00066                         theta= i*2*PI/(numNodesPerLayer-1);
00067                         points(i,1) = sin(theta)*in->radius;
00068                         points(i,2) = cos(theta)*in->radius;
00069                         //points(i,3) = 0;//matrix is filled with zeros
00070                 }    
00071                 //Rotate the new axis to the Zaxis, and 0 degree vector to the y axis
00072                 VectorType finalAxis = (in->newAxis).normalize();
00073                 MatrixType nodesXYZ = in->vesselGeom->getMatrixNodePositions();
00074                 VectorType beta(nDims);
00075                 if(nodeNum<=0)//There are no layers yet
00076                 {
00077                         beta(0) =0;
00078                         beta(0) =1;
00079                         beta(0) =0;
00080                 }
00081                 else
00082                 {
00083                         //Prevent mesh twisting
00084                         beta = nodesXYZ.get_row(nodeNum+1) - nodesXYZ.get_row(nodeNum);//align with y axis
00085                 }
00086 
00087                 //beta = beta/beta.norm();
00088                 //TODO make sure works
00089                 beta.normalize();
00090                 VectorType alpha = -vnl_cross_3d(beta,finalAxis);// cross(beta,Tvecu);
00091                 alpha.normalize();
00092                 MatrixType Rtz(nDims,nDims);// = [ alpha 0 ; beta 0;Tvecu 0; 0 0 0 1];
00093                 Rtz.fill(0);
00094                 Rtz.set_row(0,alpha);
00095                 Rtz.set_row(1,beta);
00096                 Rtz.set_row(2,finalAxis);
00097                 //Now if Rnz takes Tvecu to the z axis, then Rtz^-1 takes the Z-axis to
00098                 //Tvecu
00099 
00100                 //Perform the transformation (rotation + translation)
00101                 MatrixType Rtzi = vnl_matrix_inverse<Type>(Rtz) ;
00102                 if(nodeNum<0)
00103                 {
00104                         for(int i=0; i<numNodesPerLayer;i++)
00105                                 points.set_row(i,Rtzi*points.get_row(i) + in->locXYZ);
00106                 }
00107                 else
00108                 {
00109                         for(int i=0; i<numNodesPerLayer;i++)
00110                                 points.set_row(i,Rtzi*points.get_row(i));
00111                         //If two layers are nearby and turn sharply they can cross one another
00112                         //This would produce uwanted folds in the mesh.
00113                         //Find the set of points on the wrong side of the plane defined by the
00114                         //previous layer
00115                         VectorType p_norm = nodesXYZ.get_row(nodeNum) - nodesXYZ.get_row(nodeNum-numNodesPerLayer);
00116                         VectorType growDirection = in->locXYZ - nodesXYZ.get_row(nodeNum);      
00117                         growDirection.normalize();
00118                         p_norm.normalize();
00119                         VectorType signVec(nDims);
00120                         Type dp =0;
00121                         Type maxDist =in->growDistance;//At least this distance must be used
00122                         Type dist =0;
00123                         for(int a=0; a<numNodesPerLayer;a++)// a = 1:length(pointsXYZ(:,1))
00124                         {
00125                                 signVec = points.get_row(a) - nodesXYZ.get_row(nodeNum); //This is a point on our plane
00126                                 dp = dot_product(signVec,p_norm);
00127                                 if( dp <0)
00128                                 {
00129                                         dist = abs(dp/dot_product(p_norm,finalAxis));
00130                                         if(dist > maxDist)
00131                                                 maxDist = dist;
00132                                 }
00133                         }
00134                         if(maxDist >2)
00135                                 maxDist = 2;
00136                         //[Yv,Indm] = max(w_dist);
00137                         //Yv = max(min(Yv,2),0);
00138 
00139                         //now find a vector that places this point on the correct side of the
00140                         //plane. This vector is the norm * the w_dist;
00141                         for(int i=0; i<numNodesPerLayer;i++)
00142                         {
00143                                 points.set_row(i,points.get_row(i) + maxDist*growDirection);
00144                         }
00145                 }
00146 
00147                 return points;
00148         }
00149 
00150 }//end namespace mial
00151 
00152 #endif

Generated on Wed Jul 19 13:05:16 2006 for IDO by  doxygen 1.4.7