void PtexTriangleFilter::applyAcrossEdge(PtexTriangleKernel& k, const Ptex::FaceInfo& f, int eid) { int afid = f.adjface(eid), aeid = f.adjedge(eid); const Ptex::FaceInfo& af = _tx->getFaceInfo(afid); k.reorient(eid, aeid); splitAndApply(k, afid, af); }
void PtexSeparableFilter::applyToCornerFace(PtexSeparableKernel& k, const Ptex::FaceInfo& f, int eid, int cfid, const Ptex::FaceInfo& cf, int ceid) { // adjust uv coord and res for face/subface boundary bool fIsSubface = f.isSubface(), cfIsSubface = cf.isSubface(); if (fIsSubface != cfIsSubface) { if (cfIsSubface) k.adjustMainToSubface(eid + 3); else k.adjustSubfaceToMain(eid + 3); } // rotate and apply (resplit if going to a subface) k.rotate(eid - ceid + 2); if (cfIsSubface) splitAndApply(k, cfid, cf); else apply(k, cfid, cf); }
void PtexTriangleFilter::splitAndApply(PtexTriangleKernel& k, int faceid, const Ptex::FaceInfo& f) { // do we need to split? if so, split kernel and apply across edge(s) if (k.u1 < 0 && f.adjface(2) >= 0) { PtexTriangleKernel ka; k.splitU(ka); applyAcrossEdge(ka, f, 2); } if (k.v1 < 0 && f.adjface(0) >= 0) { PtexTriangleKernel ka; k.splitV(ka); applyAcrossEdge(ka, f, 0); } if (k.w1 < 0 && f.adjface(1) >= 0) { PtexTriangleKernel ka; k.splitW(ka); applyAcrossEdge(ka, f, 1); } // apply to local face apply(k, faceid, f); }
void DumpFaceInfo(const Ptex::FaceInfo& f) { Ptex::Res res = f.res; std::cout << " res: " << int(res.ulog2) << ' ' << int(res.vlog2) << " (" << res.u() << " x " << res.v() << ")" << " adjface: " << f.adjfaces[0] << ' ' << f.adjfaces[1] << ' ' << f.adjfaces[2] << ' ' << f.adjfaces[3] << " adjedge: " << f.adjedge(0) << ' ' << f.adjedge(1) << ' ' << f.adjedge(2) << ' ' << f.adjedge(3) << " flags:"; // output flag names if (f.flags == 0) std::cout << " (none)"; else { if (f.isSubface()) std::cout << " subface"; if (f.isConstant()) std::cout << " constant"; if (f.isNeighborhoodConstant()) std::cout << " nbconstant"; if (f.hasEdits()) std::cout << " hasedits"; } std::cout << std::endl; }
void PtexSeparableFilter::applyAcrossEdge(PtexSeparableKernel& k, int faceid, const Ptex::FaceInfo& f, int eid) { int afid = f.adjface(eid), aeid = f.adjedge(eid); const Ptex::FaceInfo* af = &_tx->getFaceInfo(afid); int rot = eid - aeid + 2; // adjust uv coord and res for face/subface boundary bool fIsSubface = f.isSubface(), afIsSubface = af->isSubface(); if (fIsSubface != afIsSubface) { if (afIsSubface) { // main face to subface transition // adjust res and offset uv coord for primary subface bool primary = k.adjustMainToSubface(eid); if (!primary) { // advance ajacent face and edge id to secondary subface int neid = (aeid + 3) % 4; afid = af->adjface(neid); aeid = af->adjedge(neid); af = &_tx->getFaceInfo(afid); rot += neid - aeid + 2; } } else { // subface to main face transition // Note: the transform depends on which subface the kernel is // coming from. The "primary" subface is the one the main // face is pointing at. The secondary subface adjustment // happens to be the same as for the primary subface for the // next edge, so the cases can be combined. bool primary = (af->adjface(aeid) == faceid); k.adjustSubfaceToMain(eid - primary); } } // rotate and apply (resplit if going to a subface) k.rotate(rot); if (afIsSubface) splitAndApply(k, afid, *af); else apply(k, afid, *af); }
void PtexSeparableFilter::splitAndApply(PtexSeparableKernel& k, int faceid, const Ptex::FaceInfo& f) { // do we need to split? (i.e. does kernel span an edge?) bool splitR = (k.u+k.uw > k.res.u()), splitL = (k.u < 0); bool splitT = (k.v+k.vw > k.res.v()), splitB = (k.v < 0); #ifdef NOEDGEBLEND // for debugging only if (splitR) k.mergeR(_uMode); if (splitL) k.mergeL(_uMode); if (splitT) k.mergeT(_vMode); if (splitB) k.mergeB(_vMode); #else if (splitR || splitL || splitT || splitB) { PtexSeparableKernel ka, kc; if (splitR) { if (f.adjface(e_right) >= 0) { k.splitR(ka); if (splitT) { if (f.adjface(e_top) >= 0) { ka.splitT(kc); applyToCorner(kc, faceid, f, e_top); } else ka.mergeT(_vMode); } if (splitB) { if (f.adjface(e_bottom) >= 0) { ka.splitB(kc); applyToCorner(kc, faceid, f, e_right); } else ka.mergeB(_vMode); } applyAcrossEdge(ka, faceid, f, e_right); } else k.mergeR(_uMode); } if (splitL) { if (f.adjface(e_left) >= 0) { k.splitL(ka); if (splitT) { if (f.adjface(e_top) >= 0) { ka.splitT(kc); applyToCorner(kc, faceid, f, e_left); } else ka.mergeT(_vMode); } if (splitB) { if (f.adjface(e_bottom) >= 0) { ka.splitB(kc); applyToCorner(kc, faceid, f, e_bottom); } else ka.mergeB(_vMode); } applyAcrossEdge(ka, faceid, f, e_left); } else k.mergeL(_uMode); } if (splitT) { if (f.adjface(e_top) >= 0) { k.splitT(ka); applyAcrossEdge(ka, faceid, f, e_top); } else k.mergeT(_vMode); } if (splitB) { if (f.adjface(e_bottom) >= 0) { k.splitB(ka); applyAcrossEdge(ka, faceid, f, e_bottom); } else k.mergeB(_vMode); } } #endif // do local face apply(k, faceid, f); }