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(); }
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; }
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 }
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; }