LocalFromWorldPoint.hpp

00001 #ifndef __LOCALFROMWORLDPOINT_HPP
00002 #define __LOCALFROMWORLDPOINT_HPP
00003 
00004 #include <fish/fiber/field/DirectProductArray.hpp> 
00005 #include <fish/fiber/vector/Interpolate.hpp>
00006 #include <fish/fiber/vector/LinearIpol.hpp>
00007 #include <fish/fiber/baseop/UniGridMapper.hpp>
00008 #include <fish/fiber/baseop/ExpandBBox.hpp>
00009 
00010 #include <fish/fiber/field/Fragment.hpp>
00011 #include <fish/fiber/grid/Chart.hpp>
00012 
00013 #include <fish/fiber/baseop/BundleBaseSpaceFunctions.hpp>
00014 
00015 #include <eagle/PhysicalSpace.hpp>
00016 #include <aerie/KDTree.hpp>
00017 #include <eagle/FixedArray.hpp>
00018 
00019 #include <memcore/RefPtr.hpp>
00020 #include "FragmentSkeleton.hpp"
00021 #include "PointSearch.hpp"
00022 
00023 
00024 #include "gridopDllApi.h"
00025 
00026 namespace Fiber
00027 {
00028 
00029 using namespace Eagle;
00030 using namespace Eagle::PhysicalSpace;
00031 
00032 
00039 class   gridop_API LocalFromWorldPoint : public MemCore::ReferenceBase<LocalFromWorldPoint >
00040 {
00041         // info retrieved from iterator, which is called once
00042 //      bool curvi_coords; 
00043 //      bool fragmented_coords; 
00044 
00045 //      bool inited; 
00046 
00047 //      RefPtr<Slice> slice;
00048         RefPtr<Field> coords; 
00049 
00050         CartesianFragments      FragmentProperties; 
00051         PointSearch             UniformPointSearch;
00052 
00053         RefPtr<Grid>&grid() { return FragmentProperties.TheGrid; }
00054 
00055 
00056         double TreeQueryFac;
00057         RefPtr<KDTree<3, int> > MyTree;
00058 
00064         static  inline MultiIndex<3> getFragmentOffset(const RefPtr<FragmentID>&f)
00065         {
00066          MultiIndex<3> Offset; 
00067                  if ( RefPtr<FragmentLocation<3> > F3 = interface_cast<FragmentLocation<3> > (f) )
00068                  {
00069                          Offset = F3->Offset; 
00070                  } 
00071                  else
00072                  {
00073                          Offset = 0, 0, 0;
00074                  } 
00075 
00076                  return Offset;
00077         }
00078 
00079         typedef MemArray<3, Eagle::tvector3>           VectorArray_t; 
00080         typedef MemArray<3, double>                    ScalarArray_t; 
00081         typedef MemArray<3, Eagle::point3>             CoordsArray_t; 
00082         typedef MemArray<1, Eagle::point3>             CoordsArray1D_t;
00083         typedef MemArray<1, std::string>               FragmentIDs_t; 
00084 
00085         typedef FixedArray<point,8>                    Vertexlist_t;
00086 
00094         typedef MemArray<1, RefPtr<BoundingBox> >      FragmentBounds_t;
00095         typedef DirectProductMemArray<Eagle::point3>   ProcArray_t; 
00096 
00097         // Remember Fragment IDs and Bounding Boxes, and UniGRid object in class after initialization 
00098 //      RefPtr<FragmentIDs_t>    MyFragIds; 
00099 //      RefPtr<FragmentBounds_t> MyFragBBs; 
00100         RefPtr<Field>&UniMapperField()
00101         {
00102                 return UniformPointSearch.UniMapperField;
00103         }
00104 
00108         struct  MyIterator : Field::Iterator
00109         {
00110                 int             c;
00111 
00112                 RefPtr<Field> FragmentBoxes;
00113 
00114                 RefPtr<Field>           Coords;
00115                 RefPtr<KDTree<3, int> > Tree;
00116                 double last_radius;
00117 
00118                 bool build_tree;
00119 
00120 //              RefPtr<FragmentIDs_t>    MyFragIds; 
00121 //              RefPtr<FragmentBounds_t> MyFragBBs;
00122 
00123                 MyIterator(const RefPtr<Field>&FragmentBoxesPositions,
00124                            const RefPtr<Field>&CoordsP, 
00125                            const RefPtr<KDTree<3,int> >&TreeP,
00126                            const bool build_treeP)
00127 //, const RefPtr<FragmentIDs_t>&FragIdsP, const RefPtr<FragmentBounds_t>&FragBBsP )
00128                 :c(0)
00129                 , FragmentBoxes( FragmentBoxesPositions )
00130                 , Coords(CoordsP)
00131                 , Tree(TreeP)
00132                 , last_radius(0)
00133                 , build_tree(build_treeP)
00134 //              , MyFragIds(FragIdsP)
00135 //              , MyFragBBs(FragBBsP)
00136                 {}
00137                 
00138                 bool apply(const RefPtr<FragmentID>&f, const MemCore::StrongPtr<Fiber::CreativeArrayBase>&DC);
00139 
00140         } ; 
00141 
00142 
00143 
00148         class BBSelectorBase
00149         {
00150         protected:
00151 
00152                 
00153         public:
00154                 BBSelectorBase() {}
00155                 virtual ~BBSelectorBase(){}
00156         
00157                 virtual unsigned int getNext() = 0;
00158                 virtual bool hasNext() = 0;
00159                 virtual void reset(const int _last, const point& pos) = 0;
00160         };      
00161 
00162  public:
00167         class BBSelectorMemoryTree : public BBSelectorBase
00168         {
00169                 int last, current, size;
00170                 point reset_pos;
00171                 map<double, int>m;
00172                 map<double, int>::iterator it;
00173                 double TreeQueryFac;
00174                 RefPtr<KDTree<3,int> > Tree;
00175         public:
00176                 BBSelectorMemoryTree(const RefPtr<KDTree<3, int> >TreeP, const double TreeQueryFacP) 
00177                 : reset_pos(point(0,0,0))
00178                 , TreeQueryFac(TreeQueryFacP)
00179                 , Tree(TreeP)
00180                 {
00181                         m.clear(); 
00182                         last=0; 
00183                         current=0; 
00184                         size=0;
00185                 }
00186                 
00187                 unsigned int getNext();
00188                 bool hasNext();
00189                 void reset( const int _last, const point& pos );
00190         };
00191         
00192         
00197         class FindCell
00198         {
00199         protected:
00200                 RefPtr<CoordsArray_t>          CoordsArr;
00201                 RefPtr<VectorArray_t>          VecsArr;
00202                 MultiIndex<3> iAx, iAy, iAz; 
00203         public:
00204                 FindCell()
00205                         {
00206                                 iAx = 1, 0, 0; 
00207                                 iAy = 0, 1, 0; 
00208                                 iAz = 0, 0, 1;
00209                         }
00210                 
00211                 virtual ~FindCell(){}
00212                 
00213                 void setCoords(const RefPtr<CoordsArray_t>  CA)  { CoordsArr = CA; }
00214                 void setVecs  (const RefPtr<VectorArray_t>  VA)  { VecsArr   = VA; }
00215 
00216                 inline tvector cross(const tvector&t1, const tvector&t2)
00217                         {
00218                         tvector res; 
00219                                 res =  t1[1]*t2[2] - t1[2]*t2[1],
00220                                        -( t1[0]*t2[2] - t1[2]*t2[0] ),
00221                                        t1[0]*t2[1] - t1[1]*t2[0]; 
00222 
00223                                 return res;
00224                         }
00225 
00226                 virtual int    pointInCell( const point&P ) = 0;
00227                 virtual point  localUVW   ( const point&p ) = 0;
00228         };
00229 
00230         
00234         class HexaHedralCellNewton : public FindCell
00235         {
00236                 RefPtr<UniGridMapper> UniMap;
00237 
00238                 point uvw;
00239                 int point_type;
00240                 double block_epsilon;
00241 
00242         public:
00243                 HexaHedralCellNewton():FindCell()
00244                 {}
00245  
00246                 virtual ~HexaHedralCellNewton(){}
00247 
00248                 void  setUniMap  ( RefPtr<UniGridMapper> unimap ) { UniMap = unimap; }
00249                 int   pointInCell( const point&P );
00250                 point localUVW   ( const point&p );
00251 
00252                 void setEpsilon(const double e) { block_epsilon = e; }
00253         }; 
00254 
00255 
00256         bool rayTriangleIntersect(  const point orig, const tvector dir, 
00257                                     const point vert0, const point vert1, const point vert2, 
00258                                     double&t, double&u, double&v,
00259                                     point&intersection );
00260                 
00261 
00262         bool rayQuaderIntersect(  const point orig, const tvector dir, 
00263                                   Vertexlist_t & QV,
00264                                   double&t, double&u, double&v,
00265                                   point&intersection, bivector&normal, unsigned&face ); 
00266 
00267         FixedArray<FixedArray<int, 3>,12> Facelist; 
00268 
00269         // to be removed later
00270         double block_epsilon; 
00271 
00272                 // parameters for unigrid building
00273         double  res_scale, prec_scale;
00274 
00275 public: 
00276         int     MaxListSize;
00277 
00285         LocalFromWorldPoint( Slice&SourceSliceP, const RefPtr<Grid>&SourceGridP,
00286                              const string&Gridname,
00287                              const RefPtr<Field>&SourceCoordsP,
00288                              double     res_scale = 1.0, double prec_scale = 0.1);
00289 
00291         ~LocalFromWorldPoint();
00292 
00300         bool get( const point position, pair<point, string>&data ); 
00301 
00302 
00303         /* Set an epsilon value for widening the block boundary test. This is a hack solution and should be done internally via
00304          * neighbourhood information avoiding espsilons. Some tests showed that a value of 0.05 seems to do pretty ok.
00305          */
00306         void setBlockBoundaryEpsilon(const double block_epsilonP) { block_epsilon = block_epsilonP; }
00307 
00308 
00312         int numberOfBordersOfCell( const pair<point, string> localdata, int&hint1, int&hint2 ); 
00313 
00314 
00320         bool getBorderIntersectionNormal( const point worldposition, 
00321                                           const pair<point, string> localpoint, 
00322                                           const tvector direction,  
00323                                           point&intersection, bivector&normal ); 
00324 };
00325 
00326 } // namespace
00327 
00328 #endif