/* btdf.c: Bidirectional Transmittance Distribution Functions */ #include "btdf.h" #include "brdf.h" #include "pools.h" #include "Boolean.h" #include "error.h" #ifdef NOPOOLS #define NEWBTDF() (BTDF *)Alloc(sizeof(BTDF)) #define DISPOSEBTDF(ptr) Free((char *)ptr, sizeof(BTDF)) #else static POOL *btdfPool = (POOL *)NULL; #define NEWBTDF() (BTDF *)NewPoolCell(sizeof(BTDF), 0, "btdfs", &btdfPool) #define DISPOSEBTDF(ptr) Dispose((char *)ptr, &btdfPool) #endif /* Creates a BTDF instance with given data and methods. A pointer * to the created BTDF struct is returned. */ BTDF *BtdfCreate(void *data, BTDF_METHODS *methods) { BTDF *btdf; btdf = NEWBTDF(); btdf->data = data; btdf->methods = methods; return btdf; } /* Creates and returns a duplicate of the given BTDF */ BTDF *BtdfDuplicate(BTDF *obtdf) { BTDF *btdf; if (!obtdf) return obtdf; btdf = NEWBTDF(); btdf->data = obtdf->methods->Duplicate(obtdf->data); btdf->methods = obtdf->methods; return btdf; } /* Creates an editor widget for the BTDF, returns the Widget casted * to a void * in order not to have to include all X window system files. */ void *BtdfCreateEditor(void *parent, BTDF *btdf) { if (!btdf) Fatal(-1, "BtdfCreateEditor", "NULL btdf pointer passed."); return btdf->methods->CreateEditor(parent, btdf->data); } /* disposes of the memory occupied by the BTDF instance */ void BtdfDestroy(BTDF *btdf) { if (!btdf) return; btdf->methods->Destroy(btdf->data); DISPOSEBTDF(btdf); } /* Returns the transmittance of the BTDF */ COLOR BtdfTransmittance(BTDF *btdf, XXDFFLAGS flags) { if (btdf && btdf->methods->Transmittance) return btdf->methods->Transmittance(btdf->data, flags); else { static COLOR refl; COLORCLEAR(refl); return refl; } } void BtdfIndexOfRefraction(BTDF *btdf, REFRACTIONINDEX *index) { if (btdf && btdf->methods->IndexOfRefraction) { btdf->methods->IndexOfRefraction(btdf->data, index); } else { index->nr = 1.0; index->ni = 0.0; /* Vacuum */ } } /* Btdf evaluations */ COLOR BtdfEval(BTDF *btdf, REFRACTIONINDEX inIndex, REFRACTIONINDEX outIndex, VECTOR *in, VECTOR *out, VECTOR *normal, XXDFFLAGS flags) { if (btdf && btdf->methods->Eval) return btdf->methods->Eval(btdf->data, inIndex, outIndex, in, out, normal, flags); else { static COLOR refl; COLORCLEAR(refl); return refl; } } VECTOR BtdfSample(BTDF *btdf, REFRACTIONINDEX inIndex, REFRACTIONINDEX outIndex, VECTOR *in, VECTOR *normal, int doRussianRoulette, XXDFFLAGS flags, double x_1, double x_2, double *pdf) { if (btdf && btdf->methods->Sample) return btdf->methods->Sample(btdf->data, inIndex, outIndex, in, normal, doRussianRoulette, flags, x_1, x_2, pdf); else { VECTOR dummy = {0., 0., 0.}; *pdf = 0; return dummy; } } void BtdfEvalPdf(BTDF *btdf, REFRACTIONINDEX inIndex, REFRACTIONINDEX outIndex, VECTOR *in, VECTOR *out, VECTOR *normal, XXDFFLAGS flags, double *pdf, double *pdfRR) { if (btdf && btdf->methods->EvalPdf) btdf->methods->EvalPdf(btdf->data, inIndex, outIndex, in, out, normal, flags, pdf, pdfRR); else { *pdf = 0; } } /* Print the btdf data the to specified file pointer */ void BtdfPrint(FILE *out, BTDF *btdf) { if (!btdf) fprintf(out, "(NULL BTDF)\n"); else btdf->methods->Print(out, btdf->data); }