diff --git a/applications/projects/SceneChecking/CMakeLists.txt b/applications/projects/SceneChecking/CMakeLists.txt index e0832b0ad65..f4ce6b70cab 100644 --- a/applications/projects/SceneChecking/CMakeLists.txt +++ b/applications/projects/SceneChecking/CMakeLists.txt @@ -12,6 +12,7 @@ set(HEADER_FILES ${SCENECHECK_SRC_DIR}/config.h.in ${SCENECHECK_SRC_DIR}/init.h ${SCENECHECK_SRC_DIR}/SceneCheckAPIChange.h + ${SCENECHECK_SRC_DIR}/SceneCheckCollisionPipelineAndModels.h ${SCENECHECK_SRC_DIR}/SceneCheckCollisionResponse.h ${SCENECHECK_SRC_DIR}/SceneCheckDeprecatedComponents.h ${SCENECHECK_SRC_DIR}/SceneCheckDuplicatedName.h @@ -26,6 +27,7 @@ set(HEADER_FILES set(SOURCE_FILES ${SCENECHECK_SRC_DIR}/init.cpp ${SCENECHECK_SRC_DIR}/SceneCheckAPIChange.cpp + ${SCENECHECK_SRC_DIR}/SceneCheckCollisionPipelineAndModels.cpp ${SCENECHECK_SRC_DIR}/SceneCheckCollisionResponse.cpp ${SCENECHECK_SRC_DIR}/SceneCheckDeprecatedComponents.cpp ${SCENECHECK_SRC_DIR}/SceneCheckDuplicatedName.cpp diff --git a/applications/projects/SceneChecking/src/SceneChecking/SceneCheckCollisionPipelineAndModels.cpp b/applications/projects/SceneChecking/src/SceneChecking/SceneCheckCollisionPipelineAndModels.cpp new file mode 100644 index 00000000000..fad0c9e50d3 --- /dev/null +++ b/applications/projects/SceneChecking/src/SceneChecking/SceneCheckCollisionPipelineAndModels.cpp @@ -0,0 +1,104 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program 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 program 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 program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#include "SceneCheckCollisionPipelineAndModels.h" + +#include +#include +#include +#include + +namespace sofa::_scenechecking_ +{ + +const bool SceneCheckCollisionPipelineAndModelsRegistered = sofa::simulation::SceneCheckMainRegistry::addToRegistry(SceneCheckCollisionPipelineAndModels::newSPtr()); + +using sofa::simulation::Node; + +const std::string SceneCheckCollisionPipelineAndModels::getName() +{ + return "SceneCheckCollisionPipelineAndModels"; +} + +const std::string SceneCheckCollisionPipelineAndModels::getDesc() +{ + return "Ensure the consistency of the existence of a collision pipeline, and collision models in the scene."; +} + +void SceneCheckCollisionPipelineAndModels::doInit(Node* node) +{ + SOFA_UNUSED(node); +} + +void SceneCheckCollisionPipelineAndModels::doCheckOn(Node* node) +{ + const sofa::core::objectmodel::BaseContext* root = node->getContext()->getRootContext(); + + if(!root) + { + return; + } + + sofa::core::collision::Pipeline::SPtr anyPipeline{}; + root->get(anyPipeline, sofa::core::objectmodel::BaseContext::SearchDirection::SearchDown); + sofa::core::CollisionModel::SPtr anyCollisionModel{}; + root->get(anyCollisionModel, sofa::core::objectmodel::BaseContext::SearchDirection::SearchDown); + + if(anyPipeline) + { + if(anyCollisionModel) + { + // there is a collision pipeline and (at least one) collision model(s), carry on. + } + else + { + // there is a collision pipeline but no collision model. + // Either the collision pipeline is superfluous; + // or the collision model(s) has been forgotten. + m_message = "There is no collision model in this scene, but there is a collision pipeline. Either add a collision model or remove the collision pipeline."; + } + } + else + { + if(anyCollisionModel) + { + // At least one collision model has been detected but without any pipeline. + // Either the collision pipeline has been forgotten; + // or the collision model(s) is useless. + m_message = "At least one collision model has been found, but there is no collision pipeline. You may add a collision pipeline (or remove the collision model if no collision detection is expected)."; + } + else + { + // there is no collision pipeline and no collision model, the scene certainly does not involve any collision feature. + } + } +} + +void SceneCheckCollisionPipelineAndModels::doPrintSummary() +{ + if(!m_message.empty()) + { + msg_warning(this->getName()) << m_message; + } +} + + +} // namespace sofa::_scenechecking_ diff --git a/applications/projects/SceneChecking/src/SceneChecking/SceneCheckCollisionPipelineAndModels.h b/applications/projects/SceneChecking/src/SceneChecking/SceneCheckCollisionPipelineAndModels.h new file mode 100644 index 00000000000..0ce57d79d77 --- /dev/null +++ b/applications/projects/SceneChecking/src/SceneChecking/SceneCheckCollisionPipelineAndModels.h @@ -0,0 +1,54 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program 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 program 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 program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once + +#include +#include + +#include +#include + +namespace sofa::_scenechecking_ +{ + +class SOFA_SCENECHECKING_API SceneCheckCollisionPipelineAndModels : public sofa::simulation::SceneCheck +{ +public: + virtual ~SceneCheckCollisionPipelineAndModels() {} + typedef std::shared_ptr SPtr; + static SPtr newSPtr() { return SPtr(new SceneCheckCollisionPipelineAndModels()); } + virtual const std::string getName() override; + virtual const std::string getDesc() override; + void doInit(sofa::simulation::Node* node) override; + void doCheckOn(sofa::simulation::Node* node) override; + void doPrintSummary() override; + +private: + std::string m_message; +}; + +} // namespace sofa::_scenechecking_ + +namespace sofa::scenechecking +{ + using _scenechecking_::SceneCheckCollisionPipelineAndModels; +} diff --git a/applications/projects/SceneChecking/tests/SceneChecker_test.cpp b/applications/projects/SceneChecking/tests/SceneChecker_test.cpp index 2ffe0b510c4..96c15f66513 100644 --- a/applications/projects/SceneChecking/tests/SceneChecker_test.cpp +++ b/applications/projects/SceneChecking/tests/SceneChecker_test.cpp @@ -38,6 +38,8 @@ using sofa::scenechecking::SceneCheckMissingRequiredPlugin; using sofa::scenechecking::SceneCheckDuplicatedName; #include using sofa::scenechecking::SceneCheckUsingAlias; +#include +using sofa::scenechecking::SceneCheckCollisionPipelineAndModels; #include using sofa::helper::system::PluginManager; @@ -238,6 +240,74 @@ struct SceneChecker_test : public BaseSimulationTest checker.validate(root.get(), &sceneLoader); } } + + void checkCollisionPipelineModels(bool withPipeline, bool withCollisionModel) + { + std::string scenePrefix = R"(" + + + + + + +)"; + std::string scenePipeline = R"(" + + + + + +)"; + std::string sceneModel = R"(" + + + + +)"; + std::string sceneSuffix = R"(" + +)"; + std::string scene = scenePrefix; + if(withPipeline) + { + scene += scenePipeline; + } + if(withCollisionModel) + { + scene += sceneModel; + } + scene += sceneSuffix; + + SceneCheckerVisitor checker(sofa::core::execparams::defaultInstance()); + checker.addCheck( SceneCheckCollisionPipelineAndModels::newSPtr() ); + + SceneLoaderXML sceneLoader; + const Node::SPtr root = sceneLoader.doLoadFromMemory("testscene", scene.c_str()); + ASSERT_NE(root.get(), nullptr); + root->init(sofa::core::execparams::defaultInstance()); + + if(!withPipeline && !withCollisionModel) + { + EXPECT_MSG_NOEMIT(Warning); + checker.validate(root.get(), &sceneLoader); + } + if(withPipeline && !withCollisionModel) + { + EXPECT_MSG_EMIT(Warning); + checker.validate(root.get(), &sceneLoader); + } + if(!withPipeline && withCollisionModel) + { + EXPECT_MSG_EMIT(Warning); + checker.validate(root.get(), &sceneLoader); + } + if(withPipeline && withCollisionModel) + { + EXPECT_MSG_NOEMIT(Warning); + checker.validate(root.get(), &sceneLoader); + } + + } }; TEST_F(SceneChecker_test, checkMissingRequiredPlugin ) @@ -279,3 +349,20 @@ TEST_F(SceneChecker_test, checkUsingAlias_withoutAlias ) { checkUsingAlias(false); } + +TEST_F(SceneChecker_test, checkCollisionPipelineModels_nothing ) +{ + checkCollisionPipelineModels(false, false); +} +TEST_F(SceneChecker_test, checkCollisionPipelineModels_onlyPipeline ) +{ + checkCollisionPipelineModels(true, false); +} +TEST_F(SceneChecker_test, checkCollisionPipelineModels_onlyModel ) +{ + checkCollisionPipelineModels(false, true); +} +TEST_F(SceneChecker_test, checkCollisionPipelineModels_both ) +{ + checkCollisionPipelineModels(true, true); +}