Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compact color table args #1457

Open
wants to merge 8 commits into
base: develop
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -229,16 +229,30 @@ parse_color_table(const conduit::Node &color_table_node)

if(color_table_node.has_child("control_points"))
{
bool clear = false;
const Node &control_points_node = color_table_node.fetch("control_points");

// check to see if we have rgb points and clear the table
NodeConstIterator itr = color_table_node.fetch("control_points").children();
while(itr.has_next())
bool clear = false;
if (control_points_node.dtype().is_list())
{
const Node &peg = itr.next();
if (peg["type"].as_string() == "rgb")
NodeConstIterator itr = color_table_node.fetch("control_points").children();
while(itr.has_next())
{
clear = true;
break;
const Node &peg = itr.next();
if (peg["type"].as_string() == "rgb")
{
clear = true;
break;
}
}
}
else if (control_points_node.dtype().is_object())
{
if (control_points_node.has_child("r") &&
control_points_node.has_child("g") &&
control_points_node.has_child("b"))
{
clear = true;
}
}

Expand All @@ -247,51 +261,122 @@ parse_color_table(const conduit::Node &color_table_node)
color_table.ClearColors();
}

itr = color_table_node.fetch("control_points").children();
while(itr.has_next())
if (control_points_node.dtype().is_list())
{
const Node &peg = itr.next();
if(!peg.has_child("position"))
NodeConstIterator itr = color_table_node.fetch("control_points").children();
while(itr.has_next())
{
// FIXME: This should be an error
ASCENT_WARN("Color map control point must have a position");
const Node &peg = itr.next();
if(!peg.has_child("position"))
{
// FIXME: This should be an error
ASCENT_WARN("Color map control point must have a position");
}

float64 position = peg["position"].to_float64();

if(position > 1.0 || position < 0.0)
{
ASCENT_WARN("Cannot add color map control point position "
<< position
<< ". Must be a normalized scalar.");
}

if (peg["type"].as_string() == "rgb")
{
conduit::Node n;
peg["color"].to_float64_array(n);
const float64 *color = n.as_float64_ptr();

vtkm::Vec<vtkm::Float64,3> ecolor(color[0], color[1], color[2]);

for(int i = 0; i < 3; ++i)
{
ecolor[i] = std::min(1., std::max(ecolor[i], 0.));
}

color_table.AddPoint(position, ecolor);
}
else if (peg["type"].as_string() == "alpha")
{
float64 alpha = peg["alpha"].to_float64();
alpha = std::min(1., std::max(alpha, 0.));
color_table.AddPointAlpha(position, alpha);
}
else
{
ASCENT_WARN("Unknown color table control point type "
<< peg["type"].as_string()<<
"\nValid types are 'alpha' and 'rgb'");
}
}
}
else if (control_points_node.dtype().is_object())
{
if(!control_points_node.has_child("r"))
{
ASCENT_ERROR("Color map control point must provide r values");
}

if(!control_points_node.has_child("g"))
{
ASCENT_ERROR("Color map control point must provide g values");
}

float64 position = peg["position"].to_float64();
if(!control_points_node.has_child("b"))
{
ASCENT_ERROR("Color map control point must provide b values");
}

if(position > 1.0 || position < 0.0)
if(!control_points_node.has_child("position"))
{
ASCENT_WARN("Cannot add color map control point position "
<< position
<< ". Must be a normalized scalar.");
ASCENT_ERROR("Color map control point must have a position");
}

if (peg["type"].as_string() == "rgb")
float64_array r_vals = control_points_node.fetch("r").value();
float64_array g_vals = control_points_node.fetch("g").value();
float64_array b_vals = control_points_node.fetch("b").value();
float64_array pos_vals = control_points_node.fetch("position").value();

if(r_vals.number_of_elements() != g_vals.number_of_elements() ||
g_vals.number_of_elements() != b_vals.number_of_elements() ||
b_vals.number_of_elements() != pos_vals.number_of_elements())
{
conduit::Node n;
peg["color"].to_float64_array(n);
const float64 *color = n.as_float64_ptr();
ASCENT_ERROR("Color map color channels should all be of the same size");
}

vtkm::Vec<vtkm::Float64,3> ecolor(color[0], color[1], color[2]);
for(index_t i=0; i<r_vals.number_of_elements();i++)
{
vtkm::Vec<vtkm::Float64,3> ecolor(r_vals[i], g_vals[i], b_vals[i]);

for(int i = 0; i < 3; ++i)
{
ecolor[i] = std::min(1., std::max(ecolor[i], 0.));
ecolor[i] = std::min(1., std::max(ecolor[i], 0.));
}

color_table.AddPoint(position, ecolor);
}
else if (peg["type"].as_string() == "alpha")
{
float64 alpha = peg["alpha"].to_float64();
alpha = std::min(1., std::max(alpha, 0.));
color_table.AddPointAlpha(position, alpha);
if(pos_vals[i] > 1.0 || pos_vals[i] < 0.0)
{
ASCENT_ERROR("Cannot add color map control point position "
<< pos_vals[i]
<< ". Must be a normalized scalar.");
}

color_table.AddPoint(pos_vals[i], ecolor);
}
else

if(control_points_node.has_child("a"))
{
ASCENT_WARN("Unknown color table control point type "
<< peg["type"].as_string()<<
"\nValid types are 'alpha' and 'rgb'");
float64_array alpha_vals = control_points_node.fetch("a").value();

if(pos_vals.number_of_elements() != alpha_vals.number_of_elements())
{
ASCENT_ERROR("Color map alpha channel should have same size as color channels");
}

for(index_t i=0; i<r_vals.number_of_elements();i++)
{
color_table.AddPointAlpha(pos_vals[i], std::min(1., std::max(alpha_vals[i], 0.)));
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,18 +104,37 @@ check_color_table_surprises(const conduit::Node &color_table)
surprises += surprise_check(valid_paths, ignore_paths, color_table);
if(color_table.has_path("control_points"))
{
std::vector<std::string> c_valid_paths;
c_valid_paths.push_back("type");
c_valid_paths.push_back("alpha");
c_valid_paths.push_back("color");
c_valid_paths.push_back("position");

const conduit::Node &control_points = color_table["control_points"];
const int num_points = control_points.number_of_children();
for(int i = 0; i < num_points; ++i)
{
const conduit::Node &point = control_points.child(i);
surprises += surprise_check(c_valid_paths, point);
const Node &control_points_node = color_table.fetch("control_points");

if (control_points_node.dtype().is_list())
{
// Valid path options for the expanded control points input format
std::vector<std::string> c_valid_paths;
c_valid_paths.push_back("type");
c_valid_paths.push_back("alpha");
c_valid_paths.push_back("color");
c_valid_paths.push_back("position");

const conduit::Node &control_points = color_table["control_points"];
const int num_points = control_points.number_of_children();
for(int i = 0; i < num_points; ++i)
{
const conduit::Node &point = control_points.child(i);
surprises += surprise_check(c_valid_paths, point);
}
}
else if (control_points_node.dtype().is_object())
{
// Valid path options for the compressed control points input format
std::vector<std::string> c_valid_paths;
c_valid_paths.push_back("r");
c_valid_paths.push_back("g");
c_valid_paths.push_back("b");
c_valid_paths.push_back("a");
c_valid_paths.push_back("position");


surprises += surprise_check(c_valid_paths, control_points_node);
}
}

Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
83 changes: 83 additions & 0 deletions src/tests/ascent/t_ascent_render_3d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1878,6 +1878,89 @@ TEST(ascent_render_3d, test_render_3d_milk_chocolate)
ASCENT_ACTIONS_DUMP(actions,output_file,msg);
}

//-----------------------------------------------------------------------------
TEST(ascent_render_3d, test_render_3d_compressed_color_table)
{
// the ascent runtime is currently our only rendering runtime
Node n;
ascent::about(n);
// only run this test if ascent was built with vtkm support
if(n["runtimes/ascent/vtkm/status"].as_string() == "disabled")
{
ASCENT_INFO("Ascent support disabled, skipping 3D default"
"Pipeline test");

return;
}

//
// Create an example mesh.
//
Node data, verify_info;
conduit::blueprint::mesh::examples::braid("uniform",
EXAMPLE_MESH_SIDE_DIM,
EXAMPLE_MESH_SIDE_DIM,
EXAMPLE_MESH_SIDE_DIM,
data);

EXPECT_TRUE(conduit::blueprint::mesh::verify(data,verify_info));


ASCENT_INFO("Testing 3D Rendering with Default Pipeline");

string output_path = prepare_output_dir();
string image_prefix0 = "compressed_color_table";
string output_file = conduit::utils::join_file_path(output_path,image_prefix0);

// remove old images before rendering
remove_test_image(output_file);

//
// Create the actions.
//

conduit::Node control_points;
control_points["r"] = {.23, .48, .99};
control_points["g"] = {0.08, .23, 1.};
control_points["b"] = {0.08, .04, .96};
control_points["a"] = {1., 1., 1.};
control_points["position"] = {0., .5, 1.};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!


conduit::Node scenes;
scenes["s1/plots/p1/type"] = "pseudocolor";
scenes["s1/plots/p1/field"] = "braid";
scenes["s1/plots/p1/color_table/control_points"] = control_points;

scenes["s1/image_prefix"] = output_file;

scenes["s1/renders/r1/image_width"] = 512;
scenes["s1/renders/r1/image_height"] = 512;
scenes["s1/renders/r1/image_prefix"] = output_file;

conduit::Node actions;
conduit::Node &add_plots = actions.append();
add_plots["action"] = "add_scenes";
add_plots["scenes"] = scenes;

//
// Run Ascent
//

Ascent ascent;

Node ascent_opts;
ascent_opts["runtime/type"] = "ascent";
ascent.open(ascent_opts);
ascent.publish(data);
ascent.execute(actions);
ascent.close();

// check that we created an image
EXPECT_TRUE(check_test_image(output_file));
std::string msg = "An example of creating a custom compressed color map.";
ASCENT_ACTIONS_DUMP(actions,output_file,msg);
}

//-----------------------------------------------------------------------------
TEST(ascent_render_3d, test_render_3d_disable_color_bar)
{
Expand Down