コード例 #1
0
ファイル: loopsubdiv.cpp プロジェクト: AI42/OM3D
// LoopSubdiv Inline Functions
inline int SDVertex::valence() {
    SDFace *f = startFace;
    if (!boundary) {
        // Compute valence of interior vertex
        int nf = 1;
        while ((f = f->nextFace(this)) != startFace)
            ++nf;
        return nf;
    }
    else {
        // Compute valence of boundary vertex
        int nf = 1;
        while ((f = f->nextFace(this)) != NULL)
            ++nf;
        f = startFace;
        while ((f = f->prevFace(this)) != NULL)
            ++nf;
        return nf+1;
    }
}
コード例 #2
0
ファイル: loopsubdiv.cpp プロジェクト: AI42/OM3D
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);
    }
}
コード例 #3
0
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;
}
コード例 #4
0
ファイル: loopsubdiv.cpp プロジェクト: AI42/OM3D
// LoopSubdiv Method Definitions
LoopSubdiv::LoopSubdiv(const Transform *o2w, const Transform *w2o,
                       bool ro, int nfaces, int nvertices,
                       const int *vertexIndices, const PbrtPoint *P, int nl)
    : Shape(o2w, w2o, ro) {
    nLevels = nl;
    // Allocate _LoopSubdiv_ vertices and faces
    int i;
    SDVertex *verts = new SDVertex[nvertices];
    for (i = 0; i < nvertices; ++i) {
        verts[i] = SDVertex(P[i]);
        vertices.push_back(&verts[i]);
    }
    SDFace *fs = new SDFace[nfaces];
    for (i = 0; i < nfaces; ++i)
        faces.push_back(&fs[i]);

    // Set face to vertex pointers
    const int *vp = vertexIndices;
    for (i = 0; i < nfaces; ++i) {
        SDFace *f = faces[i];
        for (int j = 0; j < 3; ++j) {
            SDVertex *v = vertices[vp[j]];
            f->v[j] = v;
            v->startFace = f;
        }
        vp += 3;
    }

    // Set neighbor pointers in _faces_
    set<SDEdge> edges;
    for (i = 0; i < nfaces; ++i) {
        SDFace *f = faces[i];
        for (int edgeNum = 0; edgeNum < 3; ++edgeNum) {
            // Update neighbor pointer for _edgeNum_
            int v0 = edgeNum, v1 = NEXT(edgeNum);
            SDEdge e(f->v[v0], f->v[v1]);
            if (edges.find(e) == edges.end()) {
                // Handle new edge
                e.f[0] = f;
                e.f0edgeNum = edgeNum;
                edges.insert(e);
            }
            else {
                // Handle previously seen edge
                e = *edges.find(e);
                e.f[0]->f[e.f0edgeNum] = f;
                f->f[edgeNum] = e.f[0];
                edges.erase(e);
            }
        }
    }

    // Finish vertex initialization
    for (i = 0; i < nvertices; ++i) {
        SDVertex *v = vertices[i];
        SDFace *f = v->startFace;
        do {
            f = f->nextFace(v);
        } while (f && f != v->startFace);
        v->boundary = (f == NULL);
        if (!v->boundary && v->valence() == 6)
            v->regular = true;
        else if (v->boundary && v->valence() == 4)
            v->regular = true;
        else
            v->regular = false;
    }
}
コード例 #5
0
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;
}
コード例 #6
0
void LoopSubdiv::ApplyDisplacementMap(const vector<SDVertex *> verts) const
{
	// Dade - apply the displacement map
	SHAPE_LOG(name, LUX_INFO,LUX_NOERROR) << "Applying displacement map to " << verts.size() << " vertices";
	SpectrumWavelengths swl;
	swl.Sample(.5f);

	for (u_int i = 0; i < verts.size(); i++) {
		SDVertex *v = verts[i];
		// Special use of the child member to detect that
		// the vertex has already been displaced
		if (v->child == v)
			continue;
		Vector dpdu, dpdv;
		CoordinateSystem(Vector(v->n), &dpdu, &dpdv);
		Vector displacement(v->n);

		SDFace *face = v->startFace;
		u_int nf = 0;
		float dl = 0.f;
		vector<SDVertex *> vlist;
		vlist.reserve(v->valence());
		if (v->boundary) {
			do {
				SDVertex *vv = face->v[face->vnum(v->P)];
				DifferentialGeometry dg(v->P, v->n, dpdu, dpdv,
					Normal(0, 0, 0), Normal(0, 0, 0),
					vv->u, vv->v, NULL);

				dl += displacementMap->Evaluate(swl, dg);
				++nf;
				if (vv->child != vv) {
					vlist.push_back(vv);
					vv->child = vv;
				}
				face = face->nextFace(v->P);
			} while (face);
			face = v->startFace->prevFace(v->P);
			while (face) {
				SDVertex *vv = face->v[face->vnum(v->P)];
				DifferentialGeometry dg(v->P, v->n, dpdu, dpdv,
					Normal(0, 0, 0), Normal(0, 0, 0),
					vv->u, vv->v, NULL);

				dl += displacementMap->Evaluate(swl, dg);
				++nf;
				if (vv->child != vv) {
					vlist.push_back(vv);
					vv->child = vv;
				}
				face = face->prevFace(v->P);
			}
		} else {
			do {
				SDVertex *vv = face->v[face->vnum(v->P)];
				DifferentialGeometry dg(v->P, v->n, dpdu, dpdv,
					Normal(0, 0, 0), Normal(0, 0, 0),
					vv->u, vv->v, NULL);

				dl += displacementMap->Evaluate(swl, dg);
				++nf;
				if (vv->child != vv) {
					vlist.push_back(vv);
					vv->child = vv;
				}
				face = face->nextFace(v->P);
			} while (face != v->startFace);
		}
		dl = (dl * displacementMapScale / nf + displacementMapOffset);
		// Average the displacement
		displacement *= dl;

		// Apply displacement to all vertices in the list
		for (u_int j = 0; j < vlist.size(); ++j)
			vlist[j]->P += displacement;
	}
}
コード例 #7
0
// LoopSubdiv Method Definitions
LoopSubdiv::LoopSubdiv(u_int nfaces, u_int nvertices, const int *vertexIndices,
	const Point *P, const float *uv, const Normal *n, u_int nl,
	const boost::shared_ptr<Texture<float> > &dismap, float dmscale,
	float dmoffset, bool dmnormalsmooth, bool dmsharpboundary,
	bool normalsplit, const string &sname)
	: displacementMap(dismap),
	displacementMapScale(dmscale), displacementMapOffset(dmoffset),
	displacementMapNormalSmooth(dmnormalsmooth),
	displacementMapSharpBoundary(dmsharpboundary),
	name(sname)
{
	nLevels = nl;
	hasUV = (uv != NULL);
	normalSplit = normalsplit && n != NULL;

	// Allocate _LoopSubdiv_ vertices and faces
	SDVertex *verts = new SDVertex[nvertices];
	vertices.reserve(nvertices);
	for (u_int i = 0; i < nvertices; ++i) {
		if (hasUV)
			verts[i] = SDVertex(P[i], uv[2 * i], uv[2 * i + 1]);
		else
			verts[i] = SDVertex(P[i]);
		if (normalSplit)
			verts[i].n = n[i];

		vertices.push_back(&verts[i]);
	}

	SDFace *fs = new SDFace[nfaces];
	faces.reserve(nfaces);
	for (u_int i = 0; i < nfaces; ++i)
		faces.push_back(&fs[i]);
	// Set face to vertex pointers
	const int *vp = vertexIndices;
	for (u_int i = 0; i < nfaces; ++i) {
		SDFace *f = faces[i];
		for (u_int j = 0; j < 3; ++j) {
			SDVertex *v = vertices[vp[j]];
			f->v[j] = v;
			f->f[j] = NULL;
			f->children[j] = NULL;
			v->startFace = f;
		}
		f->children[3] = NULL;
		vp += 3;
	}

	// Set neighbor pointers in _faces_
	set<SDEdge> edges;
	for (u_int i = 0; i < nfaces; ++i) {
		SDFace *f = faces[i];
		for (u_int edgeNum = 0; edgeNum < 3; ++edgeNum) {
			// Update neighbor pointer for _edgeNum_
			u_int v0 = edgeNum, v1 = NEXT(edgeNum);
			Normal n0, n1;
			SDEdge e(f->v[v0], f->v[v1]);
			if (edges.find(e) == edges.end()) {
				// Handle new edge
				e.f[0] = f;
				e.f0edgeNum = edgeNum;
				edges.insert(e);
			} else {
				// Handle previously-seen edge
				e = *edges.find(e);
				e.f[0]->f[e.f0edgeNum] = f;
				f->f[edgeNum] = e.f[0];
				// NOTE - lordcrc - check winding of 
				// other face is opposite of the 
				// current face, otherwise we have 
				// inconsistent winding
				u_int otherv0 = e.f[0]->vnum(f->v[v0]->P);
				u_int otherv1 = e.f[0]->vnum(f->v[v1]->P);
				if (PREV(otherv0) != otherv1) {
					SHAPE_LOG(name, LUX_ERROR,LUX_CONSISTENCY)<< "Inconsistent vertex winding in mesh, aborting subdivision.";
					// prevent subdivision
					nLevels = 0;
					return;
				};
				edges.erase(e);
			}
		}
	}

	// Finish vertex initialization
	for (u_int i = 0; i < nvertices; ++i) {
		SDVertex *v = vertices[i];
		SDFace *f = v->startFace;
		do {
			f = f->nextFace(v->P);
		} while (f && f != v->startFace);
		v->boundary = (f == NULL);
		if (!v->boundary && v->valence() == 6)
			v->regular = true;
		else if (v->boundary && v->valence() == 4)
			v->regular = true;
		else
			v->regular = false;
	}
}