00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
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
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
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
00113 ref<Geometry> box_outline = makeBox(AABB((vec3)minCorner(),(vec3)maxCorner()));
00114 box_outline->setColor(white);
00115
00116
00117
00118 MarchingCubes mc;
00119
00120 mIsosurfaceGeometry->setVertexArray(mc.mVertsArray.get());
00121 mIsosurfaceGeometry->setNormalArray(mc.mNormsArray.get());
00122 mIsosurfaceGeometry->drawCalls()->clear();
00123 mIsosurfaceGeometry->drawCalls()->push_back(mc.mDrawElements.get());
00124
00125 mIsosurfaceActor->setLod(0, mIsosurfaceGeometry.get());
00126 mIsosurfaceActor->setEffect(mIsosurfaceEffect.get());
00127 mIsosurfaceActor->setTransform(mPlotTransform.get());
00128 mActors.push_back(mIsosurfaceActor.get());
00129 mActors.push_back( new Actor(box_outline.get(),mBoxEffect.get(),mPlotTransform.get()) );
00130
00131 ref<Volume> volume = new Volume;
00132 volume->setup( NULL, false, false, minCorner(), maxCorner(), mSamplingResolution );
00133
00134 mc.volumeInfo()->push_back( new VolumeInfo( volume.get(), threshold ) );
00135
00136 evaluateFunction(volume->values(), minCorner(), maxCorner(), func);
00137
00138
00139 mc.run(false);
00140
00141
00142 setupLabels(labelFormat(), minCorner(), maxCorner(), labelFont(), mPlotTransform.get());
00143
00144 for(unsigned i=0; i<mActors.size(); ++i)
00145 actorTreeMulti()->actors()->push_back(mActors[i].get());
00146 }
00147
00148 void VolumePlot::setupLabels(const String& format, const fvec3& min_corner, const fvec3& max_corner, Font* font, Transform* root_tr)
00149 {
00150 ref< Effect > text_fx = new Effect;
00151 text_fx->shader()->enable(EN_BLEND);
00152 text_fx->shader()->enable(EN_DEPTH_TEST);
00153
00154 float coords[][3] =
00155 {
00156 {min_corner.x(), min_corner.y(), min_corner.z()},
00157 {max_corner.x(), min_corner.y(), min_corner.z()},
00158 {max_corner.x(), max_corner.y(), min_corner.z()},
00159 {min_corner.x(), max_corner.y(), min_corner.z()},
00160 {min_corner.x(), min_corner.y(), max_corner.z()},
00161 {max_corner.x(), min_corner.y(), max_corner.z()},
00162 {max_corner.x(), max_corner.y(), max_corner.z()},
00163 {min_corner.x(), max_corner.y(), max_corner.z()}
00164 };
00165
00166 String coord_label[] =
00167 {
00168 Say(format) << min_corner.x() << min_corner.y() << min_corner.z(),
00169 Say(format) << max_corner.x() << min_corner.y() << min_corner.z(),
00170 Say(format) << max_corner.x() << max_corner.y() << min_corner.z(),
00171 Say(format) << min_corner.x() << max_corner.y() << min_corner.z(),
00172 Say(format) << min_corner.x() << min_corner.y() << max_corner.z(),
00173 Say(format) << max_corner.x() << min_corner.y() << max_corner.z(),
00174 Say(format) << max_corner.x() << max_corner.y() << max_corner.z(),
00175 Say(format) << min_corner.x() << max_corner.y() << max_corner.z()
00176 };
00177
00178 for(int i=0; i<8; ++i)
00179 {
00180 ref<Text> text = new Text;
00181 text->setDisplayListEnabled(false);
00182 text->setVBOEnabled(false);
00183 text->setFont( font );
00184 text->setAlignment(AlignHCenter| AlignVCenter);
00185 text->setText(coord_label[i]);
00186
00187 text->setColor( textTemplate()->color() );
00188 text->setBorderColor( textTemplate()->borderColor() );
00189 text->setBorderEnabled( textTemplate()->borderEnabled() );
00190 text->setBackgroundColor( textTemplate()->backgroundColor() );
00191 text->setBackgroundEnabled( textTemplate()->backgroundEnabled() );
00192 text->setMargin( textTemplate()->margin() );
00193 text->setOutlineColor( textTemplate()->outlineColor() );
00194 text->setOutlineEnabled( textTemplate()->outlineEnabled() );
00195 text->setShadowColor( textTemplate()->shadowColor() );
00196 text->setShadowEnabled( textTemplate()->shadowEnabled() );
00197 text->setShadowVector( textTemplate()->shadowVector() );
00198 text->setMatrix( textTemplate()->matrix() );
00199
00200 ref<Actor> text_a = new Actor( text.get(), text_fx.get(), new Transform );
00201 text_a->transform()->setLocalMatrix( mat4::getTranslation(coords[i][0],coords[i][1],coords[i][2]) );
00202 if (root_tr)
00203 root_tr->addChild( text_a->transform() );
00204 text_a->transform()->computeWorldMatrix();
00205
00206 mActors.push_back( text_a.get() );
00207 }
00208 }
00209
00210 void VolumePlot::evaluateFunction(float* scalar, const fvec3& min_corner, const fvec3& max_corner, const Function& func)
00211 {
00212 fvec3 v;
00213 int w = mSamplingResolution.x();
00214 int h = mSamplingResolution.y();
00215 int d = mSamplingResolution.z();
00216 for(int z=0; z<d; ++z)
00217 {
00218 float tz = (float)z/(d-1);
00219 v.z() = min_corner.z()*(1.0f-tz) + max_corner.z()*tz;
00220 for(int y=0; y<h; ++y)
00221 {
00222 float ty = (float)y/(h-1);
00223 v.y() = min_corner.y()*(1.0f-ty) + max_corner.y()*ty;
00224 for(int x=0; x<w; ++x)
00225 {
00226 float tx = (float)x/(w-1);
00227 v.x() = min_corner.x()*(1.0f-tx) + max_corner.x()*tx;
00228
00229 scalar[x+y*w+z*w*h] = func(v.x(),v.y(),v.z());
00230 }
00231 }
00232 }
00233 }
00234