fshake3d
0.0.1
FreeformDensity3DSurfaceEditor
|
00001 #ifndef FSHAKE3D_FunctionMixer_hpp 00002 #define FSHAKE3D_FunctionMixer_hpp 00003 00004 #include "scene_ElevationGrid.hpp" 00005 #include "math.hpp" 00006 #include "opengl.hpp" 00007 #include "boost/math/distributions/normal.hpp" 00008 #include <map> 00009 #include <fstream> 00010 #include "scene_Slider.hpp" 00011 #include "scene_Plot1D.hpp" 00012 00013 class IFunction1D 00014 { 00015 public: 00016 virtual double compute(double x) = 0; 00017 }; 00018 00019 /* 00020 template<typename T, typename F> 00021 struct DFun : public IFunction1D 00022 { 00023 DFun(const F& f) : mFunction(f) { } 00024 template<typename A> 00025 double operator () (T x) const { mFunction(x); } 00026 F mFunction; 00027 }; 00028 00029 DFun<normal> gDefaultNormalFunc(); 00030 */ 00031 00032 class NormalDistribution : public IFunction1D 00033 { 00034 public: 00035 virtual double compute(double x) 00036 { 00037 return pdf( mDistribution, x); 00038 } 00039 void setMean(double mean) 00040 { 00041 mDistribution = boost::math::normal( mean, mDistribution.standard_deviation() ); 00042 } 00043 void setSD(double sd) 00044 { 00045 mDistribution = boost::math::normal( mDistribution.mean(), sd ); 00046 } 00047 double getMean() const 00048 { 00049 return mDistribution.mean(); 00050 } 00051 double getSD() const 00052 { 00053 return mDistribution.standard_deviation(); 00054 } 00055 private: 00056 boost::math::normal mDistribution; 00057 }; 00058 00059 class HotSpot 00060 { 00061 public: 00062 HotSpot(double xmean, double ymean, double xsd=0.6, double ysd=0.6, double alpha=0.0) 00063 : mNx(xmean,xsd), mNy(ymean,ysd), mAlpha(alpha) 00064 { 00065 } 00066 double compute(double x, double y) const 00067 { 00068 return pdf( mNx, x) * pdf( mNy, y) * mAlpha; 00069 } 00070 double computeBase(double x, double y) const 00071 { 00072 return pdf( mNx, x) * pdf( mNy, y); 00073 } 00074 double computeX(double x) const 00075 { 00076 return pdf( mNx, x); 00077 } 00078 double computeY(double y) const 00079 { 00080 return pdf( mNy, y); 00081 } 00082 void setAlpha(double a) 00083 { 00084 mAlpha = a; 00085 } 00086 double getAlpha() const 00087 { 00088 return mAlpha; 00089 } 00090 double getXSD() const 00091 { 00092 return mNx.standard_deviation(); 00093 } 00094 double getXMean() const 00095 { 00096 return mNx.mean(); 00097 } 00098 double getYSD() const 00099 { 00100 return mNy.standard_deviation(); 00101 } 00102 double getYMean() const 00103 { 00104 return mNy.mean(); 00105 } 00106 void setXSD(double xsd) 00107 { 00108 mNx = boost::math::normal( mNx.mean(), xsd ); 00109 } 00110 void setYSD(double ysd) 00111 { 00112 mNy = boost::math::normal( mNy.mean(), ysd ); 00113 } 00114 private: 00115 boost::math::normal mNx; 00116 boost::math::normal mNy; 00117 double mAlpha; 00118 }; 00119 00120 // using Point2d as key type for maps: 00121 template<> struct std::less<Point2d> : public std::binary_function<Point2d, Point2d, bool> 00122 { // functor for operator< 00123 bool operator()(const Point2d& l, const Point2d& r) const 00124 { // apply operator< to operands 00125 if ( l[0] == r[0] ) 00126 return l[1] < r[1]; 00127 return l[0] < r[0]; 00128 } 00129 }; 00130 00131 enum Layers 00132 { 00133 LAYER_NORMALS 00134 , LAYER_GRID 00135 , LAYER_CONTROLPOINTS 00136 , LAYER_SURFACE 00137 , LAYER_HOTSPOTS 00138 // , LAYER_CONTROLPOINTS_POINTS 00139 }; 00140 00141 class FunctionMixer : public Node, public Shape, public Control3D 00142 { 00143 public: 00144 // constructor: 00145 FunctionMixer(); 00146 00147 // model: 00148 void setElevationGrid(ElevationGrid* pElevationGrid); 00149 // HotSpot* getHotSpotAtGridIndex(int x, int y); 00150 HotSpot* getHotSpotAtPoint2d(const Point2d& p); 00151 void addHotSpot(HotSpot* hs); 00152 void removeHotSpot(HotSpot* hs); 00153 void clear(); 00154 double mDefaultXSD; 00155 double mDefaultYSD; 00156 double mDefaultAlpha; 00157 size_t getHotSpotCount() { return mHotSpots.size(); } 00158 HotSpot& getHotSpotAtIndex(size_t index) { return *( mHotSpots[index] ); } 00159 00160 // elevation computation: 00161 double computeAt(double x, double y); 00162 double computeAtWithout(double x, double y, HotSpot* pHotSpot); 00163 00164 // HotSpot control: 00165 // void selectHotSpot(int x, int y); 00166 void selectHotSpot(const Point2d& p); 00167 void updateHotSpotZ(double z); 00168 void removeSelected(); 00169 void setPointSize(double pointsize); 00170 // X SD control: 00171 void setXSD(double xsd); 00172 void setYSD(double ysd); 00173 // user input: 00174 bool select(const Rayd& r, SceneView& view); 00175 bool drag(const Rayd& r, SceneView& view); 00176 void unselect(); 00177 // display: 00178 void toggleLayer(int layerid) { mLayerMask ^= (1<<layerid); } 00179 bool isLayerEnabled(int layerid) const { return ( mLayerMask & (1<<layerid) ) ? true : false; } 00180 void display(); 00181 00182 void updateElevationGrid(); 00183 private: 00184 void initControls(); 00185 void displaySurface(); 00186 void displayControls(); 00187 void displayFunctionPlots(); 00188 void displayAlpha(); 00189 00190 // compute Elevation z-values: 00191 00192 // link: 00193 00194 ElevationGrid* mpElevationGrid; 00195 00196 // model: 00197 00198 std::vector<HotSpot*> mHotSpots; 00199 // std::map< std::pair<int,int>, HotSpot* > mHotSpotMap; 00200 std::map< Point2d, HotSpot* > mHotSpotMap; 00201 00202 // view: 00203 00204 // OpenGL display list for control point geometry (glutSphere) 00205 int mList; 00206 00207 // OpenGL color map 1D texture 00208 GLuint mTex; 00209 // Control point size (propagated to controls) 00210 double mPointSize; 00211 // notify to update ControlPoint geometry. 00212 bool mPointSizeChanged; 00213 unsigned int mLayerMask; 00214 00215 // control: 00216 00217 HotSpot* mSelectHotSpot; 00218 double mSelectHotSpotZ; 00219 double mSelectBaseZ; 00220 Point3d mSelectPoint; 00221 00222 Slider mControlZ; 00223 Slider mControlXSD; 00224 Slider mControlYSD; 00225 Plot1D mPlotX; 00226 Plot1D mPlotY; 00227 }; 00228 00229 00230 #endif