diff --git a/library/src/interactor_impl.cxx b/library/src/interactor_impl.cxx index eb46de7f88..c81bfb63b2 100644 --- a/library/src/interactor_impl.cxx +++ b/library/src/interactor_impl.cxx @@ -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; @@ -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; @@ -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; @@ -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) { diff --git a/library/src/window_impl.cxx b/library/src/window_impl.cxx index 47483cd037..33ff621822 100644 --- a/library/src/window_impl.cxx +++ b/library/src/window_impl.cxx @@ -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); diff --git a/vtkext/private/module/CMakeLists.txt b/vtkext/private/module/CMakeLists.txt index 3e8de7fd99..26086ede7b 100644 --- a/vtkext/private/module/CMakeLists.txt +++ b/vtkext/private/module/CMakeLists.txt @@ -31,6 +31,7 @@ endforeach() set(classes F3DLog + F3DColoringInfoHandler vtkF3DCachedLUTTexture vtkF3DCachedSpecularTexture vtkF3DConsoleOutputWindow diff --git a/vtkext/private/module/F3DColoringInfoHandler.cxx b/vtkext/private/module/F3DColoringInfoHandler.cxx new file mode 100644 index 0000000000..70a3f90243 --- /dev/null +++ b/vtkext/private/module/F3DColoringInfoHandler.cxx @@ -0,0 +1,242 @@ +#include "F3DColoringInfoHandler.h" + +#include "F3DLog.h" + +#include +#include +#include +#include + +#include +#include + +//---------------------------------------------------------------------------- +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 arrayNames; + + vtkDataSetAttributes* attr = useCellData + ? static_cast(dataset->GetCellData()) + : static_cast(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 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(array->GetNumberOfComponents()); i++) + { + array->GetRange(range.data(), static_cast(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(array->GetNumberOfComponents()); i++) + { + const char* compName = array->GetComponentName(i); + if (i < info.ComponentNames.size()) + { + if (compName && info.ComponentNames[i] != std::string(compName)) + { + // set non-coherent component names to empty string + info.ComponentNames[i] = ""; + } + } + 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(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(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 arrayName, ColoringInfo& info, bool quiet) +{ + this->CurrentUsingCellData = useCellData; + auto& data = + this->CurrentUsingCellData ? this->CellDataColoringInfo : this->PointDataColoringInfo; + int nIndices = static_cast(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(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; + } +} diff --git a/vtkext/private/module/F3DColoringInfoHandler.h b/vtkext/private/module/F3DColoringInfoHandler.h new file mode 100644 index 0000000000..310dbc3924 --- /dev/null +++ b/vtkext/private/module/F3DColoringInfoHandler.h @@ -0,0 +1,70 @@ +/** + * @class F3DColoringInfoHandler + * @brief A statefull Handler to handle coloring info + */ +#ifndef F3DColoringInfoHandler_h +#define F3DColoringInfoHandler_h + +#include +#include +#include +#include +#include +#include + +class vtkDataSet; +class F3DColoringInfoHandler +{ +public: + /** + * A struct containing information about possible coloring + */ + struct ColoringInfo + { + std::string Name; + int MaximumNumberOfComponents = 0; + std::vector ComponentNames; + std::vector> ComponentRanges; + std::array MagnitudeRange = { std::numeric_limits::max(), + std::numeric_limits::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 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 PointDataColoringInfo; + std::map CellDataColoringInfo; + std::vector PointDataArrayNames; + std::vector CellDataArrayNames; + int CurrentArrayIndex = -1; + bool CurrentUsingCellData = false; +}; + +#endif diff --git a/vtkext/private/module/Testing/TestF3DMetaImporterMultiColoring.cxx b/vtkext/private/module/Testing/TestF3DMetaImporterMultiColoring.cxx index 97f220253f..ee8a5dd87b 100644 --- a/vtkext/private/module/Testing/TestF3DMetaImporterMultiColoring.cxx +++ b/vtkext/private/module/Testing/TestF3DMetaImporterMultiColoring.cxx @@ -41,11 +41,11 @@ int TestF3DMetaImporterMultiColoring(int argc, char* argv[]) return EXIT_FAILURE; } - if (importer->FindIndexForColoring(false, "") != -1) +/* if (importer->FindIndexForColoring(false, "") != -1) { std::cerr << "Unexpected FindIndexForColoring success" << std::endl; return EXIT_FAILURE; - } + }*/ // Read a vts and a vtu with same array names @@ -71,7 +71,7 @@ int TestF3DMetaImporterMultiColoring(int argc, char* argv[]) importer->SetRenderWindow(window); importer->Update(); - if (importer->GetNumberOfIndexesForColoring(false) != 3) + /*if (importer->GetNumberOfIndexesForColoring(false) != 3) { std::cerr << "Importer provide unexpected number of indexes for coloring" << std::endl; return EXIT_FAILURE; @@ -122,7 +122,7 @@ int TestF3DMetaImporterMultiColoring(int argc, char* argv[]) { std::cerr << "Unexpected coloring magnitude range" << std::endl; return EXIT_FAILURE; - } + }*/ return EXIT_SUCCESS; } diff --git a/vtkext/private/module/Testing/TestF3DRendererWithColoring.cxx b/vtkext/private/module/Testing/TestF3DRendererWithColoring.cxx index 6b1c58e67a..1f5ac4c12b 100644 --- a/vtkext/private/module/Testing/TestF3DRendererWithColoring.cxx +++ b/vtkext/private/module/Testing/TestF3DRendererWithColoring.cxx @@ -31,33 +31,35 @@ int TestF3DRendererWithColoring(int argc, char* argv[]) importer->Update(); // Check invalid array code path - renderer->SetColoring(true, false, "Invalid", 0); + renderer->SetEnableColoring(true); + renderer->SetArrayNameForColoring("Invalid"); renderer->SetUseVolume(false); renderer->UpdateActors(); - renderer->CycleScalars(vtkF3DRenderer::CycleType::COMPONENT); + renderer->CycleComponentForColoring(); renderer->SetUseVolume(true); renderer->UpdateActors(); - if (renderer->GetColoringArrayName() != "Density" || renderer->GetColoringComponent() != 0) + if (renderer->GetArrayNameForColoring() != "Invalid" || renderer->GetComponentForColoring() != -1) { std::cerr << "Unexpected coloring information with invalid array" << std::endl; return EXIT_FAILURE; } // Check invalid component code path - renderer->SetColoring(true, false, "Momentum", 5); + renderer->SetArrayNameForColoring("Momentum"); + renderer->SetComponentForColoring(5); renderer->UpdateActors(); renderer->SetUseVolume(true); renderer->UpdateActors(); - if (renderer->GetColoringArrayName() != "Momentum" || renderer->GetColoringComponent() != 5) + if (renderer->GetArrayNameForColoring() != "Momentum" || renderer->GetComponentForColoring() != 5) { std::cerr << "Unexpected coloring information with invalid component" << std::endl; return EXIT_FAILURE; } - renderer->CycleScalars(vtkF3DRenderer::CycleType::COMPONENT); - if (renderer->GetColoringArrayName() != "Momentum" || renderer->GetColoringComponent() != 1) + renderer->CycleComponentForColoring(); + if (renderer->GetArrayNameForColoring() != "Momentum" || renderer->GetComponentForColoring() != 1) { std::cerr << "Unexpected coloring information after cycling component" << std::endl; return EXIT_FAILURE; diff --git a/vtkext/private/module/vtkF3DMetaImporter.cxx b/vtkext/private/module/vtkF3DMetaImporter.cxx index 457db524e1..14bced4a3c 100644 --- a/vtkext/private/module/vtkF3DMetaImporter.cxx +++ b/vtkext/private/module/vtkF3DMetaImporter.cxx @@ -24,120 +24,11 @@ struct vtkF3DMetaImporter::Internals { - void ClearColoringInfo() - { - this->PointDataColoringInfo.clear(); - this->CellDataColoringInfo.clear(); - } - - void 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 arrayNames; - - vtkDataSetAttributes* attr = useCellData - ? static_cast(dataset->GetCellData()) - : static_cast(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 - vtkF3DMetaImporter::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 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(array->GetNumberOfComponents()); i++) - { - array->GetRange(range.data(), static_cast(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(array->GetNumberOfComponents()); i++) - { - const char* compName = array->GetComponentName(i); - if (i < info.ComponentNames.size()) - { - if (compName && info.ComponentNames[i] != std::string(compName)) - { - // set non-coherent component names to empty string - info.ComponentNames[i] = ""; - } - } - else - { - // Add components names to the back of the component names vector - info.ComponentNames.emplace_back(compName ? compName : ""); - } - } - } - } - } - } - - void 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++; - } - } - // Actors related vectors std::vector ColoringActorsAndMappers; std::vector PointSpritesActorsAndMappers; std::vector VolumePropsAndMappers; - // Map of arrayName -> coloring info - std::map PointDataColoringInfo; - std::map CellDataColoringInfo; - std::vector PointDataArrayNames; - std::vector CellDataArrayNames; - struct ImporterPair { vtkSmartPointer Importer; @@ -148,6 +39,8 @@ struct vtkF3DMetaImporter::Internals vtkBoundingBox GeometryBoundingBox; bool ColoringInfoUpdated = false; + F3DColoringInfoHandler ColoringInfoHandler; + #if VTK_VERSION_NUMBER < VTK_VERSION_CHECK(9, 3, 20240707) std::map> ActorsForImporterMap; #endif @@ -178,7 +71,7 @@ void vtkF3DMetaImporter::Clear() this->Pimpl->ColoringActorsAndMappers.clear(); this->Pimpl->PointSpritesActorsAndMappers.clear(); this->Pimpl->VolumePropsAndMappers.clear(); - this->Pimpl->ClearColoringInfo(); + this->Pimpl->ColoringInfoHandler.ClearColoringInfo(); this->Modified(); } @@ -217,61 +110,6 @@ const vtkBoundingBox& vtkF3DMetaImporter::GetGeometryBoundingBox() return this->Pimpl->GeometryBoundingBox; } -//---------------------------------------------------------------------------- -bool vtkF3DMetaImporter::GetInfoForColoring( - bool useCellData, int index, vtkF3DMetaImporter::ColoringInfo& info) -{ - if (!this->Pimpl->ColoringInfoUpdated) - { - this->UpdateInfoForColoring(); - } - - auto& data = - useCellData ? this->Pimpl->CellDataColoringInfo : this->Pimpl->PointDataColoringInfo; - auto& names = - useCellData ? this->Pimpl->CellDataArrayNames : this->Pimpl->PointDataArrayNames; - - if (index < 0 || index >= static_cast(data.size())) - { - return false; - } - - info = data[names[index]]; - return true; -} - -//---------------------------------------------------------------------------- -int vtkF3DMetaImporter::GetNumberOfIndexesForColoring(bool useCellData) -{ - if (!this->Pimpl->ColoringInfoUpdated) - { - this->UpdateInfoForColoring(); - } - - auto& data = - useCellData ? this->Pimpl->CellDataColoringInfo : this->Pimpl->PointDataColoringInfo; - return static_cast(data.size()); -} - -//---------------------------------------------------------------------------- -int vtkF3DMetaImporter::FindIndexForColoring(bool useCellData, const std::string& arrayName) -{ - if (!this->Pimpl->ColoringInfoUpdated) - { - this->UpdateInfoForColoring(); - } - - auto& data = - useCellData ? this->Pimpl->CellDataColoringInfo : this->Pimpl->PointDataColoringInfo; - - auto it = data.find(arrayName); - if (it != data.end()) - { - return it->second.Index; - } - return -1; -} - //---------------------------------------------------------------------------- const std::vector& vtkF3DMetaImporter::GetColoringActorsAndMappers() @@ -672,13 +510,13 @@ void vtkF3DMetaImporter::UpdateInfoForColoring() datasetForColoring = genericImporter->GetImportedPoints(); } } - this->Pimpl->UpdateColoringInfo(datasetForColoring, false); - this->Pimpl->UpdateColoringInfo(datasetForColoring, true); + this->Pimpl->ColoringInfoHandler.UpdateColoringInfo(datasetForColoring, false); + this->Pimpl->ColoringInfoHandler.UpdateColoringInfo(datasetForColoring, true); } } - this->Pimpl->FinalizeColoringInfo(false); - this->Pimpl->FinalizeColoringInfo(true); + this->Pimpl->ColoringInfoHandler.FinalizeColoringInfo(false); + this->Pimpl->ColoringInfoHandler.FinalizeColoringInfo(true); this->Pimpl->ColoringInfoUpdated = true; } @@ -715,3 +553,14 @@ std::string vtkF3DMetaImporter::GetMetaDataDescription() const description += std::to_string(nCells); return description; } + +//---------------------------------------------------------------------------- +F3DColoringInfoHandler& vtkF3DMetaImporter::GetColoringInfoHandler() +{ + if (!this->Pimpl->ColoringInfoUpdated) + { + this->UpdateInfoForColoring(); + } + + return this->Pimpl->ColoringInfoHandler; +} diff --git a/vtkext/private/module/vtkF3DMetaImporter.h b/vtkext/private/module/vtkF3DMetaImporter.h index 37b2ee4999..cb6a53a72f 100644 --- a/vtkext/private/module/vtkF3DMetaImporter.h +++ b/vtkext/private/module/vtkF3DMetaImporter.h @@ -7,6 +7,7 @@ #define vtkF3DMetaImporter_h #include "vtkF3DImporter.h" +#include "F3DColoringInfoHandler.h" #include #include @@ -77,20 +78,6 @@ class vtkF3DMetaImporter : public vtkF3DImporter }; ///@} - /** - * A struct containing information about possible coloring - */ - struct ColoringInfo - { - std::string Name; - int MaximumNumberOfComponents = 0; - std::vector ComponentNames; - std::vector> ComponentRanges; - std::array MagnitudeRange = { std::numeric_limits::max(), - std::numeric_limits::min() }; - int Index = -1; - }; - /** * Clear all importers and internal structures */ @@ -112,23 +99,8 @@ class vtkF3DMetaImporter : public vtkF3DImporter */ std::string GetMetaDataDescription() const; - /** - * 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); + F3DColoringInfoHandler& GetColoringInfoHandler(); ///@{ /** diff --git a/vtkext/private/module/vtkF3DRenderer.cxx b/vtkext/private/module/vtkF3DRenderer.cxx index 6dcf884f91..09d837e460 100644 --- a/vtkext/private/module/vtkF3DRenderer.cxx +++ b/vtkext/private/module/vtkF3DRenderer.cxx @@ -2,6 +2,7 @@ #include "F3DDefaultHDRI.h" #include "F3DLog.h" +#include "F3DColoringInfoHandler.h" #include "vtkF3DCachedLUTTexture.h" #include "vtkF3DCachedSpecularTexture.h" #include "vtkF3DConfigure.h" @@ -281,9 +282,6 @@ void vtkF3DRenderer::Initialize() this->AnimationNameInfo = ""; this->GridInfo = ""; - this->ArrayIndexForColoring = -1; - this->ComponentForColoring = -1; - this->AddActor2D(this->ScalarBarActor); this->ScalarBarActor->VisibilityOff(); @@ -338,7 +336,7 @@ void vtkF3DRenderer::InitializeUpVector(const std::string& upString) } else { - F3DLog::Print(F3DLog::Severity::Warning, upString + " is not a valid up direction"); + F3DLog::Print(F3DLog::Severity::Warning, upString + " is not a valid up direction\n"); } } @@ -405,7 +403,7 @@ void vtkF3DRenderer::ConfigureRenderPasses() else { F3DLog::Print(F3DLog::Severity::Warning, - "Final shader must define a function named \"pixel\""); + "Final shader must define a function named \"pixel\"\n"); } } @@ -427,7 +425,7 @@ void vtkF3DRenderer::ConfigureRenderPasses() if (this->UseRaytracing || this->UseRaytracingDenoiser) { F3DLog::Print(F3DLog::Severity::Warning, - "Raytracing options can't be used if F3D has not been built with raytracing"); + "Raytracing options can't be used if F3D has not been built with raytracing\n"); } #endif this->RenderPassesConfigured = true; @@ -502,7 +500,7 @@ void vtkF3DRenderer::ShowAxis(bool show) } else { - F3DLog::Print(F3DLog::Severity::Error, "Axis widget cannot be shown without an interactor"); + F3DLog::Print(F3DLog::Severity::Error, "Axis widget cannot be shown without an interactor\n"); } } @@ -789,7 +787,7 @@ void vtkF3DRenderer::ConfigureHDRIReader() if (!vtksys::SystemTools::FileExists(this->HDRIFile.value(), true)) { F3DLog::Print( - F3DLog::Severity::Warning, std::string("HDRI file does not exist ") + this->HDRIFile.value()); + F3DLog::Severity::Warning, std::string("HDRI file does not exist ") + this->HDRIFile.value() + "\n"); } else { @@ -803,7 +801,7 @@ void vtkF3DRenderer::ConfigureHDRIReader() { F3DLog::Print(F3DLog::Severity::Warning, std::string("Cannot open HDRI file ") + this->HDRIFile.value() + - std::string(". Using default HDRI")); + std::string(". Using default HDRI\n")); } } } @@ -1121,7 +1119,7 @@ void vtkF3DRenderer::ConfigureTextActors() else { F3DLog::Print( - F3DLog::Severity::Warning, std::string("Cannot find \"") + tmpFontFile + "\" font file."); + F3DLog::Severity::Warning, std::string("Cannot find \"") + tmpFontFile + "\" font file.\n"); } } @@ -1369,11 +1367,54 @@ void vtkF3DRenderer::ShowCheatSheet(bool show) //---------------------------------------------------------------------------- void vtkF3DRenderer::ConfigureCheatSheet() { + assert(this->Importer); if (this->CheatSheetVisible) { + F3DColoringInfoHandler::ColoringInfo info; + bool hasColoring = + this->Importer->GetColoringInfoHandler().GetCurrentColoring(info); + std::stringstream cheatSheetText; cheatSheetText << "\n"; - this->FillCheatSheetHotkeys(cheatSheetText); + cheatSheetText << " C: Cell scalars coloring [" << (this->UseCellColoring ? "ON" : "OFF") + << "]\n"; + cheatSheetText << " S: Scalars coloring [" + << (hasColoring ? vtkF3DRenderer::ShortName(info.Name, 19) : "OFF") << "]\n"; + cheatSheetText << " Y: Coloring component [" + << vtkF3DRenderer::ComponentToString(this->ComponentForColoring) + << "]\n"; + cheatSheetText << " B: Scalar bar " << (this->ScalarBarVisible ? "[ON]" : "[OFF]") << "\n"; + cheatSheetText << " V: Volume representation " << (this->UseVolume ? "[ON]" : "[OFF]") << "\n"; + cheatSheetText << " I: Inverse volume opacity " + << (this->UseInverseOpacityFunction ? "[ON]" : "[OFF]") << "\n"; + cheatSheetText << " O: Point sprites " << (this->UsePointSprites ? "[ON]" : "[OFF]") << "\n"; + cheatSheetText << " W: Cycle animation [" + << vtkF3DRenderer::ShortName(this->AnimationNameInfo, 22) << "]\n"; + cheatSheetText << " P: Translucency support " << (this->UseDepthPeelingPass ? "[ON]" : "[OFF]") + << "\n"; + cheatSheetText << " Q: Ambient occlusion " << (this->UseSSAOPass ? "[ON]" : "[OFF]") << "\n"; + cheatSheetText << " A: Anti-aliasing " << (this->UseFXAAPass ? "[ON]" : "[OFF]") << "\n"; + cheatSheetText << " T: Tone mapping " << (this->UseToneMappingPass ? "[ON]" : "[OFF]") << "\n"; + cheatSheetText << " E: Edge visibility " << (this->EdgeVisible ? "[ON]" : "[OFF]") << "\n"; + cheatSheetText << " X: Axis " << (this->AxisVisible ? "[ON]" : "[OFF]") << "\n"; + cheatSheetText << " G: Grid " << (this->GridVisible ? "[ON]" : "[OFF]") << "\n"; + cheatSheetText << " N: File name " << (this->FilenameVisible ? "[ON]" : "[OFF]") << "\n"; + cheatSheetText << " M: Metadata " << (this->MetaDataVisible ? "[ON]" : "[OFF]") << "\n"; + cheatSheetText << " Z: FPS Timer " << (this->TimerVisible ? "[ON]" : "[OFF]") << "\n"; +#if F3D_MODULE_RAYTRACING + cheatSheetText << " R: Raytracing " << (this->UseRaytracing ? "[ON]" : "[OFF]") << "\n"; + cheatSheetText << " D: Denoiser " << (this->UseRaytracingDenoiser ? "[ON]" : "[OFF]") << "\n"; +#endif + cheatSheetText << " U: Blur background " << (this->UseBlurBackground ? "[ON]" : "[OFF]") << "\n"; + cheatSheetText << " K: Trackball interaction " << (this->UseTrackball ? "[ON]" : "[OFF]") << "\n"; + cheatSheetText << " F: HDRI ambient lighting " + << (this->GetUseImageBasedLighting() ? "[ON]" : "[OFF]") << "\n"; + cheatSheetText << " J: HDRI skybox " << (this->HDRISkyboxVisible ? "[ON]" : "[OFF]") << "\n"; + cheatSheetText.precision(2); + cheatSheetText << std::fixed; + cheatSheetText << " L: Light (increase, shift+L: decrease) [" << this->LightIntensity << "]" + << " \n"; + cheatSheetText << "\n H : Cheat sheet \n"; cheatSheetText << " ? : Print scene descr to terminal\n"; cheatSheetText << " ESC : Quit \n"; @@ -1386,7 +1427,7 @@ void vtkF3DRenderer::ConfigureCheatSheet() cheatSheetText << " 3: Right View camera\n"; cheatSheetText << " 4: Roll the camera left by 90 degrees\n"; cheatSheetText << " 5: Toggle Orthographic Projection " - << (this->UseOrthographicProjection ? "[ON]" : "[OFF]") << "\n"; + << (this->UseOrthographicProjection ? "[ON]" : "[OFF]") << "\n"; cheatSheetText << " 6: Roll the camera right by 90 degrees\n"; cheatSheetText << " 7: Top View camera\n"; cheatSheetText << " 9: Isometric View camera\n"; @@ -1424,56 +1465,6 @@ void vtkF3DRenderer::ShowHDRISkybox(bool show) } } -//---------------------------------------------------------------------------- -void vtkF3DRenderer::FillCheatSheetHotkeys(std::stringstream& cheatSheetText) -{ - assert(this->Importer); - - vtkF3DMetaImporter::ColoringInfo info; - bool hasColoring = - this->Importer->GetInfoForColoring(this->UseCellColoring, this->ArrayIndexForColoring, info); - - cheatSheetText << " C: Cell scalars coloring [" << (this->UseCellColoring ? "ON" : "OFF") - << "]\n"; - cheatSheetText << " S: Scalars coloring [" - << (hasColoring ? vtkF3DRenderer::ShortName(info.Name, 19) : "OFF") << "]\n"; - cheatSheetText << " Y: Coloring component [" - << vtkF3DRenderer::ComponentToString(this->ComponentForColoring) - << "]\n"; - cheatSheetText << " B: Scalar bar " << (this->ScalarBarVisible ? "[ON]" : "[OFF]") << "\n"; - - cheatSheetText << " V: Volume representation " << (this->UseVolume ? "[ON]" : "[OFF]") << "\n"; - cheatSheetText << " I: Inverse volume opacity " - << (this->UseInverseOpacityFunction ? "[ON]" : "[OFF]") << "\n"; - cheatSheetText << " O: Point sprites " << (this->UsePointSprites ? "[ON]" : "[OFF]") << "\n"; - cheatSheetText << " W: Cycle animation [" - << vtkF3DRenderer::ShortName(this->AnimationNameInfo, 22) << "]\n"; - cheatSheetText << " P: Translucency support " << (this->UseDepthPeelingPass ? "[ON]" : "[OFF]") - << "\n"; - cheatSheetText << " Q: Ambient occlusion " << (this->UseSSAOPass ? "[ON]" : "[OFF]") << "\n"; - cheatSheetText << " A: Anti-aliasing " << (this->UseFXAAPass ? "[ON]" : "[OFF]") << "\n"; - cheatSheetText << " T: Tone mapping " << (this->UseToneMappingPass ? "[ON]" : "[OFF]") << "\n"; - cheatSheetText << " E: Edge visibility " << (this->EdgeVisible ? "[ON]" : "[OFF]") << "\n"; - cheatSheetText << " X: Axis " << (this->AxisVisible ? "[ON]" : "[OFF]") << "\n"; - cheatSheetText << " G: Grid " << (this->GridVisible ? "[ON]" : "[OFF]") << "\n"; - cheatSheetText << " N: File name " << (this->FilenameVisible ? "[ON]" : "[OFF]") << "\n"; - cheatSheetText << " M: Metadata " << (this->MetaDataVisible ? "[ON]" : "[OFF]") << "\n"; - cheatSheetText << " Z: FPS Timer " << (this->TimerVisible ? "[ON]" : "[OFF]") << "\n"; -#if F3D_MODULE_RAYTRACING - cheatSheetText << " R: Raytracing " << (this->UseRaytracing ? "[ON]" : "[OFF]") << "\n"; - cheatSheetText << " D: Denoiser " << (this->UseRaytracingDenoiser ? "[ON]" : "[OFF]") << "\n"; -#endif - cheatSheetText << " U: Blur background " << (this->UseBlurBackground ? "[ON]" : "[OFF]") << "\n"; - cheatSheetText << " K: Trackball interaction " << (this->UseTrackball ? "[ON]" : "[OFF]") << "\n"; - cheatSheetText << " F: HDRI ambient lighting " - << (this->GetUseImageBasedLighting() ? "[ON]" : "[OFF]") << "\n"; - cheatSheetText << " J: HDRI skybox " << (this->HDRISkyboxVisible ? "[ON]" : "[OFF]") << "\n"; - cheatSheetText.precision(2); - cheatSheetText << std::fixed; - cheatSheetText << " L: Light (increase, shift+L: decrease) [" << this->LightIntensity << "]" - << " \n"; -} - //---------------------------------------------------------------------------- void vtkF3DRenderer::ShowEdge(const std::optional& show) { @@ -1916,7 +1907,7 @@ void vtkF3DRenderer::ConfigureActorsProperties() emissiveFactor = this->EmissiveFactor.value().data(); } } - + bool setBackfaceCulling = false; bool backfaceCulling = true; if (this->BackfaceType.has_value()) @@ -1933,7 +1924,7 @@ void vtkF3DRenderer::ConfigureActorsProperties() else { setBackfaceCulling = false; - F3DLog::Print(F3DLog::Severity::Warning, this->BackfaceType.value() + " is not a valid backface type, assuming it is not set"); + F3DLog::Print(F3DLog::Severity::Warning, this->BackfaceType.value() + " is not a valid backface type, assuming it is not set\n"); } } @@ -2071,7 +2062,7 @@ void vtkF3DRenderer::SetPointSpritesProperties(SplatType type, double pointSprit { F3DLog::Print(F3DLog::Severity::Warning, "Compute shaders are not supported, gaussians are not sorted, resulting in blending " - "artifacts"); + "artifacts\n"); } #endif } @@ -2106,7 +2097,7 @@ void vtkF3DRenderer::SetPointSpritesProperties(SplatType type, double pointSprit mapper->SetLowpassMatrix(lowPass); #else F3DLog::Print(F3DLog::Severity::Warning, - "Gaussian splatting selected but VTK <= 9.3 only supports isotropic gaussians"); + "Gaussian splatting selected but VTK <= 9.3 only supports isotropic gaussians\n"); #endif actor->ForceTranslucentOn(); @@ -2231,154 +2222,68 @@ void vtkF3DRenderer::SetColormap(const std::vector& colormap) } //---------------------------------------------------------------------------- -void vtkF3DRenderer::CycleScalars(CycleType type) +void vtkF3DRenderer::SetEnableColoring(bool enable) { - switch (type) + if (enable != this->EnableColoring) { - case (CycleType::NONE): - return; - break; - case (CycleType::FIELD): - this->CycleFieldForColoring(); - break; - case (CycleType::ARRAY_INDEX): - this->CycleArrayIndexForColoring(); - break; - case (CycleType::COMPONENT): - this->CycleComponentForColoring(); - break; - default: - break; + this->EnableColoring = enable; + this->CheatSheetConfigured = false; + this->ColoringConfigured = false; } - - // Check attributes are valid and cycle recursively if needed - this->CycleScalars(this->CheckColoring()); - - this->ColorTransferFunctionConfigured = false; - this->ColoringMappersConfigured = false; - this->PointSpritesMappersConfigured = false; - this->VolumePropsAndMappersConfigured = false; - this->ScalarBarActorConfigured = false; - this->CheatSheetConfigured = false; - this->ColoringConfigured = false; } //---------------------------------------------------------------------------- -vtkF3DRenderer::CycleType vtkF3DRenderer::CheckColoring() +void vtkF3DRenderer::SetUseCellColoring(bool useCell) { - assert(this->Importer); - - // Never force change of anything if we are currently not coloring - if (this->ArrayIndexForColoring < 0) - { - return CycleType::NONE; - } - - // Never force change of CellData/PointData coloring on the user - if (this->Importer->GetNumberOfIndexesForColoring(this->UseCellColoring) == 0) - { - return CycleType::NONE; - } - - // Suggest to change the array index only if current index is not valid - vtkF3DMetaImporter::ColoringInfo info; - if (!this->Importer->GetInfoForColoring(this->UseCellColoring, this->ArrayIndexForColoring, info)) + if (useCell != this->UseCellColoring) { - return CycleType::ARRAY_INDEX; - } - - // Suggest to change the component if current component is invalid - if (this->ComponentForColoring >= info.MaximumNumberOfComponents) - { - return CycleType::COMPONENT; + this->UseCellColoring = useCell; + this->ColorTransferFunctionConfigured = false; + this->ColoringMappersConfigured = false; + this->PointSpritesMappersConfigured = false; + this->VolumePropsAndMappersConfigured = false; + this->ScalarBarActorConfigured = false; + this->CheatSheetConfigured = false; + this->ColoringConfigured = false; } - - return CycleType::NONE; } //---------------------------------------------------------------------------- -void vtkF3DRenderer::SetColoring(bool enable, - bool useCellData, const std::optional& arrayName, int component) +void vtkF3DRenderer::SetArrayNameForColoring(const std::optional& arrayName) { - assert(this->Importer); - - // XXX This should be reworked to avoid handling multiple information in one parameters - // while still being future-proof and flexible enough. - if (enable != (this->ArrayIndexForColoring >= 0) - || useCellData != this->UseCellColoring - || component != this->ComponentForColoring - || arrayName != this->GetColoringArrayName()) + if (arrayName != this->ArrayNameForColoring) { - this->UseCellColoring = useCellData; - this->ComponentForColoring = component; - - int nIndexes = this->Importer->GetNumberOfIndexesForColoring(this->UseCellColoring); - if (!enable) - { - // Not coloring - this->ArrayIndexForColoring = -1; - } - else if (nIndexes == 0) - { - // Trying to color but no array available - F3DLog::Print(F3DLog::Severity::Debug, "No array to color with"); - this->ArrayIndexForColoring = -1; - } - else if (!arrayName.has_value()) - { - // Coloring with first array - this->ArrayIndexForColoring = 0; - } - else - { - // Coloring with named array - this->ArrayIndexForColoring = this->Importer->FindIndexForColoring(useCellData, arrayName.value()); - if (this->ArrayIndexForColoring == -1) - { - // Could not find named array - F3DLog::Print(F3DLog::Severity::Warning, "Unknown scalar array: \"" + arrayName.value() + "\"\n"); - } - } - + this->ArrayNameForColoring = arrayName; this->ColorTransferFunctionConfigured = false; this->ColoringMappersConfigured = false; this->PointSpritesMappersConfigured = false; this->VolumePropsAndMappersConfigured = false; this->ScalarBarActorConfigured = false; + this->CheatSheetConfigured = false; this->ColoringConfigured = false; } } //---------------------------------------------------------------------------- -bool vtkF3DRenderer::GetColoringEnabled() -{ - return this->ArrayIndexForColoring >= 0; -} - -//---------------------------------------------------------------------------- -bool vtkF3DRenderer::GetColoringUseCell() +std::optional vtkF3DRenderer::GetArrayNameForColoring() { - return this->UseCellColoring; + return this->ArrayNameForColoring; } //---------------------------------------------------------------------------- -std::optional vtkF3DRenderer::GetColoringArrayName() +void vtkF3DRenderer::SetComponentForColoring(int component) { - assert(this->Importer); - - std::optional arrayName; - vtkF3DMetaImporter::ColoringInfo info; - if (this->Importer && this->Importer->GetInfoForColoring(this->UseCellColoring, this->ArrayIndexForColoring, info)) + if (component != this->ComponentForColoring) { - arrayName = info.Name; + this->ComponentForColoring = component; + this->ColorTransferFunctionConfigured = false; + this->ColoringMappersConfigured = false; + this->PointSpritesMappersConfigured = false; + this->VolumePropsAndMappersConfigured = false; + this->ScalarBarActorConfigured = false; + this->CheatSheetConfigured = false; + this->ColoringConfigured = false; } - return arrayName; -} - -//---------------------------------------------------------------------------- -int vtkF3DRenderer::GetColoringComponent() -{ - return this->ComponentForColoring; } //---------------------------------------------------------------------------- @@ -2386,20 +2291,11 @@ void vtkF3DRenderer::ConfigureColoring() { assert(this->Importer); - // Recover coloring information - vtkF3DMetaImporter::ColoringInfo info; - bool hasColoring = - this->Importer->GetInfoForColoring(this->UseCellColoring, this->ArrayIndexForColoring, info); - - bool volumeVisible = !this->UseRaytracing && this->UseVolume; - if (!hasColoring && volumeVisible) - { - // When showing volume, always try to find an array to color with - this->CycleScalars(vtkF3DRenderer::CycleType::ARRAY_INDEX); - hasColoring = - this->Importer->GetInfoForColoring(this->UseCellColoring, this->ArrayIndexForColoring, info); - } - + // Recover coloring information and update handler + bool enableColoring = this->EnableColoring || (!this->UseRaytracing && this->UseVolume); + F3DColoringInfoHandler& coloringHandler = this->Importer->GetColoringInfoHandler(); + F3DColoringInfoHandler::ColoringInfo info; + bool hasColoring = coloringHandler.SetCurrentColoring(enableColoring, this->UseCellColoring, this->ArrayNameForColoring, info, false); if (hasColoring && !this->ColorTransferFunctionConfigured) { this->ConfigureRangeAndCTFForColoring(info); @@ -2463,6 +2359,7 @@ void vtkF3DRenderer::ConfigureColoring() } // Handle Volume prop + bool volumeVisible = !this->UseRaytracing && this->UseVolume; const auto& volPropsAndMappers = this->Importer->GetVolumePropsAndMappers(); for (const auto& [prop, mapper] : volPropsAndMappers) { @@ -2486,7 +2383,7 @@ void vtkF3DRenderer::ConfigureColoring() if (!visible) { F3DLog::Print( - F3DLog::Severity::Warning, "Cannot find the array \"" + info.Name + "\" to display volume with"); + F3DLog::Severity::Warning, "Cannot find the array \"" + info.Name + "\" to display volume with\n"); } } } @@ -2498,7 +2395,7 @@ void vtkF3DRenderer::ConfigureColoring() if (!this->VolumePropsAndMappersConfigured && volPropsAndMappers.size() == 0) { F3DLog::Print( - F3DLog::Severity::Error, "Cannot use volume with this data"); + F3DLog::Severity::Error, "Cannot use volume with this data\n"); } this->VolumePropsAndMappersConfigured = true; } @@ -2523,8 +2420,8 @@ std::string vtkF3DRenderer::GetColoringDescription() assert(this->Importer); std::stringstream stream; - vtkF3DMetaImporter::ColoringInfo info; - if (this->Importer->GetInfoForColoring(this->UseCellColoring, this->ArrayIndexForColoring, info)) + F3DColoringInfoHandler::ColoringInfo info; + if (this->Importer->GetColoringInfoHandler().GetCurrentColoring(info)) { stream << "Coloring using " << (this->UseCellColoring ? "cell" : "point") << " array named " << info.Name << ", " @@ -2563,7 +2460,7 @@ bool vtkF3DRenderer::ConfigureMapperForColoring(vtkPolyDataMapper* mapper, const { // comp > 4 is actually not supported and would fail with a vtk error F3DLog::Print(F3DLog::Severity::Warning, - "Direct scalars rendering not supported by array with more than 4 components"); + "Direct scalars rendering not supported by array with more than 4 components\n"); return false; } else @@ -2615,7 +2512,7 @@ bool vtkF3DRenderer::ConfigureVolumeForColoring(vtkSmartVolumeMapper* mapper, { // comp > 4 is actually not supported and would fail with a vtk error F3DLog::Print(F3DLog::Severity::Warning, - "Direct scalars rendering not supported by array with more than 4 components"); + "Direct scalars rendering not supported by array with more than 4 components\n"); return false; } else @@ -2657,7 +2554,7 @@ void vtkF3DRenderer::ConfigureScalarBarActorForColoring( //---------------------------------------------------------------------------- void vtkF3DRenderer::ConfigureRangeAndCTFForColoring( - const vtkF3DMetaImporter::ColoringInfo& info) + const F3DColoringInfoHandler::ColoringInfo& info) { if (this->ComponentForColoring == -2) { @@ -2721,7 +2618,7 @@ void vtkF3DRenderer::ConfigureRangeAndCTFForColoring( else { F3DLog::Print(F3DLog::Severity::Warning, - "Specified color map list count is not a multiple of 4, ignoring it."); + "Specified color map list count is not a multiple of 4, ignoring it.\n"); } } @@ -2739,30 +2636,35 @@ void vtkF3DRenderer::ConfigureRangeAndCTFForColoring( //---------------------------------------------------------------------------- void vtkF3DRenderer::CycleFieldForColoring() { - // A generic approach will be better when adding categorical field data coloring - this->UseCellColoring = !this->UseCellColoring; + // XXX: A generic approach will be better when adding categorical field data coloring + this->SetUseCellColoring(!this->UseCellColoring); + bool enableColoring = this->EnableColoring || (!this->UseRaytracing && this->UseVolume); + F3DColoringInfoHandler& coloringHandler = this->Importer->GetColoringInfoHandler(); + F3DColoringInfoHandler::ColoringInfo info; + if (!coloringHandler.SetCurrentColoring(enableColoring, this->UseCellColoring, this->ArrayNameForColoring, info, true)) + { + // Cycle array if the current one is not valid + this->CycleArrayForColoring(); + } } //---------------------------------------------------------------------------- -void vtkF3DRenderer::CycleArrayIndexForColoring() +void vtkF3DRenderer::CycleArrayForColoring() { assert(this->Importer); + this->Importer->GetColoringInfoHandler().CycleColoringArray(!this->UseVolume); //TODO check this cond + F3DColoringInfoHandler::ColoringInfo info; + bool enable = this->Importer->GetColoringInfoHandler().GetCurrentColoring(info); - int nIndex = this->Importer->GetNumberOfIndexesForColoring(this->UseCellColoring); - if (nIndex <= 0) - { - return; - } - - if (this->UseVolume) + this->SetEnableColoring(enable); + if (this->EnableColoring) { - this->ArrayIndexForColoring = (this->ArrayIndexForColoring + 1) % nIndex; - } - else - { - // Cycle through arrays looping back to -1 - // -1 0 1 2 -1 0 1 2 ... - this->ArrayIndexForColoring = (this->ArrayIndexForColoring + 2) % (nIndex + 1) - 1; + this->SetArrayNameForColoring(info.Name); + if (this->ComponentForColoring >= info.MaximumNumberOfComponents) + { + // Cycle component if the current one is not valid + this->CycleComponentForColoring(); + } } } @@ -2771,15 +2673,15 @@ void vtkF3DRenderer::CycleComponentForColoring() { assert(this->Importer); - vtkF3DMetaImporter::ColoringInfo info; - if (!this->Importer->GetInfoForColoring(this->UseCellColoring, this->ArrayIndexForColoring, info)) + F3DColoringInfoHandler::ColoringInfo info; + if (!this->Importer->GetColoringInfoHandler().GetCurrentColoring(info)) { return; } // -2 -1 0 1 2 3 4 - this->ComponentForColoring = - (this->ComponentForColoring + 3) % (info.MaximumNumberOfComponents + 2) - 2; + this->SetComponentForColoring( + (this->ComponentForColoring + 3) % (info.MaximumNumberOfComponents + 2) - 2); } //---------------------------------------------------------------------------- @@ -2797,9 +2699,8 @@ std::string vtkF3DRenderer::ComponentToString(int component) } else { - vtkF3DMetaImporter::ColoringInfo info; - if (!this->Importer->GetInfoForColoring( - this->UseCellColoring, this->ArrayIndexForColoring, info)) + F3DColoringInfoHandler::ColoringInfo info; + if (!this->Importer->GetColoringInfoHandler().GetCurrentColoring(info)) { return ""; } diff --git a/vtkext/private/module/vtkF3DRenderer.h b/vtkext/private/module/vtkF3DRenderer.h index 973862a47d..085e28b528 100644 --- a/vtkext/private/module/vtkF3DRenderer.h +++ b/vtkext/private/module/vtkF3DRenderer.h @@ -282,46 +282,44 @@ class vtkF3DRenderer : public vtkOpenGLRenderer */ void SetColormap(const std::vector& colormap); - enum class CycleType - { - NONE, - FIELD, - ARRAY_INDEX, - COMPONENT - }; - /** - * Cycle the shown scalars according to the cycle type + * Set the meta importer to recover coloring information from */ - void CycleScalars(CycleType type); + void SetImporter(vtkF3DMetaImporter* importer); + + void SetEnableColoring(bool enable); + vtkGetMacro(EnableColoring, bool); + + void SetUseCellColoring(bool useCell); + vtkGetMacro(UseCellColoring, bool); + + void SetArrayNameForColoring(const std::optional& arrayName); + std::optional GetArrayNameForColoring(); + + void SetComponentForColoring(int component); + vtkGetMacro(ComponentForColoring, int); /** - * Set the meta importer to recover coloring information from + * Get information about the current coloring */ - void SetImporter(vtkF3DMetaImporter* importer); + virtual std::string GetColoringDescription(); /** - * Set coloring information. - * This method will try to find the corresponding array in the coloring attributes and will - * position ArrayIndexForColoring and DataForColoring accordingly. + * Switch between point data and cell data coloring */ - void SetColoring(bool enable, bool useCellData, const std::optional& arrayName, int component); + void CycleFieldForColoring(); - ///@{ /** - * Get current coloring information, - * Useful after using Cycle methods + * TODO */ - bool GetColoringEnabled(); - bool GetColoringUseCell(); - std::optional GetColoringArrayName(); - int GetColoringComponent(); - ///@} + void CycleArrayForColoring(); /** - * Get information about the current coloring + * Cycle the component in used for rendering + * looping back to direct scalars */ - virtual std::string GetColoringDescription(); + void CycleComponentForColoring(); + private: vtkF3DRenderer(); @@ -369,7 +367,7 @@ class vtkF3DRenderer : public vtkOpenGLRenderer void ConfigureActorsProperties(); /** - * Configure the cheatsheet text and mark it for rendering + * Configure the cheatsheet text and hotkeys and mark it for rendering */ void ConfigureCheatSheet(); @@ -383,11 +381,6 @@ class vtkF3DRenderer : public vtkOpenGLRenderer */ void ConfigureRenderPasses(); - /** - * Add all hotkeys options to the cheatsheet. - */ - void FillCheatSheetHotkeys(std::stringstream& sheet); - /** * Generate a padded metadata description * using the internal importer @@ -434,30 +427,7 @@ class vtkF3DRenderer : public vtkOpenGLRenderer * Configure internal range and color transfer function according to provided * coloring info */ - void ConfigureRangeAndCTFForColoring(const vtkF3DMetaImporter::ColoringInfo& info); - - /** - * Switch between point data and cell data coloring - */ - void CycleFieldForColoring(); - - /** - * Increment the array index or loop it back - * When not using volume, it will loop back - * to not coloring - */ - void CycleArrayIndexForColoring(); - - /** - * Cycle the component in used for rendering - * looping back to direct scalars - */ - void CycleComponentForColoring(); - - /** - * Check coloring is currently valid and return a cycle type to perform if not - */ - CycleType CheckColoring(); + void ConfigureRangeAndCTFForColoring(const F3DColoringInfoHandler::ColoringInfo& info); /** * Convert a component index into a string @@ -580,9 +550,10 @@ class vtkF3DRenderer : public vtkOpenGLRenderer double ColorRange[2] = { 0.0, 1.0 }; bool ColorTransferFunctionConfigured = false; + bool EnableColoring = false; bool UseCellColoring = false; - int ArrayIndexForColoring = -1; int ComponentForColoring = -1; + std::optional ArrayNameForColoring; bool ScalarBarVisible = false; bool UsePointSprites = false;