void PtexUtils::divalpha(void* data, int npixels, DataType dt, int nchannels, int alphachan) { double scale = OneValue(dt); switch(dt) { case dt_uint8: ::divalpha((uint8_t*) data, npixels, nchannels, alphachan, scale); break; case dt_uint16: ::divalpha((uint16_t*) data, npixels, nchannels, alphachan, scale); break; case dt_half: ::divalpha((PtexHalf*) data, npixels, nchannels, alphachan, scale); break; case dt_float: ::divalpha((float*) data, npixels, nchannels, alphachan, scale); break; } }
PTEX_NAMESPACE_BEGIN void PtexTriangleFilter::eval(float* result, int firstChan, int nChannels, int faceid, float u, float v, float uw1, float vw1, float uw2, float vw2, float width, float blur) { // init if (!_tx || nChannels <= 0) return; if (faceid < 0 || faceid >= _tx->numFaces()) return; _ntxchan = _tx->numChannels(); _dt = _tx->dataType(); _firstChanOffset = firstChan*DataSize(_dt); _nchan = PtexUtils::min(nChannels, _ntxchan-firstChan); // get face info const FaceInfo& f = _tx->getFaceInfo(faceid); // if neighborhood is constant, just return constant value of face if (f.isNeighborhoodConstant()) { PtexPtr<PtexFaceData> data ( _tx->getData(faceid, 0) ); if (data) { char* d = (char*) data->getData() + _firstChanOffset; Ptex::ConvertToFloat(result, d, _dt, _nchan); } return; } // clamp u and v u = PtexUtils::clamp(u, 0.0f, 1.0f); v = PtexUtils::clamp(v, 0.0f, 1.0f); // build kernel PtexTriangleKernel k; buildKernel(k, u, v, uw1, vw1, uw2, vw2, width, blur, f.res); // accumulate the weight as we apply _weight = 0; // allocate temporary result _result = (float*) alloca(sizeof(float)*_nchan); memset(_result, 0, sizeof(float)*_nchan); // apply to faces splitAndApply(k, faceid, f); // normalize (both for data type and cumulative kernel weight applied) // and output result float scale = 1.0f / (_weight * OneValue(_dt)); for (int i = 0; i < _nchan; i++) result[i] = float(_result[i] * scale); // clear temp result _result = 0; }
int set_menu_opts(MENU *m, int opt) { ITEM **ip; if (m) { if (Posted(m)) { return (E_POSTED); } /* Check to see if the ROWMAJOR option is changing. If so, */ /* set top and current to 0. */ if ((opt & O_ROWMAJOR) != RowMajor(m)) { Top(m) = 0; Current(m) = IthItem(m, 0); (void) set_menu_format(m, FRows(m), FCols(m)); } /* if O_NONCYCLIC option changed, set bit to re-link items */ if ((opt & O_NONCYCLIC) != (Mopt(m) & O_NONCYCLIC)) { SetLink(m); } Mopt(m) = opt; if (OneValue(m) && Items(m)) { for (ip = Items(m); *ip; ip++) { /* Unset values if selection not allowed. */ Value(*ip) = FALSE; } } _scale(m); /* Redo sizing information */ } else { Mopt(Dfl_Menu) = opt; } return (E_OK); }
void PtexSeparableFilter::eval(float* result, int firstChan, int nChannels, int faceid, float u, float v, float uw1, float vw1, float uw2, float vw2, float width, float blur) { // init if (!_tx || nChannels <= 0) return; if (faceid < 0 || faceid >= _tx->numFaces()) return; _ntxchan = _tx->numChannels(); _dt = _tx->dataType(); _firstChanOffset = firstChan*DataSize(_dt); _nchan = PtexUtils::min(nChannels, _ntxchan-firstChan); // get face info const FaceInfo& f = _tx->getFaceInfo(faceid); // if neighborhood is constant, just return constant value of face if (f.isNeighborhoodConstant()) { PtexPtr<PtexFaceData> data ( _tx->getData(faceid, 0) ); if (data) { char* d = (char*) data->getData() + _firstChanOffset; Ptex::ConvertToFloat(result, d, _dt, _nchan); } return; } // find filter width as bounding box of vectors w1 and w2 float uw = fabs(uw1) + fabs(uw2), vw = fabs(vw1) + fabs(vw2); // handle border modes switch (_uMode) { case m_clamp: u = PtexUtils::clamp(u, 0.0f, 1.0f); break; case m_periodic: u = u-floor(u); break; case m_black: break; // do nothing } switch (_vMode) { case m_clamp: v = PtexUtils::clamp(v, 0.0f, 1.0f); break; case m_periodic: v = v-floor(v); case m_black: break; // do nothing } // build kernel PtexSeparableKernel k; if (f.isSubface()) { // for a subface, build the kernel as if it were on a main face and then downres uw = uw * width + blur * 2; vw = vw * width + blur * 2; buildKernel(k, u*.5, v*.5, uw*.5, vw*.5, f.res); if (k.res.ulog2 == 0) k.upresU(); if (k.res.vlog2 == 0) k.upresV(); k.res.ulog2--; k.res.vlog2--; } else { uw = uw * width + blur; vw = vw * width + blur; buildKernel(k, u, v, uw, vw, f.res); } k.stripZeros(); // check kernel (debug only) assert(k.uw > 0 && k.vw > 0); assert(k.uw <= PtexSeparableKernel::kmax && k.vw <= PtexSeparableKernel::kmax); _weight = k.weight(); // allocate temporary double-precision result _result = (double*) alloca(sizeof(double)*_nchan); memset(_result, 0, sizeof(double)*_nchan); // apply to faces splitAndApply(k, faceid, f); // normalize (both for data type and cumulative kernel weight applied) // and output result double scale = 1.0 / (_weight * OneValue(_dt)); for (int i = 0; i < _nchan; i++) result[i] = float(_result[i] * scale); // clear temp result _result = 0; }