Skip to content

Commit

Permalink
Merge pull request #1987 from Haydelj/ShowFieldRefactorPart2
Browse files Browse the repository at this point in the history
closes #1968, #1956, and #1934
  • Loading branch information
dcwhite committed Oct 1, 2019
2 parents 8440f1f + 54895f4 commit 5deb514
Show file tree
Hide file tree
Showing 43 changed files with 483 additions and 2,189 deletions.
9 changes: 6 additions & 3 deletions src/Core/Datatypes/ColorMap.cc
Expand Up @@ -215,7 +215,8 @@ double alpha(double transformedValue)
* @return The RGB value mapped from the scalar.
*/
ColorRGB ColorMap::valueToColor(double scalar) const {
return getColorMapVal(scalar);
ColorRGB color = getColorMapVal(scalar);
return color;
}
/**
* @name valueToColor
Expand All @@ -227,7 +228,8 @@ ColorRGB ColorMap::valueToColor(Tensor &tensor) const {
double eigen1, eigen2, eigen3;
tensor.get_eigenvalues(eigen1, eigen2, eigen3);
double magnitude = Vector(eigen1, eigen2, eigen3).length();
return getColorMapVal(magnitude);
ColorRGB color = getColorMapVal(magnitude);
return color;
}
/**
* @name valueToColor
Expand All @@ -238,7 +240,8 @@ ColorRGB ColorMap::valueToColor(Tensor &tensor) const {
ColorRGB ColorMap::valueToColor(const Vector &vector) const {
//TODO this is probably not implemented correctly.
// return ColorRGB(getTransformedColor(fabs(vector.x())),getTransformedColor(fabs(vector.y())), getTransformedColor(fabs(vector.z())));
return getColorMapVal(vector.length());
ColorRGB color = getColorMapVal(vector.length());
return color;
}

// This Rainbow takes into account scientific visualization recommendations.
Expand Down
1 change: 1 addition & 0 deletions src/Graphics/Datatypes/GeometryImpl.h
Expand Up @@ -109,6 +109,7 @@ namespace SCIRun {
POINTS,
LINES,
TRIANGLES,
QUADS
};

SpireIBO() : indexSize(0), prim(PRIMITIVE::POINTS) {}
Expand Down
250 changes: 117 additions & 133 deletions src/Graphics/Glyphs/GlyphGeom.cc
Expand Up @@ -28,6 +28,7 @@ DEALINGS IN THE SOFTWARE.

#include <Graphics/Glyphs/GlyphGeom.h>
#include <Core/Datatypes/DenseMatrix.h>
#include <Core/Datatypes/ColorMap.h>
#include <Core/Math/MiscMath.h>
#include <Core/GeometryPrimitives/Transform.h>

Expand All @@ -42,167 +43,150 @@ GlyphGeom::GlyphGeom() : numVBOElements_(0), lineIndex_(0)

}

void GlyphGeom::buildObject(GeometryObjectSpire& geom, const std::string& uniqueNodeID, const bool isTransparent, const double transparencyValue,
const ColorScheme& colorScheme, RenderState state, const SpireIBO::PRIMITIVE& primIn, const BBox& bbox)
void GlyphGeom::buildObject(GeometryObjectSpire& geom, const std::string& uniqueNodeID,
const bool isTransparent, const double transparencyValue, const ColorScheme& colorScheme,
RenderState state, const SpireIBO::PRIMITIVE& primIn, const BBox& bbox, const bool isClippable,
const Core::Datatypes::ColorMapHandle colorMap)
{
std::string vboName = uniqueNodeID + "VBO";
std::string iboName = uniqueNodeID + "IBO";
std::string passName = uniqueNodeID + "Pass";
bool useColor = colorScheme == ColorScheme::COLOR_IN_SITU || colorScheme == ColorScheme::COLOR_MAP;
bool useNormals = normals_.size() == points_.size();
int numAttributes = 3;

bool useTriangles = primIn == SpireIBO::PRIMITIVE::TRIANGLES;
RenderType renderType = RenderType::RENDER_VBO_IBO;
ColorRGB dft = state.defaultColor;

// Construct VBO.
std::string shader = "Shaders/UniformColor";
std::string shader = (useNormals ? "Shaders/Phong" : "Shaders/Flat");
std::vector<SpireVBO::AttributeData> attribs;
attribs.push_back(SpireVBO::AttributeData("aPos", 3 * sizeof(float)));
if (useTriangles)
attribs.push_back(SpireVBO::AttributeData("aNormal", 3 * sizeof(float)));
RenderType renderType = RenderType::RENDER_VBO_IBO;
std::vector<SpireSubPass::Uniform> uniforms;

//ColorScheme colorScheme = COLOR_UNIFORM;
attribs.push_back(SpireVBO::AttributeData("aPos", 3 * sizeof(float)));
uniforms.push_back(SpireSubPass::Uniform("uUseClippingPlanes", isClippable));
uniforms.push_back(SpireSubPass::Uniform("uUseFog", true));

std::vector<SpireSubPass::Uniform> uniforms;
if (isTransparent)
uniforms.push_back(SpireSubPass::Uniform("uTransparency", static_cast<float>(transparencyValue)));
// TODO: add colormapping options
if (colorScheme == ColorScheme::COLOR_MAP)
if (useNormals)
{
attribs.push_back(SpireVBO::AttributeData("aColor", 4 * sizeof(float)));
if (useTriangles)
{
shader = "Shaders/DirPhongCMap";
uniforms.push_back(SpireSubPass::Uniform("uAmbientColor",
glm::vec4(0.1f, 0.1f, 0.1f, 1.0f)));
uniforms.push_back(SpireSubPass::Uniform("uSpecularColor",
glm::vec4(0.1f, 0.1f, 0.1f, 0.1f)));
uniforms.push_back(SpireSubPass::Uniform("uSpecularPower", 32.0f));
}
else
{
shader = "Shaders/ColorMap";
}
numAttributes += 3;
attribs.push_back(SpireVBO::AttributeData("aNormal", 3 * sizeof(float)));
uniforms.push_back(SpireSubPass::Uniform("uAmbientColor", glm::vec4(0.1f, 0.1f, 0.1f, 1.0f)));
uniforms.push_back(SpireSubPass::Uniform("uSpecularColor", glm::vec4(0.1f, 0.1f, 0.1f, 0.1f)));
uniforms.push_back(SpireSubPass::Uniform("uSpecularPower", 32.0f));
}
else if (colorScheme == ColorScheme::COLOR_IN_SITU)

SpireText text;
SpireTexture2D texture;
if (useColor)
{
attribs.push_back(SpireVBO::AttributeData("aColor", 4 * sizeof(float)));
if (useTriangles)
if(colorMap)
{
shader = "Shaders/DirPhongInSitu";
uniforms.push_back(SpireSubPass::Uniform("uAmbientColor",
glm::vec4(0.1f, 0.1f, 0.1f, 1.0f)));
uniforms.push_back(SpireSubPass::Uniform("uSpecularColor",
glm::vec4(0.1f, 0.1f, 0.1f, 0.1f)));
uniforms.push_back(SpireSubPass::Uniform("uSpecularPower", 32.0f));
numAttributes += 2;
shader += "_ColorMap";
attribs.push_back(SpireVBO::AttributeData("aTexCoords", 2 * sizeof(float)));

const static int colorMapResolution = 256;
for(int i = 0; i < colorMapResolution; ++i)
{
ColorRGB color = colorMap->valueToColor(static_cast<float>(i)/colorMapResolution * 2.0f - 1.0f);
texture.bitmap.push_back(color.r()*255.99f);
texture.bitmap.push_back(color.g()*255.99f);
texture.bitmap.push_back(color.b()*255.99f);
texture.bitmap.push_back(color.a()*255.99f);
}

texture.name = "ColorMap";
texture.height = 1;
texture.width = colorMapResolution;
}
else
{
shader = "Shaders/InSituColor";
numAttributes += 4;
shader += "_Color";
attribs.push_back(SpireVBO::AttributeData("aColor", 4 * sizeof(float)));
}
}
else if (colorScheme == ColorScheme::COLOR_UNIFORM)
else
{
ColorRGB dft = state.defaultColor;
if (useTriangles)
{
if (geom.isClippable())
shader = "Shaders/DirPhong";
else
shader = "Shaders/DirPhongNoClipping";
uniforms.push_back(SpireSubPass::Uniform("uAmbientColor",
glm::vec4(0.1f, 0.1f, 0.1f, 1.0f)));
uniforms.push_back(SpireSubPass::Uniform("uDiffuseColor",
glm::vec4(dft.r(), dft.g(), dft.b(), static_cast<float>(transparencyValue))));
uniforms.push_back(SpireSubPass::Uniform("uSpecularColor",
glm::vec4(0.1f, 0.1f, 0.1f, 0.1f)));
uniforms.push_back(SpireSubPass::Uniform("uSpecularPower", 32.0f));
}
else
{
uniforms.emplace_back("uColor", glm::vec4(dft.r(), dft.g(), dft.b(), static_cast<float>(transparencyValue)));
}
uniforms.push_back(SpireSubPass::Uniform("uDiffuseColor",
glm::vec4(dft.r(), dft.g(), dft.b(), static_cast<float>(transparencyValue))));
}

uint32_t iboSize = 0;
uint32_t vboSize = 0;

vboSize = static_cast<uint32_t>(points_.size()) * 3 * sizeof(float);
vboSize += static_cast<uint32_t>(normals_.size()) * 3 * sizeof(float);
if (colorScheme == ColorScheme::COLOR_IN_SITU || colorScheme == ColorScheme::COLOR_MAP)
vboSize += static_cast<uint32_t>(colors_.size()) * 4 * sizeof(float); //RGBA
iboSize = static_cast<uint32_t>(indices_.size()) * sizeof(uint32_t);
/// \todo To reduce memory requirements, we can use a 16bit index buffer.

/// \todo To further reduce a large amount of memory, get rid of the index
/// buffer and use glDrawArrays to render without an IBO. An IBO is
/// a waste of space.
/// http://www.opengl.org/sdk/docs/man3/xhtml/glDrawArrays.xml

/// \todo Switch to unique_ptrs and move semantics.
std::shared_ptr<spire::VarBuffer> iboBufferSPtr(new spire::VarBuffer(iboSize));
std::shared_ptr<spire::VarBuffer> vboBufferSPtr(new spire::VarBuffer(vboSize));

// Accessing the pointers like this is contrived. We only do this for
// speed since we will be using the pointers in a tight inner loop.
auto iboBuffer = iboBufferSPtr.get();
auto vboBuffer = vboBufferSPtr.get();

//write to the IBO/VBOs

for (auto a : indices_)
iboBuffer->write(a);
if (isTransparent) uniforms.push_back(SpireSubPass::Uniform("uTransparency", static_cast<float>(transparencyValue)));

BBox newBBox;

const bool writeNormals = normals_.size() == points_.size();
for (size_t i = 0; i < points_.size(); i++)
size_t pointsLeft = points_.size();
size_t startOfPass = 0;
int passNumber = 0;
while(pointsLeft > 0)
{
// Write first point on line
vboBuffer->write(static_cast<float>(points_.at(i).x()));
vboBuffer->write(static_cast<float>(points_.at(i).y()));
vboBuffer->write(static_cast<float>(points_.at(i).z()));

newBBox.extend(Point(points_.at(i).x(), points_.at(i).y(), points_.at(i).z()));

if (writeNormals)
std::string passID = uniqueNodeID + "_" + std::to_string(passNumber++);
std::string vboName = passID + "VBO";
std::string iboName = passID + "IBO";
std::string passName = passID + "Pass";

const static size_t maxPointsPerPass = 3 << 24; //must be a number divisible by 2, 3 and, 4
uint32_t pointsInThisPass = std::min(pointsLeft, maxPointsPerPass);
size_t endOfPass = startOfPass + pointsInThisPass;
pointsLeft -= pointsInThisPass;

size_t vboSize = static_cast<size_t>(pointsInThisPass) * numAttributes * sizeof(float);
size_t iboSize = static_cast<size_t>(pointsInThisPass) * sizeof(uint32_t);
std::shared_ptr<spire::VarBuffer> iboBufferSPtr(new spire::VarBuffer(iboSize));
std::shared_ptr<spire::VarBuffer> vboBufferSPtr(new spire::VarBuffer(vboSize));
auto iboBuffer = iboBufferSPtr.get();
auto vboBuffer = vboBufferSPtr.get();

for (auto a : indices_) if(a >= startOfPass && a < endOfPass)
iboBuffer->write(static_cast<uint32_t>(a - startOfPass));

BBox newBBox;
for (size_t i = startOfPass; i < endOfPass; ++i)
{
vboBuffer->write(static_cast<float>(normals_.at(i).x()));
vboBuffer->write(static_cast<float>(normals_.at(i).y()));
vboBuffer->write(static_cast<float>(normals_.at(i).z()));
}
if (colorScheme == ColorScheme::COLOR_MAP || colorScheme == ColorScheme::COLOR_IN_SITU)
{
vboBuffer->write(static_cast<float>(colors_.at(i).r()));
vboBuffer->write(static_cast<float>(colors_.at(i).g()));
vboBuffer->write(static_cast<float>(colors_.at(i).b()));
vboBuffer->write(static_cast<float>(colors_.at(i).a()));
//vboBuffer->write(static_cast<float>(1.f));
} // no color writing otherwise
}
Vector point = points_.at(i);
newBBox.extend(Point(point.x(), point.y(), point.z()));
vboBuffer->write(static_cast<float>(point.x()));
vboBuffer->write(static_cast<float>(point.y()));
vboBuffer->write(static_cast<float>(point.z()));

if(!bbox.valid())
newBBox.reset();

// If true, then the VBO will be placed on the GPU. We don't want to place
// VBOs on the GPU when we are generating rendering lists.
SpireVBO geomVBO(vboName, attribs, vboBufferSPtr, numVBOElements_, newBBox, true);
if (useNormals)
{
Vector normal = normals_.at(i);
vboBuffer->write(static_cast<float>(normal.x()));
vboBuffer->write(static_cast<float>(normal.y()));
vboBuffer->write(static_cast<float>(normal.z()));
}

// Construct IBO.
SpireIBO geomIBO(iboName, primIn, sizeof(uint32_t), iboBufferSPtr);
if (useColor)
{
ColorRGB color = colors_.at(i);
if(!colorMap)
{
vboBuffer->write(static_cast<float>(color.r()));
vboBuffer->write(static_cast<float>(color.g()));
vboBuffer->write(static_cast<float>(color.b()));
vboBuffer->write(static_cast<float>(color.a()));
}
else
{
vboBuffer->write(static_cast<float>(color.r()));
vboBuffer->write(static_cast<float>(color.r()));
}
}
}
if(!bbox.valid()) newBBox.reset();

state.set(RenderState::IS_ON, true);
state.set(RenderState::HAS_DATA, true);
startOfPass = endOfPass;

SpireText text;
SpireVBO geomVBO(vboName, attribs, vboBufferSPtr, numVBOElements_, newBBox, true);
SpireIBO geomIBO(iboName, primIn, sizeof(uint32_t), iboBufferSPtr);

// Construct Pass.
SpireSubPass pass(passName, vboName, iboName, shader, colorScheme, state, renderType, geomVBO, geomIBO, text);
state.set(RenderState::IS_ON, true);
state.set(RenderState::HAS_DATA, true);
SpireSubPass pass(passName, vboName, iboName, shader, colorScheme, state, renderType, geomVBO, geomIBO, text, texture);

// Add all uniforms generated above to the pass.
for (const auto& uniform : uniforms) { pass.addUniform(uniform); }
for (const auto& uniform : uniforms) pass.addUniform(uniform);

geom.vbos().push_back(geomVBO);
geom.ibos().push_back(geomIBO);
geom.passes().push_back(pass);
geom.vbos().push_back(geomVBO);
geom.ibos().push_back(geomIBO);
geom.passes().push_back(pass);
}
}

void GlyphGeom::addArrow(const Point& p1, const Point& p2, double radius, double ratio, int resolution,
Expand Down
8 changes: 4 additions & 4 deletions src/Graphics/Glyphs/GlyphGeom.h
Expand Up @@ -51,7 +51,7 @@ namespace SCIRun {

void buildObject(Datatypes::GeometryObjectSpire& geom, const std::string& uniqueNodeID, const bool isTransparent, const double transparencyValue,
const Datatypes::ColorScheme& colorScheme, RenderState state,
const Datatypes::SpireIBO::PRIMITIVE& primIn, const Core::Geometry::BBox& bbox);
const Datatypes::SpireIBO::PRIMITIVE& primIn, const Core::Geometry::BBox& bbox, const bool isClippable = true, const Core::Datatypes::ColorMapHandle colorMap = nullptr);

void addArrow(const Core::Geometry::Point& p1, const Core::Geometry::Point& p2, double radius, double ratio, int resolution,
const Core::Datatypes::ColorRGB& color1, const Core::Datatypes::ColorRGB& color2, bool render_cylinder_base, bool render_cone_base);
Expand Down Expand Up @@ -102,9 +102,9 @@ namespace SCIRun {
std::vector<Core::Geometry::Vector> points_;
std::vector<Core::Geometry::Vector> normals_;
std::vector<Core::Datatypes::ColorRGB> colors_;
std::vector<uint32_t> indices_;
int64_t numVBOElements_;
uint32_t lineIndex_;
std::vector<size_t> indices_;
size_t numVBOElements_;
size_t lineIndex_;

void generateCylinder(const Core::Geometry::Point& p1, const Core::Geometry::Point& p2, double radius1, double radius2, int resolution, const Core::Datatypes::ColorRGB& color1, const Core::Datatypes::ColorRGB& color2);
void generateSphere(const Core::Geometry::Point& center, double radius, int resolution, const Core::Datatypes::ColorRGB& color);
Expand Down

0 comments on commit 5deb514

Please sign in to comment.