Visualization Library v1.0.3A lightweight C++ OpenGL middleware for 2D/3D graphics |
[Download] [Tutorials] [All Classes] [Grouped Classes] |
00001 /**************************************************************************************/ 00002 /* */ 00003 /* Visualization Library */ 00004 /* http://visualizationlibrary.org */ 00005 /* */ 00006 /* Copyright (c) 2005-2010, Michele Bosi */ 00007 /* All rights reserved. */ 00008 /* */ 00009 /* Redistribution and use in source and binary forms, with or without modification, */ 00010 /* are permitted provided that the following conditions are met: */ 00011 /* */ 00012 /* - Redistributions of source code must retain the above copyright notice, this */ 00013 /* list of conditions and the following disclaimer. */ 00014 /* */ 00015 /* - Redistributions in binary form must reproduce the above copyright notice, this */ 00016 /* list of conditions and the following disclaimer in the documentation and/or */ 00017 /* other materials provided with the distribution. */ 00018 /* */ 00019 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND */ 00020 /* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED */ 00021 /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */ 00022 /* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR */ 00023 /* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES */ 00024 /* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */ 00025 /* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON */ 00026 /* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ 00027 /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */ 00028 /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 00029 /* */ 00030 /**************************************************************************************/ 00031 00032 #include <vlVolume/VolumePlot.hpp> 00033 #include <vlGraphics/Light.hpp> 00034 #include <vlGraphics/SceneManager.hpp> 00035 #include <vlGraphics/FontManager.hpp> 00036 #include <vlCore/VisualizationLibrary.hpp> 00037 #include <vlGraphics/GeometryPrimitives.hpp> 00038 00039 using namespace vl; 00040 00069 //----------------------------------------------------------------------------- 00070 // VolumePlot 00071 //----------------------------------------------------------------------------- 00072 VolumePlot::VolumePlot() 00073 { 00074 VL_DEBUG_SET_OBJECT_NAME() 00075 mActorTreeMulti = new ActorTree; 00076 mPlotTransform = new Transform; 00077 mIsosurfaceActor = new Actor; 00078 mIsosurfaceGeometry = new Geometry; 00079 mIsosurfaceEffect = new Effect; 00080 mBoxEffect = new Effect; 00081 mTextTemplate = new Text; 00082 mSamplingResolution = ivec3(64,64,64); 00083 mLabelFormat = "(%.2n %.2n %.2n)"; 00084 mLabelFont = defFontManager()->acquireFont("/font/bitstream-vera/VeraMono.ttf", 8); 00085 mMinCorner = fvec3(-1,-1,-1); 00086 mMaxCorner = fvec3(+1,+1,+1); 00087 00088 // defaults 00089 00090 mIsosurfaceEffect->shader()->setRenderState( new Light, 0 ); 00091 mIsosurfaceEffect->shader()->gocMaterial()->setFrontDiffuse(red); 00092 mIsosurfaceEffect->shader()->gocMaterial()->setBackDiffuse(green); 00093 mIsosurfaceEffect->shader()->enable(EN_LIGHTING); 00094 mIsosurfaceEffect->shader()->enable(EN_DEPTH_TEST); 00095 mIsosurfaceEffect->shader()->gocLightModel()->setTwoSide(true); 00096 00097 mBoxEffect->shader()->gocPolygonMode()->set(PM_LINE, PM_LINE); 00098 mBoxEffect->shader()->enable(EN_DEPTH_TEST); 00099 00100 textTemplate()->setColor(white); 00101 } 00102 //----------------------------------------------------------------------------- 00107 void VolumePlot::compute(const Function& func, float threshold) 00108 { 00109 actorTreeMulti()->actors()->clear(); 00110 mActors.clear(); 00111 00112 // volume_box outline 00113 ref<Geometry> box_outline = makeBox(AABB((vec3)minCorner(),(vec3)maxCorner())); 00114 00115 // setup isosurface and actors 00116 00117 MarchingCubes mc; 00118 00119 mIsosurfaceGeometry->setVertexArray(mc.mVertsArray.get()); 00120 mIsosurfaceGeometry->setNormalArray(mc.mNormsArray.get()); 00121 mIsosurfaceGeometry->drawCalls()->clear(); 00122 mIsosurfaceGeometry->drawCalls()->push_back(mc.mDrawElements.get()); 00123 00124 mIsosurfaceActor->setLod(0, mIsosurfaceGeometry.get()); 00125 mIsosurfaceActor->setEffect(mIsosurfaceEffect.get()); 00126 mIsosurfaceActor->setTransform(mPlotTransform.get()); 00127 mActors.push_back(mIsosurfaceActor.get()); 00128 mActors.push_back( new Actor(box_outline.get(),mBoxEffect.get(),mPlotTransform.get()) ); 00129 00130 ref<Volume> volume = new Volume; 00131 volume->setup( NULL, false, false, minCorner(), maxCorner(), mSamplingResolution ); 00132 00133 mc.volumeInfo()->push_back( new VolumeInfo( volume.get(), threshold ) ); 00134 00135 evaluateFunction(volume->values(), minCorner(), maxCorner(), func); 00136 00137 // generate vertices and polygons 00138 mc.run(false); 00139 00140 // setup labels 00141 setupLabels(labelFormat(), minCorner(), maxCorner(), labelFont(), mPlotTransform.get()); 00142 00143 for(unsigned i=0; i<mActors.size(); ++i) 00144 actorTreeMulti()->actors()->push_back(mActors[i].get()); 00145 } 00146 //----------------------------------------------------------------------------- 00147 void VolumePlot::setupLabels(const String& format, const fvec3& min_corner, const fvec3& max_corner, Font* font, Transform* root_tr) 00148 { 00149 ref< Effect > text_fx = new Effect; 00150 text_fx->shader()->enable(EN_BLEND); 00151 text_fx->shader()->enable(EN_DEPTH_TEST); 00152 00153 float coords[][3] = 00154 { 00155 {min_corner.x(), min_corner.y(), min_corner.z()}, 00156 {max_corner.x(), min_corner.y(), min_corner.z()}, 00157 {max_corner.x(), max_corner.y(), min_corner.z()}, 00158 {min_corner.x(), max_corner.y(), min_corner.z()}, 00159 {min_corner.x(), min_corner.y(), max_corner.z()}, 00160 {max_corner.x(), min_corner.y(), max_corner.z()}, 00161 {max_corner.x(), max_corner.y(), max_corner.z()}, 00162 {min_corner.x(), max_corner.y(), max_corner.z()} 00163 }; 00164 00165 String coord_label[] = 00166 { 00167 Say(format) << min_corner.x() << min_corner.y() << min_corner.z(), 00168 Say(format) << max_corner.x() << min_corner.y() << min_corner.z(), 00169 Say(format) << max_corner.x() << max_corner.y() << min_corner.z(), 00170 Say(format) << min_corner.x() << max_corner.y() << min_corner.z(), 00171 Say(format) << min_corner.x() << min_corner.y() << max_corner.z(), 00172 Say(format) << max_corner.x() << min_corner.y() << max_corner.z(), 00173 Say(format) << max_corner.x() << max_corner.y() << max_corner.z(), 00174 Say(format) << min_corner.x() << max_corner.y() << max_corner.z() 00175 }; 00176 00177 for(int i=0; i<8; ++i) 00178 { 00179 ref<Text> text = new Text; 00180 text->setDisplayListEnabled(false); 00181 text->setBufferObjectEnabled(false); 00182 text->setFont( font ); 00183 text->setAlignment(AlignHCenter| AlignVCenter); 00184 text->setText(coord_label[i]); 00185 // template parameters 00186 text->setColor( textTemplate()->color() ); 00187 text->setBorderColor( textTemplate()->borderColor() ); 00188 text->setBorderEnabled( textTemplate()->borderEnabled() ); 00189 text->setBackgroundColor( textTemplate()->backgroundColor() ); 00190 text->setBackgroundEnabled( textTemplate()->backgroundEnabled() ); 00191 text->setMargin( textTemplate()->margin() ); 00192 text->setOutlineColor( textTemplate()->outlineColor() ); 00193 text->setOutlineEnabled( textTemplate()->outlineEnabled() ); 00194 text->setShadowColor( textTemplate()->shadowColor() ); 00195 text->setShadowEnabled( textTemplate()->shadowEnabled() ); 00196 text->setShadowVector( textTemplate()->shadowVector() ); 00197 text->setMatrix( textTemplate()->matrix() ); 00198 00199 ref<Actor> text_a = new Actor( text.get(), text_fx.get(), new Transform ); 00200 text_a->transform()->setLocalMatrix( mat4::getTranslation(coords[i][0],coords[i][1],coords[i][2]) ); 00201 if (root_tr) 00202 root_tr->addChild( text_a->transform() ); 00203 text_a->transform()->computeWorldMatrix(); 00204 00205 mActors.push_back( text_a.get() ); 00206 } 00207 } 00208 //----------------------------------------------------------------------------- 00209 void VolumePlot::evaluateFunction(float* scalar, const fvec3& min_corner, const fvec3& max_corner, const Function& func) 00210 { 00211 fvec3 v; 00212 int w = mSamplingResolution.x(); 00213 int h = mSamplingResolution.y(); 00214 int d = mSamplingResolution.z(); 00215 for(int z=0; z<d; ++z) 00216 { 00217 float tz = (float)z/(d-1); 00218 v.z() = min_corner.z()*(1.0f-tz) + max_corner.z()*tz; 00219 for(int y=0; y<h; ++y) 00220 { 00221 float ty = (float)y/(h-1); 00222 v.y() = min_corner.y()*(1.0f-ty) + max_corner.y()*ty; 00223 for(int x=0; x<w; ++x) 00224 { 00225 float tx = (float)x/(w-1); 00226 v.x() = min_corner.x()*(1.0f-tx) + max_corner.x()*tx; 00227 // evaluate function 00228 scalar[x+y*w+z*w*h] = func(v.x(),v.y(),v.z()); 00229 } 00230 } 00231 } 00232 } 00233 //-----------------------------------------------------------------------------