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 #include "paramset.h"
00026
00027 ParamSet::ParamSet(const ParamSet &p2) {
00028 *this = p2;
00029 }
00030 ParamSet &ParamSet::operator=(const ParamSet &p2) {
00031 if (&p2 != this) {
00032 Clear();
00033 u_int i;
00034 for (i = 0; i < p2.ints.size(); ++i)
00035 ints.push_back(p2.ints[i]->Clone());
00036 for (i = 0; i < p2.bools.size(); ++i)
00037 bools.push_back(p2.bools[i]->Clone());
00038 for (i = 0; i < p2.floats.size(); ++i)
00039 floats.push_back(p2.floats[i]->Clone());
00040 for (i = 0; i < p2.points.size(); ++i)
00041 points.push_back(p2.points[i]->Clone());
00042 for (i = 0; i < p2.vectors.size(); ++i)
00043 vectors.push_back(p2.vectors[i]->Clone());
00044 for (i = 0; i < p2.normals.size(); ++i)
00045 normals.push_back(p2.normals[i]->Clone());
00046 for (i = 0; i < p2.spectra.size(); ++i)
00047 spectra.push_back(p2.spectra[i]->Clone());
00048 for (i = 0; i < p2.strings.size(); ++i)
00049 strings.push_back(p2.strings[i]->Clone());
00050 for (i = 0; i < p2.textures.size(); ++i)
00051 textures.push_back(p2.textures[i]->Clone());
00052 }
00053 return *this;
00054 }
00055 void ParamSet::AddFloat(const string &name,
00056 const float *data,
00057 int nItems) {
00058 EraseFloat(name);
00059 floats.push_back(new ParamSetItem<float>(name,
00060 data,
00061 nItems));
00062 }
00063 void ParamSet::AddInt(const string &name, const int *data, int nItems) {
00064 EraseInt(name);
00065 ADD_PARAM_TYPE(int, ints);
00066 }
00067 void ParamSet::AddBool(const string &name, const bool *data, int nItems) {
00068 EraseInt(name);
00069 ADD_PARAM_TYPE(bool, bools);
00070 }
00071 void ParamSet::AddPoint(const string &name, const Point *data, int nItems) {
00072 ErasePoint(name);
00073 ADD_PARAM_TYPE(Point, points);
00074 }
00075 void ParamSet::AddVector(const string &name, const Vector *data, int nItems) {
00076 EraseVector(name);
00077 ADD_PARAM_TYPE(Vector, vectors);
00078 }
00079 void ParamSet::AddNormal(const string &name, const Normal *data, int nItems) {
00080 EraseNormal(name);
00081 ADD_PARAM_TYPE(Normal, normals);
00082 }
00083 void ParamSet::AddSpectrum(const string &name, const Spectrum *data, int nItems) {
00084 EraseSpectrum(name);
00085 ADD_PARAM_TYPE(Spectrum, spectra);
00086 }
00087 void ParamSet::AddString(const string &name, const string *data, int nItems) {
00088 EraseString(name);
00089 ADD_PARAM_TYPE(string, strings);
00090 }
00091 void ParamSet::AddTexture(const string &name, const string &value) {
00092 EraseTexture(name);
00093 textures.push_back(new ParamSetItem<string>(name, (string *)&value, 1));
00094 }
00095 bool ParamSet::EraseInt(const string &n) {
00096 for (u_int i = 0; i < ints.size(); ++i)
00097 if (ints[i]->name == n) {
00098 delete ints[i];
00099 ints.erase(ints.begin() + i);
00100 return true;
00101 }
00102 return false;
00103 }
00104 bool ParamSet::EraseBool(const string &n) {
00105 for (u_int i = 0; i < bools.size(); ++i)
00106 if (bools[i]->name == n) {
00107 delete bools[i];
00108 bools.erase(bools.begin() + i);
00109 return true;
00110 }
00111 return false;
00112 }
00113 bool ParamSet::EraseFloat(const string &n) {
00114 for (u_int i = 0; i < floats.size(); ++i)
00115 if (floats[i]->name == n) {
00116 delete floats[i];
00117 floats.erase(floats.begin() + i);
00118 return true;
00119 }
00120 return false;
00121 }
00122 bool ParamSet::ErasePoint(const string &n) {
00123 for (u_int i = 0; i < points.size(); ++i)
00124 if (points[i]->name == n) {
00125 delete points[i];
00126 points.erase(points.begin() + i);
00127 return true;
00128 }
00129 return false;
00130 }
00131 bool ParamSet::EraseVector(const string &n) {
00132 for (u_int i = 0; i < vectors.size(); ++i)
00133 if (vectors[i]->name == n) {
00134 delete vectors[i];
00135 vectors.erase(vectors.begin() + i);
00136 return true;
00137 }
00138 return false;
00139 }
00140 bool ParamSet::EraseNormal(const string &n) {
00141 for (u_int i = 0; i < normals.size(); ++i)
00142 if (normals[i]->name == n) {
00143 delete normals[i];
00144 normals.erase(normals.begin() + i);
00145 return true;
00146 }
00147 return false;
00148 }
00149 bool ParamSet::EraseSpectrum(const string &n) {
00150 for (u_int i = 0; i < spectra.size(); ++i)
00151 if (spectra[i]->name == n) {
00152 delete spectra[i];
00153 spectra.erase(spectra.begin() + i);
00154 return true;
00155 }
00156 return false;
00157 }
00158 bool ParamSet::EraseString(const string &n) {
00159 for (u_int i = 0; i < strings.size(); ++i)
00160 if (strings[i]->name == n) {
00161 delete strings[i];
00162 strings.erase(strings.begin() + i);
00163 return true;
00164 }
00165 return false;
00166 }
00167 bool ParamSet::EraseTexture(const string &n) {
00168 for (u_int i = 0; i < textures.size(); ++i)
00169 if (textures[i]->name == n) {
00170 delete textures[i];
00171 textures.erase(textures.begin() + i);
00172 return true;
00173 }
00174 return false;
00175 }
00176 float ParamSet::FindOneFloat(const string &name,
00177 float d) const {
00178 for (u_int i = 0; i < floats.size(); ++i)
00179 if (floats[i]->name == name &&
00180 floats[i]->nItems == 1) {
00181 floats[i]->lookedUp = true;
00182 return *(floats[i]->data);
00183 }
00184 return d;
00185 }
00186 const float *ParamSet::FindFloat(const string &name,
00187 int *nItems) const {
00188 for (u_int i = 0; i < floats.size(); ++i)
00189 if (floats[i]->name == name) {
00190 *nItems = floats[i]->nItems;
00191 floats[i]->lookedUp = true;
00192 return floats[i]->data;
00193 }
00194 return NULL;
00195 }
00196 const int *ParamSet::FindInt(const string &name, int *nItems) const {
00197 LOOKUP_PTR(ints);
00198 }
00199 const bool *ParamSet::FindBool(const string &name, int *nItems) const {
00200 LOOKUP_PTR(bools);
00201 }
00202 int ParamSet::FindOneInt(const string &name, int d) const {
00203 LOOKUP_ONE(ints);
00204 }
00205 bool ParamSet::FindOneBool(const string &name, bool d) const {
00206 LOOKUP_ONE(bools);
00207 }
00208 const Point *ParamSet::FindPoint(const string &name, int *nItems) const {
00209 LOOKUP_PTR(points);
00210 }
00211 Point ParamSet::FindOnePoint(const string &name, const Point &d) const {
00212 LOOKUP_ONE(points);
00213 }
00214 const Vector *ParamSet::FindVector(const string &name, int *nItems) const {
00215 LOOKUP_PTR(vectors);
00216 }
00217 Vector ParamSet::FindOneVector(const string &name, const Vector &d) const {
00218 LOOKUP_ONE(vectors);
00219 }
00220 const Normal *ParamSet::FindNormal(const string &name, int *nItems) const {
00221 LOOKUP_PTR(normals);
00222 }
00223 Normal ParamSet::FindOneNormal(const string &name, const Normal &d) const {
00224 LOOKUP_ONE(normals);
00225 }
00226 const Spectrum *ParamSet::FindSpectrum(const string &name, int *nItems) const {
00227 LOOKUP_PTR(spectra);
00228 }
00229 Spectrum ParamSet::FindOneSpectrum(const string &name, const Spectrum &d) const {
00230 LOOKUP_ONE(spectra);
00231 }
00232 const string *ParamSet::FindString(const string &name, int *nItems) const {
00233 LOOKUP_PTR(strings);
00234 }
00235 string ParamSet::FindOneString(const string &name, const string &d) const {
00236 LOOKUP_ONE(strings);
00237 }
00238 string ParamSet::FindTexture(const string &name) const {
00239 string d = "";
00240 LOOKUP_ONE(textures);
00241 }
00242 void ParamSet::ReportUnused() const {
00243 #define CHECK_UNUSED(v) \
00244 for (i = 0; i < (v).size(); ++i) \
00245 if (!(v)[i]->lookedUp) \
00246 Warning("Parameter \"%s\" not used", \
00247 (v)[i]->name.c_str())
00248 u_int i;
00249 CHECK_UNUSED(ints); CHECK_UNUSED(bools);
00250 CHECK_UNUSED(floats); CHECK_UNUSED(points);
00251 CHECK_UNUSED(vectors); CHECK_UNUSED(normals);
00252 CHECK_UNUSED(spectra); CHECK_UNUSED(strings);
00253 CHECK_UNUSED(textures);
00254 }
00255 void ParamSet::Clear() {
00256 #define DEL_PARAMS(name) \
00257 for (u_int i = 0; i < (name).size(); ++i) \
00258 delete (name)[i]; \
00259 (name).erase((name).begin(), (name).end())
00260 DEL_PARAMS(ints); DEL_PARAMS(bools);
00261 DEL_PARAMS(floats); DEL_PARAMS(points);
00262 DEL_PARAMS(vectors); DEL_PARAMS(normals);
00263 DEL_PARAMS(spectra); DEL_PARAMS(strings);
00264 DEL_PARAMS(textures);
00265 #undef DEL_PARAMS
00266 }
00267 string ParamSet::ToString() const {
00268 string ret;
00269 u_int i;
00270 int j;
00271 string typeString;
00272 const int bufLen = 48*1024*1024;
00273 static char *buf = new char[bufLen];
00274 char *bufEnd = buf + bufLen;
00275 for (i = 0; i < ints.size(); ++i) {
00276 char *bufp = buf;
00277 *bufp = '\0';
00278 ParamSetItem<int> *item = ints[i];
00279 typeString = "integer ";
00280
00281 int nPrint = item->nItems;
00282 ret += string("\"");
00283 ret += typeString;
00284 ret += item->name;
00285 ret += string("\"");
00286 ret += string(" [");
00287 for (j = 0; j < nPrint; ++j)
00288 bufp += snprintf(bufp, bufEnd - bufp, "%d ", item->data[j]);
00289 ret += buf;
00290 ret += string("] ");
00291 }
00292 for (i = 0; i < bools.size(); ++i) {
00293 char *bufp = buf;
00294 *bufp = '\0';
00295 ParamSetItem<bool> *item = bools[i];
00296 typeString = "bool ";
00297
00298 int nPrint = item->nItems;
00299 ret += string("\"");
00300 ret += typeString;
00301 ret += item->name;
00302 ret += string("\"");
00303 ret += string(" [");
00304 for (j = 0; j < nPrint; ++j)
00305 bufp += snprintf(bufp, bufEnd - bufp, "\"%s\" ", item->data[j] ? "true" : "false");
00306 ret += buf;
00307 ret += string("] ");
00308 }
00309 for (i = 0; i < floats.size(); ++i) {
00310 char *bufp = buf;
00311 *bufp = '\0';
00312 ParamSetItem<float> *item = floats[i];
00313 typeString = "float ";
00314
00315 int nPrint = item->nItems;
00316 ret += string("\"");
00317 ret += typeString;
00318 ret += item->name;
00319 ret += string("\"");
00320 ret += string(" [");
00321 for (j = 0; j < nPrint; ++j)
00322 bufp += snprintf(bufp, bufEnd - bufp, "%.8g ", item->data[j]);
00323 ret += buf;
00324 ret += string("] ");
00325 }
00326 for (i = 0; i < points.size(); ++i) {
00327 char *bufp = buf;
00328 *bufp = '\0';
00329 ParamSetItem<Point> *item = points[i];
00330 typeString = "point ";
00331
00332 int nPrint = item->nItems;
00333 ret += string("\"");
00334 ret += typeString;
00335 ret += item->name;
00336 ret += string("\"");
00337 ret += string(" [");
00338 for (j = 0; j < nPrint; ++j)
00339 bufp += snprintf(bufp, bufEnd - bufp, "%.8g %.8g %.8g ", item->data[j].x,
00340 item->data[j].y, item->data[j].z);
00341 ret += buf;
00342 ret += string("] ");
00343 }
00344 for (i = 0; i < vectors.size(); ++i) {
00345 char *bufp = buf;
00346 *bufp = '\0';
00347 ParamSetItem<Vector> *item = vectors[i];
00348 typeString = "vector ";
00349
00350 int nPrint = item->nItems;
00351 ret += string("\"");
00352 ret += typeString;
00353 ret += item->name;
00354 ret += string("\"");
00355 ret += string(" [");
00356 for (j = 0; j < nPrint; ++j)
00357 bufp += snprintf(bufp, bufEnd - bufp, "%.8g %.8g %.8g ", item->data[j].x,
00358 item->data[j].y, item->data[j].z);
00359 ret += buf;
00360 ret += string("] ");
00361 }
00362 for (i = 0; i < normals.size(); ++i) {
00363 char *bufp = buf;
00364 *bufp = '\0';
00365 ParamSetItem<Normal> *item = normals[i];
00366 typeString = "normal ";
00367
00368 int nPrint = item->nItems;
00369 ret += string("\"");
00370 ret += typeString;
00371 ret += item->name;
00372 ret += string("\"");
00373 ret += string(" [");
00374 for (j = 0; j < nPrint; ++j)
00375 bufp += snprintf(bufp, bufEnd - bufp, "%.8g %.8g %.8g ", item->data[j].x,
00376 item->data[j].y, item->data[j].z);
00377 ret += buf;
00378 ret += string("] ");
00379 }
00380 for (i = 0; i < strings.size(); ++i) {
00381 char *bufp = buf;
00382 *bufp = '\0';
00383 ParamSetItem<string> *item = strings[i];
00384 typeString = "string ";
00385
00386 int nPrint = item->nItems;
00387 ret += string("\"");
00388 ret += typeString;
00389 ret += item->name;
00390 ret += string("\"");
00391 ret += string(" [");
00392 for (j = 0; j < nPrint; ++j)
00393 bufp += snprintf(bufp, bufEnd - bufp, "\"%s\" ", item->data[j].c_str());
00394 ret += buf;
00395 ret += string("] ");
00396 }
00397 for (i = 0; i < textures.size(); ++i) {
00398 char *bufp = buf;
00399 *bufp = '\0';
00400 ParamSetItem<string> *item = textures[i];
00401 typeString = "texture ";
00402
00403 int nPrint = item->nItems;
00404 ret += string("\"");
00405 ret += typeString;
00406 ret += item->name;
00407 ret += string("\"");
00408 ret += string(" [");
00409 for (j = 0; j < nPrint; ++j)
00410 bufp += snprintf(bufp, bufEnd - bufp, "\"%s\" ", item->data[j].c_str());
00411 ret += buf;
00412 ret += string("] ");
00413 }
00414 for (i = 0; i < spectra.size(); ++i) {
00415 char *bufp = buf;
00416 *bufp = '\0';
00417 ParamSetItem<Spectrum> *item = spectra[i];
00418 typeString = "color ";
00419
00420 int nPrint = item->nItems;
00421 ret += string("\"");
00422 ret += typeString;
00423 ret += item->name;
00424 ret += string("\"");
00425 ret += string(" [");
00426 for (j = 0; j < nPrint; ++j)
00427 bufp += snprintf(bufp, bufEnd - bufp, "%.8g %.8g %.8g ", item->data[j].c[0],
00428 item->data[j].c[1], item->data[j].c[2]);
00429 ret += buf;
00430 ret += string("] ");
00431 }
00432 return ret;
00433 }
00434
00435 Reference<Texture<Spectrum> >
00436 TextureParams::GetSpectrumTexture(const string &n,
00437 const Spectrum &def) const {
00438 string name = geomParams.FindTexture(n);
00439 if (name == "") name = materialParams.FindTexture(n);
00440 if (name != "") {
00441 if (spectrumTextures.find(name) !=
00442 spectrumTextures.end())
00443 return spectrumTextures[name];
00444 else
00445 Error("Couldn't find spectrum"
00446 "texture named \"%s\"", n.c_str());
00447 }
00448 Spectrum val = geomParams.FindOneSpectrum(n,
00449 materialParams.FindOneSpectrum(n, def));
00450 return new ConstantTexture<Spectrum>(val);
00451 }
00452 Reference<Texture<float> > TextureParams::GetFloatTexture(const string &n,
00453 float def) const {
00454 string name = geomParams.FindTexture(n);
00455 if (name == "") name = materialParams.FindTexture(n);
00456 if (name != "") {
00457 if (floatTextures.find(name) != floatTextures.end())
00458 return floatTextures[name];
00459 else
00460 Error("Couldn't find float texture named \"%s\"", n.c_str());
00461 }
00462 float val = geomParams.FindOneFloat(n,
00463 materialParams.FindOneFloat(n, def));
00464 return new ConstantTexture<float>(val);
00465 }