Blob.cpp

Go to the documentation of this file.
00001 /**<!-------------------------------------------------------------------->
00002    @file   Blob.cpp
00003    @author Travis Fischer (fisch0920@gmail.com)
00004    @author Matthew Jacobs (jacobs.mh@gmail.com)
00005    @date   Spring 2008
00006    
00007    @brief
00008       Blobby isosurface composed of a set of MetaObjects, all of which 
00009    combine to form a scalar field whose contour at this blob's threshold 
00010    value defines the surface. Upon initialization (Blob::init), the implicit 
00011    surface is polygonized into triangles using a variant of the well-known 
00012    Marching Cubes algorithm.
00013    
00014    @see also MetaObject
00015    <!-------------------------------------------------------------------->**/
00016 
00017 #include "Blob.h"
00018 #include "Mesh.h"
00019 #include "MarchingCubes.h"
00020 
00021 #include <SurfacePoint.h>
00022 
00023 Blob::~Blob() {
00024    FOREACH(MetaObjectListIter, m_metaObjects, iter) {
00025       MetaObject *meta = (*iter);
00026       
00027       safeDelete(meta);
00028    }
00029    
00030    safeDelete(m_mesh);
00031 }
00032 
00033 void Blob::init() {
00034    if (NULL == m_mesh) {
00035       MetaObject::init();
00036       
00037       m_threshold = getValue<real_t>("threshold", m_threshold);
00038       const Vector3 &resolution = getValue<Vector3>("resolution", 
00039                                                     Vector3(128, 128, 128));
00040       
00041       // no triangles will be generated with a threshold of zero because 
00042       // the value of the field will never be "on the other side" of zero
00043       // (it's bounded to be zero when there is no charge)
00044       // note: now handled in MarchingCubes algorithm instead
00045       //if (m_threshold == 0)
00046       //   m_threshold = EPSILON;
00047       
00048       m_aabb = AABB();
00049       m_aabb = AABB();
00050       
00051       // initialize metaObjects
00052       FOREACH(MetaObjectListIter, m_metaObjects, iter) {
00053          MetaObject *meta = (*iter);
00054          ASSERT(meta);
00055          
00056          meta->init();
00057          
00058          // keep track of aggregate AABB now because it will be used by 
00059          // the marching cubes algorithm
00060          m_aabb.add(meta->getAABB());
00061       }
00062       
00063       MarchingCubes marchingCubes(resolution);
00064       
00065       // initialize mesh
00066       m_mesh = marchingCubes.polygonize(*this, m_threshold);
00067       ASSERT(m_mesh);
00068       
00069       m_mesh->setMaterial(m_material);
00070       m_mesh->inherit(*this);
00071       m_mesh->init();
00072       
00073       if (m_mesh->getNoTriangles() <= 0 || m_mesh->getNoVertices() <= 0) {
00074          cerr << "Warning: blobby metaobject produced invalid mesh (no triangles)" 
00075               << endl;
00076       }
00077       
00078       // overwrite original, conservative AABB with tighter AABB
00079       m_objSpaceAABB = m_mesh->getAABB();
00080       
00081       // transform AABB into parent coordinate system
00082       Transformable::init();
00083    }
00084 }
00085 
00086 void Blob::preview() {
00087    ASSERT(m_mesh);
00088    Transformable::preview();
00089    
00090    m_mesh->preview();
00091 }
00092 
00093 real_t Blob::getIntersection(const Ray &ray, SurfacePoint &pt) {
00094    ASSERT(m_mesh);
00095    
00096    // TODO: creating a new Ray here is rather inefficient...
00097    Point3  P;
00098    Vector3 D;
00099    _transformRayWorldToObj(ray, P, D);
00100    
00101    return m_mesh->getIntersection(Ray(P, D), pt);
00102 }
00103 
00104 bool Blob::intersects(const Ray &ray, real_t tMax) {
00105    ASSERT(m_mesh);
00106    
00107    // TODO: creating a new Ray here is rather inefficient...
00108    Point3  P;
00109    Vector3 D;
00110    _transformRayWorldToObj(ray, P, D);
00111    
00112    return m_mesh->intersects(Ray(P, D), tMax);
00113 }
00114 
00115 real_t Blob::evaluate(const Point3 &pt) const {
00116    real_t charge = 0;
00117    
00118    FOREACH(MetaObjectListConstIter, m_metaObjects, iter) {
00119       const MetaObject *meta = (*iter);
00120       
00121       const real_t curCharge = meta->evaluate(pt);
00122       if (!meta->isNegative())
00123          charge += curCharge;
00124       else charge -= curCharge;
00125    }
00126    
00127    return charge;
00128 }
00129 
00130 AABB Blob::getAABB() const {
00131    return m_aabb;
00132 }
00133 
00134 void Blob::_getUV(SurfacePoint &pt) const {
00135    NYI(); // TODO / or just defer to Mesh (current)
00136 }
00137 
00138 void Blob::_getGeometricNormal(SurfacePoint &pt) const {
00139    NYI(); // TODO / or just defer to Mesh (current)
00140 }
00141 

Generated on 28 Feb 2009 for Milton by doxygen 1.5.6