MeshGeometry PrimitiveGeometryBuilder::buildCylinderMesh(std::vector<tgt::vec3>& vertices, size_t numSides, tgt::vec3 color) {
    // Transform vec3 to vec4
    tgt::vec4 color4(color[0], color[1], color[2], 1.f);
    
    // Build cylinder's sides
    MeshGeometry cyl;
    for (size_t i = 0; i < 2*numSides; i+=2) {
        FaceGeometry face;
        
        tgt::vec3 faceNormal = tgt::cross(vertices[i+1] - vertices[i], vertices[i+2] - vertices[i]);
        
        // Face vertices
        // TODO Replace faceNormal with vertex normals for smoother representation
        VertexGeometry fv1(vertices[i], tgt::vec3(0.f), color4, faceNormal);
        VertexGeometry fv2(vertices[i+1], tgt::vec3(0.f), color4, faceNormal);
        VertexGeometry fv3(vertices[i+3], tgt::vec3(0.f), color4, faceNormal);
        VertexGeometry fv4(vertices[i+2], tgt::vec3(0.f), color4, faceNormal);
        face.addVertex(fv1);
        face.addVertex(fv2);
        face.addVertex(fv3);
        face.addVertex(fv4);
        
        cyl.addFace(face);
    }
    return cyl;
}
FaceGeometry PrimitiveGeometryBuilder::createFace(std::vector<tgt::vec3>& vertices, tgt::vec4 color) {
        FaceGeometry face;
        
        tgt::vec3 faceNormal = tgt::cross(vertices[1] - vertices[0], vertices[2] - vertices[0]);
        
        // Face vertices
        // TODO Replace faceNormal with vertex normals for smoother representation
        for (size_t i = 0; i < vertices.size(); i++) {
            VertexGeometry fv(vertices[i], tgt::vec3(0.f), color, faceNormal);
            face.addVertex(fv);
        }
        
        return face;
}
示例#3
0
MeshGeometry MeshGeometry::clip(const vec4& clipplane, double epsilon) {
    // Clip all faces...
    for (iterator it = begin(); it != end(); ++it)
        it->clip(clipplane, epsilon);

    // Remove empty faces...
    for (size_t i = 0; i < faces_.size(); ++i) {
        // Is face empty?
        if (faces_.at(i).getVertexCount() < 3)
            faces_.erase(faces_.begin() + i--);
    }

    // Close convex polyhedron if necessary...
    typedef std::pair<VertexGeometry, VertexGeometry> EdgeType;
    typedef std::vector<EdgeType> EdgeListType;
    typedef std::vector<VertexGeometry> VertexListType;

    EdgeListType edgeList;
    FaceGeometry closingFace;

    // Search all face edges on the clipping plane...
    for (size_t i = 0; i < faces_.size(); ++i) {
        FaceGeometry face = faces_.at(i);

        VertexListType verticesOnClipplane;

        for (size_t j = 0; j < face.getVertexCount(); ++j) {
            if (face.getVertex(j).getDistanceToPlane(clipplane, epsilon) == 0)
                verticesOnClipplane.push_back(face.getVertex(j));

            // Is face in the same plane as the clipping plane?
            if (verticesOnClipplane.size() > 2)
                break;
        }

        // Does one face edge corresponds with clipping plane?
        if (verticesOnClipplane.size() == 2)
            edgeList.push_back(std::make_pair(verticesOnClipplane[0], verticesOnClipplane[1]));
    }

    // Is closing necessary?
    if (edgeList.size() > 1) {
        // Sort edges to produce contiguous vertex order...
        bool reverseLastEdge = false;
        for (size_t i = 0; i < edgeList.size() - 1; ++i) {
            for (size_t j = i + 1; j < edgeList.size(); ++j) {
                VertexGeometry connectionVertex;
                if (reverseLastEdge)
                    connectionVertex = edgeList.at(i).first;
                else
                    connectionVertex = edgeList.at(i).second;

                if (edgeList.at(j).first.equals(connectionVertex, epsilon)) {
                    std::swap(edgeList.at(i + 1), edgeList.at(j));
                    reverseLastEdge = false;
                    break;
                }
                else if (edgeList.at(j).second.equals(connectionVertex, epsilon)) {
                    std::swap(edgeList.at(i + 1), edgeList.at(j));
                    reverseLastEdge = true;
                    break;
                }
            }
        }

        // Convert sorted edge list to sorted vertex list...
        VertexListType closingFaceVertices;
        for (size_t i = 0; i < edgeList.size(); ++i) {
            bool reverseEdge = i != 0 && !closingFaceVertices.at(closingFaceVertices.size() - 1).equals(edgeList.at(i).first);

            VertexGeometry first = (reverseEdge ? edgeList.at(i).second : edgeList.at(i).first);
            VertexGeometry second = (reverseEdge ? edgeList.at(i).first : edgeList.at(i).second);

            if (i == 0)
                closingFaceVertices.push_back(first);
            else
                closingFaceVertices.at(closingFaceVertices.size() - 1).combine(first);

            if (i < (edgeList.size() - 1))
                closingFaceVertices.push_back(second);
            else
                closingFaceVertices[0].combine(second);
        }

        // Convert vertex order to counter clockwise if necessary...
        vec3 closingFaceNormal(0, 0, 0);
        for (size_t i = 0; i < closingFaceVertices.size(); ++i)
            closingFaceNormal += tgt::cross(closingFaceVertices[i].getCoords(), closingFaceVertices[(i + 1) % closingFaceVertices.size()].getCoords());
        closingFaceNormal = tgt::normalize(closingFaceNormal);

        if (tgt::dot(clipplane.xyz(), closingFaceNormal) < 0)
            std::reverse(closingFaceVertices.begin(), closingFaceVertices.end());

        // Close convex polyhedron...
        for (VertexListType::iterator it = closingFaceVertices.begin(); it != closingFaceVertices.end(); ++it) {
            // TODO(b_bolt01): Remove debug message...
            //std::cout << " cfv " << it->getCoords() << std::endl;
            closingFace.addVertex(*it);
        }
        addFace(closingFace);
    }

    // If there is only the clipplane left, erase it also...
    if (faces_.size() == 1)
        faces_.clear();

    MeshGeometry closingMesh;
    if (closingFace.getVertexCount() > 0)
        closingMesh.addFace(closingFace);
    return closingMesh;
}
示例#4
0
void MeshGeometry::createCubeFaces(FaceGeometry& topFace, FaceGeometry& frontFace, FaceGeometry& leftFace,
                                   FaceGeometry& backFace, FaceGeometry& rightFace, FaceGeometry& bottomFace,
                                   tgt::vec3 coordLlf, tgt::vec3 coordUrb, tgt::vec3 texLlf,
                                   tgt::vec3 texUrb, tgt::vec3 colorLlf, tgt::vec3 colorUrb, float alpha)
{
    // expecting coordLlf < coordUrb
    if (coordLlf.x > coordUrb.x) {
        std::swap(coordLlf.x, coordUrb.x);
        std::swap(texLlf.x, texUrb.x);
        std::swap(colorLlf.x, colorUrb.x);
    }
    if (coordLlf.y > coordUrb.y) {
        std::swap(coordLlf.y, coordUrb.y);
        std::swap(texLlf.y, texUrb.y);
        std::swap(colorLlf.y, colorUrb.y);
    }
    if (coordLlf.z > coordUrb.z) {
        std::swap(coordLlf.z, coordUrb.z);
        std::swap(texLlf.z, texUrb.z);
        std::swap(colorLlf.z, colorUrb.z);
    }

    VertexGeometry llf(vec3(coordLlf.x, coordLlf.y, coordLlf.z), vec3(texLlf.x, texLlf.y, texLlf.z), vec4(colorLlf.x, colorLlf.y, colorLlf.z, alpha));
    VertexGeometry lrf(vec3(coordUrb.x, coordLlf.y, coordLlf.z), vec3(texUrb.x, texLlf.y, texLlf.z), vec4(colorUrb.x, colorLlf.y, colorLlf.z, alpha));
    VertexGeometry lrb(vec3(coordUrb.x, coordLlf.y, coordUrb.z), vec3(texUrb.x, texLlf.y, texUrb.z), vec4(colorUrb.x, colorLlf.y, colorUrb.z, alpha));
    VertexGeometry llb(vec3(coordLlf.x, coordLlf.y, coordUrb.z), vec3(texLlf.x, texLlf.y, texUrb.z), vec4(colorLlf.x, colorLlf.y, colorUrb.z, alpha));

    VertexGeometry ulb(vec3(coordLlf.x, coordUrb.y, coordUrb.z), vec3(texLlf.x, texUrb.y, texUrb.z), vec4(colorLlf.x, colorUrb.y, colorUrb.z, alpha));
    VertexGeometry ulf(vec3(coordLlf.x, coordUrb.y, coordLlf.z), vec3(texLlf.x, texUrb.y, texLlf.z), vec4(colorLlf.x, colorUrb.y, colorLlf.z, alpha));
    VertexGeometry urf(vec3(coordUrb.x, coordUrb.y, coordLlf.z), vec3(texUrb.x, texUrb.y, texLlf.z), vec4(colorUrb.x, colorUrb.y, colorLlf.z, alpha));
    VertexGeometry urb(vec3(coordUrb.x, coordUrb.y, coordUrb.z), vec3(texUrb.x, texUrb.y, texUrb.z), vec4(colorUrb.x, colorUrb.y, colorUrb.z, alpha));

    topFace.addVertex(urb);
    topFace.addVertex(urf);
    topFace.addVertex(ulf);
    topFace.addVertex(ulb);

    frontFace.addVertex(llf);
    frontFace.addVertex(ulf);
    frontFace.addVertex(urf);
    frontFace.addVertex(lrf);

    leftFace.addVertex(llf);
    leftFace.addVertex(llb);
    leftFace.addVertex(ulb);
    leftFace.addVertex(ulf);

    backFace.addVertex(urb);
    backFace.addVertex(ulb);
    backFace.addVertex(llb);
    backFace.addVertex(lrb);

    rightFace.addVertex(urb);
    rightFace.addVertex(lrb);
    rightFace.addVertex(lrf);
    rightFace.addVertex(urf);

    bottomFace.addVertex(llf);
    bottomFace.addVertex(lrf);
    bottomFace.addVertex(lrb);
    bottomFace.addVertex(llb);
}
void MultiPlanarProxyGeometry::process() {
    // input volume
    const VolumeBase* inputVolume = inport_.getData();
    tgtAssert(inputVolume, "No input volume");
    tgt::vec3 llf = inputVolume->getLLF();
    tgt::vec3 urb = inputVolume->getURB();
    tgt::vec3 texLlf = tgt::vec3(0.f);
    tgt::vec3 texUrb = tgt::vec3(1.f);

    //
    // x-face
    //
    const float slicePosX = llf.x + slicePosX_.get()*(urb.x - llf.x);
    const float sliceTexX = slicePosX_.get();
    VertexGeometry xLL(tgt::vec3(slicePosX, llf.y, llf.z), tgt::vec3(sliceTexX, texLlf.y, texLlf.z));
    VertexGeometry xLR(tgt::vec3(slicePosX, urb.y, llf.z), tgt::vec3(sliceTexX, texUrb.y, texLlf.z));
    VertexGeometry xUR(tgt::vec3(slicePosX, urb.y, urb.z), tgt::vec3(sliceTexX, texUrb.y, texUrb.z));
    VertexGeometry xUL(tgt::vec3(slicePosX, llf.y, urb.z), tgt::vec3(sliceTexX, texLlf.y, texUrb.z));

    FaceGeometry xFace;
    xFace.addVertex(xLL);
    xFace.addVertex(xLR);
    xFace.addVertex(xUR);
    xFace.addVertex(xUL);

    // We need to double each of the three faces with antiparallel normal vectors,
    // in order to make sure that we have front and back faces. This is necessary,
    // because the MeshEntryExitPoints processor derives the exit points from back faces.

    // these offsets are added to the back faces' slice and tex coords for preventing
    // the ray direction (exitPoint - entryPoint) becoming the null vector.
    const float texCoordOffset = 0.001f;
    const float sliceCoordOffset = 0.00001f;

    const float slicePosXBack = slicePosX-sliceCoordOffset;
    const float sliceTexXBack = sliceTexX-texCoordOffset;
    VertexGeometry xLLBack(tgt::vec3(slicePosXBack, llf.y, llf.z), tgt::vec3(sliceTexXBack, texLlf.y, texLlf.z));
    VertexGeometry xLRBack(tgt::vec3(slicePosXBack, urb.y, llf.z), tgt::vec3(sliceTexXBack, texUrb.y, texLlf.z));
    VertexGeometry xURBack(tgt::vec3(slicePosXBack, urb.y, urb.z), tgt::vec3(sliceTexXBack, texUrb.y, texUrb.z));
    VertexGeometry xULBack(tgt::vec3(slicePosXBack, llf.y, urb.z), tgt::vec3(sliceTexXBack, texLlf.y, texUrb.z));
    FaceGeometry xFaceBack;   //< reverse order of vertices for back face
    xFaceBack.addVertex(xLLBack);
    xFaceBack.addVertex(xULBack);
    xFaceBack.addVertex(xURBack);
    xFaceBack.addVertex(xLRBack);


    //
    // y-face
    //
    const float slicePosY = llf.y + slicePosY_.get()*(urb.y - llf.y);
    const float sliceTexY = slicePosY_.get();
    VertexGeometry yLL(tgt::vec3(llf.x, slicePosY, llf.z), tgt::vec3(texLlf.x, sliceTexY, texLlf.z));
    VertexGeometry yLR(tgt::vec3(urb.x, slicePosY, llf.z), tgt::vec3(texUrb.x, sliceTexY, texLlf.z));
    VertexGeometry yUR(tgt::vec3(urb.x, slicePosY, urb.z), tgt::vec3(texUrb.x, sliceTexY, texUrb.z));
    VertexGeometry yUL(tgt::vec3(llf.x, slicePosY, urb.z), tgt::vec3(texLlf.x, sliceTexY, texUrb.z));
    FaceGeometry yFace;
    yFace.addVertex(yLL);
    yFace.addVertex(yUL);
    yFace.addVertex(yUR);
    yFace.addVertex(yLR);

    // y back face (see above)
    const float slicePosYBack = slicePosY-sliceCoordOffset;
    const float sliceTexYBack = sliceTexY-texCoordOffset;
    VertexGeometry yLLBack(tgt::vec3(llf.x, slicePosYBack, llf.z), tgt::vec3(texLlf.x, sliceTexYBack, texLlf.z));
    VertexGeometry yLRBack(tgt::vec3(urb.x, slicePosYBack, llf.z), tgt::vec3(texUrb.x, sliceTexYBack, texLlf.z));
    VertexGeometry yURBack(tgt::vec3(urb.x, slicePosYBack, urb.z), tgt::vec3(texUrb.x, sliceTexYBack, texUrb.z));
    VertexGeometry yULBack(tgt::vec3(llf.x, slicePosYBack, urb.z), tgt::vec3(texLlf.x, sliceTexYBack, texUrb.z));
    FaceGeometry yFaceBack;
    yFaceBack.addVertex(yLLBack);
    yFaceBack.addVertex(yLRBack);
    yFaceBack.addVertex(yURBack);
    yFaceBack.addVertex(yULBack);


    //
    // z-face
    //
    const float slicePosZ = llf.z + slicePosZ_.get()*(urb.z - llf.z);
    const float sliceTexZ = slicePosZ_.get();
    VertexGeometry zLL(tgt::vec3(llf.x, llf.y, slicePosZ), tgt::vec3(texLlf.x, texLlf.y, sliceTexZ));
    VertexGeometry zLR(tgt::vec3(urb.x, llf.y, slicePosZ), tgt::vec3(texUrb.x, texLlf.y, sliceTexZ));
    VertexGeometry zUR(tgt::vec3(urb.x, urb.y, slicePosZ), tgt::vec3(texUrb.x, texUrb.y, sliceTexZ));
    VertexGeometry zUL(tgt::vec3(llf.x, urb.y, slicePosZ), tgt::vec3(texLlf.x, texUrb.y, sliceTexZ));
    FaceGeometry zFace;
    zFace.addVertex(zLL);
    zFace.addVertex(zLR);
    zFace.addVertex(zUR);
    zFace.addVertex(zUL);

    // z back face (see above)
    const float slicePosZBack = slicePosZ-sliceCoordOffset;
    const float sliceTexZBack = sliceTexZ-texCoordOffset;
    VertexGeometry zLLBack(tgt::vec3(llf.x, llf.y, slicePosZBack), tgt::vec3(texLlf.x, texLlf.y, sliceTexZBack));
    VertexGeometry zLRBack(tgt::vec3(urb.x, llf.y, slicePosZBack), tgt::vec3(texUrb.x, texLlf.y, sliceTexZBack));
    VertexGeometry zURBack(tgt::vec3(urb.x, urb.y, slicePosZBack), tgt::vec3(texUrb.x, texUrb.y, sliceTexZBack));
    VertexGeometry zULBack(tgt::vec3(llf.x, urb.y, slicePosZBack), tgt::vec3(texLlf.x, texUrb.y, sliceTexZBack));
    FaceGeometry zFaceBack;
    zFaceBack.addVertex(zLLBack);
    zFaceBack.addVertex(zULBack);
    zFaceBack.addVertex(zURBack);
    zFaceBack.addVertex(zLRBack);

    // construct output mesh from faces
    MeshGeometry* geometry = new MeshGeometry();
    geometry->addFace(xFace);
    geometry->addFace(xFaceBack);
    geometry->addFace(yFace);
    geometry->addFace(yFaceBack);
    geometry->addFace(zFace);
    geometry->addFace(zFaceBack);

    // assign vertex tex coords as vertex colors so the mesh can be rendered directly (debugging, ...)
    for (size_t faceID=0; faceID<geometry->getFaceCount(); faceID++) {
        for (size_t vertexID=0; vertexID<geometry->getFace(faceID).getVertexCount(); vertexID++) {
            tgt::vec3 texCoords = geometry->getFace(faceID).getVertex(vertexID).getTexCoords();
            geometry->getFace(faceID).getVertex(vertexID).setColor(texCoords);
        }
    }

    outport_.setData(geometry);
}