#include <QHelpEngine>
// Paraview includes
-#include <vtkPVConfig.h> // for symbol PARAVIEW_VERSION
+#include <vtkPVVersion.h> // for symbol PARAVIEW_VERSION
#include <vtkProcessModule.h>
#include <vtkPVSession.h>
#include <vtkPVProgressHandler.h>
// Initialize ParaView client and associated behaviors
// and connect to externally launched pvserver
- PVViewer_Core::ParaviewInitApp(aDesktop);
+ PVViewer_Core::ParaviewInitApp();
// Clear old copies of embedded macros files
//QString aDestPath = QString( "%1/.config/%2/Macros" ).arg( QDir::homePath() ).arg( QApplication::applicationName() );
--- /dev/null
+# Copyright (C) 2023 CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+cmake_minimum_required(VERSION 3.8)
+project(CADRepresentations)
+
+find_package(ParaView REQUIRED)
+
+if (NOT PARAVIEW_USE_QT)
+ message(ERROR
+ ": Please make sure ParaView has been built with PARAVIEW_USE_QT enabled.")
+ return ()
+endif()
+
+include(GNUInstallDirs)
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}")
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
+
+option(BUILD_SHARED_LIBS "Build shared libraries" ON)
+
+paraview_plugin_scan(
+ PLUGIN_FILES
+ cadRepresentations/paraview.plugin
+ PROVIDES_PLUGINS plugins
+ ENABLE_BY_DEFAULT ON
+ HIDE_PLUGINS_FROM_CACHE ON)
+
+paraview_plugin_build(
+ RUNTIME_DESTINATION "${CMAKE_INSTALL_BINDIR}"
+ LIBRARY_DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+ #LIBRARY_SUBDIRECTORY "${PARAVIEW_PLUGIN_SUBDIR}"
+ #INSTALL_EXPORT CADViewerParaViewPlugins
+ CMAKE_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/CADRepresentations
+ PLUGINS ${plugins}
+ TARGET CADRepresentationPlugin
+ #cadviewer_paraview_plugins
+ )
--- /dev/null
+<ServerManagerConfiguration>
+ <ProxyGroup name="representations">
+ <RepresentationProxy class="vtkCADRepresentation"
+ name="CADRepresentation"
+ processes="client|renderserver|dataserver">
+ <Documentation>
+ CAD Representation.
+ </Documentation>
+ <InputProperty command="SetInputConnection"
+ name="Input">
+ <Documentation>
+ Set the input to the representation. Must be a vtkPolyData producer.
+ </Documentation>
+ <DataTypeDomain composite_data_supported="0"
+ name="input_type">
+ <DataType value="vtkImageData" />
+ </DataTypeDomain>
+ </InputProperty>
+ <InputProperty command="SetSelectionConnection"
+ name="Selection">
+ <DataTypeDomain name="input_type">
+ <DataType value="vtkSelection" />
+ </DataTypeDomain>
+ <Documentation>Set the selection.</Documentation>
+ </InputProperty>
+ <IntVectorProperty command="SetVisibility"
+ default_values="1"
+ name="Visibility"
+ number_of_elements="1">
+ <BooleanDomain name="bool" />
+ <Documentation>
+ Set the visibility for this representation.
+ </Documentation>
+ </IntVectorProperty>
+ <IntVectorProperty command="SetGroupVisibility"
+ default_values="-1 0"
+ name="SetGroupVisibility"
+ number_of_elements="2">
+ <Documentation>
+ Set the group to show in Group Mode.
+ </Documentation>
+ </IntVectorProperty>
+ <IntVectorProperty command="SetGroupOpacity"
+ default_values="-1 0"
+ name="SetGroupOpacity"
+ number_of_elements="2">
+ <Documentation>
+ Set the opacity of the given group.
+ </Documentation>
+ </IntVectorProperty>
+ <IntVectorProperty command="SetGroupModeEnabled"
+ default_values="0"
+ name="GroupMode"
+ number_of_elements="1">
+ <BooleanDomain name="bool" />
+ <Documentation>
+ Enable or disable the Group Mode.
+ </Documentation>
+ </IntVectorProperty>
+ <Property command="Reset" name="Reset"/>
+ <Property command="BeginSelect" name="BeginSelect"/>
+ <Property command="EndSelect" name="EndSelect"/>
+ <Property command="CreateGroup" name="CreateGroup"/>
+ </RepresentationProxy>
+ </ProxyGroup>
+</ServerManagerConfiguration>
--- /dev/null
+# Copyright (C) 2023 CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+set(classes
+ vtkCADMapper
+ vtkCADRepresentation)
+
+vtk_module_add_module(CADRepresentations
+ FORCE_STATIC
+ CLASSES ${classes})
+
+paraview_add_server_manager_xmls(
+ XMLS CADRepresentation.xml)
--- /dev/null
+NAME
+ CADRepresentations
+DEPENDS
+ ParaView::RemotingViews
+ VTK::RenderingOpenGL2
+ VTK::CommonDataModel
+ VTK::glew
+PRIVATE_DEPENDS
+ VTK::CommonCore
--- /dev/null
+// Copyright (C) 2023 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "vtkCADMapper.h"
+
+#include <vtkCellData.h>
+#include <vtkObjectFactory.h>
+#include <vtkOpenGLBufferObject.h>
+#include <vtkOpenGLCellToVTKCellMap.h>
+#include <vtkOpenGLRenderWindow.h>
+#include <vtkPolyData.h>
+#include <vtkProperty.h>
+#include <vtkRenderer.h>
+#include <vtkTextureObject.h>
+#include <vtkSelectionNode.h>
+
+vtkStandardNewMacro(vtkCADMapper);
+
+//-----------------------------------------------------------------------------
+void vtkCADMapper::SetOpacity(vtkIdType cellId, unsigned char opacity)
+{
+ if(this->PrimColors.empty())
+ {
+ return;
+ }
+
+ for (vtkIdType primId : this->CellToPrimMap[cellId])
+ {
+ this->PrimColors[4 * primId + 3] = opacity;
+ }
+}
+
+//-----------------------------------------------------------------------------
+void vtkCADMapper::ToggleResetColor(vtkIdType cellId)
+{
+ if(this->PrimColors.empty())
+ {
+ return;
+ }
+
+ const int opacity = this->GroupModeEnabled ? 0 : 255;
+
+ // Retrieve "default" colors
+ unsigned char color[4];
+ this->Colors->GetTypedTuple(cellId, color);
+
+ for (vtkIdType primId : this->CellToPrimMap[cellId])
+ {
+ this->PrimColors[4 * primId] = color[0];
+ this->PrimColors[4 * primId + 1] = color[1];
+ this->PrimColors[4 * primId + 2] = color[2];
+ this->PrimColors[4 * primId + 3] = opacity;
+ }
+}
+
+//-----------------------------------------------------------------------------
+void vtkCADMapper::ToggleSelectColor(vtkIdType cellId)
+{
+ if(this->PrimColors.empty())
+ {
+ return;
+ }
+
+ auto* selectionColors =
+ this->GroupModeEnabled ? this->GroupSelectionColor : this->SelectionColor;
+
+ const int opacity = this->GroupModeEnabled ? this->SavedCellOpacities[cellId] : 255;
+
+ for (vtkIdType primId : this->CellToPrimMap[cellId])
+ {
+ this->PrimColors[4 * primId] = selectionColors[0];
+ this->PrimColors[4 * primId + 1] = selectionColors[1];
+ this->PrimColors[4 * primId + 2] = selectionColors[2];
+ this->PrimColors[4 * primId + 3] = opacity;
+ }
+}
+
+//-----------------------------------------------------------------------------
+void vtkCADMapper::TogglePreselectColor(vtkIdType cellId)
+{
+ if(this->PrimColors.empty())
+ {
+ return;
+ }
+
+ for (vtkIdType primId : this->CellToPrimMap[cellId])
+ {
+ this->PrimColors[4 * primId] = this->PreselectionColor[0];
+ this->PrimColors[4 * primId + 1] = this->PreselectionColor[1];
+ this->PrimColors[4 * primId + 2] = this->PreselectionColor[2];
+ this->PrimColors[4 * primId + 3] = 255;
+ }
+}
+
+//-----------------------------------------------------------------------------
+void vtkCADMapper::ForceUpdate()
+{
+ this->Modified();
+ this->NeedUpdate = true;
+}
+
+//-----------------------------------------------------------------------------
+void vtkCADMapper::BuildCellTextures(vtkRenderer* ren, vtkActor* vtkNotUsed(actor),
+ vtkCellArray* vtkNotUsed(prims)[4], int vtkNotUsed(representation))
+{
+ if (!this->NeedUpdate)
+ {
+ return;
+ }
+
+ // Add the preselection
+ for (vtkIdType idx :
+ this->SelectionCache[std::make_tuple(0, 0, this->PreselectedCellId)])
+ {
+ this->TogglePreselectColor(idx);
+ }
+
+ // Fill OpenGL related buffers
+ if (!this->CellScalarTexture)
+ {
+ this->CellScalarTexture = vtkTextureObject::New();
+ this->CellScalarBuffer = vtkOpenGLBufferObject::New();
+ this->CellScalarBuffer->SetType(vtkOpenGLBufferObject::TextureBuffer);
+ }
+ this->CellScalarTexture->SetContext(static_cast<vtkOpenGLRenderWindow*>(ren->GetVTKWindow()));
+ this->CellScalarBuffer->Upload(this->PrimColors, vtkOpenGLBufferObject::TextureBuffer);
+ this->CellScalarTexture->CreateTextureBuffer(
+ static_cast<unsigned int>(this->PrimColors.size() / 4), 4, VTK_UNSIGNED_CHAR,
+ this->CellScalarBuffer);
+
+ // Reset preselection
+ for (vtkIdType idx :
+ this->SelectionCache[std::make_tuple(0, 0, this->PreselectedCellId)])
+ {
+ this->ToggleResetColor(idx);
+ }
+
+ this->NeedUpdate = false;
+}
+
+//-----------------------------------------------------------------------------
+void vtkCADMapper::BeginSelect()
+{
+ this->Selecting = true;
+}
+
+//-----------------------------------------------------------------------------
+void vtkCADMapper::EndSelect()
+{
+ this->Selecting = false;
+}
+
+//-----------------------------------------------------------------------------
+void vtkCADMapper::CreateGroup()
+{
+ this->SavedGroups.emplace_back(std::make_pair(this->SelectedIds, this->CurrentArrayName));
+ this->SavedGroupVisibilities.emplace_back(false);
+ this->ResetSelection();
+}
+
+//-----------------------------------------------------------------------------
+void vtkCADMapper::SetGroupVisibility(int groupIdx, bool visibility)
+{
+ if(!this->GroupModeEnabled)
+ {
+ return;
+ }
+
+ // Reconstruct the cache if needed (if a different array for selection by value is choosen)
+ this->BuildSelectionCache(this->SavedGroups[groupIdx].second.c_str(), 0, this->CurrentInput);
+
+ // Save the group visibility
+ this->SavedGroupVisibilities[groupIdx] = visibility;
+
+ // Show the selected group
+ for (vtkIdType id : this->SavedGroups[groupIdx].first)
+ {
+ for (vtkIdType idx : this->SelectionCache[std::make_tuple(0, 0, id)])
+ {
+ if (visibility)
+ {
+ this->ToggleSelectColor(idx);
+ }
+ else
+ {
+ this->ToggleResetColor(idx);
+ }
+ }
+ this->SelectedIds.emplace(id);
+ }
+ this->ForceUpdate();
+}
+
+//-----------------------------------------------------------------------------
+void vtkCADMapper::SetGroupOpacity(int groupIdx, unsigned char opacity)
+{
+ if(!this->GroupModeEnabled)
+ {
+ return;
+ }
+
+ // Reconstruct the cache if needed (if a different array for selection by value is choosen)
+ this->BuildSelectionCache(this->SavedGroups[groupIdx].second.c_str(), 0, this->CurrentInput);
+
+ // Save the opacity of the selected group and update it directly if currently visible
+ for (vtkIdType id : this->SavedGroups[groupIdx].first)
+ {
+ for (vtkIdType idx : this->SelectionCache[std::make_tuple(0, 0, id)])
+ {
+ this->SavedCellOpacities[idx] = opacity;
+ if(this->SavedGroupVisibilities[groupIdx])
+ {
+ this->SetOpacity(idx, opacity);
+ }
+ }
+ }
+ this->ForceUpdate();
+}
+
+//-----------------------------------------------------------------------------
+void vtkCADMapper::SetGroupModeEnabled(bool enabled)
+{
+ this->GroupModeEnabled = enabled;
+
+ // Set the group mode colors and opacity and clear the selections
+ this->InitializePrimColors();
+ this->SelectedIds.clear();
+ this->PreselectedCellId = -1;
+
+ // Show all visible groups
+ for (vtkIdType groupId = 0; groupId < this->SavedGroups.size(); groupId++)
+ {
+ if (this->SavedGroupVisibilities[groupId])
+ {
+ this->SetGroupVisibility(groupId, true);
+ }
+ }
+
+ this->ForceUpdate();
+}
+
+//-----------------------------------------------------------------------------
+void vtkCADMapper::ResetSelection()
+{
+ for (vtkIdType id : this->SelectedIds)
+ {
+ for (vtkIdType idx : this->SelectionCache[std::make_tuple(0, 0, id)])
+ {
+ this->ToggleResetColor(idx);
+ }
+ }
+
+ this->SelectedIds.clear();
+ this->PreselectedCellId = -1;
+ this->ForceUpdate();
+}
+
+//-----------------------------------------------------------------------------
+void vtkCADMapper::Initialize()
+{
+ vtkPolyData* input = vtkPolyData::SafeDownCast(this->GetInput());
+ if(!input)
+ {
+ vtkErrorMacro("Unable to retrieve input polydata.");
+ return;
+ }
+
+ vtkCellArray* prims[4];
+
+ prims[0] = input->GetVerts();
+ prims[1] = input->GetLines();
+ prims[2] = input->GetPolys();
+ prims[3] = input->GetStrips();
+
+ vtkIdType nbVerts = input->GetNumberOfVerts();
+ vtkIdType nbLines = input->GetNumberOfLines();
+ vtkIdType nbPolys = input->GetNumberOfPolys();
+
+ // Store the mapping from OpenGL primitives to VTK cells
+ this->CellCellMap->BuildCellSupportArrays(prims, VTK_SURFACE, input->GetPoints());
+
+ // Create the mapping from VTK cells to OpenGL primitives (inverse of CellCellMap)
+ this->CellToPrimMap.clear();
+ this->CellToPrimMap.resize(nbVerts + nbLines + nbPolys);
+ for (auto& v : this->CellToPrimMap)
+ {
+ // heuristic : for performances, we assume that we will have at most 10 primitives per cell
+ // it's just a reserve, the algorithm will still works if there is more primitives
+ v.reserve(10);
+ }
+
+ for (size_t i = 0; i < this->CellCellMap->GetSize(); i++)
+ {
+ this->CellToPrimMap[this->CellCellMap->GetValue(i)].push_back(i);
+ }
+
+ // Reset the default colors for all VTK cells
+ if (vtkUnsignedCharArray::SafeDownCast(input->GetCellData()->GetArray("RGB")))
+ {
+ input->GetCellData()->RemoveArray("RGB");
+ }
+
+ vtkNew<vtkUnsignedCharArray> colorArray;
+ colorArray->SetNumberOfComponents(3);
+ colorArray->SetNumberOfTuples(nbVerts + nbLines + nbPolys);
+ colorArray->SetName("RGB");
+
+ input->GetCellData()->SetScalars(colorArray);
+
+ for (int i = 0; i < nbVerts; i++)
+ {
+ colorArray->SetTypedTuple(i, this->VertexColor);
+ }
+
+ for (int i = 0; i < nbLines; i++)
+ {
+ colorArray->SetTypedTuple(nbVerts + i, this->EdgeColor);
+ }
+
+ for (int i = 0; i < nbPolys; i++)
+ {
+ colorArray->SetTypedTuple(nbVerts + nbLines + i, this->FaceColor);
+ }
+
+ // Initialize the primitive colors from the created color array
+ this->InitializePrimColors();
+
+ // Clear saved group visibilities
+ this->SavedGroupVisibilities.clear();
+
+ // Initialize saved cell opacities
+ this->SavedCellOpacities.clear();
+ this->SavedCellOpacities.resize(nbVerts + nbLines + nbPolys, 255);
+
+ // Reset texture and selection
+ if (this->CellScalarTexture)
+ {
+ this->CellScalarTexture->Delete();
+ this->CellScalarTexture = nullptr;
+ }
+
+ if (this->CellScalarBuffer)
+ {
+ this->CellScalarBuffer->Delete();
+ this->CellScalarBuffer = nullptr;
+ }
+
+ this->SelectedIds.clear();
+ this->PreselectedCellId = -1;
+ this->ForceUpdate();
+}
+
+//----------------------------------------------------------------------------
+void vtkCADMapper::InitializePrimColors()
+{
+ vtkPolyData* input = vtkPolyData::SafeDownCast(this->GetInput());
+ if(!input)
+ {
+ vtkErrorMacro("Unable to retrieve input polydata.");
+ return;
+ }
+
+ vtkUnsignedCharArray* colorArray = vtkUnsignedCharArray::SafeDownCast(input->GetCellData()->GetAbstractArray("RGB"));
+ if(!colorArray)
+ {
+ vtkErrorMacro("Unable to retrieve the input color array.");
+ return;
+ }
+
+ // Map the VTK cell color values to the OpenGL primitives color values
+ unsigned char* colorPtr = colorArray->GetPointer(0);
+ const int opacity = this->GroupModeEnabled ? 0 : 255;
+
+ this->PrimColors.clear();
+ this->PrimColors.reserve(4 * this->CellCellMap->GetSize());
+ for (size_t i = 0; i < this->CellCellMap->GetSize(); i++)
+ {
+ for (int j = 0; j < 3; j++)
+ {
+ this->PrimColors.push_back(colorPtr[this->CellCellMap->GetValue(i) * 3 + j]);
+ }
+ this->PrimColors.push_back(opacity);
+ }
+}
+
+//----------------------------------------------------------------------------
+void vtkCADMapper::PrintSelf(ostream& os, vtkIndent indent)
+{
+ this->Superclass::PrintSelf(os, indent);
+}
+
+//----------------------------------------------------------------------------
+void vtkCADMapper::AddCellIdsToSelectionPrimitives(vtkPolyData* poly, const char* arrayName,
+ unsigned int processId, unsigned int compositeIndex, vtkIdType selectedId)
+{
+ this->BuildSelectionCache(arrayName, false, poly);
+ this->CurrentArrayName = arrayName;
+
+ // If we are selecting an already selected cell, remove it
+ auto idIterator = this->SelectedIds.find(selectedId);
+ if (idIterator != this->SelectedIds.end())
+ {
+ if (!this->Selecting)
+ {
+ return;
+ }
+ for (vtkIdType idx :
+ this->SelectionCache[std::make_tuple(processId, compositeIndex, selectedId)])
+ {
+ this->ToggleResetColor(idx);
+ }
+ this->SelectedIds.erase(idIterator);
+ return;
+ }
+
+ if (!this->Selecting)
+ {
+ if (this->PreselectedCellId == selectedId)
+ {
+ return;
+ }
+ this->PreselectedCellId = selectedId;
+ this->ForceUpdate();
+ }
+ else
+ {
+ this->PreselectedCellId = -1;
+ for (vtkIdType idx :
+ this->SelectionCache[std::make_tuple(processId, compositeIndex, selectedId)])
+ {
+ this->ToggleSelectColor(idx);
+ }
+ this->SelectedIds.emplace(selectedId);
+ this->ForceUpdate();
+ }
+}
--- /dev/null
+// Copyright (C) 2023 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef vtkCADMapper_h
+#define vtkCADMapper_h
+
+#include "CADRepresentationsModule.h" // for export macro
+
+#include <vtkOpenGLPolyDataMapper.h>
+
+#include <set>
+#include <vector>
+
+class CADREPRESENTATIONS_EXPORT vtkCADMapper : public vtkOpenGLPolyDataMapper
+{
+public:
+ static vtkCADMapper* New();
+ vtkTypeMacro(vtkCADMapper, vtkOpenGLPolyDataMapper);
+ void PrintSelf(ostream& os, vtkIndent indent) override;
+
+ /**
+ * Set the opacity value for the given VTK cell.
+ */
+ void SetOpacity(vtkIdType id, unsigned char opacity);
+
+ /**
+ * Set the reset color value for the given VTK cell.
+ */
+ void ToggleResetColor(vtkIdType id);
+
+
+ /**
+ * Set the select color value for the given VTK cell.
+ */
+ void ToggleSelectColor(vtkIdType id);
+
+
+ /**
+ * Set the preselect color value for the given VTK cell.
+ */
+ void TogglePreselectColor(vtkIdType id);
+
+ /**
+ * Initialize the map between the VTK cells and OpenGL primitives.
+ * Initialize also the colors of the primitives using this map
+ * and the defined colors (Face/Vertex/Edge colors)
+ */
+ void Initialize();
+
+ /**
+ * Force BuildCellTextures to execute for the next rendering step.
+ */
+ void ForceUpdate();
+
+ ///@{
+ /**
+ * Mark the begining and the end of the selection.
+ */
+ void BeginSelect();
+ void EndSelect();
+ ///@}
+
+ /**
+ * Create a new selection group, and reset the selection.
+ */
+ void CreateGroup();
+
+ /**
+ * If in group mode, set the visibility of the given selection group.
+ */
+ void SetGroupVisibility(int groupIdx, bool visibility);
+
+ /**
+ * If in group mode, set the opacity of the given selection group.
+ */
+ void SetGroupOpacity(int groupIdx, unsigned char opacity);
+
+ /**
+ * Enable/disable the Group Mode. In this mode, you visualize
+ * groups you saved (with the CreateGroup function). Only one
+ * group can be displayed at a time.
+ */
+ void SetGroupModeEnabled(bool enabled);
+
+ /**
+ * Reset the current selection.
+ */
+ void ResetSelection();
+
+protected:
+ vtkCADMapper() = default;
+ ~vtkCADMapper() = default;
+
+ /**
+ * Called each time a render pass is done. Pushes the primitive colors (PrimColors)
+ * on the OpenGL side.
+ */
+ void BuildCellTextures(
+ vtkRenderer* ren, vtkActor* actor, vtkCellArray* prims[4], int representation) override;
+
+private:
+ vtkCADMapper(const vtkCADMapper&) = delete;
+ void operator=(const vtkCADMapper&) = delete;
+
+ /**
+ * Called during the render pass if the mapper's selection (vtkSelection) changed.
+ * - Save the preselected id in order to render pre-selection when BuildCellTextures is called
+ * - If a new selected id is furnished, add it to the SelectedId cache and toggle
+ * the selection color for the corresponding vtkCell ids using the SelectionCache map.
+ *
+ * Selected / preselected ids are values of the data array (arrayName), which allow to
+ * map geometry elements to their vtkCell counterparts. This mapping is stored in the
+ * SelectionCache map.
+ */
+ void AddCellIdsToSelectionPrimitives(vtkPolyData* poly, const char* arrayName,
+ unsigned int processId, unsigned int compositeIndex, vtkIdType selectedId) override;
+
+ /**
+ * Initialise the primitive colors using color array stored in the input polydata.
+ * Also initialize the opacity values (depending on current mode).
+ */
+ void InitializePrimColors();
+
+ // VTK cells to OpenGL primitives map
+ std::vector<std::vector<vtkIdType>> CellToPrimMap;
+ // Store the currenly selected ids (array values)
+ std::set<vtkIdType> SelectedIds;
+ // Store all the saved selection groups and their respective array name
+ // (type of cell to select)
+ std::vector<std::pair<std::set<vtkIdType>, std::string>> SavedGroups;
+ // OpenGL primitives color, used in the BuildCellTextures method.
+ std::vector<unsigned char> PrimColors;
+ // Store the current preselected id (array value)
+ vtkIdType PreselectedCellId = -1;
+ bool NeedUpdate = false;
+ bool Selecting = false;
+ std::string CurrentArrayName;
+ bool GroupModeEnabled = false;
+
+ std::vector<bool> SavedGroupVisibilities;
+ std::vector<unsigned char> SavedCellOpacities;
+
+ const unsigned char FaceColor[3] = { 255, 255, 255 };
+ const unsigned char EdgeColor[3] = { 0, 255, 0 };
+ const unsigned char VertexColor[3] = { 255, 128, 0 };
+ const unsigned char PreselectionColor[3] = { 0, 0, 255 };
+ const unsigned char SelectionColor[3] = { 255, 0, 0 };
+ const unsigned char GroupSelectionColor[3] = { 0, 255, 255 };
+};
+
+#endif
--- /dev/null
+// Copyright (C) 2023 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "vtkCADMapper.h"
+#include "vtkCADRepresentation.h"
+
+#include <vtkActor.h>
+#include <vtkCellData.h>
+#include <vtkDataObject.h>
+#include <vtkInformation.h>
+#include <vtkInformationVector.h>
+#include <vtkObjectFactory.h>
+#include <vtkPolyData.h>
+#include <vtkPVRenderView.h>
+#include <vtkPVView.h>
+#include <vtkRenderer.h>
+#include <vtkSelection.h>
+
+#include <vtkMultiProcessController.h>
+#include <vtkAlgorithmOutput.h>
+#include <vtkSMSession.h>
+#include <vtkProcessModule.h>
+#include <vtkSelectionNode.h>
+
+vtkStandardNewMacro(vtkCADRepresentation);
+//----------------------------------------------------------------------------
+vtkCADRepresentation::vtkCADRepresentation()
+{
+ this->Actor->SetMapper(this->Mapper);
+
+ vtkNew<vtkSelection> sel;
+ this->Mapper->SetSelection(sel);
+
+ this->SetArrayIdNames(nullptr, nullptr);
+}
+
+//----------------------------------------------------------------------------
+int vtkCADRepresentation::ProcessViewRequest(vtkInformationRequestKey* request_type, vtkInformation* inInfo,
+ vtkInformation* outInfo)
+{
+ if (!this->Superclass::ProcessViewRequest(request_type, inInfo, outInfo))
+ {
+ return 0;
+ }
+
+ if (request_type == vtkPVView::REQUEST_UPDATE())
+ {
+ vtkPVRenderView::SetPiece(inInfo, this, this->PolyData);
+ vtkPVRenderView::SetGeometryBounds(inInfo, this, this->PolyData->GetBounds());
+ }
+ else if (request_type == vtkPVView::REQUEST_RENDER())
+ {
+ vtkAlgorithmOutput* producerPort = vtkPVRenderView::GetPieceProducer(inInfo, this);
+ this->Mapper->SetInputConnection(producerPort);
+
+ if(!this->IsInitialized)
+ {
+ this->Mapper->Initialize();
+ this->IsInitialized = true;
+ }
+ }
+
+ return 1;
+}
+
+//------------------------------------------------------------------------------
+void vtkCADRepresentation::SetVisibility(bool value)
+{
+ this->Superclass::SetVisibility(value);
+ this->Actor->SetVisibility(value);
+}
+
+//----------------------------------------------------------------------------
+void vtkCADRepresentation::BeginSelect()
+{
+ if(this->IsInitialized)
+ {
+ this->Mapper->BeginSelect();
+ }
+}
+
+//----------------------------------------------------------------------------
+void vtkCADRepresentation::EndSelect()
+{
+ if(this->IsInitialized)
+ {
+ this->Mapper->EndSelect();
+ }
+}
+
+//----------------------------------------------------------------------------
+void vtkCADRepresentation::CreateGroup()
+{
+ if(this->IsInitialized)
+ {
+ this->Mapper->CreateGroup();
+ }
+}
+
+//----------------------------------------------------------------------------
+void vtkCADRepresentation::SetGroupVisibility(int groupIdx, bool visibility)
+{
+ if(this->IsInitialized)
+ {
+ this->Mapper->SetGroupVisibility(groupIdx, visibility);
+ }
+}
+
+//----------------------------------------------------------------------------
+void vtkCADRepresentation::SetGroupOpacity(int groupIdx, unsigned char opacity)
+{
+ if(this->IsInitialized)
+ {
+ this->Mapper->SetGroupOpacity(groupIdx, opacity);
+ }
+}
+
+//----------------------------------------------------------------------------
+void vtkCADRepresentation::SetGroupModeEnabled(bool enabled)
+{
+ if(this->IsInitialized)
+ {
+ this->Mapper->SetGroupModeEnabled(enabled);
+ }
+}
+
+//----------------------------------------------------------------------------
+void vtkCADRepresentation::Reset()
+{
+ if(this->IsInitialized)
+ {
+ this->Mapper->ResetSelection();
+ }
+}
+
+//------------------------------------------------------------------------------
+int vtkCADRepresentation::FillInputPortInformation(int vtkNotUsed(port), vtkInformation* info)
+{
+ info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkPolyData");
+
+ // Saying INPUT_IS_OPTIONAL() is essential, since representations don't have
+ // any inputs on client-side (in client-server, client-render-server mode) and
+ // render-server-side (in client-render-server mode).
+ info->Set(vtkAlgorithm::INPUT_IS_OPTIONAL(), 1);
+
+ return 1;
+}
+
+//------------------------------------------------------------------------------
+int vtkCADRepresentation::RequestData(
+ vtkInformation* request, vtkInformationVector** inputVector, vtkInformationVector* outputVector)
+{
+ if (inputVector[0]->GetNumberOfInformationObjects() == 1)
+ {
+ vtkInformation* inInfo = inputVector[0]->GetInformationObject(0);
+ vtkPolyData* polyData = vtkPolyData::SafeDownCast(inInfo->Get(vtkDataObject::DATA_OBJECT()));
+ this->PolyData->ShallowCopy(polyData);
+ }
+ else
+ {
+ this->PolyData->Initialize();
+ }
+
+ return this->Superclass::RequestData(request, inputVector, outputVector);
+}
+
+//------------------------------------------------------------------------------
+bool vtkCADRepresentation::AddToView(vtkView* view)
+{
+ vtkPVRenderView* rview = vtkPVRenderView::SafeDownCast(view);
+ if (rview)
+ {
+ rview->GetRenderer()->AddActor(this->Actor);
+
+ // Indicate that this is prop that we are rendering when hardware selection
+ // is enabled.
+ rview->RegisterPropForHardwareSelection(this, this->Actor);
+ return this->Superclass::AddToView(view);
+ }
+ return false;
+}
+
+//------------------------------------------------------------------------------
+bool vtkCADRepresentation::RemoveFromView(vtkView* view)
+{
+ vtkPVRenderView* rview = vtkPVRenderView::SafeDownCast(view);
+ if (rview)
+ {
+ rview->GetRenderer()->RemoveActor(this->Actor);
+ rview->UnRegisterPropForHardwareSelection(this, this->Actor);
+ return this->Superclass::RemoveFromView(view);
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+void vtkCADRepresentation::PrintSelf(ostream& os, vtkIndent indent)
+{
+ this->Superclass::PrintSelf(os, indent);
+}
+
+//----------------------------------------------------------------------------
+void vtkCADRepresentation::SetSelectionConnection(vtkAlgorithmOutput* input)
+{
+ // Copied from vtkCompositeRepresentation
+ if (!input)
+ {
+ return;
+ }
+
+ vtkMultiProcessController* controller = vtkMultiProcessController::GetGlobalController();
+ int numPiece = controller->GetNumberOfProcesses();
+ int piece = controller->GetLocalProcessId();
+ input->GetProducer()->UpdatePiece(piece, numPiece, 0);
+
+ vtkSmartPointer<vtkSelection> sel;
+ int actualNbPieces = numPiece;
+
+ vtkSMSession* session =
+ vtkSMSession::SafeDownCast(vtkProcessModule::GetProcessModule()->GetSession());
+ if (session)
+ {
+ actualNbPieces = session->GetNumberOfProcesses(vtkPVSession::DATA_SERVER);
+ }
+
+ // in order to handle the case where we are connected to a parallel server using
+ // local rendering, we have to compare the number of processes here
+ if (numPiece < actualNbPieces && piece == 0)
+ {
+ vtkSelection* localSel =
+ vtkSelection::SafeDownCast(input->GetProducer()->GetOutputDataObject(0));
+ sel = vtkSmartPointer<vtkSelection>::New();
+ sel->ShallowCopy(localSel);
+
+ for (int i = 1; i < actualNbPieces; i++)
+ {
+ input->GetProducer()->UpdatePiece(i, actualNbPieces, 0);
+ localSel = vtkSelection::SafeDownCast(input->GetProducer()->GetOutputDataObject(0));
+ if (localSel->GetNumberOfNodes() > 1)
+ {
+ vtkWarningMacro("Only the first node of a selection will be considered.");
+ }
+ vtkSelectionNode* node = localSel->GetNode(0);
+ node->GetProperties()->Set(vtkSelectionNode::PROCESS_ID(), i);
+ sel->AddNode(localSel->GetNode(0));
+ }
+ }
+ else
+ {
+ sel = vtkSelection::SafeDownCast(input->GetProducer()->GetOutputDataObject(0));
+ if (sel->GetNumberOfNodes() > 1)
+ {
+ vtkWarningMacro("Only the first node of a selection will be considered.");
+ }
+ sel->GetNode(0)->GetProperties()->Set(vtkSelectionNode::PROCESS_ID(), piece);
+ }
+
+ this->Mapper->GetSelection()->ShallowCopy(sel);
+}
+
+//----------------------------------------------------------------------------
+void vtkCADRepresentation::SetArrayIdNames(const char* pointArray, const char* cellArray)
+{
+ vtkCADMapper* mapper = vtkCADMapper::SafeDownCast(this->Mapper);
+ mapper->SetPointIdArrayName(pointArray ? pointArray : "vtkOriginalPointIds");
+ mapper->SetCellIdArrayName(cellArray ? cellArray : "vtkOriginalCellIds");
+}
--- /dev/null
+// Copyright (C) 2023 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef vtkCADRepresentation_h
+#define vtkCADRepresentation_h
+
+#include "CADRepresentationsModule.h" // for export macro
+
+#include <vtkPVDataRepresentation.h>
+
+#include <array>
+#include <map>
+#include <unordered_set>
+#include <vector>
+
+class vtkActor;
+class vtkCADMapper;
+
+enum SelectionType : unsigned char
+{
+ GeometrySolids = 0,
+ GeometryVertices,
+ GeometryEdges,
+ GeometryFaces,
+ SelectionTypeCount
+};
+class CADREPRESENTATIONS_EXPORT vtkCADRepresentation
+ : public vtkPVDataRepresentation
+{
+public:
+ static vtkCADRepresentation* New();
+ vtkTypeMacro(vtkCADRepresentation, vtkPVDataRepresentation);
+ void PrintSelf(ostream& os, vtkIndent indent) override;
+
+ int ProcessViewRequest(vtkInformationRequestKey* request_type, vtkInformation* inInfo,
+ vtkInformation* outInfo) override;
+
+ /**
+ * Set the pre-configured selection source for making the selection.
+ * The vtkSelection is obtained internally and forwarded to the mapper
+ */
+ void SetSelectionConnection(vtkAlgorithmOutput* input);
+
+ /**
+ * Set the visibility of the rendered actor.
+ */
+ void SetVisibility(bool val) override;
+
+ void Reset();
+ void BeginSelect();
+ void EndSelect();
+
+ /**
+ * Create a new selection group, and reset the selection.
+ * Forwarded to the mapper.
+ */
+ void CreateGroup();
+
+ /**
+ * If in group mode, set the visibility of the given selection group.
+ * Forwarded to the mapper.
+ */
+ void SetGroupVisibility(int groupIdx, bool visibility);
+
+ /**
+ * If in group mode, set the opacity of the given selection group.
+ * Forwarded to the mapper.
+ */
+ void SetGroupOpacity(int groupIdx, unsigned char opacity);
+
+ /**
+ * Enable/disable the Group Mode. In this mode, you visualize
+ * groups you saved (with the CreateGroup function). Only one
+ * group can be displayed at a time.
+ * Forwarded to the mapper.
+ */
+ void SetGroupModeEnabled(bool enabled);
+
+ /**
+ * Add a shape to the list of selected shapes that will
+ * be modified by setOpacity / toggleColor functions
+ * (for debugging purposes).
+ */
+ void AddShape(vtkIdType groupId, vtkIdType cellId);
+
+ void SetArrayIdNames(const char* pointArray, const char* cellArray) override;
+protected:
+ vtkCADRepresentation();
+ ~vtkCADRepresentation() = default;
+
+ int FillInputPortInformation(int port, vtkInformation* info) override;
+ int RequestData(vtkInformation*, vtkInformationVector**, vtkInformationVector*) override;
+ bool AddToView(vtkView* view) override;
+ bool RemoveFromView(vtkView* view) override;
+
+ bool IsInitialized = false;
+ vtkNew<vtkActor> Actor;
+ vtkNew<vtkCADMapper> Mapper;
+ vtkNew<vtkPolyData> PolyData;
+
+private:
+ vtkCADRepresentation(const vtkCADRepresentation&) = delete;
+ void operator=(const vtkCADRepresentation&) = delete;
+};
+
+#endif // vtkCADRepresentation_h
--- /dev/null
+# Copyright (C) 2023 CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+paraview_add_plugin(CADRepresentation
+ VERSION "1.0"
+ MODULES CADRepresentations
+ MODULE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/CADRepresentations/vtk.module"
+ XML_DOCUMENTATION OFF)
--- /dev/null
+NAME
+ CADRepresentation
+DESCRIPTION
+ CADViewer plugin providing representations.
+REQUIRES_MODULES
+ ParaView::RemotingViews
+ VTK::CommonCore
+ VTK::CommonDataModel
+ VTK::RenderingOpenGL2
GaussToCell
VoroGauss
BivariateRepresentations
+ CADRepresentation
)
IF(NOT SALOME_LIGHT_ONLY)