diff --git a/Core/Factory.h b/Core/Factory.h index 423fc25ab04d9138c22aec3e11dacc8433e6331a..91a01b8da0858746c4fe5cb163858e1bc0fd0670 100644 --- a/Core/Factory.h +++ b/Core/Factory.h @@ -55,7 +55,7 @@ #define RegisterFactoryClass(BASECLASS,SUBCLASS,GROUP) \ SIMMEDTK_BEGIN_DYNAMIC_LOADER() \ - SIMMEDTK_BEGIN_ONLOAD(register_IOMeshVTKDelegate) \ + SIMMEDTK_BEGIN_ONLOAD(register_##SUBCLASS) \ SIMMEDTK_REGISTER_CLASS(BASECLASS, BASECLASS, SUBCLASS, GROUP) \ SIMMEDTK_FINISH_ONLOAD() \ SIMMEDTK_FINISH_DYNAMIC_LOADER() diff --git a/Core/Factory.hpp b/Core/Factory.hpp index 0747e198fde01552a1c7fb3ab2aade1e66a7e3ea..ca83141e9a8decff88069f09710924c83d7fe05f 100644 --- a/Core/Factory.hpp +++ b/Core/Factory.hpp @@ -115,9 +115,9 @@ std::shared_ptr<T> Factory<T>::createConcreteClassForGroup( typename FactoryConfigurationOptions::const_iterator cit; for (bit = Factory::s_catalog->begin(); bit != Factory::s_catalog->end(); ++bit) for (cit = bit->second.begin(); cit != bit->second.end(); ++cit) - if (cit->subclassname == classname && cit->group == group) + if ((cit->subclassname == classname) && (cit->group == group)) { - std::cout << "Creating " << cit->subclassname << " (" << classname << " implied)\n"; + std::cout << "Creating " << cit->subclassname << " (" << classname << ", " << cit->group << ")\n"; return cit->constructor(); } diff --git a/Core/RenderDelegate.h b/Core/RenderDelegate.h index 9f43316a323b258c550739a092fc963e59ac9798..1754fe2a7a6bf29bbcaf5aab8da3236f4cfb115b 100644 --- a/Core/RenderDelegate.h +++ b/Core/RenderDelegate.h @@ -11,8 +11,8 @@ public: enum RendererType { - VTK = 300, - Other = 400 + VTK, + Other }; typedef std::shared_ptr<RenderDelegate> Ptr; @@ -40,9 +40,9 @@ public: { return this->sourceGeometry.sourceAs<T>(); } - protected: GeometrySource sourceGeometry; // object to render when draw() is called + std::string type; }; #endif // SMRENDERABLE_H diff --git a/Core/SDK.cpp b/Core/SDK.cpp index 2a36e9704c580a5e186c6ba16b559d0ffde60a8f..10ed417f83d499ee3f5fe2cb8ae8d12343f87fc3 100644 --- a/Core/SDK.cpp +++ b/Core/SDK.cpp @@ -177,7 +177,7 @@ void SDK::run() this->viewer->exec(); // Now wait for other modules to shut down - while (!shutdown) + while (this->viewer->isValid() && !shutdown) { std::this_thread::sleep_for(std::chrono::seconds(1)); } diff --git a/Core/SDK.h b/Core/SDK.h index 1ecc69dbc2ac44e5a9ca597aef5b050abdeeefc9..17083959783387381bc6a0098ac3ffd91d8e06b7 100644 --- a/Core/SDK.h +++ b/Core/SDK.h @@ -33,7 +33,9 @@ #include "Core/DataStructures.h" #include "Core/MakeUnique.h" #include "Rendering/OpenGLViewer.h" +#include "VTKRendering/VTKRendering.h" #include "RenderDelegates/Config.h" +#include "IO/IO.h" /// \brief maximum entities in the framework #define SIMMEDTK_SDK_MAXMESHES 100 diff --git a/Core/StaticSceneObject.cpp b/Core/StaticSceneObject.cpp index 7d6bbbbc8996ea3b252306d170bd9c8cabf9f8a0..5735532751bca9a658df0cf4f95c9b90330f8983 100644 --- a/Core/StaticSceneObject.cpp +++ b/Core/StaticSceneObject.cpp @@ -34,6 +34,8 @@ StaticSceneObject::StaticSceneObject(std::shared_ptr<ErrorLog> /*p_log*/) : Scen this->setRenderDelegate( Factory<RenderDelegate>::createConcreteClassForGroup( "StaticSceneObjectRenderDelegate",RenderDelegate::RendererType::VTK)); + + std::cout << this->getRenderDelegate() << std::endl; } StaticSceneObject::~StaticSceneObject() diff --git a/Core/ViewerBase.cpp b/Core/ViewerBase.cpp index 778d2722092d269ce8166d90863db2a782ecbb1d..82dbf62e79b028a42d80a3e2232533b0c35eb35f 100644 --- a/Core/ViewerBase.cpp +++ b/Core/ViewerBase.cpp @@ -51,6 +51,7 @@ ViewerBase::ViewerBase() unlimitedFPSVariableChanged = 1; screenResolutionWidth = 1680; screenResolutionHeight = 1050; + valid = true; } ///affects the framebuffer size and depth buffer size diff --git a/Core/ViewerBase.h b/Core/ViewerBase.h index e2a034ac73d73052b88b53206246984bab18b643..c1c2364bdac9c48fb6559026e12d49af2e3da094 100644 --- a/Core/ViewerBase.h +++ b/Core/ViewerBase.h @@ -147,10 +147,24 @@ public: unsigned int p_width, unsigned int p_height); virtual void setGlobalAxisLength(const float len); + + virtual const bool &isValid() + { + return this->valid; + } + + virtual void setIsValid(const bool newValid) + { + this->valid = newValid; + } + std::string windowTitle; Color defaultDiffuseColor; Color defaultAmbientColor; Color defaultSpecularColor; + bool valid; + /// \brief initialize, run the event loop (processWindowEvents) and clean up. + virtual void exec(); protected: /// \brief Renders the render operation to screen @@ -188,8 +202,6 @@ protected: virtual void render(); /// \brief adjust rendering FPS void adjustFPS(); - /// \brief initialize, run the event loop (processWindowEvents) and clean up. - virtual void exec(); }; #endif // SMVIEWERBASE_H diff --git a/Examples/renderCube/CMakeLists.txt b/Examples/renderCube/CMakeLists.txt index 64765cbca2e0a9dfcd2b6ed5b9dee386cf0bf263..32639594a3710508a41981c6a22de67fc120fff0 100644 --- a/Examples/renderCube/CMakeLists.txt +++ b/Examples/renderCube/CMakeLists.txt @@ -2,6 +2,7 @@ add_executable(renderCube main.cpp) target_link_libraries(renderCube Core + VTKRendering Rendering RenderDelegates Mesh @@ -9,5 +10,4 @@ target_link_libraries(renderCube Collision ExamplesCommon Geometry - VTKRendering ) diff --git a/Examples/renderCube/main.cpp b/Examples/renderCube/main.cpp index 317154ee743af3223689b1d12a04c6953b4ce3db..af83f439bbcb4f72de6796ebf9b5efbd8702cce7 100644 --- a/Examples/renderCube/main.cpp +++ b/Examples/renderCube/main.cpp @@ -34,6 +34,8 @@ int main() { + const bool useVTKRenderer = true; + std::shared_ptr<SDK> sdk; std::shared_ptr<Scene> scene1; std::shared_ptr<Light> light; @@ -46,18 +48,29 @@ int main() sdk = SDK::getInstance(); // Default viewer is based on vtk - auto viewer = sdk->createViewer(); + std::shared_ptr<ViewerBase> viewer; + if(useVTKRenderer) + { + viewer = sdk->createViewer(); + } + else + { + viewer = std::make_shared<OpenGLViewer>(); + sdk->addViewer(viewer); + } //Create a new scene to work in scene1 = sdk->createScene(); //Create the camera controller - camCtl = std::make_shared<mstk::Examples::Common::wasdCameraController>(); - keyShutdown = std::make_shared<mstk::Examples::Common::KeyPressSDKShutdown>(); - pzrCamCtl = std::make_shared<mstk::Examples::Common::pzrMouseCameraController>(); - + if(!useVTKRenderer) + { + camCtl = std::make_shared<mstk::Examples::Common::wasdCameraController>(); + keyShutdown = std::make_shared<mstk::Examples::Common::KeyPressSDKShutdown>(); + pzrCamCtl = std::make_shared<mstk::Examples::Common::pzrMouseCameraController>(); + } auto cubeModel = std::make_shared<MeshModel>(); - TextureManager::addTexture("textures/cube.png", "cubetex"); + TextureManager::addTexture("textures/cube.jpg", "cubetex"); cubeModel->load("models/cube.obj"); std::static_pointer_cast<SurfaceMesh>(cubeModel->getMesh())->assignTexture("cubetex"); @@ -67,15 +80,19 @@ int main() cube = std::make_shared<StaticSceneObject>(); // If you want to use the GL renderer you need to specify the appropiate render delegates - // This can be automated in the future, for now VTK is the default renderer -// cube->setModel(cubeModel); -// auto renderDelegate = Factory<RenderDelegate>::createConcreteClassForGroup( -// "StaticSceneObjectRenderDelegate",RenderDelegate::RendererType::Other); -// cube->setRenderDelegate(renderDelegate); -// -// renderDelegate = Factory<RenderDelegate>::createConcreteClassForGroup( -// "MeshRenderDelegate",RenderDelegate::RendererType::Other); -// cubeModel->getMesh()->setRenderDelegate(renderDelegate); + // This can be automated in the future, for now VTK is the default renderer and the delegates + // need to be reset. + cube->setModel(cubeModel); + if(!useVTKRenderer) + { + auto renderDelegate = Factory<RenderDelegate>::createConcreteClassForGroup( + "StaticSceneObjectRenderDelegate",RenderDelegate::RendererType::Other); + cube->setRenderDelegate(renderDelegate); + + renderDelegate = Factory<RenderDelegate>::createConcreteClassForGroup( + "MeshRenderDelegate",RenderDelegate::RendererType::Other); + cubeModel->getMesh()->setRenderDelegate(renderDelegate); + } //Add the cube to the scene to be rendered scene1->addSceneObject(cube); @@ -93,32 +110,37 @@ int main() //viewer->viewerRenderDetail |= SIMMEDTK_VIEWERRENDER_FULLSCREEN; // Setup Scene lighting - light = Light::getDefaultLighting(); - assert(light); - scene1->addLight(light); - - // Camera setup - sceneCamera = Camera::getDefaultCamera(); - assert(sceneCamera); - sceneCamera->setPos(3, 3, 5); - sceneCamera->setFocus(0, 0, -1); - sceneCamera->genProjMat(); - sceneCamera->genViewMat(); - scene1->addCamera(sceneCamera); - camCtl->setCamera(sceneCamera); - pzrCamCtl->setCamera(sceneCamera); - - //Link up the event system between this the camera controller and the viewer - viewer->attachEvent(core::EventType::Keyboard, camCtl); - viewer->attachEvent(core::EventType::Keyboard, keyShutdown); - viewer->attachEvent(core::EventType::MouseMove, pzrCamCtl); - viewer->attachEvent(core::EventType::MouseButton, pzrCamCtl); - + if(!useVTKRenderer) + { + light = Light::getDefaultLighting(); + assert(light); + scene1->addLight(light); + + // Camera setup + sceneCamera = Camera::getDefaultCamera(); + assert(sceneCamera); + sceneCamera->setPos(3, 3, 5); + sceneCamera->setFocus(0, 0, -1); + sceneCamera->genProjMat(); + sceneCamera->genViewMat(); + scene1->addCamera(sceneCamera); + camCtl->setCamera(sceneCamera); + pzrCamCtl->setCamera(sceneCamera); + + + //Link up the event system between this the camera controller and the viewer + viewer->attachEvent(core::EventType::Keyboard, camCtl); + viewer->attachEvent(core::EventType::Keyboard, keyShutdown); + viewer->attachEvent(core::EventType::MouseMove, pzrCamCtl); + viewer->attachEvent(core::EventType::MouseButton, pzrCamCtl); + } + + viewer->exec(); //run the framework - sdk->run(); +// sdk->run(); //cleanup - sdk->releaseScene(scene1); +// sdk->releaseScene(scene1); return 0; } diff --git a/Examples/vegaFem/main.cpp b/Examples/vegaFem/main.cpp index 1a56600972ee288016c58ae0cd4ad6549a392c55..4d28cc2880db4c748be5ed83ad3f293ffc7e92e6 100644 --- a/Examples/vegaFem/main.cpp +++ b/Examples/vegaFem/main.cpp @@ -24,12 +24,7 @@ #include <memory> // Core SimMedTK includes -#include "Core/Config.h" -#include "Core/ErrorLog.h" -#include "Core/CoreClass.h" #include "Core/SDK.h" -#include "Rendering/OpenGLViewer.h" -#include "Core/SceneObject.h" // Include required types scene objects #include "Simulators/VegaFemSceneObject.h" diff --git a/IO/IO.h b/IO/IO.h index eed5d50340b4a1a781c08e6b63ee6548848cdc1b..73f85426648bf808cd155e911c9f78dc51751a08 100644 --- a/IO/IO.h +++ b/IO/IO.h @@ -32,4 +32,4 @@ SIMMEDTK_RUN_LOADER(register_IOMeshAssimpDelegate); SIMMEDTK_RUN_LOADER(register_IOMeshVegaDelegate); SIMMEDTK_RUN_LOADER(register_IOMeshVTKDelegate); -#endif // IOMESH_H +#endif // IO_H diff --git a/IO/IOMesh.cpp b/IO/IOMesh.cpp index 8ed5d8f16e0756704d6b1f47dd666fb279a27cd0..70f8c3a0c947f64407ac83c4ad9d4a3d01d6337c 100644 --- a/IO/IOMesh.cpp +++ b/IO/IOMesh.cpp @@ -103,7 +103,7 @@ IOMesh::IOMesh(const IOMesh::ReaderGroup &priorityGroup) : this->delegator->addDelegator(MeshFileType::VEG,"IOMeshVegaDelegate"); // // The readers for obj,stl and ply are based on a priority group (defaults to vtk io's) - this->delegator->addGroupDelegator(MeshFileType::OBJ,"IOMeshDelegate",priorityGroup); + this->delegator->addGroupDelegator(MeshFileType::OBJ,"IOMeshDelegate",ReaderGroup::Assimp); this->delegator->addGroupDelegator(MeshFileType::STL,"IOMeshDelegate",priorityGroup); this->delegator->addGroupDelegator(MeshFileType::PLY,"IOMeshDelegate",priorityGroup); // diff --git a/IO/IOMeshAssimpDelegate.cpp b/IO/IOMeshAssimpDelegate.cpp index 97f48b0cc570f6de72568cc44bcec62b9825eacd..f2c7f9e729f052ef62879d92eb383926b229a15f 100644 --- a/IO/IOMeshAssimpDelegate.cpp +++ b/IO/IOMeshAssimpDelegate.cpp @@ -62,9 +62,7 @@ public: // Extract the information from the aiScene's mesh objects aiMesh *mesh = scene->mMeshes[0]; //Guarenteed to have atleast one mesh - auto surfaceMesh = std::make_shared<SurfaceMesh>(); - auto &vertices = surfaceMesh->getVertices(); - + std::vector<core::Vec3d> vertices; vertices.reserve(mesh->mNumVertices); // Get indexed vertex data @@ -74,7 +72,27 @@ public: mesh->mVertices[i][1], mesh->mVertices[i][2]); } - surfaceMesh->updateOriginalVertsWithCurrent(); + + std::vector<std::array<size_t,3>> triangleArray; + triangleArray.reserve(mesh->mNumFaces); + + // Setup triangle/face data + for (unsigned int i = 0; i < mesh->mNumFaces; i++) + { + //Make sure that the face is triangular + if (mesh->mFaces[i].mNumIndices != 3) + { + std::cerr << "Error: Error loading mesh, non-triangular face found." << std::endl; + return; + } + + std::array<size_t,3> t = {mesh->mFaces[i].mIndices[0], + mesh->mFaces[i].mIndices[1], + mesh->mFaces[i].mIndices[2]}; + triangleArray.emplace_back(t); + } + + this->setSurfaceMesh(vertices,triangleArray); // Get indexed texture coordinate data if (mesh->HasTextureCoords(0)) @@ -86,6 +104,7 @@ public: return; } + auto surfaceMesh = std::static_pointer_cast<SurfaceMesh>(this->meshIO->getMesh()); auto &textureCoordinates = surfaceMesh->getTextureCoordinates(); // Extract the texture data for (unsigned int i = 0; i < mesh->mNumVertices; i++) @@ -94,27 +113,6 @@ public: mesh->mTextureCoords[0][i][1]); } } - - auto &triangles = surfaceMesh->getTriangles(); - triangles.reserve(mesh->mNumFaces); - - // Setup triangle/face data - for (unsigned int i = 0; i < mesh->mNumFaces; i++) - { - //Make sure that the face is triangular - if (mesh->mFaces[i].mNumIndices != 3) - { - std::cerr << "Error: Error loading mesh, non-triangular face found." << std::endl; - return; - } - - std::array<size_t,3> t = {mesh->mFaces[i].mIndices[0], - mesh->mFaces[i].mIndices[1], - mesh->mFaces[i].mIndices[2]}; - triangles.emplace_back(t); - } - - this->meshIO->setMesh(surfaceMesh); } void write(){} }; diff --git a/IO/IOMeshDelegate.h b/IO/IOMeshDelegate.h index 5e48d5e9ce2032f860f0c3cebdaf6433fa7e3130..66bbe13183e4966f472474aaa3968544fc00079a 100644 --- a/IO/IOMeshDelegate.h +++ b/IO/IOMeshDelegate.h @@ -94,6 +94,8 @@ protected: auto mesh = std::make_shared<SurfaceMesh>(); mesh->setVertices(vertices); mesh->setTriangles(triangleArray); + mesh->computeTriangleNormals(); + mesh->computeVertexNormals(); this->meshIO->setMesh(mesh); } diff --git a/Mesh/SurfaceMesh.cpp b/Mesh/SurfaceMesh.cpp index 69d67a41c708195f083a885ac4bed044d3964bce..85c61ba233d0840a2f204d7ff8b1339a4ffee0fb 100644 --- a/Mesh/SurfaceMesh.cpp +++ b/Mesh/SurfaceMesh.cpp @@ -61,7 +61,7 @@ core::Vec3d SurfaceMesh::computeTriangleNormal(int triangle) } void SurfaceMesh::computeTriangleNormals() { - this->triangleNormals.resize(this->triangleArray.size()); + this->triangleNormals.resize(this->triangleArray.size(),core::Vec3d::Zero()); for(size_t i = 0, end = this->triangleArray.size(); i < end; ++i) { @@ -75,6 +75,11 @@ void SurfaceMesh::computeVertexNormals() { this->vertexNormals.resize(this->vertices.size(),core::Vec3d::Zero()); + if(this->vertexTriangleNeighbors.size() == 0) + { + this->computeVertexTriangleNeighbors(); + } + for(size_t i = 0, end = this->vertices.size(); i < end; ++i) { for(auto const &j : this->vertexTriangleNeighbors[i]) diff --git a/Rendering/OpenGLRenderer.cpp b/Rendering/OpenGLRenderer.cpp index fd3ef7a301dcb5fdc029dfa6485679037816f728..c9b6c4700113eac637da307f2f23a47a2e6e16ad 100644 --- a/Rendering/OpenGLRenderer.cpp +++ b/Rendering/OpenGLRenderer.cpp @@ -207,7 +207,7 @@ void OpenGLRenderer::drawSurfaceMeshTriangles( glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(3, GL_DOUBLE, 0, p_surfaceMesh->getVertices().data()->data()); glEnableClientState(GL_NORMAL_ARRAY); - glNormalPointer(GL_DOUBLE, 0, p_surfaceMesh->getVertexNormals().data()); + glNormalPointer(GL_DOUBLE, 0, p_surfaceMesh->getVertexNormals().data()->data()); auto &meshTextures = p_surfaceMesh->getTextures(); if (p_surfaceMesh->getRenderDetail()->getRenderType() & SIMMEDTK_RENDER_TEXTURE) @@ -232,12 +232,15 @@ void OpenGLRenderer::drawSurfaceMeshTriangles( if (p_surfaceMesh->getRenderDetail()->getRenderType() & SIMMEDTK_RENDER_FACES) { - auto data = (unsigned int*)p_surfaceMesh->getTriangles().data()->data(); - int size = p_surfaceMesh->getTriangles().size() * 3; - // - // TODO: Investigate a crash here when using the opengl renderer - // - glDrawElements(GL_TRIANGLES, size, GL_UNSIGNED_INT, data); + // TODO: Investigate why this expensive copy needs to be performed. + std::vector<unsigned int> data; + for(auto t : p_surfaceMesh->getTriangles()) + { + data.emplace_back(t[0]); + data.emplace_back(t[1]); + data.emplace_back(t[2]); + } + glDrawElements(GL_TRIANGLES, data.size(), GL_UNSIGNED_INT, data.data()); } if ((p_surfaceMesh->getRenderDetail()->getRenderType() & (SIMMEDTK_RENDER_VERTICES))) diff --git a/VTKRendering/VTKMeshRenderDelegate.cpp b/VTKRendering/VTKMeshRenderDelegate.cpp index 661fec5799c35c02851f9738ec20bdfbc97a386b..22053e590d9a3b7cdf614cf7a1dc6827a413cc04 100644 --- a/VTKRendering/VTKMeshRenderDelegate.cpp +++ b/VTKRendering/VTKMeshRenderDelegate.cpp @@ -54,9 +54,11 @@ class MeshRenderDelegate : public VTKRenderDelegate public: virtual bool isTargetTextured() const override; - vtkActor *getActor() const; - void initDraw(); - void modified(); + vtkActor *getActor() override; + void initDraw() override; + void modified() override; + void draw() const + { } private: vtkNew<vtkActor> actor; @@ -168,7 +170,7 @@ bool MeshRenderDelegate::isTargetTextured() const return geom->isMeshTextured(); } -vtkActor *MeshRenderDelegate::getActor() const +vtkActor *MeshRenderDelegate::getActor() { return this->actor.GetPointer(); } diff --git a/VTKRendering/VTKPlaneRenderDelegate.cpp b/VTKRendering/VTKPlaneRenderDelegate.cpp index ea6f61062e32b6ec3a53e36046918a4039d84b41..e54fa469aeb789a92cb0404c5a2a251da05e87c7 100644 --- a/VTKRendering/VTKPlaneRenderDelegate.cpp +++ b/VTKRendering/VTKPlaneRenderDelegate.cpp @@ -35,8 +35,10 @@ class PlaneRenderDelegate : public VTKRenderDelegate { public: - vtkActor *getActor() const override; + vtkActor *getActor() override; virtual void initDraw() override; + void draw() const + { } private: vtkNew<vtkActor> actor; @@ -67,7 +69,7 @@ void PlaneRenderDelegate::initDraw() this->actor->SetMapper(mapper); } -vtkActor *PlaneRenderDelegate::getActor() const +vtkActor *PlaneRenderDelegate::getActor() { return actor.GetPointer(); } diff --git a/VTKRendering/VTKRenderDelegate.h b/VTKRendering/VTKRenderDelegate.h index 67ffe84195d0b7896f742310ed6f2a67c2fad1f4..6c2313407945e6a62e28b803ef982a222b67f695 100644 --- a/VTKRendering/VTKRenderDelegate.h +++ b/VTKRendering/VTKRenderDelegate.h @@ -8,9 +8,11 @@ class vtkActor; class VTKRenderDelegate : public RenderDelegate { public: - virtual vtkActor *getActor() const = 0; - virtual void initDraw(){} - virtual void modified(){} + virtual vtkActor *getActor() = 0; + virtual void initDraw() override{} + virtual void modified() override{} + virtual void draw() const + { } }; #endif // SMRENDERABLE_H diff --git a/VTKRendering/VTKRendering.h b/VTKRendering/VTKRendering.h new file mode 100644 index 0000000000000000000000000000000000000000..6c2863f7a9c10ac94b90e0f4b881a9d531d2fd34 --- /dev/null +++ b/VTKRendering/VTKRendering.h @@ -0,0 +1,35 @@ +// This file is part of the SimMedTK project. +// Copyright (c) Center for Modeling, Simulation, and Imaging in Medicine, +// Rensselaer Polytechnic Institute +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//--------------------------------------------------------------------------- +// +// Authors: +// +// Contact: +//--------------------------------------------------------------------------- +#ifndef VTKRENDERING_H +#define VTKRENDERING_H + +#include "Core/Config.h" + +/// NOTE: Make sure that this file is included only once per application. + +SIMMEDTK_RUN_LOADER(register_MeshRenderDelegate); +SIMMEDTK_RUN_LOADER(register_PlaneRenderDelegate); +SIMMEDTK_RUN_LOADER(register_SceneObjectDeformableRenderDelegate); +SIMMEDTK_RUN_LOADER(register_StaticSceneObjectRenderDelegate); + +#endif // VTKRENDERING_H diff --git a/VTKRendering/VTKSceneObjectDeformableRenderDelegate.cpp b/VTKRendering/VTKSceneObjectDeformableRenderDelegate.cpp index 7d117d685749d3ce4d3146873c8312c1b7ae6cef..7b268c4a14344415d7e5802c87bce6b2872a846e 100644 --- a/VTKRendering/VTKSceneObjectDeformableRenderDelegate.cpp +++ b/VTKRendering/VTKSceneObjectDeformableRenderDelegate.cpp @@ -35,10 +35,12 @@ class SceneObjectDeformableRenderDelegate : public VTKRenderDelegate { public: - vtkActor *getActor() const override; + vtkActor *getActor() override; + void draw() const + { } }; -vtkActor *SceneObjectDeformableRenderDelegate::getActor() const +vtkActor *SceneObjectDeformableRenderDelegate::getActor() { auto geom = this->getSourceGeometryAs<VegaFemSceneObject>(); diff --git a/VTKRendering/VTKStaticSceneObjectRenderDelegate.cpp b/VTKRendering/VTKStaticSceneObjectRenderDelegate.cpp index 2bbf91d2110d16b745887779ea2e9ac292072c57..c7ee61c2292689905aaf6774ac865cdbdad1ddda 100644 --- a/VTKRendering/VTKStaticSceneObjectRenderDelegate.cpp +++ b/VTKRendering/VTKStaticSceneObjectRenderDelegate.cpp @@ -26,6 +26,7 @@ #include "Core/StaticSceneObject.h" #include "VTKRendering/VTKRenderDelegate.h" #include "Geometry/PlaneModel.h" +#include "Geometry/MeshModel.h" // VTK includes #include <vtkActor.h> @@ -33,10 +34,12 @@ class StaticSceneObjectRenderDelegate : public VTKRenderDelegate { public: - vtkActor *getActor() const override; + vtkActor *getActor() override; + void draw() const + { } }; -vtkActor *StaticSceneObjectRenderDelegate::getActor() const +vtkActor *StaticSceneObjectRenderDelegate::getActor() { StaticSceneObject* geom = this->getSourceGeometryAs<StaticSceneObject>(); if (!geom) @@ -47,20 +50,32 @@ vtkActor *StaticSceneObjectRenderDelegate::getActor() const auto planeModel = std::dynamic_pointer_cast<PlaneModel>( geom->getModel()); - if(!planeModel) + if(planeModel) { - return nullptr; + auto delegate = std::dynamic_pointer_cast<VTKRenderDelegate>( + planeModel->getPlaneModel()->getRenderDelegate()); + if(!delegate) + { + return nullptr; + } + delegate->initDraw(); + return delegate->getActor(); } - auto delegate = std::dynamic_pointer_cast<VTKRenderDelegate>( - planeModel->getPlaneModel()->getRenderDelegate()); + auto meshModel = std::dynamic_pointer_cast<MeshModel>( + geom->getModel()); - if(!delegate) + if(meshModel) { - return nullptr; + auto delegate = std::dynamic_pointer_cast<VTKRenderDelegate>( + meshModel->getMesh()->getRenderDelegate()); + if(!delegate) + { + return nullptr; + } + delegate->initDraw(); + return delegate->getActor(); } - delegate->initDraw(); - return delegate->getActor(); } RegisterFactoryClass(RenderDelegate, diff --git a/VTKRendering/VTKViewer.cpp b/VTKRendering/VTKViewer.cpp index 24721842e073840c6f1a20970e5c097e23c49436..706c0126556b911b9f5e14e0ad36a2f28af9c169 100644 --- a/VTKRendering/VTKViewer.cpp +++ b/VTKRendering/VTKViewer.cpp @@ -40,48 +40,44 @@ /// class VTKViewer::VTKRenderer : public vtkCommand { - //typedef void(*FunctionType)(vtkObject *, unsigned long, void*, void*); - //using FunctionType = void(vtkObject *,unsigned long,void*,void*); - //using CallBackFunctionType = std::function<FunctionType>; public: VTKRenderer(VTKViewer *activeViewer) : timerId(-1), viewer(activeViewer) { - auto timerEvent = [&](vtkObject*,unsigned long,void *callData, void*) - { - if(this->timerId == *static_cast<int*>(callData)) - { - this->renderWindow->Render(); - } - }; - auto keyPress = [](vtkObject *caller,unsigned long,void*,void*) - { - vtkRenderWindowInteractor *iren = - static_cast<vtkRenderWindowInteractor*>(caller); - // Close the window - iren->GetRenderWindow()->Finalize(); - - // Stop the interactor - iren->TerminateApp(); - std::cout << "Closing window..." << std::endl; - }; - - //callBacks.emplace(vtkCommand::TimerEvent,timerEvent); - //callBacks.emplace(vtkCommand::KeyPressEvent,keyPress); + } /// /// \brief Callback method /// - void Execute(vtkObject *vtkNotUsed(caller), - unsigned long vtkNotUsed(eventId), - void *callData) + void Execute(vtkObject *caller, unsigned long eventId, void *callData) { - if(timerId == *static_cast<int*>(callData)) + switch(eventId) { - this->renderWindow->Render(); + case vtkCommand::TimerEvent: + { + if(timerId == *static_cast<int*>(callData)) + { + this->renderWindow->Render(); + } + break; + } + case vtkCommand::ExitEvent: + { + std::cout << "Closing window..." << std::endl; + vtkRenderWindowInteractor *iren = + static_cast<vtkRenderWindowInteractor*>(caller); + // Close the window + iren->GetRenderWindow()->Finalize(); + + // Stop the interactor + iren->TerminateApp(); + viewer->setIsValid(false); + viewer->cleanUp(); + break; + } } } @@ -101,21 +97,17 @@ public: this->viewer->adjustFPS(); this->renderWindow->Render(); this->renderWindowInteractor->AddObserver(vtkCommand::TimerEvent,this); + + this->renderWindowInteractor->AddObserver(vtkCommand::ExitEvent,this); + this->timerId = renderWindowInteractor->CreateRepeatingTimer(1000.0/60.0); this->renderWindowInteractor->Start(); this->renderWindowInteractor->DestroyTimer(this->timerId); } - void setObservers() - { -// for(auto f : this->callBacks) -// { -// vtkNew<vtkCallbackCommand> callback; -// callback->SetCallback(f.second.target<FunctionType>()); -// this->renderWindowInteractor->AddObserver(f.first,callback.GetPointer()); -// } - } - + /// + /// \brief Remove renderer from render window. + /// void removeRenderer(vtkRenderer* renderer) { this->renderWindow->RemoveRenderer(renderer); @@ -132,13 +124,17 @@ public: { this->renderWindow->FullScreenOn(); } + else + { + this->renderWindow->SetSize(this->viewer->height(),this->viewer->width()); + } - this->renderWindow->SetWindowName("MSTK"); - this->renderWindowInteractor->SetRenderWindow(renderWindow.GetPointer()); - vtkSmartPointer<vtkInteractorStyleSwitch> style = - vtkSmartPointer<vtkInteractorStyleSwitch>::New(); + this->renderWindow->SetWindowName(this->viewer->windowTitle.data()); + this->renderWindowInteractor->SetRenderWindow(this->renderWindow.GetPointer()); + vtkNew<vtkInteractorStyleSwitch> style; style->SetCurrentStyleToTrackballCamera(); - renderWindowInteractor->SetInteractorStyle( style ); + renderWindowInteractor->SetInteractorStyle(style.GetPointer()); + // The actors are obtained from VTKRenderDelegates std::shared_ptr<VTKRenderDelegate> delegate; for(auto &ro : this->viewer->renderOperations) @@ -172,7 +168,6 @@ public: VTKViewer *viewer; vtkNew<vtkRenderWindow> renderWindow; vtkNew<vtkRenderWindowInteractor> renderWindowInteractor; -// std::map<vtkCommand::EventIds,CallBackFunctionType> callBacks; }; VTKViewer::VTKViewer() : renderer(Core::make_unique<VTKRenderer> (this)) @@ -201,12 +196,6 @@ void VTKViewer::render() this->endModule(); } -bool VTKViewer::isValid() -{ - return ( this->renderer != nullptr ) - && ( this->renderer->renderWindow.GetPointer() != nullptr ) - && ( this->renderer->renderWindowInteractor.GetPointer() != nullptr ); -} void VTKViewer::initResources() { this->renderer->addRenderer(); diff --git a/VTKRendering/VTKViewer.h b/VTKRendering/VTKViewer.h index f7acf02d3545a81d0638cdeb92e0a654eba1b367..bc40ac41eb07308cf5c414bd405a6e505644844c 100644 --- a/VTKRendering/VTKViewer.h +++ b/VTKRendering/VTKViewer.h @@ -77,11 +77,6 @@ public: /// void endFrame() override {} - /// - /// \brief Verify that the rendering pipeline initializes properly - /// - bool isValid(); - protected: /// /// \brief Renders the render operation to screen