All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends

BV_splitter.h

00001 /*
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Copyright (c) 2011, Willow Garage, Inc.
00005  *  All rights reserved.
00006  *
00007  *  Redistribution and use in source and binary forms, with or without
00008  *  modification, are permitted provided that the following conditions
00009  *  are met:
00010  *
00011  *   * Redistributions of source code must retain the above copyright
00012  *     notice, this list of conditions and the following disclaimer.
00013  *   * Redistributions in binary form must reproduce the above
00014  *     copyright notice, this list of conditions and the following
00015  *     disclaimer in the documentation and/or other materials provided
00016  *     with the distribution.
00017  *   * Neither the name of Willow Garage, Inc. nor the names of its
00018  *     contributors may be used to endorse or promote products derived
00019  *     from this software without specific prior written permission.
00020  *
00021  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032  *  POSSIBILITY OF SUCH DAMAGE.
00033  */
00034 
00037 #ifndef FCL_BV_SPLITTER_H
00038 #define FCL_BV_SPLITTER_H
00039 
00040 #include "fcl/BVH/BVH_internal.h"
00041 #include "fcl/BV/kIOS.h"
00042 #include "fcl/BV/OBBRSS.h"
00043 #include <vector>
00044 #include <iostream>
00045 
00046 namespace fcl
00047 {
00048 
00050 template<typename BV>
00051 class BVSplitterBase
00052 {
00053 public:
00055   virtual void set(Vec3f* vertices_, Triangle* tri_indices_, BVHModelType type_) = 0;
00056 
00058   virtual void computeRule(const BV& bv, unsigned int* primitive_indices, int num_primitives) = 0;
00059 
00061   virtual bool apply(const Vec3f& q) const = 0;
00062 
00064   virtual void clear() = 0;
00065 };
00066 
00067 
00069 enum SplitMethodType {SPLIT_METHOD_MEAN, SPLIT_METHOD_MEDIAN, SPLIT_METHOD_BV_CENTER};
00070 
00071 
00073 template<typename BV>
00074 class BVSplitter : public BVSplitterBase<BV>
00075 {
00076 public:
00077 
00078   BVSplitter(SplitMethodType method) : split_method(method)
00079   {
00080   }
00081 
00083   virtual ~BVSplitter() {}
00084 
00086   void set(Vec3f* vertices_, Triangle* tri_indices_, BVHModelType type_)
00087   {
00088     vertices = vertices_;
00089     tri_indices = tri_indices_;
00090     type = type_;
00091   }
00092 
00094   void computeRule(const BV& bv, unsigned int* primitive_indices, int num_primitives)
00095   {
00096     switch(split_method)
00097     {
00098     case SPLIT_METHOD_MEAN:
00099       computeRule_mean(bv, primitive_indices, num_primitives);
00100       break;
00101     case SPLIT_METHOD_MEDIAN:
00102       computeRule_median(bv, primitive_indices, num_primitives);
00103       break;
00104     case SPLIT_METHOD_BV_CENTER:
00105       computeRule_bvcenter(bv, primitive_indices, num_primitives);
00106       break;
00107     default:
00108       std::cerr << "Split method not supported" << std::endl;
00109     }
00110   }
00111 
00113   bool apply(const Vec3f& q) const
00114   {
00115     return q[split_axis] > split_value;
00116   }
00117 
00119   void clear()
00120   {
00121     vertices = NULL;
00122     tri_indices = NULL;
00123     type = BVH_MODEL_UNKNOWN;
00124   }
00125 
00126 private:
00127 
00130   int split_axis;
00131   Vec3f split_vector;
00132 
00134   FCL_REAL split_value;
00135 
00137   Vec3f* vertices;
00138 
00140   Triangle* tri_indices;
00141 
00143   BVHModelType type;
00144 
00146   SplitMethodType split_method;
00147 
00149   void computeRule_bvcenter(const BV& bv, unsigned int* primitive_indices, int num_primitives)
00150   {
00151     Vec3f center = bv.center();
00152     int axis = 2;
00153 
00154     if(bv.width() >= bv.height() && bv.width() >= bv.depth())
00155       axis = 0;
00156     else if(bv.height() >= bv.width() && bv.height() >= bv.depth())
00157       axis = 1;
00158 
00159     split_axis = axis;
00160     split_value = center[axis];
00161   }
00162 
00164   void computeRule_mean(const BV& bv, unsigned int* primitive_indices, int num_primitives)
00165   {
00166     int axis = 2;
00167 
00168     if(bv.width() >= bv.height() && bv.width() >= bv.depth())
00169       axis = 0;
00170     else if(bv.height() >= bv.width() && bv.height() >= bv.depth())
00171       axis = 1;
00172 
00173     split_axis = axis;
00174     FCL_REAL sum = 0;
00175 
00176     if(type == BVH_MODEL_TRIANGLES)
00177     {
00178       for(int i = 0; i < num_primitives; ++i)
00179       {
00180         const Triangle& t = tri_indices[primitive_indices[i]];
00181         sum += (vertices[t[0]][split_axis] + vertices[t[1]][split_axis] + vertices[t[2]][split_axis]);
00182       }
00183 
00184       sum /= 3;
00185     }
00186     else if(type == BVH_MODEL_POINTCLOUD)
00187     {
00188       for(int i = 0; i < num_primitives; ++i)
00189       {
00190         sum += vertices[primitive_indices[i]][split_axis];
00191       }
00192     }
00193 
00194     split_value = sum / num_primitives;
00195   }
00196 
00198   void computeRule_median(const BV& bv, unsigned int* primitive_indices, int num_primitives)
00199   {
00200     int axis = 2;
00201 
00202     if(bv.width() >= bv.height() && bv.width() >= bv.depth())
00203       axis = 0;
00204     else if(bv.height() >= bv.width() && bv.height() >= bv.depth())
00205       axis = 1;
00206 
00207     split_axis = axis;
00208     std::vector<FCL_REAL> proj(num_primitives);
00209 
00210     if(type == BVH_MODEL_TRIANGLES)
00211     {
00212       for(int i = 0; i < num_primitives; ++i)
00213       {
00214         const Triangle& t = tri_indices[primitive_indices[i]];
00215         proj[i] = (vertices[t[0]][split_axis] + vertices[t[1]][split_axis] + vertices[t[2]][split_axis]) / 3;
00216       }
00217     }
00218     else if(type == BVH_MODEL_POINTCLOUD)
00219     {
00220       for(int i = 0; i < num_primitives; ++i)
00221         proj[i] = vertices[primitive_indices[i]][split_axis];
00222     }
00223 
00224     std::sort(proj.begin(), proj.end());
00225 
00226     if(num_primitives % 2 == 1)
00227     {
00228       split_value = proj[(num_primitives - 1) / 2];
00229     }
00230     else
00231     {
00232       split_value = (proj[num_primitives / 2] + proj[num_primitives / 2 - 1]) / 2;
00233     }
00234   }
00235 };
00236 
00237 
00238 template<>
00239 bool BVSplitter<OBB>::apply(const Vec3f& q) const;
00240 
00241 template<>
00242 bool BVSplitter<RSS>::apply(const Vec3f& q) const;
00243 
00244 template<>
00245 bool BVSplitter<kIOS>::apply(const Vec3f& q) const;
00246 
00247 template<>
00248 bool BVSplitter<OBBRSS>::apply(const Vec3f& q) const;
00249 
00250 template<>
00251 void BVSplitter<OBB>::computeRule_bvcenter(const OBB& bv, unsigned int* primitive_indices, int num_primitives);
00252 
00253 template<>
00254 void BVSplitter<OBB>::computeRule_mean(const OBB& bv, unsigned int* primitive_indices, int num_primitives);
00255 
00256 template<>
00257 void BVSplitter<OBB>::computeRule_median(const OBB& bv, unsigned int* primitive_indices, int num_primitives);
00258 
00259 template<>
00260 void BVSplitter<RSS>::computeRule_bvcenter(const RSS& bv, unsigned int* primitive_indices, int num_primitives);
00261           
00262 template<>                        
00263 void BVSplitter<RSS>::computeRule_mean(const RSS& bv, unsigned int* primitive_indices, int num_primitives);
00264 
00265 template<>
00266 void BVSplitter<RSS>::computeRule_median(const RSS& bv, unsigned int* primitive_indices, int num_primitives);
00267 
00268 template<>
00269 void BVSplitter<kIOS>::computeRule_bvcenter(const kIOS& bv, unsigned int* primitive_indices, int num_primitives);
00270 
00271 template<>
00272 void BVSplitter<kIOS>::computeRule_mean(const kIOS& bv, unsigned int* primitive_indices, int num_primitives);
00273 
00274 template<>
00275 void BVSplitter<kIOS>::computeRule_median(const kIOS& bv, unsigned int* primitive_indices, int num_primitives);
00276 
00277 template<>
00278 void BVSplitter<OBBRSS>::computeRule_bvcenter(const OBBRSS& bv, unsigned int* primitive_indices, int num_primitives);
00279 
00280 template<>
00281 void BVSplitter<OBBRSS>::computeRule_mean(const OBBRSS& bv, unsigned int* primitive_indices, int num_primitives);
00282 
00283 template<>
00284 void BVSplitter<OBBRSS>::computeRule_median(const OBBRSS& bv, unsigned int* primitive_indices, int num_primitives);
00285 
00286 }
00287 
00288 #endif