From: mbs Date: Fri, 24 Mar 2023 17:18:34 +0000 (+0000) Subject: added ParaView plugins for new viewer X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=57f0d06f8c692bd8af4c1f2778097ef337a525e2;p=modules%2Fgui.git added ParaView plugins for new viewer --- diff --git a/src/PV3DViewer/resources/CMakeLists.txt b/src/PV3DViewer/resources/CMakeLists.txt new file mode 100644 index 000000000..c5b2f86f9 --- /dev/null +++ b/src/PV3DViewer/resources/CMakeLists.txt @@ -0,0 +1,27 @@ +# Copyright (C) 2010-2022 CEA/DEN, EDF R&D, OPEN CASCADE +# +# 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(dist_salomeres_DATA + ParaViewFilters.xml + ParaViewSources.xml + ) + +FOREACH(f ${dist_salomeres_DATA}) + INSTALL(FILES ${f} DESTINATION ${SALOME_GUI_INSTALL_RES_DATA}) +ENDFOREACH(f ${dist_salomeres_DATA}) diff --git a/src/PV3DViewer/resources/ParaViewFilters.xml b/src/PV3DViewer/resources/ParaViewFilters.xml new file mode 100644 index 000000000..060d098ba --- /dev/null +++ b/src/PV3DViewer/resources/ParaViewFilters.xml @@ -0,0 +1,309 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/PV3DViewer/resources/ParaViewReaders.xml b/src/PV3DViewer/resources/ParaViewReaders.xml new file mode 100644 index 000000000..dd88e53a0 --- /dev/null +++ b/src/PV3DViewer/resources/ParaViewReaders.xml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/PV3DViewer/resources/ParaViewSources.xml b/src/PV3DViewer/resources/ParaViewSources.xml new file mode 100644 index 000000000..f89f10efe --- /dev/null +++ b/src/PV3DViewer/resources/ParaViewSources.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/PV3DViewer/resources/ParaViewWriters.xml b/src/PV3DViewer/resources/ParaViewWriters.xml new file mode 100644 index 000000000..db7fd3e1c --- /dev/null +++ b/src/PV3DViewer/resources/ParaViewWriters.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/PV3DViewer/resources/README b/src/PV3DViewer/resources/README new file mode 100644 index 000000000..287b0ff3b --- /dev/null +++ b/src/PV3DViewer/resources/README @@ -0,0 +1,12 @@ +README +------ + +The purpose of the XML files in this folder is the following: + +1. ParaViewFilters.xml - this file describes ParaView filters which are available in the SALOME +2. ParaViewSources.xml - this file describes ParaView sources which are available in the SALOME +3. ParaViewReaders.xml - deprecated +4. ParaViewWriters.xml - deprecated + +Initially these files are available in the ParaView sources, they ensure proper loading of the ParaView resources such as icons and names of an actions. +ParaViewFilters.xml and ParaViewSources.xml should be updated during migration to newer ParaView version. diff --git a/src/SALOME_PYQT/SalomePyQt/SalomePyQt.cxx b/src/SALOME_PYQT/SalomePyQt/SalomePyQt.cxx index eea242463..483e1379f 100644 --- a/src/SALOME_PYQT/SalomePyQt/SalomePyQt.cxx +++ b/src/SALOME_PYQT/SalomePyQt/SalomePyQt.cxx @@ -53,6 +53,10 @@ #include "PVViewer_ViewManager.h" #include "PVViewer_ViewModel.h" #endif // DISABLE_PVVIEWER +#ifndef DISABLE_PV3DVIEWER +#include "PV3DViewer_ViewManager.h" +#include "PV3DViewer_ViewModel.h" +#endif // DISABLE_PV3DVIEWER #include "QtxActionMenuMgr.h" #include "QtxWorkstack.h" #include "QtxTreeView.h" @@ -3450,6 +3454,19 @@ public: myResult = true; } #endif // DISABLE_PVVIEWER + } + else if ( type == "ParaView3D") { + //MBS: +#ifndef DISABLE_PV3DVIEWER + // specific processing for ParaView3D viewer: + // hierarchy of ParaView3D viewer is much more complex than for usual view; + // we look for sub-widget named "Viewport" + QList lst = wnd->findChildren( "Viewport" ); + if ( !lst.isEmpty() ) { + lst[0]->resize( myWndWidth, myWndHeight ); + myResult = true; + } +#endif // DISABLE_PV3DVIEWER } else { if ( wnd->centralWidget() ) { diff --git a/src/SPV3D/plugins/CMakeLists.txt b/src/SPV3D/plugins/CMakeLists.txt new file mode 100644 index 000000000..72c37840f --- /dev/null +++ b/src/SPV3D/plugins/CMakeLists.txt @@ -0,0 +1,20 @@ +option(BUILD_SHARED_LIBS "Build shared libraries" ON) + +paraview_plugin_scan( + PLUGIN_FILES + cadSources/paraview.plugin + 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}" + PLUGINS_FILE_NAME "salome.xml" + INSTALL_EXPORT SPV3DParaViewPlugins + CMAKE_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/SPV3D + LIBRARY_SUBDIRECTORY "salome" + PLUGINS ${plugins} + TARGET salome_paraview_plugins) diff --git a/src/SPV3D/plugins/cadRepresentations/CADRepresentations/CADRepresentation.xml b/src/SPV3D/plugins/cadRepresentations/CADRepresentations/CADRepresentation.xml new file mode 100644 index 000000000..b79338f24 --- /dev/null +++ b/src/SPV3D/plugins/cadRepresentations/CADRepresentations/CADRepresentation.xml @@ -0,0 +1,66 @@ + + + + + CAD Representation. + + + + Set the input to the representation. Must be a vtkPolyData producer. + + + + + + + + + + Set the selection. + + + + + Set the visibility for this representation. + + + + + Set the group to show in Group Mode. + + + + + Set the opacity of the given group. + + + + + + Enable or disable the Group Mode. + + + + + + + + + diff --git a/src/SPV3D/plugins/cadRepresentations/CADRepresentations/CMakeLists.txt b/src/SPV3D/plugins/cadRepresentations/CADRepresentations/CMakeLists.txt new file mode 100644 index 000000000..b8961707b --- /dev/null +++ b/src/SPV3D/plugins/cadRepresentations/CADRepresentations/CMakeLists.txt @@ -0,0 +1,10 @@ +set(classes + vtkCADMapper + vtkCADRepresentation) + +vtk_module_add_module(CADRepresentations + FORCE_STATIC + CLASSES ${classes}) + +paraview_add_server_manager_xmls( + XMLS CADRepresentation.xml) diff --git a/src/SPV3D/plugins/cadRepresentations/CADRepresentations/MBDebug.h b/src/SPV3D/plugins/cadRepresentations/CADRepresentations/MBDebug.h new file mode 100644 index 000000000..53f42ed1c --- /dev/null +++ b/src/SPV3D/plugins/cadRepresentations/CADRepresentations/MBDebug.h @@ -0,0 +1,243 @@ +#ifndef MBDebug_HeaderFile +#define MBDebug_HeaderFile + +//--------------------------------------------------------------- +// Usage of the logging facilities: +// +// (1) At the beginning of each class file to be debugged, there +// should be a static string variable defined with the name +// of the class. Then, include the "MBDebug.h" header file. +// +// //--------------------------------------------------------- +// #define USE_DEBUG +// static const char *dbg_class = "ClassName"; +// #include "MBDebug.h" +// //--------------------------------------------------------- +// +// (2) At the beginning of each class method, call the DBG_FUN +// macro. +// +// int ClassName::MyMethod(int x) +// { +// DBG_FUN(); +// ... +// } +// +// NOTE: For static methods, call the DBG_FUNC() macro!! +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// This debugging/logging class is a "header-only" solution and +// does NOT require any additional implementation (.cpp) file! +//--------------------------------------------------------------- + +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef MB_IGNORE_QT +# include +#endif + +//--------------------------------------------------------------- +// Set the debug flags dependent on the preprocessor definitions +//--------------------------------------------------------------- +#ifdef USE_DEBUG +# define MBS_DEBUG_FLAG MBDebug::DF_DEBUG +#else +# define MBS_DEBUG_FLAG 0 +#endif /*DEBUG*/ + +#define MBS_DBG_FLAGS (MBS_DEBUG_FLAG) + + +//--------------------------------------------------------------- +// Define the global debug macros +//--------------------------------------------------------------- +#define DLOG MBDebug::LogPrint() +#define RETURN(var) { RET(var); return (var); } + +#ifdef USE_DEBUG + +# define DBG_FUN() MBDebug _dbg(dbg_class, __FUNCTION__, MBS_DBG_FLAGS, (void*)this) +# define DBG_FUNC() MBDebug _dbg(dbg_class, __FUNCTION__, MBS_DBG_FLAGS) +# define DBG_FUNB(blk) MBDebug _dbg(dbg_class, blk, MBS_DBG_FLAGS) +# define MSGEL(txt) MBDebug::LogPrint() << txt << std::endl +# define PRINT(txt) MBDebug::LogPrint() << txt +# define SHOW2(var,typ) DumpVar(#var,(typ)(var)) +# define SHOW(var) DumpVar(#var,var) +# define ARG(var) do { PRINT("in:"); DumpVar(#var,var); } while (0) +# define ARG2(var,typ) do { PRINT("in:"); DumpVar(#var,(typ)(var)); } while (0) +# define RET(var) do { PRINT("out:"); DumpVar(#var,var); } while (0) +# define MSG(txt) MBDebug::LogPrint() << txt + +#else /*!USE_DEBUG*/ + +# define DBG_FUN() +# define DBG_FUNC() +# define DBG_FUNB(blk) +# define MSGEL(txt) +# define PRINT(txt) +# define SHOW2(var,typ) +# define SHOW(var) +# define ARG(var) +# define ARG2(var,typ) +# define RET(var) +# define MSG(txt) + +#endif /*USE_DEBUG*/ + + +//--------------------------------------------------------------- +// Declare the debugging and profiling class +//--------------------------------------------------------------- +class MBDebug +{ +public: + enum { + DF_NONE = 0x00, // no debug + DF_DEBUG = 0x01 // debug a function + }; + + MBDebug(const char* aClassName, const char* aFuncName, const short aFlag, void* aThis=NULL) + :mClassName(aClassName),mFuncName(aFuncName),mThis(aThis),mFlags((unsigned char)aFlag) + { + if (mFlags & (DF_DEBUG)) + { + std::cout << "{ENTER: " << mClassName + "::" + mFuncName; + if (mThis) std::cout << "(this=" << mThis << ")"; + std::cout << std::endl; + } + } + virtual ~MBDebug() + { + if (mFlags & (DF_DEBUG)) + std::cout << "}LEAVE: " << mClassName << "::" << mFuncName << std::endl; + } + + // Log file output management + static std::ostream& LogPrint() { return std::cout; } + +private: + std::string mClassName; // Name of class to be debugged + std::string mFuncName; // Name of function to be debugged + void* mThis; // The "this" pointer to the class being debugged + unsigned char mFlags; // Debug mode flags +}; + + + +#define YesNo(b) (b ? "Yes" : "No") + + + +inline std::string w2s(std::wstring ws) +{ + using convert_typeX = std::codecvt_utf8; + std::wstring_convert converterX; + return(converterX.to_bytes(ws)); +} + +// Primitive types +inline void DumpVar(const char *szName, char value) +{ + DLOG << "[chr]: " << szName << "='" << value << "'" << std::endl; +} + +inline void DumpVar(const char *szName, bool value) +{ + DLOG << "[bool]: " << szName << "=" << (value ? "true" : "false") << std::endl; +} + +inline void DumpVar(const char *szName, short value) +{ + DLOG << "[shrt]: " << szName << "=" << value << std::endl; +} + +inline void DumpVar(const char *szName, int value) +{ + DLOG << "[int]: " << szName << "=" << value << std::endl; +} + +inline void DumpVar(const char *szName, long value) +{ + DLOG << "[long]: " << szName << "=" << value << std::endl; +} + +inline void DumpVar(const char *szName, double value) +{ + DLOG << "[dbl]: " << szName << "=" << value << std::endl; +} + +inline void DumpVar(const char *szName, unsigned char value) +{ + DLOG << "[byte]: " << szName << "=0x" << std::hex << value << std::dec << std::endl; +} + +inline void DumpVar(const char *szName, unsigned short value) +{ + DLOG << "[word]: " << szName << "=0x" << std::hex << value << std::dec << std::endl; +} + +inline void DumpVar(const char *szName, unsigned int value) +{ + DLOG << "[uint]: " << szName << "=0x" << std::hex << value << std::dec << std::endl; +} + +inline void DumpVar(const char *szName, unsigned long value) +{ + DLOG << "[dword]: " << szName << "=0x" << std::hex << value << std::dec << std::endl; +} + +inline void DumpVar(const char *szName, const char* value) +{ + DLOG << "[str]: " << szName << "=\"" << (value ? value : "") << "\"" << std::endl; +} + +inline void DumpVar(const char *szName, const std::string &value) +{ + DLOG << "[Str]: " << szName << "=\"" << value << "\"" << std::endl; +} + +inline void DumpVar(const char *szName, const std::wstring &value) +{ + DLOG << "[WStr]: " << szName << "=\"" << w2s(value) << "\"" << std::endl; +} + +#ifndef MB_IGNORE_QT +inline void DumpVar(const char *szName, const QString &value) +{ + DLOG << "[QStr]: " << szName << "=\"" << value.toStdString() << "\"" << std::endl; +} +#endif + +inline void DumpVar(const char *szName, const void* value) +{ + DLOG << "[ptr]: " << szName << "=" << value << std::endl; +} + + +// Collection of primitive types +inline void DumpVar(const char *szName, const std::set &values) +{ + DLOG << "[intSet]: " << szName << "={" << values.size() << "}["; + bool bFirst = true; + for (auto it=values.cbegin(); it!=values.cend(); ++it) + DLOG << (bFirst ? "" : ",") << *it; + DLOG << "]" << std::endl; +} + +inline void DumpVar(const char *szName, const std::list& values) +{ + DLOG << "[boolList]: " << szName << "={" << values.size() << "}["; + bool bFirst = true; + for (auto it=values.cbegin(); it!=values.cend(); ++it) + DLOG << (bFirst ? "" : ",") << (*it ? "Y" : "N"); + DLOG << "]" << std::endl; +} + + +#endif // MBDebug_HeaderFile + diff --git a/src/SPV3D/plugins/cadRepresentations/CADRepresentations/vtk.module b/src/SPV3D/plugins/cadRepresentations/CADRepresentations/vtk.module new file mode 100644 index 000000000..515f266e4 --- /dev/null +++ b/src/SPV3D/plugins/cadRepresentations/CADRepresentations/vtk.module @@ -0,0 +1,9 @@ +NAME + CADRepresentations +DEPENDS + ParaView::RemotingViews + VTK::RenderingOpenGL2 + VTK::CommonDataModel + VTK::glew +PRIVATE_DEPENDS + VTK::CommonCore diff --git a/src/SPV3D/plugins/cadRepresentations/CADRepresentations/vtkCADMapper.cxx b/src/SPV3D/plugins/cadRepresentations/CADRepresentations/vtkCADMapper.cxx new file mode 100644 index 000000000..df91e282b --- /dev/null +++ b/src/SPV3D/plugins/cadRepresentations/CADRepresentations/vtkCADMapper.cxx @@ -0,0 +1,495 @@ +#include "vtkCADMapper.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//--------------------------------------------------------- +#define USE_DEBUG +#define MB_IGNORE_QT +static const char *dbg_class = "vtkCADMapper"; +#include "MBDebug.h" +//--------------------------------------------------------- + + +vtkStandardNewMacro(vtkCADMapper); + +//----------------------------------------------------------------------------- +void vtkCADMapper::SetOpacity(vtkIdType cellId, unsigned char opacity) +{ + DBG_FUN(); + ARG2(cellId, long); + ARG2(opacity, int); + + if(this->PrimColors.empty()) + { + return; + } + + for (vtkIdType primId : this->CellToPrimMap[cellId]) + { + this->PrimColors[4 * primId + 3] = opacity; + } +} + +//----------------------------------------------------------------------------- +void vtkCADMapper::ToggleResetColor(vtkIdType cellId) +{ + DBG_FUN(); + ARG2(cellId, long); + + 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) +{ + DBG_FUN(); + ARG2(cellId, long); + + 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) +{ + // DBG_FUN(); + // ARG2(cellId, long); + + 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() +{ + DBG_FUN(); + + this->Modified(); + this->NeedUpdate = true; +} + +//----------------------------------------------------------------------------- +void vtkCADMapper::BuildCellTextures(vtkRenderer* ren, vtkActor* vtkNotUsed(actor), + vtkCellArray* vtkNotUsed(prims)[4], int vtkNotUsed(representation)) +{ + DBG_FUN(); + + 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(ren->GetVTKWindow())); + this->CellScalarBuffer->Upload(this->PrimColors, vtkOpenGLBufferObject::TextureBuffer); + this->CellScalarTexture->CreateTextureBuffer( + static_cast(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() +{ + DBG_FUN(); + MSGEL("...vtkMapper::BeginSelect()"); + + this->Selecting = true; +} + +//----------------------------------------------------------------------------- +void vtkCADMapper::EndSelect() +{ + DBG_FUN(); + MSGEL("...vtkMapper::EndSelect()"); + + this->Selecting = false; +} + +//----------------------------------------------------------------------------- +void vtkCADMapper::CreateGroup() +{ + DBG_FUN(); + + 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) +{ + DBG_FUN(); + ARG(groupIdx); + ARG(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) +{ + DBG_FUN(); + ARG(groupIdx); + ARG2(opacity, int); + + 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) +{ + DBG_FUN(); + ARG(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() +{ + DBG_FUN(); + + 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() +{ + DBG_FUN(); + + 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(); + SHOW2(nbVerts, long); + SHOW2(nbLines, long); + SHOW2(nbPolys, long); + + // 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 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() +{ + DBG_FUN(); + + 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) +{ + DBG_FUN(); + + this->Superclass::PrintSelf(os, indent); +} + +//---------------------------------------------------------------------------- +void vtkCADMapper::AddCellIdsToSelectionPrimitives(vtkPolyData* poly, const char* arrayName, + unsigned int processId, unsigned int compositeIndex, vtkIdType selectedId) +{ + MSGEL("...vtkCADMapper::AddCellIdsToSelectionPrimitives(array=" << (arrayName ? arrayName : "") << ", procId=" << processId << ", compIdx=" << compositeIndex << ", selId=" << (int)selectedId << ")"); + // DBG_FUN(); + // ARG(arrayName); + // ARG(processId); + // ARG(compositeIndex); + // ARG2(selectedId, long); + + 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(); + } +} diff --git a/src/SPV3D/plugins/cadRepresentations/CADRepresentations/vtkCADMapper.h b/src/SPV3D/plugins/cadRepresentations/CADRepresentations/vtkCADMapper.h new file mode 100644 index 000000000..214878071 --- /dev/null +++ b/src/SPV3D/plugins/cadRepresentations/CADRepresentations/vtkCADMapper.h @@ -0,0 +1,148 @@ +#ifndef vtkCADMapper_h +#define vtkCADMapper_h + +#include "CADRepresentationsModule.h" // for export macro + +#include + +#include +#include + +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> CellToPrimMap; + // Store the currenly selected ids (array values) + std::set SelectedIds; + // Store all the saved selection groups and their respective array name + // (type of cell to select) + std::vector, std::string>> SavedGroups; + // OpenGL primitives color, used in the BuildCellTextures method. + std::vector 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 SavedGroupVisibilities; + std::vector 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 diff --git a/src/SPV3D/plugins/cadRepresentations/CADRepresentations/vtkCADRepresentation.cxx b/src/SPV3D/plugins/cadRepresentations/CADRepresentations/vtkCADRepresentation.cxx new file mode 100644 index 000000000..d1e879d9d --- /dev/null +++ b/src/SPV3D/plugins/cadRepresentations/CADRepresentations/vtkCADRepresentation.cxx @@ -0,0 +1,319 @@ +#include "vtkCADMapper.h" +#include "vtkCADRepresentation.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +//--------------------------------------------------------- +#define USE_DEBUG +#define MB_IGNORE_QT +static const char *dbg_class = "vtkCADRepresentation"; +#include "MBDebug.h" +//--------------------------------------------------------- + + +vtkStandardNewMacro(vtkCADRepresentation); + +//---------------------------------------------------------------------------- +vtkCADRepresentation::vtkCADRepresentation() +{ + DBG_FUN(); + + this->Actor->SetMapper(this->Mapper); + + vtkNew sel; + this->Mapper->SetSelection(sel); + + this->SetArrayIdNames(nullptr, nullptr); +} + +//---------------------------------------------------------------------------- +int vtkCADRepresentation::ProcessViewRequest(vtkInformationRequestKey* request_type, vtkInformation* inInfo, + vtkInformation* outInfo) +{ + DBG_FUN(); + + if (!this->Superclass::ProcessViewRequest(request_type, inInfo, outInfo)) + { + return 0; + } + + if (request_type == vtkPVView::REQUEST_UPDATE()) + { + MSGEL("....vtkCADRepresentation::ProcessViewRequest(REQUEST_UPDATE)"); + vtkPVRenderView::SetPiece(inInfo, this, this->PolyData); + vtkPVRenderView::SetGeometryBounds(inInfo, this, this->PolyData->GetBounds()); + } + else if (request_type == vtkPVView::REQUEST_RENDER()) + { + MSGEL("....vtkCADRepresentation::ProcessViewRequest(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) +{ + DBG_FUN(); + ARG(value); + + this->Superclass::SetVisibility(value); + this->Actor->SetVisibility(value); +} + +//---------------------------------------------------------------------------- +void vtkCADRepresentation::BeginSelect() +{ + DBG_FUN(); + + if(this->IsInitialized) + { + this->Mapper->BeginSelect(); + } +} + +//---------------------------------------------------------------------------- +void vtkCADRepresentation::EndSelect() +{ + DBG_FUN(); + + if(this->IsInitialized) + { + this->Mapper->EndSelect(); + } +} + +//---------------------------------------------------------------------------- +void vtkCADRepresentation::CreateGroup() +{ + DBG_FUN(); + + if(this->IsInitialized) + { + this->Mapper->CreateGroup(); + } +} + +//---------------------------------------------------------------------------- +void vtkCADRepresentation::SetGroupVisibility(int groupIdx, bool visibility) +{ + DBG_FUN(); + ARG(groupIdx); + ARG(visibility); + + if(this->IsInitialized) + { + this->Mapper->SetGroupVisibility(groupIdx, visibility); + } +} + +//---------------------------------------------------------------------------- +void vtkCADRepresentation::SetGroupOpacity(int groupIdx, unsigned char opacity) +{ + DBG_FUN(); + ARG(groupIdx); + ARG2(opacity, int); + + if(this->IsInitialized) + { + this->Mapper->SetGroupOpacity(groupIdx, opacity); + } +} + +//---------------------------------------------------------------------------- +void vtkCADRepresentation::SetGroupModeEnabled(bool enabled) +{ + DBG_FUN(); + ARG(enabled); + + if(this->IsInitialized) + { + this->Mapper->SetGroupModeEnabled(enabled); + } +} + +//---------------------------------------------------------------------------- +void vtkCADRepresentation::Reset() +{ + DBG_FUN(); + + if(this->IsInitialized) + { + this->Mapper->ResetSelection(); + } +} + +//------------------------------------------------------------------------------ +int vtkCADRepresentation::FillInputPortInformation(int vtkNotUsed(port), vtkInformation* info) +{ + DBG_FUN(); + + 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) +{ + DBG_FUN(); + + if (inputVector[0]->GetNumberOfInformationObjects() == 1) + { + MSGEL("....for a SINGLE info object"); + 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) +{ + DBG_FUN(); + + vtkPVRenderView* rview = vtkPVRenderView::SafeDownCast(view); + if (rview) + { + MSGEL("....Renderer->AddActor()"); + 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) +{ + DBG_FUN(); + + 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) +{ + DBG_FUN(); + + this->Superclass::PrintSelf(os, indent); +} + +//---------------------------------------------------------------------------- +void vtkCADRepresentation::SetSelectionConnection(vtkAlgorithmOutput* input) +{ + DBG_FUN(); + + // 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 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::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) +{ + DBG_FUN(); + ARG(pointArray); + ARG(cellArray); + + vtkCADMapper* mapper = vtkCADMapper::SafeDownCast(this->Mapper); + mapper->SetPointIdArrayName(pointArray ? pointArray : "vtkOriginalPointIds"); + mapper->SetCellIdArrayName(cellArray ? cellArray : "vtkOriginalCellIds"); +} diff --git a/src/SPV3D/plugins/cadRepresentations/CADRepresentations/vtkCADRepresentation.h b/src/SPV3D/plugins/cadRepresentations/CADRepresentations/vtkCADRepresentation.h new file mode 100644 index 000000000..e3a277b22 --- /dev/null +++ b/src/SPV3D/plugins/cadRepresentations/CADRepresentations/vtkCADRepresentation.h @@ -0,0 +1,103 @@ +#ifndef vtkCADRepresentation_h +#define vtkCADRepresentation_h + +#include "CADRepresentationsModule.h" // for export macro + +#include + +#include +#include +#include +#include + +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 Actor; + vtkNew Mapper; + vtkNew PolyData; + +private: + vtkCADRepresentation(const vtkCADRepresentation&) = delete; + void operator=(const vtkCADRepresentation&) = delete; +}; + +#endif // vtkCADRepresentation_h diff --git a/src/SPV3D/plugins/cadRepresentations/CMakeLists.txt b/src/SPV3D/plugins/cadRepresentations/CMakeLists.txt new file mode 100644 index 000000000..57849acd4 --- /dev/null +++ b/src/SPV3D/plugins/cadRepresentations/CMakeLists.txt @@ -0,0 +1,5 @@ +paraview_add_plugin(CADRepresentation + VERSION "1.0" + MODULES CADRepresentations + MODULE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/CADRepresentations/vtk.module" + XML_DOCUMENTATION OFF) diff --git a/src/SPV3D/plugins/cadRepresentations/paraview.plugin b/src/SPV3D/plugins/cadRepresentations/paraview.plugin new file mode 100644 index 000000000..239ebf13e --- /dev/null +++ b/src/SPV3D/plugins/cadRepresentations/paraview.plugin @@ -0,0 +1,9 @@ +NAME + CADRepresentation +DESCRIPTION + CADViewer plugin providing representations. +REQUIRES_MODULES + ParaView::RemotingViews + VTK::CommonCore + VTK::CommonDataModel + VTK::RenderingOpenGL2 diff --git a/src/SPV3D/plugins/cadSources/CADSources/CADSource.xml b/src/SPV3D/plugins/cadSources/CADSources/CADSource.xml new file mode 100644 index 000000000..5911cac4a --- /dev/null +++ b/src/SPV3D/plugins/cadSources/CADSources/CADSource.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + diff --git a/src/SPV3D/plugins/cadSources/CADSources/CMakeLists.txt b/src/SPV3D/plugins/cadSources/CADSources/CMakeLists.txt new file mode 100644 index 000000000..224a42b07 --- /dev/null +++ b/src/SPV3D/plugins/cadSources/CADSources/CMakeLists.txt @@ -0,0 +1,10 @@ +set(classes + vtkGeometryGenerator + vtkMeshGenerator) + +vtk_module_add_module(CADSources + FORCE_STATIC + CLASSES ${classes}) + +paraview_add_server_manager_xmls( + XMLS CADSource.xml) diff --git a/src/SPV3D/plugins/cadSources/CADSources/MBDebug.h b/src/SPV3D/plugins/cadSources/CADSources/MBDebug.h new file mode 100644 index 000000000..bb701152f --- /dev/null +++ b/src/SPV3D/plugins/cadSources/CADSources/MBDebug.h @@ -0,0 +1,243 @@ +#ifndef MBDebug_HeaderFile +#define MBDebug_HeaderFile + +//--------------------------------------------------------------- +// Usage of the logging facilities: +// +// (1) At the beginning of each class file to be debugged, there +// should be a static string variable defined with the name +// of the class. Then, include the "MBDebug.h" header file. +// +// //--------------------------------------------------------- +// #define USE_DEBUG +// //#define MB_IGNORE_QT +// #define MB_CLASSNAME "ClassName" +// #include "MBDebug.h" +// //--------------------------------------------------------- +// +// (2) At the beginning of each class method, call the DBG_FUN +// macro. +// +// int ClassName::MyMethod(int x) +// { +// DBG_FUN(); +// ... +// } +// +// NOTE: For static methods, call the DBG_FUNC() macro!! +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// This debugging/logging class is a "header-only" solution and +// does NOT require any additional implementation (.cpp) file! +//--------------------------------------------------------------- + +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef MB_IGNORE_QT +# include +#endif + +//--------------------------------------------------------------- +// Set the debug flags dependent on the preprocessor definitions +//--------------------------------------------------------------- +#ifdef USE_DEBUG +# define MBS_DEBUG_FLAG MBDebug::DF_DEBUG +#else +# define MBS_DEBUG_FLAG 0 +#endif /*DEBUG*/ + +#define MBS_DBG_FLAGS (MBS_DEBUG_FLAG) + + +//--------------------------------------------------------------- +// Define the global debug macros +//--------------------------------------------------------------- +#define DLOG MBDebug::LogPrint() +#define RETURN(var) { RET(var); return (var); } + +#ifdef USE_DEBUG + +# define DBG_FUN() MBDebug _dbg(MB_CLASSNAME, __FUNCTION__, MBS_DBG_FLAGS, (void*)this) +# define DBG_FUNC() MBDebug _dbg(MB_CLASSNAME, __FUNCTION__, MBS_DBG_FLAGS) +# define DBG_FUNB(blk) MBDebug _dbg(MB_CLASSNAME, blk, MBS_DBG_FLAGS) +# define MSGEL(txt) MBDebug::LogPrint() << txt << std::endl +# define PRINT(txt) MBDebug::LogPrint() << txt +# define SHOW2(var,typ) DumpVar(#var,(typ)(var)) +# define SHOW(var) DumpVar(#var,var) +# define ARG(var) do { PRINT("in:"); DumpVar(#var,var); } while (0) +# define ARG2(var,typ) do { PRINT("in:"); DumpVar(#var,(typ)(var)); } while (0) +# define RET(var) do { PRINT("out:"); DumpVar(#var,var); } while (0) +# define MSG(txt) MBDebug::LogPrint() << txt + +#else /*!USE_DEBUG*/ + +# define DBG_FUN() +# define DBG_FUNC() +# define DBG_FUNB(blk) +# define MSGEL(txt) +# define PRINT(txt) +# define SHOW2(var,typ) +# define SHOW(var) +# define ARG(var) +# define ARG2(var,typ) +# define RET(var) +# define MSG(txt) + +#endif /*USE_DEBUG*/ + + +//--------------------------------------------------------------- +// Declare the debugging and profiling class +//--------------------------------------------------------------- +class MBDebug +{ +public: + enum { + DF_NONE = 0x00, // no debug + DF_DEBUG = 0x01 // debug a function + }; + + MBDebug(const char* aClassName, const char* aFuncName, const short aFlag, void* aThis=NULL) + :mClassName(aClassName),mFuncName(aFuncName),mThis(aThis),mFlags((unsigned char)aFlag) + { + if (mFlags & (DF_DEBUG)) + { + std::cout << "{ENTER: " << mClassName + "::" + mFuncName; + if (mThis) std::cout << "(this=" << mThis << ")"; + std::cout << std::endl; + } + } + virtual ~MBDebug() + { + if (mFlags & (DF_DEBUG)) + std::cout << "}LEAVE: " << mClassName << "::" << mFuncName << std::endl; + } + + // Log file output management + static std::ostream& LogPrint() { return std::cout; } + +private: + std::string mClassName; // Name of class to be debugged + std::string mFuncName; // Name of function to be debugged + void* mThis; // The "this" pointer to the class being debugged + unsigned char mFlags; // Debug mode flags +}; + + + +#define YesNo(b) (b ? "Yes" : "No") + + + +inline std::string w2s(std::wstring ws) +{ + using convert_typeX = std::codecvt_utf8; + std::wstring_convert converterX; + return(converterX.to_bytes(ws)); +} + +// Primitive types +inline void DumpVar(const char *szName, char value) +{ + DLOG << "[chr]: " << szName << "='" << value << "'" << std::endl; +} + +inline void DumpVar(const char *szName, bool value) +{ + DLOG << "[bool]: " << szName << "=" << (value ? "true" : "false") << std::endl; +} + +inline void DumpVar(const char *szName, short value) +{ + DLOG << "[shrt]: " << szName << "=" << value << std::endl; +} + +inline void DumpVar(const char *szName, int value) +{ + DLOG << "[int]: " << szName << "=" << value << std::endl; +} + +inline void DumpVar(const char *szName, long value) +{ + DLOG << "[long]: " << szName << "=" << value << std::endl; +} + +inline void DumpVar(const char *szName, double value) +{ + DLOG << "[dbl]: " << szName << "=" << value << std::endl; +} + +inline void DumpVar(const char *szName, unsigned char value) +{ + DLOG << "[byte]: " << szName << "=0x" << std::hex << value << std::dec << std::endl; +} + +inline void DumpVar(const char *szName, unsigned short value) +{ + DLOG << "[word]: " << szName << "=0x" << std::hex << value << std::dec << std::endl; +} + +inline void DumpVar(const char *szName, unsigned int value) +{ + DLOG << "[uint]: " << szName << "=0x" << std::hex << value << std::dec << std::endl; +} + +inline void DumpVar(const char *szName, unsigned long value) +{ + DLOG << "[dword]: " << szName << "=0x" << std::hex << value << std::dec << std::endl; +} + +inline void DumpVar(const char *szName, const char* value) +{ + DLOG << "[str]: " << szName << "=\"" << (value ? value : "") << "\"" << std::endl; +} + +inline void DumpVar(const char *szName, const std::string &value) +{ + DLOG << "[Str]: " << szName << "=\"" << value << "\"" << std::endl; +} + +inline void DumpVar(const char *szName, const std::wstring &value) +{ + DLOG << "[WStr]: " << szName << "=\"" << w2s(value) << "\"" << std::endl; +} + +#ifndef MB_IGNORE_QT +inline void DumpVar(const char *szName, const QString &value) +{ + DLOG << "[QStr]: " << szName << "=\"" << value.toStdString() << "\"" << std::endl; +} +#endif + +inline void DumpVar(const char *szName, const void* value) +{ + DLOG << "[ptr]: " << szName << "=" << value << std::endl; +} + + +// Collection of primitive types +inline void DumpVar(const char *szName, const std::set &values) +{ + DLOG << "[intSet]: " << szName << "={" << values.size() << "}["; + bool bFirst = true; + for (auto it=values.cbegin(); it!=values.cend(); ++it) + DLOG << (bFirst ? "" : ",") << *it; + DLOG << "]" << std::endl; +} + +inline void DumpVar(const char *szName, const std::list& values) +{ + DLOG << "[boolList]: " << szName << "={" << values.size() << "}["; + bool bFirst = true; + for (auto it=values.cbegin(); it!=values.cend(); ++it) + DLOG << (bFirst ? "" : ",") << (*it ? "Y" : "N"); + DLOG << "]" << std::endl; +} + + +#endif // MBDebug_HeaderFile diff --git a/src/SPV3D/plugins/cadSources/CADSources/vtk.module b/src/SPV3D/plugins/cadSources/CADSources/vtk.module new file mode 100644 index 000000000..612a21139 --- /dev/null +++ b/src/SPV3D/plugins/cadSources/CADSources/vtk.module @@ -0,0 +1,7 @@ +NAME + CADSources +DEPENDS + VTK::FiltersCore +PRIVATE_DEPENDS + VTK::CommonCore + VTK::CommonExecutionModel diff --git a/src/SPV3D/plugins/cadSources/CADSources/vtkGeometryGenerator.cxx b/src/SPV3D/plugins/cadSources/CADSources/vtkGeometryGenerator.cxx new file mode 100644 index 000000000..540d7bff5 --- /dev/null +++ b/src/SPV3D/plugins/cadSources/CADSources/vtkGeometryGenerator.cxx @@ -0,0 +1,301 @@ +/*========================================================================= + + Program: Visualization Toolkit + Module: vtkGeometryGenerator.cxx + + Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen + All rights reserved. + See Copyright.txt or http://www.kitware.com/Copyright.htm for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notice for more information. + +=========================================================================*/ +#include "vtkGeometryGenerator.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +//--------------------------------------------------------- +#define USE_DEBUG +#define MB_IGNORE_QT +#define MB_CLASSNAME "vtkGeometryGenerator" +#include "MBDebug.h" +//--------------------------------------------------------- + + +vtkStandardNewMacro(vtkGeometryGenerator); + +//---------------------------------------------------------------------------- +vtkGeometryGenerator::vtkGeometryGenerator() +{ + DBG_FUN(); + this->SetNumberOfInputPorts(0); +} + +//---------------------------------------------------------------------------- +void vtkGeometryGenerator::PrintSelf(ostream& os, vtkIndent indent) +{ + DBG_FUN(); + this->Superclass::PrintSelf(os, indent); +} + +//---------------------------------------------------------------------------- +int vtkGeometryGenerator::RequestData(vtkInformation* vtkNotUsed(request), + vtkInformationVector** vtkNotUsed(inputVector), vtkInformationVector* outputVector) +{ + DBG_FUN(); + // get the output + vtkPolyData* output = vtkPolyData::GetData(outputVector); + + unsigned int nbPoints = 8 // cube points + + 12 * (this->EdgeSubdivision - 1) // additional points on edges + + 6 * (this->EdgeSubdivision - 1) * (this->EdgeSubdivision - 1) // additional points on faces + ; + + unsigned int nbLines = 12; + unsigned int nbPointsPerLine = this->EdgeSubdivision + 1; + unsigned int sizeLines = nbLines * (nbPointsPerLine + 1); + + unsigned int nbQuads = 6 * this->EdgeSubdivision * this->EdgeSubdivision; + unsigned int sizeQuads = nbQuads * 5; + SHOW2(nbPoints, int); SHOW2(nbLines, int); SHOW2(nbQuads, int); + + vtkNew points; + points->Allocate(this->NumberOfSolids * nbPoints); + + vtkNew vertices; + vertices->Allocate(this->NumberOfSolids * 8 * 2); + + vtkNew lines; + lines->Allocate(this->NumberOfSolids * sizeLines); + + vtkNew quads; + quads->Allocate(this->NumberOfSolids * sizeQuads); + + unsigned int totalCells = this->NumberOfSolids * (8 + 12 + nbQuads); + + vtkNew solidIdArray; + solidIdArray->SetName("Solid id"); + solidIdArray->SetNumberOfComponents(1); + solidIdArray->Allocate(totalCells); + + vtkNew faceIdArray; + faceIdArray->SetName("Face id"); + faceIdArray->SetNumberOfComponents(1); + faceIdArray->Allocate(totalCells); + + vtkNew edgeIdArray; + edgeIdArray->SetName("Edge id"); + edgeIdArray->SetNumberOfComponents(1); + edgeIdArray->Allocate(totalCells); + + vtkNew vertexIdArray; + vertexIdArray->SetName("Vertex id"); + vertexIdArray->SetNumberOfComponents(1); + vertexIdArray->Allocate(totalCells); + + int sizeRow; + int save_round = std::fegetround(); + std::fesetround(FE_UPWARD); + sizeRow = std::lrint(std::cbrt(this->NumberOfSolids) - 1e-10); + std::fesetround(save_round); + + // edge ids + std::array, 12> edgesIds; + for (std::vector& v : edgesIds) + { + v.resize(this->EdgeSubdivision + 1); + } + + // quads ids + std::array, 6> quadsIds; + for (std::vector& v : quadsIds) + { + v.resize((this->EdgeSubdivision + 1) * (this->EdgeSubdivision + 1)); + } + + // cube creation + const double cubeLen = 0.5; + const double cubeSpacing = 1.0; + const double edgeLen = cubeLen / static_cast(this->EdgeSubdivision); + unsigned int currentIndex = 0; + for (unsigned int i = 0; i < this->NumberOfSolids; i++) + { + double x = cubeSpacing * (i % sizeRow); + double y = cubeSpacing * ((i / sizeRow) % sizeRow); + double z = cubeSpacing * (i / (sizeRow * sizeRow)); + + // create vertices + std::array verticesIds; + + auto addPoint = [&](int id, double px, double py, double pz) { + verticesIds[id] = points->InsertNextPoint(px, py, pz); + vertices->InsertNextCell(1, &verticesIds[id]); + }; + + addPoint(0, x, y, z); + addPoint(1, x + cubeLen, y, z); + addPoint(2, x, y + cubeLen, z); + addPoint(3, x + cubeLen, y + cubeLen, z); + addPoint(4, x, y, z + cubeLen); + addPoint(5, x + cubeLen, y, z + cubeLen); + addPoint(6, x, y + cubeLen, z + cubeLen); + addPoint(7, x + cubeLen, y + cubeLen, z + cubeLen); + + // create edges + + auto addEdge = [&](int id, unsigned int vId1, unsigned int vId2, int comp) { + edgesIds[id][0] = verticesIds[vId1]; + edgesIds[id][this->EdgeSubdivision] = verticesIds[vId2]; + double p[3]; // position of starting point + points->GetPoint(verticesIds[vId1], p); + for (unsigned int j = 1; j < this->EdgeSubdivision; j++) + { + p[comp] += edgeLen; + edgesIds[id][j] = points->InsertNextPoint(p); + } + lines->InsertNextCell(this->EdgeSubdivision + 1, edgesIds[id].data()); + }; + + addEdge(0, 0, 1, 0); + addEdge(1, 1, 3, 1); + addEdge(2, 2, 3, 0); + addEdge(3, 0, 2, 1); + addEdge(4, 4, 5, 0); + addEdge(5, 4, 6, 1); + addEdge(6, 6, 7, 0); + addEdge(7, 5, 7, 1); + addEdge(8, 0, 4, 2); + addEdge(9, 1, 5, 2); + addEdge(10, 3, 7, 2); + addEdge(11, 2, 6, 2); + + // create faces + auto addFace = [&](int id, unsigned int eId1, unsigned int eId2, unsigned int eId3, + unsigned int eId4, int compU, int compV, bool orientU, bool orientV) { + for (unsigned int j = 0; j < this->EdgeSubdivision + 1; j++) + { + // vertices will be written two times (for each edges) but it should be the same + int uid = orientU ? j : this->EdgeSubdivision - j; + int vid = orientV ? j : this->EdgeSubdivision - j; + quadsIds[id][j] = edgesIds[eId1][uid]; + quadsIds[id][j + this->EdgeSubdivision * (this->EdgeSubdivision + 1)] = edgesIds[eId2][uid]; + quadsIds[id][j * (this->EdgeSubdivision + 1)] = edgesIds[eId3][vid]; + quadsIds[id][(j + 1) * (this->EdgeSubdivision + 1) - 1] = edgesIds[eId4][vid]; + } + + // create internal points + double p[3]; // position of starting corner + points->GetPoint(edgesIds[eId1][orientU ? 0 : this->EdgeSubdivision], p); + + double v = p[compV]; + for (unsigned int j = 1; j < this->EdgeSubdivision; j++) + { + p[compU] += orientV ? edgeLen : -edgeLen; + p[compV] = v; + for (unsigned int k = 1; k < this->EdgeSubdivision; k++) + { + p[compV] += orientU ? edgeLen : -edgeLen; + quadsIds[id][j * (this->EdgeSubdivision + 1) + k] = points->InsertNextPoint(p); + } + } + + // link internal points + for (unsigned int j = 0; j < this->EdgeSubdivision; j++) + { + for (unsigned int k = 0; k < this->EdgeSubdivision; k++) + { + vtkIdType q[4] = { quadsIds[id][j * (this->EdgeSubdivision + 1) + k], + quadsIds[id][(j + 1) * (this->EdgeSubdivision + 1) + k], + quadsIds[id][(j + 1) * (this->EdgeSubdivision + 1) + k + 1], + quadsIds[id][j * (this->EdgeSubdivision + 1) + k + 1] }; + quads->InsertNextCell(4, q); + } + } + }; + + addFace(0, 0, 2, 3, 1, 1, 0, true, true); + addFace(1, 9, 10, 1, 7, 1, 2, true, true); + addFace(2, 4, 6, 7, 5, 1, 0, false, true); + addFace(3, 8, 11, 5, 3, 1, 2, false, true); + addFace(4, 4, 0, 8, 9, 2, 0, true, false); + addFace(5, 2, 6, 11, 10, 2, 0, true, true); + } + + // noId indicates that no specific ID is assigned. + // -2 is used to avoid conflict with existing IDs as well as with preselection + vtkIdType noId = -2; + + // add vertex ids + for (unsigned int i = 0; i < this->NumberOfSolids; i++) + { + vtkIdType sId = i + 1; + for (unsigned int j = 0; j < 8; j++) + { + vtkIdType id = 8 * i + j + 1; + solidIdArray->InsertNextTypedTuple(&sId); + faceIdArray->InsertNextTypedTuple(&noId); + edgeIdArray->InsertNextTypedTuple(&noId); + vertexIdArray->InsertNextTypedTuple(&id); + } + } + + // add edges ids + for (unsigned int i = 0; i < this->NumberOfSolids; i++) + { + vtkIdType sId = i + 1; + for (unsigned int j = 0; j < 12; j++) + { + vtkIdType id = 12 * i + j + 1; + solidIdArray->InsertNextTypedTuple(&sId); + faceIdArray->InsertNextTypedTuple(&noId); + edgeIdArray->InsertNextTypedTuple(&id); + vertexIdArray->InsertNextTypedTuple(&noId); + } + } + + // add faces ids + for (unsigned int i = 0; i < this->NumberOfSolids; i++) + { + vtkIdType sId = i + 1; + for (unsigned int j = 0; j < 6; j++) + { + vtkIdType id = 6 * i + j + 1; + for (unsigned int k = 0; k < this->EdgeSubdivision * this->EdgeSubdivision; k++) + { + solidIdArray->InsertNextTypedTuple(&sId); + faceIdArray->InsertNextTypedTuple(&id); + edgeIdArray->InsertNextTypedTuple(&noId); + vertexIdArray->InsertNextTypedTuple(&noId); + } + } + } + + SHOW2(points->GetNumberOfPoints(), long); + SHOW2(vertices->GetNumberOfCells(), long); + SHOW2(lines->GetNumberOfCells(), long); + SHOW2(quads->GetNumberOfCells(), long); + output->SetPoints(points); + output->SetVerts(vertices); + output->SetLines(lines); + output->SetPolys(quads); + + output->GetCellData()->AddArray(solidIdArray); + output->GetCellData()->AddArray(faceIdArray); + output->GetCellData()->AddArray(edgeIdArray); + output->GetCellData()->AddArray(vertexIdArray); + + return 1; +} diff --git a/src/SPV3D/plugins/cadSources/CADSources/vtkGeometryGenerator.h b/src/SPV3D/plugins/cadSources/CADSources/vtkGeometryGenerator.h new file mode 100644 index 000000000..c435271a0 --- /dev/null +++ b/src/SPV3D/plugins/cadSources/CADSources/vtkGeometryGenerator.h @@ -0,0 +1,64 @@ +/*========================================================================= + + Program: Visualization Toolkit + Module: vtkGeometryGenerator.h + + Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen + All rights reserved. + See Copyright.txt or http://www.kitware.com/Copyright.htm for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notice for more information. + +=========================================================================*/ +/** + * @class vtkGeometryGenerator + * @brief create a polygonal mesh with BRep mapping + */ + +#ifndef vtkGeometryGenerator_h +#define vtkGeometryGenerator_h + +#include "CADSourcesModule.h" + +#include + +class CADSOURCES_EXPORT vtkGeometryGenerator : public vtkPolyDataAlgorithm +{ +public: + vtkTypeMacro(vtkGeometryGenerator, vtkPolyDataAlgorithm); + void PrintSelf(ostream& os, vtkIndent indent) override; + static vtkGeometryGenerator* New(); + + //@{ + /** + * Set/Get the number of subdivision of each edges of one cube. + */ + vtkSetMacro(EdgeSubdivision, unsigned int); + vtkGetMacro(EdgeSubdivision, unsigned int); + //@} + + //@{ + /** + * Set/Get the number of solids (cubes) generated. + */ + vtkSetMacro(NumberOfSolids, unsigned int); + vtkGetMacro(NumberOfSolids, unsigned int); + //@} + +protected: + vtkGeometryGenerator(); + ~vtkGeometryGenerator() override = default; + + int RequestData(vtkInformation*, vtkInformationVector**, vtkInformationVector*) override; + + unsigned int EdgeSubdivision = 10; + unsigned int NumberOfSolids = 5000; + +private: + vtkGeometryGenerator(const vtkGeometryGenerator&) = delete; + void operator=(const vtkGeometryGenerator&) = delete; +}; + +#endif diff --git a/src/SPV3D/plugins/cadSources/CADSources/vtkMeshGenerator.cxx b/src/SPV3D/plugins/cadSources/CADSources/vtkMeshGenerator.cxx new file mode 100644 index 000000000..0c8118283 --- /dev/null +++ b/src/SPV3D/plugins/cadSources/CADSources/vtkMeshGenerator.cxx @@ -0,0 +1,66 @@ +#include "vtkMeshGenerator.h" + +#include +#include +#include +#include +#include + +#include +#include + +//--------------------------------------------------------- +#define USE_DEBUG +#define MB_IGNORE_QT +#define MB_CLASSNAME "vtkMeshGenerator" +#include "MBDebug.h" +//--------------------------------------------------------- + + +vtkStandardNewMacro(vtkMeshGenerator); + +//---------------------------------------------------------------------------- +void vtkMeshGenerator::PrintSelf(ostream& os, vtkIndent indent) +{ + DBG_FUN(); + + this->Superclass::PrintSelf(os, indent); +} + +//------------------------------------------------------------------------------ +int vtkMeshGenerator::FillInputPortInformation(int port, vtkInformation* info) +{ + DBG_FUN(); + ARG(port); + + if (port == 0) + { + info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkPolyData"); + return 1; + } + return 0; +} + +//---------------------------------------------------------------------------- +int vtkMeshGenerator::RequestData(vtkInformation* request, + vtkInformationVector** inputVector, vtkInformationVector* outputVector) +{ + DBG_FUN(); + + vtkPolyData* input = vtkPolyData::GetData(inputVector[0]); + vtkUnstructuredGrid* output = vtkUnstructuredGrid::GetData(outputVector); + if (!input || !output) + { + return 0; + } + + MSGEL("....applying Delaunay3D filter"); + vtkNew delaunay; + delaunay->SetInputData(input); + delaunay->Update(); + + output->ShallowCopy(delaunay->GetOutput()); + + return 1; +} + diff --git a/src/SPV3D/plugins/cadSources/CADSources/vtkMeshGenerator.h b/src/SPV3D/plugins/cadSources/CADSources/vtkMeshGenerator.h new file mode 100644 index 000000000..ef5c1b3d2 --- /dev/null +++ b/src/SPV3D/plugins/cadSources/CADSources/vtkMeshGenerator.h @@ -0,0 +1,32 @@ +#ifndef vtkMeshGenerator_h +#define vtkMeshGenerator_h + +#include "CADSourcesModule.h" + +#include + +/** + * @class vtkMeshGenerator + * @brief create a mesh using a 3D Delaunay filter on a vtkPolyData + */ +class CADSOURCES_EXPORT vtkMeshGenerator : public vtkUnstructuredGridAlgorithm +{ +public: + + vtkTypeMacro(vtkMeshGenerator, vtkUnstructuredGridAlgorithm); + void PrintSelf(ostream& os, vtkIndent indent) override; + static vtkMeshGenerator* New(); + +protected: + vtkMeshGenerator() = default; + ~vtkMeshGenerator() override = default; + + int RequestData(vtkInformation*, vtkInformationVector**, vtkInformationVector*) override; + int FillInputPortInformation(int, vtkInformation*) override; + +private: + vtkMeshGenerator(const vtkMeshGenerator&) = delete; + void operator=(const vtkMeshGenerator&) = delete; +}; + +#endif diff --git a/src/SPV3D/plugins/cadSources/CMakeLists.txt b/src/SPV3D/plugins/cadSources/CMakeLists.txt new file mode 100644 index 000000000..be0a7a297 --- /dev/null +++ b/src/SPV3D/plugins/cadSources/CMakeLists.txt @@ -0,0 +1,6 @@ +paraview_add_plugin(CADSource + VERSION "1.0" + MODULES CADSources + SOURCES ${sources} + MODULE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/CADSources/vtk.module") + diff --git a/src/SPV3D/plugins/cadSources/paraview.plugin b/src/SPV3D/plugins/cadSources/paraview.plugin new file mode 100644 index 000000000..b25a87169 --- /dev/null +++ b/src/SPV3D/plugins/cadSources/paraview.plugin @@ -0,0 +1,6 @@ +NAME + CADSource +DESCRIPTION + CADViewer plugin providing sources +REQUIRES_MODULES + VTK::CommonCore