00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "lux.h"
00024 #include "texture.h"
00025 #include "paramset.h"
00026 #include "error.h"
00027 #include "blender_texlib.h"
00028
00029 namespace lux {
00030
00031 template <class T>
00032 class BlenderVoronoiTexture3D : public Texture<T> {
00033 public:
00034
00035
00036 virtual ~BlenderVoronoiTexture3D() {
00037 delete mapping;
00038 }
00039
00040 BlenderVoronoiTexture3D(
00041 boost::shared_ptr<Texture<T> > c1,
00042 boost::shared_ptr<Texture<T> > c2,
00043 short colType,
00044 short distMetric,
00045 float mExp,
00046 float ns_outscale,
00047 float noiseSize,
00048 float nabla,
00049 float w1,
00050 float w2,
00051 float w3,
00052 float w4,
00053 float bright,
00054 float contrast,
00055 TextureMapping3D *map) : mapping(map) {
00056 tex.type = TEX_VORONOI;
00057
00058 tex.vn_coltype = colType;
00059 tex.vn_distm = distMetric;
00060
00061 tex.vn_mexp = mExp;
00062 tex.ns_outscale = ns_outscale;
00063 tex.noisesize = noiseSize;
00064 tex.nabla = nabla;
00065
00066 tex.vn_w1 = w1;
00067 tex.vn_w2 = w2;
00068 tex.vn_w3 = w3;
00069 tex.vn_w4 = w4;
00070 tex.bright = bright;
00071 tex.contrast = contrast;
00072 tex.rfac = 1.0f;
00073 tex.gfac = 1.0f;
00074 tex.bfac = 1.0f;
00075
00076 tex1 = c1;
00077 tex2 = c2;
00078 }
00079
00080 virtual T Evaluate(const TsPack *tspack, const DifferentialGeometry &dg) const {
00081 Vector dpdx, dpdy;
00082 Point P = mapping->Map(dg, &dpdx, &dpdy);
00083
00084 blender::TexResult texres;
00085 int resultType = multitex(&tex, &P.x, &texres);
00086
00087 if((resultType & TEX_RGB) && (!(resultType & TEX_INT)))
00088 texres.tin = (0.35 * texres.tr + 0.45 * texres.tg
00089 + 0.2 * texres.tb);
00090 else if((resultType & TEX_INT) && (!(resultType & TEX_RGB)))
00091 texres.tr = texres.tg = texres.tb = texres.tin;
00092
00093 T t1 = tex1->Evaluate(tspack, dg), t2 = tex2->Evaluate(tspack, dg);
00094 return (1.f - texres.tin) * t1 + texres.tin * t2;
00095 }
00096 virtual void SetPower(float power, float area) {
00097
00098 tex1->SetPower(power, area);
00099 tex2->SetPower(power, area);
00100 }
00101 virtual void SetIlluminant() {
00102
00103 tex1->SetIlluminant();
00104 tex2->SetIlluminant();
00105 }
00106 static Texture<float> *CreateFloatTexture(const Transform &tex2world, const TextureParams &tp);
00107 static Texture<SWCSpectrum> *CreateSWCSpectrumTexture(const Transform &tex2world, const TextureParams &tp);
00108 private:
00109
00110
00111 TextureMapping3D *mapping;
00112 boost::shared_ptr<Texture<T> > tex1, tex2;
00113 blender::Tex tex;
00114 };
00115
00116 template <class T> Texture<float> *BlenderVoronoiTexture3D<T>::CreateFloatTexture(
00117 const Transform &tex2world,
00118 const TextureParams &tp) {
00119
00120 TextureMapping3D *map = new IdentityMapping3D(tex2world);
00121
00122 IdentityMapping3D *imap = (IdentityMapping3D*) map;
00123 imap->Apply3DTextureMappingOptions(tp);
00124
00125 boost::shared_ptr<Texture<float> > tex1 = tp.GetFloatTexture("tex1", 1.f);
00126 boost::shared_ptr<Texture<float> > tex2 = tp.GetFloatTexture("tex2", 0.f);
00127
00128
00129 short distType = TEX_DISTANCE;
00130 string sDistType = tp.FindString("distmetric");
00131 if ((sDistType == "actual_distance") || (sDistType == ""))
00132 distType = TEX_DISTANCE;
00133 else if (sDistType == "distance_squared")
00134 distType = TEX_DISTANCE_SQUARED;
00135 else if (sDistType == "manhattan")
00136 distType = TEX_MANHATTAN;
00137 else if (sDistType == "chebychev")
00138 distType = TEX_CHEBYCHEV;
00139 else if (sDistType == "minkovsky_half")
00140 distType = TEX_MINKOVSKY_HALF;
00141 else if (sDistType == "minkovsky_four")
00142 distType = TEX_MINKOVSKY_FOUR;
00143 else if (sDistType == "minkovsky")
00144 distType = TEX_MINKOVSKY;
00145 else {
00146 std::stringstream ss;
00147 ss << "Unknown distance metric '" << sDistType << "'";
00148 luxError(LUX_BADTOKEN, LUX_ERROR, ss.str().c_str());
00149 }
00150
00151 return new BlenderVoronoiTexture3D<float>(
00152 tex1,
00153 tex2,
00154 tp.FindInt("coltype", 0),
00155 distType,
00156 tp.FindFloat("minkovsky_exp", 2.5f),
00157 tp.FindFloat("outscale", 1.0f),
00158 tp.FindFloat("noisesize", 0.25f),
00159 tp.FindFloat("nabla", 0.025f),
00160 tp.FindFloat("w1", 1.0f),
00161 tp.FindFloat("w2", 0.0f),
00162 tp.FindFloat("w3", 0.0f),
00163 tp.FindFloat("w4", 0.0f),
00164 tp.FindFloat("bright", 1.0f),
00165 tp.FindFloat("contrast", 1.0f),
00166 map);
00167 }
00168
00169 template <class T> Texture<SWCSpectrum> *BlenderVoronoiTexture3D<T>::CreateSWCSpectrumTexture(
00170 const Transform &tex2world,
00171 const TextureParams &tp) {
00172
00173 TextureMapping3D *map = new IdentityMapping3D(tex2world);
00174
00175 IdentityMapping3D *imap = (IdentityMapping3D*) map;
00176 imap->Apply3DTextureMappingOptions(tp);
00177
00178 boost::shared_ptr<Texture<SWCSpectrum> > tex1 = tp.GetSWCSpectrumTexture("tex1", 1.f);
00179 boost::shared_ptr<Texture<SWCSpectrum> > tex2 = tp.GetSWCSpectrumTexture("tex2", 0.f);
00180
00181
00182 short distType = TEX_DISTANCE;
00183 string sDistType = tp.FindString("distmetric");
00184 if ((sDistType == "actual_distance") || (sDistType == ""))
00185 distType = TEX_DISTANCE;
00186 else if (sDistType == "distance_squared")
00187 distType = TEX_DISTANCE_SQUARED;
00188 else if (sDistType == "manhattan")
00189 distType = TEX_MANHATTAN;
00190 else if (sDistType == "chebychev")
00191 distType = TEX_CHEBYCHEV;
00192 else if (sDistType == "minkovsky_half")
00193 distType = TEX_MINKOVSKY_HALF;
00194 else if (sDistType == "minkovsky_four")
00195 distType = TEX_MINKOVSKY_FOUR;
00196 else if (sDistType == "minkovsky")
00197 distType = TEX_MINKOVSKY;
00198 else {
00199 std::stringstream ss;
00200 ss << "Unknown distance metric '" << sDistType << "'";
00201 luxError(LUX_BADTOKEN, LUX_ERROR, ss.str().c_str());
00202 }
00203
00204 return new BlenderVoronoiTexture3D<SWCSpectrum>(
00205 tex1,
00206 tex2,
00207 tp.FindInt("coltype", 0),
00208 distType,
00209 tp.FindFloat("minkovsky_exp", 2.5f),
00210 tp.FindFloat("outscale", 1.0f),
00211 tp.FindFloat("noisesize", 0.25f),
00212 tp.FindFloat("nabla", 0.025f),
00213 tp.FindFloat("w1", 1.0f),
00214 tp.FindFloat("w2", 0.0f),
00215 tp.FindFloat("w3", 0.0f),
00216 tp.FindFloat("w4", 0.0f),
00217 tp.FindFloat("bright", 1.0f),
00218 tp.FindFloat("contrast", 1.0f),
00219 map);
00220 }
00221
00222 }