Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions applications/projects/SceneChecking/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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 <http://www.gnu.org/licenses/>. *
*******************************************************************************
* Authors: The SOFA Team and external contributors (see Authors.txt) *
* *
* Contact information: [email protected] *
******************************************************************************/
#include "SceneCheckCollisionPipelineAndModels.h"

#include <sofa/simulation/Node.h>
#include <sofa/core/CollisionModel.h>
#include <sofa/core/collision/Pipeline.h>
#include <sofa/simulation/SceneCheckMainRegistry.h>

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 one 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 it is not used).";
}
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_
Original file line number Diff line number Diff line change
@@ -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 <http://www.gnu.org/licenses/>. *
*******************************************************************************
* Authors: The SOFA Team and external contributors (see Authors.txt) *
* *
* Contact information: [email protected] *
******************************************************************************/
#pragma once

#include <SceneChecking/config.h>
#include <sofa/simulation/SceneCheck.h>

#include <map>
#include <sstream>

namespace sofa::_scenechecking_
{

class SOFA_SCENECHECKING_API SceneCheckCollisionPipelineAndModels : public sofa::simulation::SceneCheck
{
public:
virtual ~SceneCheckCollisionPipelineAndModels() {}
typedef std::shared_ptr<SceneCheckCollisionPipelineAndModels> 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;
}
87 changes: 87 additions & 0 deletions applications/projects/SceneChecking/tests/SceneChecker_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ using sofa::scenechecking::SceneCheckMissingRequiredPlugin;
using sofa::scenechecking::SceneCheckDuplicatedName;
#include <SceneChecking/SceneCheckUsingAlias.h>
using sofa::scenechecking::SceneCheckUsingAlias;
#include <SceneChecking/SceneCheckCollisionPipelineAndModels.h>
using sofa::scenechecking::SceneCheckCollisionPipelineAndModels;

#include <sofa/helper/system/PluginManager.h>
using sofa::helper::system::PluginManager;
Expand Down Expand Up @@ -238,6 +240,74 @@ struct SceneChecker_test : public BaseSimulationTest
checker.validate(root.get(), &sceneLoader);
}
}

void checkCollisionPipelineModels(bool withPipeline, bool withCollisionModel)
{
std::string scenePrefix = R"("
<Node name='root'>
<DefaultAnimationLoop/>
<RequiredPlugin name='Sofa.Component.Collision.Detection.Algorithm' />
<RequiredPlugin name='Sofa.Component.Collision.Detection.Intersection' />
<RequiredPlugin name='Sofa.Component.Collision.Geometry' />
<RequiredPlugin name='Sofa.Component.Collision.Response.Contact' />
)";
std::string scenePipeline = R"("
<CollisionPipeline verbose="0" />
<BruteForceBroadPhase/>
<BVHNarrowPhase/>
<CollisionResponse name="Response" response="PenalityContactForceField" />
<DiscreteIntersection />
)";
std::string sceneModel = R"("
<Node name='Collision'>
<MechanicalObject position="1 1 1" />
<SphereCollisionModel name="Floor" radius="1" />
</Node>
)";
std::string sceneSuffix = R"("
</Node>
)";
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 )
Expand Down Expand Up @@ -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);
}
Loading