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

[DRAFT] Move coloring info logic into a dedicated helper #1672

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions library/src/interactor_impl.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ class interactor_impl::internals
case 'C':
if (ren)
{
ren->CycleScalars(vtkF3DRenderer::CycleType::FIELD);
ren->CycleFieldForColoring();
self->Window.PrintColoringDescription(log::VerboseLevel::DEBUG);
checkColoring = true;
render = true;
Expand All @@ -199,7 +199,7 @@ class interactor_impl::internals
case 'S':
if (ren)
{
ren->CycleScalars(vtkF3DRenderer::CycleType::ARRAY_INDEX);
ren->CycleArrayForColoring();
self->Window.PrintColoringDescription(log::VerboseLevel::DEBUG);
checkColoring = true;
render = true;
Expand All @@ -208,7 +208,7 @@ class interactor_impl::internals
case 'Y':
if (ren)
{
ren->CycleScalars(vtkF3DRenderer::CycleType::COMPONENT);
ren->CycleComponentForColoring();
self->Window.PrintColoringDescription(log::VerboseLevel::DEBUG);
checkColoring = true;
render = true;
Expand Down Expand Up @@ -379,10 +379,10 @@ class interactor_impl::internals
if (checkColoring)
{
// Resynchronise renderer coloring status with options
self->Options.model.scivis.enable = ren->GetColoringEnabled();
self->Options.model.scivis.cells = ren->GetColoringUseCell();
self->Options.model.scivis.array_name = ren->GetColoringArrayName();
self->Options.model.scivis.component = ren->GetColoringComponent();
self->Options.model.scivis.enable = ren->GetEnableColoring();
self->Options.model.scivis.cells = ren->GetUseCellColoring();
self->Options.model.scivis.array_name = ren->GetArrayNameForColoring();
self->Options.model.scivis.component = ren->GetComponentForColoring();
}
if (render)
{
Expand Down
7 changes: 5 additions & 2 deletions library/src/window_impl.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -533,8 +533,11 @@ void window_impl::UpdateDynamicOptions()
renderer->SetNormalScale(opt.model.normal.scale);
renderer->SetTextureMatCap(opt.model.matcap.texture);

renderer->SetColoring(opt.model.scivis.enable, opt.model.scivis.cells,
opt.model.scivis.array_name, opt.model.scivis.component);
renderer->SetEnableColoring(opt.model.scivis.enable);
renderer->SetUseCellColoring(opt.model.scivis.cells);
renderer->SetArrayNameForColoring(opt.model.scivis.array_name);
renderer->SetComponentForColoring(opt.model.scivis.component);

renderer->SetScalarBarRange(opt.model.scivis.range);
renderer->SetColormap(opt.model.scivis.colormap);
renderer->ShowScalarBar(opt.ui.scalar_bar);
Expand Down
1 change: 1 addition & 0 deletions vtkext/private/module/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ endforeach()

set(classes
F3DLog
F3DColoringInfoHandler
vtkF3DCachedLUTTexture
vtkF3DCachedSpecularTexture
vtkF3DConsoleOutputWindow
Expand Down
242 changes: 242 additions & 0 deletions vtkext/private/module/F3DColoringInfoHandler.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,242 @@
#include "F3DColoringInfoHandler.h"

#include "F3DLog.h"

#include <vtkDataSet.h>
#include <vtkCellData.h>
#include <vtkPointData.h>
#include <vtkDataArray.h>

#include <set>
#include <cassert>

//----------------------------------------------------------------------------
void F3DColoringInfoHandler::ClearColoringInfo()
{
this->PointDataColoringInfo.clear();
this->CellDataColoringInfo.clear();
}

//----------------------------------------------------------------------------
void F3DColoringInfoHandler::UpdateColoringInfo(vtkDataSet* dataset, bool useCellData)
{
// XXX: This assumes importer do not import actors with an empty input
assert(dataset);

// Recover all possible names
std::set<std::string> arrayNames;

vtkDataSetAttributes* attr = useCellData
? static_cast<vtkDataSetAttributes*>(dataset->GetCellData())
: static_cast<vtkDataSetAttributes*>(dataset->GetPointData());

for (int i = 0; i < attr->GetNumberOfArrays(); i++)
{
vtkDataArray* array = attr->GetArray(i);
if (array && array->GetName())
{
arrayNames.insert(array->GetName());
}
}

auto& data = useCellData ? this->CellDataColoringInfo : this->PointDataColoringInfo;

for (const std::string& arrayName : arrayNames)
{
// Recover/Create a coloring info
F3DColoringInfoHandler::ColoringInfo& info = data[arrayName];
info.Name = arrayName;

vtkDataArray* array = useCellData ? dataset->GetCellData()->GetArray(arrayName.c_str())
: dataset->GetPointData()->GetArray(arrayName.c_str());
if (array)
{
info.MaximumNumberOfComponents =
std::max(info.MaximumNumberOfComponents, array->GetNumberOfComponents());

// Set ranges
// XXX this does not take animation into account
std::array<double, 2> range;
array->GetRange(range.data(), -1);
info.MagnitudeRange[0] = std::min(info.MagnitudeRange[0], range[0]);
info.MagnitudeRange[1] = std::max(info.MagnitudeRange[1], range[1]);

for (size_t i = 0; i < static_cast<size_t>(array->GetNumberOfComponents()); i++)
{
array->GetRange(range.data(), static_cast<int>(i));
if (i < info.ComponentRanges.size())
{
info.ComponentRanges[i][0] = std::min(info.ComponentRanges[i][0], range[0]);
info.ComponentRanges[i][1] = std::max(info.ComponentRanges[i][1], range[1]);
}
else
{
info.ComponentRanges.emplace_back(range);
}
}

// Set component names
if (array->HasAComponentName())
{
for (size_t i = 0; i < static_cast<size_t>(array->GetNumberOfComponents()); i++)
{
const char* compName = array->GetComponentName(i);
if (i < info.ComponentNames.size())
{
if (compName && info.ComponentNames[i] != std::string(compName))

Check warning on line 86 in vtkext/private/module/F3DColoringInfoHandler.cxx

View check run for this annotation

Codecov / codecov/patch

vtkext/private/module/F3DColoringInfoHandler.cxx#L86

Added line #L86 was not covered by tests
{
// set non-coherent component names to empty string
info.ComponentNames[i] = "";

Check warning on line 89 in vtkext/private/module/F3DColoringInfoHandler.cxx

View check run for this annotation

Codecov / codecov/patch

vtkext/private/module/F3DColoringInfoHandler.cxx#L89

Added line #L89 was not covered by tests
}
}
else
{
// Add components names to the back of the component names vector
info.ComponentNames.emplace_back(compName ? compName : "");
}
}
}
}
}
}

//----------------------------------------------------------------------------
void F3DColoringInfoHandler::FinalizeColoringInfo(bool useCellData)
{
auto& names = useCellData ? this->CellDataArrayNames : this->PointDataArrayNames;
names.clear();

auto& data = useCellData ? this->CellDataColoringInfo : this->PointDataColoringInfo;
int index = 0;
for (auto& [name, info] : data)
{
info.Index = index;
names.emplace_back(name);
index++;
}
}

//----------------------------------------------------------------------------
/*bool F3DColoringInfoHandler::GetInfoForColoring(
bool useCellData, int index, F3DColoringInfoHandler::ColoringInfo& info)
{
auto& data =
useCellData ? this->CellDataColoringInfo : this->PointDataColoringInfo;
auto& names =
useCellData ? this->CellDataArrayNames : this->PointDataArrayNames;

if (index < 0 || index >= static_cast<int>(data.size()))
{
return false;
}

info = data[names[index]];
return true;
}

//----------------------------------------------------------------------------
int F3DColoringInfoHandler::GetNumberOfIndicesForColoring(bool useCellData)
{
auto& data =
useCellData ? this->CellDataColoringInfo : this->PointDataColoringInfo;
return static_cast<int>(data.size());
}

//----------------------------------------------------------------------------
int F3DColoringInfoHandler::FindIndexForColoring(bool useCellData, const std::string& arrayName)
{
auto& data =
useCellData ? this->CellDataColoringInfo : this->PointDataColoringInfo;

auto it = data.find(arrayName);
if (it != data.end())
{
return it->second.Index;
}
return -1;
}*/

//----------------------------------------------------------------------------
bool F3DColoringInfoHandler::SetCurrentColoring(bool enable, bool useCellData, std::optional<std::string> arrayName, ColoringInfo& info, bool quiet)
{
this->CurrentUsingCellData = useCellData;
auto& data =
this->CurrentUsingCellData ? this->CellDataColoringInfo : this->PointDataColoringInfo;
int nIndices = static_cast<int>(data.size());

if (!enable)
{
// Not coloring
this->CurrentArrayIndex = -1;
}
else if (nIndices == 0)
{
// Trying to color but no array available
F3DLog::Print(F3DLog::Severity::Debug, "No array to color with");
this->CurrentArrayIndex = -1;
}
else if (!arrayName.has_value())
{
// Coloring with first array
this->CurrentArrayIndex = 0;
}
else
{
// Coloring with named array
auto it = data.find(arrayName.value());
if (it != data.end())
{
this->CurrentArrayIndex = it->second.Index;
}
else
{
// Could not find named array
this->CurrentArrayIndex = -1;
if (!quiet)
{
F3DLog::Print(F3DLog::Severity::Warning, "Unknown scalar array: \"" + arrayName.value() + "\"\n");
}
}
}
return this->GetCurrentColoring(info);
}

//----------------------------------------------------------------------------
bool F3DColoringInfoHandler::GetCurrentColoring(ColoringInfo& info)
{
if (this->CurrentArrayIndex != -1)
{
auto& data =
this->CurrentUsingCellData ? this->CellDataColoringInfo : this->PointDataColoringInfo;
auto& names = this->CurrentUsingCellData ? this->CellDataArrayNames : this->PointDataArrayNames;
info = data[names[this->CurrentArrayIndex]];
return true;
}
else
{
return false;
}
}

//----------------------------------------------------------------------------
void F3DColoringInfoHandler::CycleColoringArray(bool cycleToNonColoring)
{
auto& data =
this->CurrentUsingCellData ? this->CellDataColoringInfo : this->PointDataColoringInfo;
int nIndices = static_cast<int>(data.size());
if (nIndices <= 0)
{
return;
}

if (cycleToNonColoring)
{
// Cycle through arrays looping back to -1
// -1 0 1 2 -1 0 1 2 ...
this->CurrentArrayIndex = (this->CurrentArrayIndex + 2) % (nIndices + 1) - 1;
}
else
{
this->CurrentArrayIndex = (this->CurrentArrayIndex + 1) % nIndices;

Check warning on line 240 in vtkext/private/module/F3DColoringInfoHandler.cxx

View check run for this annotation

Codecov / codecov/patch

vtkext/private/module/F3DColoringInfoHandler.cxx#L240

Added line #L240 was not covered by tests
}
}
70 changes: 70 additions & 0 deletions vtkext/private/module/F3DColoringInfoHandler.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/**
* @class F3DColoringInfoHandler
* @brief A statefull Handler to handle coloring info
*/
#ifndef F3DColoringInfoHandler_h
#define F3DColoringInfoHandler_h

#include <map>
#include <string>
#include <vector>
#include <array>
#include <limits>
#include <optional>

class vtkDataSet;
class F3DColoringInfoHandler
{
public:
/**
* A struct containing information about possible coloring
*/
struct ColoringInfo
{
std::string Name;
int MaximumNumberOfComponents = 0;
std::vector<std::string> ComponentNames;
std::vector<std::array<double, 2>> ComponentRanges;
std::array<double, 2> MagnitudeRange = { std::numeric_limits<float>::max(),
std::numeric_limits<float>::min() };
int Index = -1; // TODO remove
};


void UpdateColoringInfo(vtkDataSet* dataset, bool useCellData);
void FinalizeColoringInfo(bool useCellData);
void ClearColoringInfo();

bool SetCurrentColoring(bool enable, bool useCellData, std::optional<std::string> arrayName, ColoringInfo& info, bool quiet);
bool GetCurrentColoring(ColoringInfo& info);
void CycleColoringArray(bool cycleToNonColoring);

/**
* Recover information about coloring by index
* Should be called after actors have been imported
*/
// bool GetInfoForColoring(bool useCellData, int index, ColoringInfo& info);

/**
* Get the maximum index possible for coloring
* Should be called after actors have been imported
*/
// int GetNumberOfIndexesForColoring(bool useCellData);

/**
* Find an index for coloring corresponding to provided arrayName if available
* Should be called after actors have been imported
*/
// int FindIndexForColoring(bool useCellData, const std::string& arrayName);

private:
// Map of arrayName -> coloring info
std::map<std::string, ColoringInfo> PointDataColoringInfo;
std::map<std::string, ColoringInfo> CellDataColoringInfo;
std::vector<std::string> PointDataArrayNames;
std::vector<std::string> CellDataArrayNames;
int CurrentArrayIndex = -1;
bool CurrentUsingCellData = false;
};

#endif
Loading