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; }
MeshListGeometry* ROICube::generateNormalizedMesh(tgt::plane pl) const { FaceGeometry planeFace = createQuad(pl, getColor()); vec4 xm(-1.0f, 0.0f, 0.0f, 1.0f); vec4 xp(1.0f, 0.0f, 0.0f, 1.0f); vec4 ym(0.0f, -1.0f, 0.0f, 1.0f); vec4 yp(0.0f, 1.0f, 0.0f, 1.0f); vec4 zm(0.0f, 0.0f, -1.0f, 1.0f); vec4 zp(0.0f, 0.0f, 1.0f, 1.0f); planeFace.clip(xm); planeFace.clip(xp); planeFace.clip(ym); planeFace.clip(yp); planeFace.clip(zm); planeFace.clip(zp); MeshGeometry mg; if(planeFace.getVertexCount() > 2) mg.addFace(planeFace); MeshListGeometry* mlg = new MeshListGeometry(); mlg->addMesh(mg); return mlg; }
void MultiVolumeProxyGeometry::process() { tgtAssert(inport_.getData()->getVolume(), "no volume"); tgtAssert(geometry_, "no geometry object"); geometry_->clear(); std::vector<VolumeHandle*> data = inport_.getAllData(); for(size_t d=0; d<data.size(); ++d) { if(!data[d]) continue; Volume* volume = data[d]->getVolume(); tgt::vec3 volumeSize = volume->getCubeSize(); tgt::vec3 coordLlf = -(volumeSize / static_cast<tgt::vec3::ElemType>(2)); tgt::vec3 coordUrb = (volumeSize / static_cast<tgt::vec3::ElemType>(2)); MeshGeometry mesh = MeshGeometry::createCube(coordLlf, coordUrb, coordLlf, coordUrb); //apply dataset transformation matrix: mesh.transform(volume->getTransformation()); //reset tex coords to coords after transformation: for(size_t j=0; j<mesh.getFaceCount(); ++j) { FaceGeometry& fg = mesh.getFace(j); for(size_t k=0; k<fg.getVertexCount(); ++k) { VertexGeometry& vg = fg.getVertex(k); vg.setTexCoords(vg.getCoords()); } } geometry_->addMesh(mesh); } outport_.setData(geometry_); }
void MultiVolumeProxyGeometry::process() { tgtAssert(inport_.getData()->getRepresentation<VolumeRAM>(), "no volume"); MeshListGeometry* geometry = new MeshListGeometry(); std::vector<const VolumeBase*> data = inport_.getAllData(); for(size_t d=0; d<data.size(); ++d) { if(!data[d]) continue; const VolumeBase* volume = data[d]; tgt::vec3 coordLlf = volume->getLLF(); tgt::vec3 coordUrb = volume->getURB(); MeshGeometry mesh = MeshGeometry::createCube(coordLlf, coordUrb, coordLlf, coordUrb); //apply dataset transformation matrix: mesh.transform(volume->getPhysicalToWorldMatrix()); //reset tex coords to coords after transformation: for(size_t j=0; j<mesh.getFaceCount(); ++j) { FaceGeometry& fg = mesh.getFace(j); for(size_t k=0; k<fg.getVertexCount(); ++k) { VertexGeometry& vg = fg.getVertex(k); vg.setTexCoords(vg.getCoords()); } } geometry->addMesh(mesh); } outport_.setData(geometry); }
void HypercubeBuilder::rebuildProjections() { MeshListGeometry* geom = new MeshListGeometry(); // Для каждой проекции: //for (size_t i = 0; i < numProjections; i++) { const MatrixXd points = projection->getPointsMatrix(); const VectorXd distances = projection->getDistanceVector(); size_t numPoints = projection->getNumPoints(); size_t numEdges = projection->getNumEdges(); size_t numFaces = projection->getNumFaces(); double maxD = distance_.get(); // 1) Строим проекции вершин. Отображаем их кубами for (size_t j = 0; j < numPoints; j++) { double d = distances(j); if (d > maxD) continue; double a = vertexSize_.get() * 1 / (1 + d) / 10; tgt::vec3 cubeSize(a,a,a); tgt::vec3 point = pointToVec3(points, j); geom->addMesh(MeshGeometry::createCube(point-cubeSize, point+cubeSize)); } // 2) Строим проекции ребер. Отображаем их цилиндрами if (drawEdges_.get() == true) for (size_t j = 0; j < numEdges; j++) { Edge e = projection->getEdge(j); size_t i1 = e.getV1(); size_t i2 = e.getV2(); if (distances(i1) > maxD || distances(i2) > maxD) continue; tgt::vec3 v1 = pointToVec3(points, i1); tgt::vec3 v2 = pointToVec3(points, i2); geom->addMesh(PrimitiveGeometryBuilder::createCylinder(v1, v2, edgeSize_.get() / 10, 4, tgt::vec3(1.,1.,0))); } // 3) Строим проекции граней if (drawFaces_.get() == true) { MeshGeometry mesh; for (size_t j = 0; j < numFaces; j++) { Face f = projection->getFace(j); std::vector<size_t> fv = f.getVertices(); std::vector<tgt::vec3> projections; for (size_t k = 0; k < fv.size(); k++) { projections.push_back(pointToVec3(points, fv[k])); } bool br = false; for (size_t k = 0; k < fv.size(); k++) { if (distances(fv[k]) > maxD) br = true; } if (br == true) continue; mesh.addFace(PrimitiveGeometryBuilder::createFace(projections, tgt::vec4(1,1,0,0.7))); } geom->addMesh(mesh); } //} // Delete old geometry and set new outport_.setData(geom); }
void MeshListGeometry::clip(const tgt::vec4& clipPlane, MeshListGeometry& closingFaces, double epsilon) { tgtAssert(epsilon >= 0.0, "negative epsilon"); for (iterator it = begin(); it != end(); ++it) { MeshGeometry closingFace; it->clip(clipPlane, closingFace, epsilon); if (!closingFace.empty()) closingFaces.addMesh(closingFace); } }
MeshListGeometry MeshListGeometry::clip(const tgt::vec4& clipplane, double epsilon) { MeshListGeometry closingFaces; for (iterator it = begin(); it != end(); ++it) { MeshGeometry closingFace = it->clip(clipplane, epsilon); if (!closingFace.empty()) closingFaces.addMesh(closingFace); } return closingFaces; }
static MeshGeometry* ConvertObjMesh(istream& in, TextureMapLoader* textureLoader, const std::string& pathName) { ObjLoader loader; ObjMaterialLibrary* materialLibrary = NULL; MeshGeometry* mesh = loader.loadModel(in); if (mesh) { if (!loader.materialLibrary().empty()) { string materialLibraryFileName = pathName + loader.materialLibrary(); ifstream matStream(materialLibraryFileName.c_str(), ios::in); if (!matStream.good()) { VESTA_LOG("Can't find material library file '%s' for OBJ format mesh", materialLibraryFileName.c_str()); } else { ObjMaterialLibraryLoader matLoader(textureLoader); materialLibrary = matLoader.loadMaterials(matStream); } } if (materialLibrary) { const vector<string>& materials = loader.materials(); for (unsigned int i = 0; i < materials.size(); ++i) { string materialName = materials[i]; if (!materialName.empty()) { Material* material = materialLibrary->material(materialName); if (material) { Material* meshMaterial = mesh->material(i); if (meshMaterial) { *meshMaterial = *material; } } else { VESTA_LOG("Missing material in OBJ file: '%s'", materialName.c_str()); } } } delete materialLibrary; } } return mesh; }
//----------------------------------------------------------------------------- void _check_coordinates(const MeshGeometry& geometry, const Function& position) { dolfin_assert(position.function_space()); dolfin_assert(position.function_space()->mesh()); dolfin_assert(position.function_space()->dofmap()); dolfin_assert(position.function_space()->element()); dolfin_assert(position.function_space()->element()->ufc_element()); if (position.function_space()->element()->ufc_element()->family() != std::string("Lagrange")) { dolfin_error("fem_utils.cpp", "set/get mesh geometry coordinates from/to function", "expecting 'Lagrange' finite element family rather than '%s'", position.function_space()->element()->ufc_element()->family()); } if (position.value_rank() != 1) { dolfin_error("fem_utils.cpp", "set/get mesh geometry coordinates from/to function", "function has incorrect value rank %d, need 1", position.value_rank()); } if (position.value_dimension(0) != geometry.dim()) { dolfin_error("fem_utils.cpp", "set/get mesh geometry coordinates from/to function", "function value dimension %d and geometry dimension %d " "do not match", position.value_dimension(0), geometry.dim()); } if (position.function_space()->element()->ufc_element()->degree() != geometry.degree()) { dolfin_error("fem_utils.cpp", "set/get mesh geometry coordinates from/to function", "function degree %d and geometry degree %d do not match", position.function_space()->element()->ufc_element()->degree(), geometry.degree()); } }
voreen::MeshGeometry MeshGeometry::createCube(tgt::vec3 coordLlf, tgt::vec3 coordUrb, tgt::vec3 texLlf, tgt::vec3 texUrb, tgt::vec3 colorLlf, tgt::vec3 colorUrb, tgt::vec3 normalTop, tgt::vec3 normalFront, tgt::vec3 normalLeft, tgt::vec3 normalBack, tgt::vec3 normalRight, tgt::vec3 normalBottom, float alpha) { FaceGeometry top, front, left, back, right, bottom; createCubeFaces(top, front, left, back, right, bottom, coordLlf, coordUrb, texLlf, texUrb, colorLlf, colorUrb, alpha); top.setFaceNormal(normalTop); front.setFaceNormal(normalFront); left.setFaceNormal(normalLeft); back.setFaceNormal(normalBack); right.setFaceNormal(normalRight); bottom.setFaceNormal(normalBottom); MeshGeometry mesh; mesh.addFace(top); mesh.addFace(front); mesh.addFace(left); mesh.addFace(back); mesh.addFace(right); mesh.addFace(bottom); return mesh; }
MeshGeometry MeshGeometry::createCube(vec3 coordLlf, vec3 coordUrb, vec3 texLlf, vec3 texUrb, vec3 colorLlf, vec3 colorUrb, float alpha) { FaceGeometry top, front, left, back, right, bottom; createCubeFaces(top, front, left, back, right, bottom, coordLlf, coordUrb, texLlf, texUrb, colorLlf, colorUrb, alpha); MeshGeometry mesh; mesh.addFace(top); mesh.addFace(front); mesh.addFace(left); mesh.addFace(back); mesh.addFace(right); mesh.addFace(bottom); return mesh; }
std::pair<RenderData*, RenderData*> MultiVolumeRaycaster::computeEntryExitPoints(const std::vector<const ImageRepresentationGL*>& images, const CameraData* camera, const RenderData* geometryImage) { cgtAssert(_eepShader != nullptr, "EEP Shader must not be 0."); const cgt::Camera& cam = camera->getCamera(); // construct bounding box for all images cgt::Bounds b; for (size_t i = 0; i < images.size(); ++i) { b.addVolume(images[i]->getParent()->getWorldBounds()); } // create proxy geometry std::unique_ptr<MeshGeometry> cube(GeometryDataFactory::createCube(b, b)); // clip proxy geometry against near-plane to support camera in volume float nearPlaneDistToOrigin = cgt::dot(cam.getPosition(), -cam.getLook()) - cam.getNearDist() - .002f; MeshGeometry clipped = cube->clipAgainstPlane(nearPlaneDistToOrigin, -cam.getLook(), true, 0.02f); _eepShader->activate(); cgt::TextureUnit geometryDepthUnit, entryDepthUnit; _eepShader->setUniform("_viewportSizeRCP", 1.f / cgt::vec2(getEffectiveViewportSize())); _eepShader->setUniform("_projectionMatrix", cam.getProjectionMatrix()); _eepShader->setUniform("_viewMatrix", cam.getViewMatrix()); if (geometryImage != nullptr) { geometryImage->bindDepthTexture(_eepShader, geometryDepthUnit, "_geometryDepthTexture", "_geometryDepthTexParams"); _eepShader->setUniform("_integrateGeometry", true); _eepShader->setUniform("_near", cam.getNearDist()); _eepShader->setUniform("_far", cam.getFarDist()); cgt::mat4 inverseView = cgt::mat4::identity; if (cam.getViewMatrix().invert(inverseView)) _eepShader->setUniform("_inverseViewMatrix", inverseView); cgt::mat4 inverseProjection = cgt::mat4::identity; if (cam.getProjectionMatrix().invert(inverseProjection)) _eepShader->setUniform("_inverseProjectionMatrix", inverseProjection); } else { _eepShader->setUniform("_integrateGeometry", false); } glEnable(GL_CULL_FACE); glEnable(GL_DEPTH_TEST); // create entry points texture FramebufferActivationGuard f*g(this); createAndAttachTexture(GL_RGBA32F); createAndAttachDepthTexture(); _eepShader->setUniform("_isEntrypoint", true); glDepthFunc(GL_LESS); glClearDepth(1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glCullFace(GL_BACK); clipped.render(GL_TRIANGLE_FAN); RenderData* entrypoints = new RenderData(_fbo); _fbo->detachAll(); // create exit points texture createAndAttachTexture(GL_RGBA32F); createAndAttachDepthTexture(); _eepShader->setUniform("_isEntrypoint", false); if (geometryImage != nullptr) { entrypoints->bindDepthTexture(_eepShader, entryDepthUnit, "_entryDepthTexture", "_entryDepthTexParams"); } glDepthFunc(GL_GREATER); glClearDepth(0.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glCullFace(GL_FRONT); clipped.render(GL_TRIANGLE_FAN); RenderData* exitpoints = new RenderData(_fbo); decorateRenderEpilog(_eepShader); _eepShader->deactivate(); glDepthFunc(GL_LESS); glClearDepth(1.0f); glCullFace(GL_BACK); glDisable(GL_CULL_FACE); glDisable(GL_DEPTH_TEST); _eepShader->deactivate(); LGL_ERROR; return std::make_pair(entrypoints, exitpoints); }
static MeshGeometry* Convert3DSMesh(Lib3dsFile* meshfile, TextureMapLoader* textureLoader) { MeshGeometry* meshGeometry = new MeshGeometry(); for (int materialIndex = 0; materialIndex < meshfile->nmaterials; ++materialIndex) { Lib3dsMaterial* material = meshfile->materials[materialIndex]; Material* vmaterial = new Material(); // Convert a 3ds material to VESTA material vmaterial->setOpacity(1.0f - material->transparency); vmaterial->setDiffuse(Spectrum(material->diffuse)); if (material->shininess != 0.0f) { vmaterial->setSpecular(Spectrum(material->specular)); vmaterial->setPhongExponent(std::pow(2.0f, 1.0f + 10.0f * material->shininess)); } if (material->self_illum_flag) { vmaterial->setEmission(vmaterial->diffuse() * material->self_illum); } const string baseTextureName(material->texture1_map.name); if (!baseTextureName.empty()) { TextureProperties texProperties; if ((material->texture1_map.flags & LIB3DS_TEXTURE_NO_TILE) != 0) { texProperties.addressS = TextureProperties::Clamp; texProperties.addressT = TextureProperties::Clamp; } if (textureLoader) { TextureMap* baseTexture = textureLoader->loadTexture(baseTextureName, texProperties); vmaterial->setBaseTexture(baseTexture); } } meshGeometry->addMaterial(vmaterial); } for (int meshIndex = 0; meshIndex < meshfile->nmeshes; ++meshIndex) { Lib3dsMesh* mesh = meshfile->meshes[meshIndex]; if (mesh->nfaces > 0) { bool hasTextureCoords = mesh->texcos != 0; // Generate normals for the mesh float* normals = new float[mesh->nfaces * 9]; lib3ds_mesh_calculate_vertex_normals(mesh, (float(*)[3]) normals); VertexPool vertexPool; for (int faceIndex = 0; faceIndex < mesh->nfaces; ++faceIndex) { for (int i = 0; i < 3; i++) { int vertexIndex = mesh->faces[faceIndex].index[i]; vertexPool.addVec3(mesh->vertices[vertexIndex]); vertexPool.addVec3(&normals[(faceIndex * 3 + i) * 3]); if (hasTextureCoords) { // Invert the v texture coordinate, since 3ds uses a texture // coordinate system that is flipped with respect to OpenGL's vertexPool.addVec2(mesh->texcos[vertexIndex][0], 1.0f - mesh->texcos[vertexIndex][1]); } } } delete[] normals; const VertexSpec* vertexSpec = hasTextureCoords ? &VertexSpec::PositionNormalTex : &VertexSpec::PositionNormal; VertexArray* vertexArray = vertexPool.createVertexArray(mesh->nfaces * 3, *vertexSpec); PrimitiveBatch* batch = new PrimitiveBatch(PrimitiveBatch::Triangles, mesh->nfaces); // Get the material for the primitive batch // TODO: This assumes that a single material is applied to the whole mesh; however, // materials can be assigned per-face (but rarely are in most 3ds files.) unsigned int materialIndex = Submesh::DefaultMaterialIndex; if (mesh->nfaces > 0) { // Use the material of the first face materialIndex = mesh->faces[0].material; } Submesh* submesh = new Submesh(vertexArray); submesh->addPrimitiveBatch(batch, materialIndex); meshGeometry->addSubmesh(submesh); } } return meshGeometry; }
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); }
MeshGeometry* CmodLoader::loadMesh() { char headerData[16]; if (m_inputStream->readRawData(headerData, sizeof(headerData)) != sizeof(headerData)) { setError("Error reading header"); return NULL; } QString header = QString::fromLatin1(headerData, sizeof(headerData)); if (header == "#celmodel__ascii") { setError("ASCII cmod files are not supported"); return NULL; } else if (header != "#celmodel_binary") { setError("Wrong header; file is not a cmod mesh file"); return NULL; } MeshGeometry* mesh = new MeshGeometry(); // Add the default material Material* defaultMaterial = new Material(); defaultMaterial->setDiffuse(Spectrum::Flat(0.8f)); defaultMaterial->setBrdf(Material::Lambert); mesh->addMaterial(defaultMaterial); bool done = false; unsigned int meshCount = 0; while (!done && !error()) { CmodToken token = readCmodToken(); if (m_inputStream->atEnd()) { done = true; } else if (token == CmodMaterial) { if (meshCount > 0) { setError("Materials must be appear before any meshes"); } Material* material = loadMaterial(); if (material) { mesh->addMaterial(material); } } else if (token == CmodMesh) { Submesh* submesh = loadSubmesh(); if (submesh) { mesh->addSubmesh(submesh); } } else { setError("Unrecognized block in cmod (not a mesh or material)"); } } if (error()) { delete mesh; mesh = NULL; } return mesh; }
void VolumeSlicer::setupUniforms(tgt::Shader* slicingPrg) { if(!volumeInport_.isReady()) return; tgt::vec3 camPos = camera_.get().getPosition(); tgt::vec3 camLook = camera_.get().getLook(); // Handle Transformation matrix of dataset. tgt::mat4 invTransMat = volumeInport_.getData()->getWorldToPhysicalMatrix(); camPos = (invTransMat * tgt::vec4(camPos, 1.0)).xyz(); camLook = normalize((invTransMat * tgt::vec4(camLook, 0.0)).xyz()); tgt::vec3 urb; tgt::vec3 llf; // disable other than cube-formed proxygeometries for now if(!geometryInport_.isReady()) { MeshGeometry meshGeometry = volumeInport_.getData()->getBoundingBox(false); FaceGeometry f1 = meshGeometry[0]; FaceGeometry f2 = meshGeometry[1]; urb = meshGeometry.getTransformationMatrix() * f1[0].getCoords(); llf = meshGeometry.getTransformationMatrix() * f2[0].getCoords(); } else { //tgt::Bounds b = geometryInport_.getData()->getBoundingBox(true); tgt::Bounds b = geometryInport_.getData()->getBoundingBox(false); tgt::mat4 m = geometryInport_.getData()->getTransformationMatrix(); urb = m * b.getURB(); llf = m * b.getLLF(); urb = (invTransMat * tgt::vec4(urb, 1.0)).xyz(); llf = (invTransMat * tgt::vec4(llf, 1.0)).xyz(); } cubeVertices_[0] = tgt::vec3(llf.x, urb.y, urb.z); cubeVertices_[1] = tgt::vec3(urb.x, urb.y, urb.z); cubeVertices_[2] = tgt::vec3(llf.x, urb.y, llf.z); cubeVertices_[3] = tgt::vec3(llf.x, llf.y, urb.z); cubeVertices_[4] = tgt::vec3(urb.x, llf.y, urb.z); cubeVertices_[5] = tgt::vec3(urb.x, urb.y, llf.z); cubeVertices_[6] = tgt::vec3(llf.x, llf.y, llf.z); cubeVertices_[7] = tgt::vec3(urb.x, llf.y, llf.z); // compute front index needed for clipping float minCameraDistance = std::numeric_limits<float>::max(); // distance between camera and closest vertex float maxCameraDistance = 0.0; for (unsigned int i=0;i<8;i++) { float cameraDistance = dot(camLook, cubeVertices_[i] - camPos); if (cameraDistance < minCameraDistance) { minCameraDistance = cameraDistance; frontIdx_ = i; } if (cameraDistance > maxCameraDistance) { maxCameraDistance = cameraDistance; backIdx_ = i; } } maxLength_ = dot(camLook, cubeVertices_[backIdx_] - cubeVertices_[frontIdx_]); // acquire volume size for sampling tgt::ivec3 dim = volumeInport_.getData()->getRepresentation<VolumeGL>()->getTexture()->getDimensions(); // compute the distance between two adjacent slices in texture coordinates sliceDistance_ = maxLength_ / (tgt::max(dim) * samplingRate_.get()); //if (interactionMode()) // sliceDistance /= interactionQuality_.get(); //clipping uniforms slicingPrg->setUniform("frontIdx_", frontIdx_); slicingPrg->setUniform("vecView_", camLook); slicingPrg->setUniform("dPlaneStart_", dot(camLook, cubeVertices_[frontIdx_])); slicingPrg->setUniform("dPlaneIncr_", sliceDistance_); slicingPrg->setUniform("nSequence_", nSeq_, 64); slicingPrg->setUniform("vecVertices_", cubeVertices_, 8); slicingPrg->setUniform("v1_", v1_, 24); slicingPrg->setUniform("v2_", v2_, 24); }
//------------------------------------------------------------------------------ //! void DFPolygonRenderable::update() { Vector<float> egver; // vec3: pos, vec3: color Vector<float> vgver; // vec3: pos, vec3: color, flt: size Vector<uint32_t> eindices; Vector<uint32_t> vindices; const DFPolygon* poly = _editor->polygon(); // Vertices. for( auto v = poly->begin(); v != poly->end(); ++v ) { vindices.pushBack( uint(vindices.size()) ); pushBack( vgver, (*v) ); pushBack( vgver, _col_v_default ); pushBack( vgver, _siz_v_default ); pushBack( egver, (*v) ); pushBack( egver, _col_e_default ); } // Edges. const uint n = uint(poly->numVertices()); for( uint i = 0, j = n-1; i < n; j=i++ ) { eindices.pushBack( j ); eindices.pushBack( i ); } // Tweak for selection. auto& selection = _editor->selection(); for( auto cur = selection.begin(); cur != selection.end(); ++cur ) { float* ptr = vgver.data() + cur->_idx*7; Vec3f::as( ptr+3 ) = (*cur) == selection.last() ? _col_v_selected_p : _col_v_selected_s; ptr[6] = _siz_v_selected; } // Updating the meshes. MeshGeometry* emesh = edgeMesh(); MeshGeometry* vmesh = vertexMesh(); emesh->clearPatches(); emesh->deallocate(); if( !egver.empty() ) { emesh->allocateIndices( uint(eindices.size()) ); emesh->copyIndices( eindices.data() ); emesh->allocateVertices( uint(egver.size())/6 ); emesh->copyAttributes( egver.data(), 6, 6, 0 ); emesh->addPatch( 0, uint(eindices.size()) ); } emesh->updateProperties(); emesh->invalidateRenderableGeometry(); vmesh->clearPatches(); vmesh->deallocate(); if( !vgver.empty() ) { vmesh->allocateIndices( uint(vindices.size()) ); vmesh->copyIndices( vindices.data() ); vmesh->allocateVertices( uint(vgver.size())/7 ); vmesh->copyAttributes( vgver.data(), 7, 7, 0 ); vmesh->addPatch( 0, uint(vindices.size()) ); } vmesh->updateProperties(); vmesh->invalidateRenderableGeometry(); }
void SliceRenderer3D::updateResult(DataContainer& data) { std::cout << "Entering updateResult of SliceRenderer3D " << std::endl; ImageRepresentationGL::ScopedRepresentation img(data, p_sourceImageID.getValue()); ScopedTypedData<CameraData> camera(data, p_camera.getValue()); if (img != nullptr && camera != nullptr) { if (img->getDimensionality() == 3) { const cgt::Camera& cam = camera->getCamera(); // Creating the slice proxy geometry works as follows: // Create the cube proxy geometry for the volume, then clip the cube against the slice plane. // The closing face is the slice proxy geometry. // This is probably not the fastest, but an elegant solution, which also supports arbitrary slice orientations. :) cgt::Bounds volumeExtent = img->getParent()->getWorldBounds(); std::unique_ptr<MeshGeometry> cube = GeometryDataFactory::createCube(volumeExtent, cgt::Bounds(cgt::vec3(0.f), cgt::vec3(1.f))); cgt::vec3 normal(0.f, 0.f, 0.f); float p = 0.0f; switch (p_sliceOrientation.getOptionValue()) { case XY_PLANE: normal = cgt::vec3(0.f, 0.f, 1.f); p = img->getParent()->getMappingInformation().getOffset().z + (p_sliceNumber.getValue() * img->getParent()->getMappingInformation().getVoxelSize().z); break; case XZ_PLANE: normal = cgt::vec3(0.f, 1.f, 0.f); p = img->getParent()->getMappingInformation().getOffset().y + (p_sliceNumber.getValue() * img->getParent()->getMappingInformation().getVoxelSize().y); break; case YZ_PLANE: normal = cgt::vec3(1.f, 0.f, 0.f); p = img->getParent()->getMappingInformation().getOffset().x + (p_sliceNumber.getValue() * img->getParent()->getMappingInformation().getVoxelSize().x); break; } MeshGeometry clipped = cube->clipAgainstPlane(p, normal, true); const FaceGeometry& slice = clipped.getFaces().back(); // the last face is the closing face glEnable(GL_DEPTH_TEST); _shader->activate(); _shader->setIgnoreUniformLocationError(true); _shader->setUniform("_viewportSizeRCP", 1.f / cgt::vec2(getEffectiveViewportSize())); _shader->setUniform("_projectionMatrix", cam.getProjectionMatrix()); _shader->setUniform("_viewMatrix", cam.getViewMatrix()); cgt::TextureUnit inputUnit, tfUnit; img->bind(_shader, inputUnit); p_transferFunction.getTF()->bind(_shader, tfUnit); FramebufferActivationGuard f*g(this); createAndAttachColorTexture(); createAndAttachDepthTexture(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); slice.render(GL_TRIANGLE_FAN); _shader->deactivate(); cgt::TextureUnit::setZeroUnit(); glDisable(GL_DEPTH_TEST); data.addData(p_targetImageID.getValue(), new RenderData(_fbo)); } else { LERROR("Input image must have dimensionality of 3."); } } else { LDEBUG("No suitable input image found."); } std::cout << "Exiting updateResult of SliceRenderer3D " << std::endl; }
//----------------------------------------------------------------------------- // This helper function sets geometry from position (if setting) or stores // geometry into position (otherwise) void _get_set_coordinates(MeshGeometry& geometry, Function& position, const bool setting) { auto& x = geometry.x(); auto& v = *position.vector(); const auto& dofmap = *position.function_space()->dofmap(); const auto& mesh = *position.function_space()->mesh(); const auto tdim = mesh.topology().dim(); const auto gdim = mesh.geometry().dim(); std::vector<std::size_t> num_local_entities(tdim+1); std::vector<std::size_t> coords_per_entity(tdim+1); std::vector<std::vector<std::vector<std::size_t>>> local_to_local(tdim+1); std::vector<std::vector<std::size_t>> offsets(tdim+1); for (std::size_t dim = 0; dim <= tdim; ++dim) { // Get number local entities num_local_entities[dim] = mesh.type().num_entities(dim); // Get local-to-local mapping of dofs local_to_local[dim].resize(num_local_entities[dim]); for (std::size_t local_ind = 0; local_ind != num_local_entities[dim]; ++local_ind) dofmap.tabulate_entity_dofs(local_to_local[dim][local_ind], dim, local_ind); // Get entity offsets; could be retrieved directly from geometry coords_per_entity[dim] = geometry.num_entity_coordinates(dim); for (std::size_t coord_ind = 0; coord_ind != coords_per_entity[dim]; ++coord_ind) { const auto offset = geometry.get_entity_index(dim, coord_ind, 0); offsets[dim].push_back(offset); } } // Initialize needed connectivities for (std::size_t dim = 0; dim <= tdim; ++dim) { if (coords_per_entity[dim] > 0) mesh.init(tdim, dim); } ArrayView<const la_index> cell_dofs; std::vector<double> values; const unsigned int* global_entities; std::size_t xi, vi; // Get/set cell-by-cell for (CellIterator c(mesh); !c.end(); ++c) { // Get/prepare values and dofs on cell cell_dofs = dofmap.cell_dofs(c->index()); values.resize(cell_dofs.size()); if (setting) v.get_local(values.data(), cell_dofs.size(), cell_dofs.data()); // Iterate over all entities on cell for (std::size_t dim = 0; dim <= tdim; ++dim) { // Get local-to-global entity mapping global_entities = c->entities(dim); for (std::size_t local_entity = 0; local_entity != num_local_entities[dim]; ++local_entity) { for (std::size_t local_dof = 0; local_dof != coords_per_entity[dim]; ++local_dof) { for (std::size_t component = 0; component != gdim; ++component) { // Compute indices xi = gdim*(offsets[dim][local_dof] + global_entities[local_entity]) + component; vi = local_to_local[dim][local_entity][gdim*local_dof + component]; // Set one or other if (setting) x[xi] = values[vi]; else values[vi] = x[xi]; } } } } // Store cell contribution to dof vector (if getting) if (!setting) v.set_local(values.data(), cell_dofs.size(), cell_dofs.data()); } if (!setting) v.apply("insert"); }
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; }