void VTKMeshFileExporter::execute() {
    if(mFilename == "")
        throw Exception("No filename given to the VTKMeshFileExporter");

    Mesh::pointer surface = getStaticInputData<Mesh>();

    // Get transformation
    AffineTransformation::pointer transform = SceneGraph::getAffineTransformationFromData(surface);

    std::ofstream file(mFilename.c_str());

    if(!file.is_open())
        throw Exception("Unable to open the file " + mFilename);

    // Write header
    file << "# vtk DataFile Version 3.0\n"
         "vtk output\n"
         "ASCII\n"
         "DATASET POLYDATA\n";

    // Write vertices
    MeshAccess::pointer access = surface->getMeshAccess(ACCESS_READ);
    std::vector<MeshVertex> vertices = access->getVertices();
    file << "POINTS " << vertices.size() << " float\n";
    for(int i = 0; i < vertices.size(); i++) {
        MeshVertex vertex = vertices[i];
        vertex.position = (transform->matrix()*vertex.position.homogeneous()).head(3);
        file << vertex.position.x() << " " << vertex.position.y() << " " << vertex.position.z() << "\n";
    }

    // Write triangles
    std::vector<Vector3ui> triangles = access->getTriangles();
    file << "POLYGONS " << surface->getNrOfTriangles() << " " << surface->getNrOfTriangles()*4 << "\n";
    for(int i = 0; i < triangles.size(); i++) {
        Vector3ui triangle = triangles[i];
        file << "3 " << triangle.x() << " " << triangle.y() << " " << triangle.z() << "\n";
    }

    // Write normals
    file << "POINT_DATA " << vertices.size() << "\n";
    file << "NORMALS Normals float\n";
    for(int i = 0; i < vertices.size(); i++) {
        MeshVertex vertex = vertices[i];
        // Transform it
        vertex.normal = transform->linear()*vertex.normal;
        // Normalize it
        float length = vertex.normal.norm();
        if(length == 0) { // prevent NaN situations
            file << "0 1 0\n";
        } else {
            file << (vertex.normal.x()/length) << " " << (vertex.normal.y()/length) << " " << (vertex.normal.z()/length) << "\n";
        }
    }

    file.close();
}
示例#2
0
int VTKMeshExporter::RequestData(
        vtkInformation* vtkNotUsed(request),
        vtkInformationVector** inputVector,
        vtkInformationVector* outputVector) {

    update(); // Run FAST pipeline

    Mesh::pointer input = getStaticInputData<Mesh>();
    MeshAccess::pointer access = input->getMeshAccess(ACCESS_READ);

    vtkInformation *outInfo = outputVector->GetInformationObject(0);

    vtkPolyData *output = this->GetOutput();

    vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
    points->SetNumberOfPoints(input->getNrOfVertices());

    for(int i = 0; i < input->getNrOfVertices(); i++) {
    	MeshVertex v = access->getVertex(i);
    	VectorXf position = v.getPosition();
		if(input->getDimensions() == 2) {
			points->SetPoint(i, position.x(), position.y(), 0);
		} else {
			points->SetPoint(i, position.x(), position.y(), position.z());
		}
	}
	output->SetPoints(points);

    vtkSmartPointer<vtkCellArray> polys = vtkSmartPointer<vtkCellArray>::New();
    if(input->getDimensions() == 2) {
		for(int i = 0; i < input->getNrOfLines(); i++) {
			VectorXui line = access->getLine(i);
			polys->InsertNextCell(2);
			polys->InsertCellPoint(line.x());
			polys->InsertCellPoint(line.y());
		}
		output->SetLines(polys);
    } else {
    	for(int i = 0; i < input->getNrOfTriangles(); i++) {
			VectorXui triangle = access->getTriangle(i);
			polys->InsertNextCell(3);
			polys->InsertCellPoint(triangle.x());
			polys->InsertCellPoint(triangle.y());
			polys->InsertCellPoint(triangle.z());
		}
		output->SetPolys(polys);
    }
    // TODO if 3D, also export normals

    return 1;
}
示例#3
0
void MeshRenderer::draw() {
    boost::lock_guard<boost::mutex> lock(mMutex);

    glEnable(GL_NORMALIZE);
    glShadeModel(GL_SMOOTH);
    glEnable(GL_LIGHTING);

    boost::unordered_map<uint, Mesh::pointer>::iterator it;
    for(it = mMeshToRender.begin(); it != mMeshToRender.end(); it++) {
        Mesh::pointer surfaceToRender = it->second;

        if(surfaceToRender->getDimensions() != 3)
        	continue;

        // Draw the triangles in the VBO
        AffineTransformation::pointer transform = SceneGraph::getAffineTransformationFromData(surfaceToRender);

        glPushMatrix();
        glMultMatrixf(transform->data());

        float opacity = mDefaultOpacity;
        Color color = mDefaultColor;
        ProcessObjectPort port = getInputPort(it->first);
        if(mInputOpacities.count(port) > 0) {
            opacity = mInputOpacities[port];
        }
        if(mInputColors.count(port) > 0) {
            color = mInputColors[port];
        }

        // Set material properties
        if(opacity < 1) {
            // Enable transparency
            glEnable(GL_BLEND);
            glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        }
        GLfloat GLcolor[] = { color.getRedValue(), color.getGreenValue(), color.getBlueValue(), opacity };
        glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, GLcolor);
        GLfloat specReflection[] = { mDefaultSpecularReflection, mDefaultSpecularReflection, mDefaultSpecularReflection, 1.0f };
        glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specReflection);
        GLfloat shininess[] = { 16.0f };
        glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, shininess);

        VertexBufferObjectAccess::pointer access = surfaceToRender->getVertexBufferObjectAccess(ACCESS_READ, getMainDevice());
        GLuint* VBO_ID = access->get();

        // Normal Buffer
        glBindBuffer(GL_ARRAY_BUFFER, *VBO_ID);
        glEnableClientState(GL_VERTEX_ARRAY);
        glEnableClientState(GL_NORMAL_ARRAY);

        glVertexPointer(3, GL_FLOAT, 24, 0);
        glNormalPointer(GL_FLOAT, 24, (float*)(sizeof(GLfloat)*3));

        glDrawArrays(GL_TRIANGLES, 0, surfaceToRender->getNrOfTriangles()*3);

        // Release buffer
        glBindBuffer(GL_ARRAY_BUFFER, 0);
        glDisableClientState(GL_VERTEX_ARRAY);
        glDisableClientState(GL_NORMAL_ARRAY);
        if(opacity < 1) {
            // Disable transparency
            glDisable(GL_BLEND);
        }
        glPopMatrix();
    }

    glDisable(GL_LIGHTING);
    glDisable(GL_NORMALIZE);
    glColor3f(1.0f, 1.0f, 1.0f); // Reset color
}
示例#4
0
void MeshRenderer::draw2D(
                cl::BufferGL PBO,
                uint width,
                uint height,
                Eigen::Transform<float, 3, Eigen::Affine> pixelToViewportTransform,
                float PBOspacing,
                Vector2f translation
        ) {
    boost::lock_guard<boost::mutex> lock(mMutex);

    OpenCLDevice::pointer device = getMainDevice();
    cl::CommandQueue queue = device->getCommandQueue();
    std::vector<cl::Memory> v;
    v.push_back(PBO);
    queue.enqueueAcquireGLObjects(&v);

    // Map would probably be better here, but doesn't work on NVIDIA, segfault surprise!
    //float* pixels = (float*)queue.enqueueMapBuffer(PBO, CL_TRUE, CL_MAP_WRITE, 0, width*height*sizeof(float)*4);
    boost::shared_array<float> pixels(new float[width*height*sizeof(float)*4]);
    queue.enqueueReadBuffer(PBO, CL_TRUE, 0, width*height*4*sizeof(float), pixels.get());

    boost::unordered_map<uint, Mesh::pointer>::iterator it;
    for(it = mMeshToRender.begin(); it != mMeshToRender.end(); it++) {
    	Mesh::pointer mesh = it->second;
    	if(mesh->getDimensions() != 2) // Mesh must be 2D
    		continue;

		Color color = mDefaultColor;
        ProcessObjectPort port = getInputPort(it->first);
        if(mInputColors.count(port) > 0) {
            color = mInputColors[port];
        }

    	MeshAccess::pointer access = mesh->getMeshAccess(ACCESS_READ);
        std::vector<VectorXui> lines = access->getLines();
        std::vector<MeshVertex> vertices = access->getVertices();

        // Draw each line
        for(int i = 0; i < lines.size(); ++i) {
        	Vector2ui line = lines[i];
        	Vector2f a = vertices[line.x()].getPosition();
        	Vector2f b = vertices[line.y()].getPosition();
        	Vector2f direction = b - a;
        	float lengthInPixels = ceil(direction.norm() / PBOspacing);

        	// Draw the line
        	for(int j = 0; j <= lengthInPixels; ++j) {
        		Vector2f positionInMM = a + direction*((float)j/lengthInPixels);
        		Vector2f positionInPixels = positionInMM / PBOspacing;

        		int x = round(positionInPixels.x());
        		int y = round(positionInPixels.y());
        		y = height - 1 - y;
        		if(x < 0 || y < 0 || x >= width || y >= height)
        			continue;

        		pixels[4*(x + y*width)] = color.getRedValue();
        		pixels[4*(x + y*width) + 1] = color.getGreenValue();
        		pixels[4*(x + y*width) + 2] = color.getBlueValue();
        	}
        }
    }

    //queue.enqueueUnmapMemObject(PBO, pixels);
    queue.enqueueWriteBuffer(PBO, CL_TRUE, 0, width*height*4*sizeof(float), pixels.get());
    queue.enqueueReleaseGLObjects(&v);
}
void VTKMeshFileImporter::execute() {
    if(mFilename == "")
        throw Exception("No filename given to the VTKMeshFileImporter");

    // Try to open file and check that it exists
    std::ifstream file(mFilename.c_str());
    std::string line;
    if(!file.is_open()) {
        throw FileNotFoundException(mFilename);
    }

    // Check file header?

    // Read vertices
    std::vector<Vector3f> vertices;
    if(!gotoLineWithString(file, "POINTS")) {
        throw Exception("Found no vertices in the VTK surface file");
    }
    while(getline(file, line)) {
        boost::trim(line);
        if(line.size() == 0)
            break;

        if(!(isdigit(line[0]) || line[0] == '-')) {
            // Has reached end
            break;
        }

        std::vector<std::string> tokens;
        boost::split(tokens, line, boost::is_any_of(" "));

        for(int i = 0; i < tokens.size(); i += 3) {
            Vector3f v;
            v(0) = boost::lexical_cast<float>(tokens[i]);
            v(1) = boost::lexical_cast<float>(tokens[i+1]);
            v(2) = boost::lexical_cast<float>(tokens[i+2]);
            vertices.push_back(v);
        }
    }
    file.seekg(0); // set stream to start

    // Read triangles (other types of polygons not supported yet)
    std::vector<Vector3ui> triangles;
    if(!gotoLineWithString(file, "POLYGONS")) {
        throw Exception("Found no triangles in the VTK surface file");
    }
    while(getline(file, line)) {
        boost::trim(line);
        if(line.size() == 0)
            break;

        if(!isdigit(line[0])) {
            // Has reached end
            break;
        }


        std::vector<std::string> tokens;
        boost::split(tokens, line, boost::is_any_of(" "));

        if(boost::lexical_cast<int>(tokens[0]) != 3) {
            throw Exception("The VTKMeshFileImporter currently only supports reading files with triangles. Encountered a non-triangle. Aborting.");
        }
        if(tokens.size() != 4) {
            throw Exception("Error while reading triangles in VTKMeshFileImporter. Check format.");
        }

        Vector3ui triangle;
        triangle(0) = boost::lexical_cast<uint>(tokens[1]);
        triangle(1) = boost::lexical_cast<uint>(tokens[2]);
        triangle(2) = boost::lexical_cast<uint>(tokens[3]);

        triangles.push_back(triangle);

    }
    file.seekg(0); // set stream to start

    // Read normals (if any)
    std::vector<Vector3f> normals;
    if(!gotoLineWithString(file, "NORMALS")) {
        // Create dummy normals
        for(uint i = 0; i < vertices.size(); i++) {
            Vector3f dummyNormal;
            normals.push_back(dummyNormal);
        }
    } else {
        while(getline(file, line)) {
            boost::trim(line);
            if(line.size() == 0)
                break;

            if(!(isdigit(line[0]) || line[0] == '-')) {
                // Has reached end
                break;
            }

            std::vector<std::string> tokens;
            boost::split(tokens, line, boost::is_any_of(" "));

            for(int i = 0; i < tokens.size(); i += 3) {
                Vector3f v;
                v(0) = boost::lexical_cast<float>(tokens[i]);
                v(1) = boost::lexical_cast<float>(tokens[i+1]);
                v(2) = boost::lexical_cast<float>(tokens[i+2]);
                normals.push_back(v);
            }
        }

        if(normals.size() != vertices.size()) {
            std::string message = "Read different amount of vertices (" + boost::lexical_cast<std::string>(vertices.size()) + ") and normals (" + boost::lexical_cast<std::string>(normals.size()) + ").";
            throw Exception(message);
        }
    }

    Mesh::pointer output = getOutputData<Mesh>(0);

    // Add data to output
    output->create(vertices, normals, triangles);
    reportInfo() << "MESH IMPORTED vertices " << vertices.size() << " normals " << normals.size() << " triangles " << triangles.size() << Reporter::end;
}