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;
}
Example #2
0
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;
}