void LoopSubdiv::weightOneRing(SDVertex *destVert, SDVertex *vert, float beta) const { // Put _vert_ one-ring in _Pring_ u_int valence = vert->valence(); SDVertex **Vring = (SDVertex **)alloca(valence * sizeof(SDVertex *)); SDVertex **VR = Vring; // Get one ring vertices for interior vertex SDFace *face = vert->startFace; bool uvSplit = false; do { SDVertex *v = face->v[face->vnum(vert->P)]; if (v->u != vert->u || v->v != vert->v) uvSplit = true; SDVertex *v2 = face->nextVert(vert->P); float vu = v2->u; float vv = v2->v; *VR++ = v2; face = face->nextFace(vert->P); v2 = face->prevVert(vert->P); if (vu != v2->u || vv != v2->v) uvSplit = true; } while (face != vert->startFace); Point P((1 - valence * beta) * vert->P); float u = (1 - valence * beta) * vert->u; float v = (1 - valence * beta) * vert->v; Normal N((1 - valence * beta) * vert->n); for (u_int i = 0; i < valence; ++i) { P += beta * Vring[i]->P; u += beta * Vring[i]->u; v += beta * Vring[i]->v; N += beta * Vring[i]->n; } destVert->P = P; if (uvSplit) { destVert->u = vert->u; destVert->v = vert->v; } else { destVert->u = u; destVert->v = v; } destVert->n = N; }
void SDVertex::oneRing(PbrtPoint *P) { if (!boundary) { // Get one-ring vertices for interior vertex SDFace *face = startFace; do { *P++ = face->nextVert(this)->P; face = face->nextFace(this); } while (face != startFace); } else { // Get one-ring vertices for boundary vertex SDFace *face = startFace, *f2; while ((f2 = face->nextFace(this)) != NULL) face = f2; *P++ = face->nextVert(this)->P; do { *P++ = face->prevVert(this)->P; face = face->prevFace(this); } while (face != NULL); } }
void LoopSubdiv::weightBoundary(SDVertex *destVert, SDVertex *vert, float beta) const { // Put _vert_ one-ring in _Pring_ u_int valence = vert->valence(); if (displacementMapSharpBoundary) { destVert->P = vert->P; destVert->u = vert->u; destVert->v = vert->v; destVert->n = vert->n; return; } SDVertex **Vring = (SDVertex **)alloca(valence * sizeof(SDVertex *)); SDVertex **VR = Vring; // Get one ring vertices for boundary vertex SDFace *face = vert->startFace, *f2; // Go to the last face in the list while ((f2 = face->nextFace(vert->P)) != NULL) face = f2; // Add the last vertex (on the boundary) *VR++ = face->nextVert(vert->P); // Add all vertices up to the first one (on the boundary) bool uvSplit = false; do { SDVertex *v = face->v[face->vnum(vert->P)]; if (v->u != vert->u || v->v != vert->v) uvSplit = true; SDVertex *v2 = face->prevVert(vert->P); float vu = v2->u; float vv = v2->v; *VR++ = v2; face = face->prevFace(vert->P); if (face) { v2 = face->nextVert(vert->P); if (vu != v2->u || vv != v2->v) uvSplit = true; } } while (face != NULL); Point P((1 - 2 * beta) * vert->P); P += beta * Vring[0]->P; P += beta * Vring[valence - 1]->P; destVert->P = P; if (uvSplit) { destVert->u = vert->u; destVert->v = vert->v; } else { float u = (1.f - 2.f * beta) * vert->u; float v = (1.f - 2.f * beta) * vert->v; u += beta * (Vring[0]->u + Vring[valence - 1]->u); v += beta * (Vring[0]->v + Vring[valence - 1]->v); destVert->u = u; destVert->v = v; } Normal N((1 - 2 * beta) * vert->n); N += beta * Vring[0]->n; N += beta * Vring[valence - 1]->n; destVert->n = N; }