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