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