diff --git a/include/sdf/Root.hh b/include/sdf/Root.hh index 8a93192bf..6ad91ba63 100644 --- a/include/sdf/Root.hh +++ b/include/sdf/Root.hh @@ -246,6 +246,11 @@ namespace sdf public: sdf::ElementPtr ToElement( const OutputConfig &_config = OutputConfig::GlobalConfig()) const; + /// \brief Remove the actor, light, or model if one of them exists. + /// The SDF Root object can only hold one, or none, from the set + /// [Actor, Light, Model]. + public: void ClearActorLightModel(); + /// \brief Private data pointer GZ_UTILS_IMPL_PTR(dataPtr) }; diff --git a/python/src/sdf/pyRoot.cc b/python/src/sdf/pyRoot.cc index 2da83830a..af94e78b5 100644 --- a/python/src/sdf/pyRoot.cc +++ b/python/src/sdf/pyRoot.cc @@ -96,6 +96,10 @@ void defineRoot(pybind11::object module) .def("set_light", &sdf::Root::SetLight, "Set the light object. This will override any existing model, " "actor, and light object.") + .def("clear_actor_light_model", &sdf::Root::ClearActorLightModel, + "Remove the actor, light, or model if one of them exists." + "The SDF Root object can only hold one, or none, from the set" + "[Actor, Light, Model].") .def("add_world", [](Root &self, const World &_world) { ThrowIfErrors(self.AddWorld(_world)); diff --git a/python/test/pyRoot_TEST.py b/python/test/pyRoot_TEST.py index 0a41bf667..785f94de3 100644 --- a/python/test/pyRoot_TEST.py +++ b/python/test/pyRoot_TEST.py @@ -358,5 +358,33 @@ def test_resolve_auto_inertials_with_save_calculation_configuration(self): self.assertEqual(len(inertialErr), 0) self.assertTrue(link.auto_inertia_saved()) + def test_clear_actor_light_model(self): + root = Root() + + # \TODO(anyone) Wrap the Actor class. + # self.assertEqual(None, root.actor()) + # actor1 = Actor() + # actor1.set_name("actor1") + # root.set_actor(actor1) + # self.assertNotEqual(None, root.actor()) + # root.clear_actor_light_model() + # self.assertEqual(None, root.actor()) + + self.assertEqual(None, root.light()) + light1 = Light() + light1.set_name("light1") + root.set_light(light1) + self.assertNotEqual(None, root.light()) + root.clear_actor_light_model() + self.assertEqual(None, root.light()) + + self.assertEqual(None, root.model()) + model1 = Model() + model1.set_name("model1") + root.set_model(model1) + self.assertNotEqual(None, root.model()) + root.clear_actor_light_model() + self.assertEqual(None, root.model()) + if __name__ == '__main__': unittest.main() diff --git a/src/Root.cc b/src/Root.cc index 34e2f2103..b6e412d2f 100644 --- a/src/Root.cc +++ b/src/Root.cc @@ -644,3 +644,9 @@ sdf::ElementPtr Root::ToElement(const OutputConfig &_config) const return elem; } + +///////////////////////////////////////////////// +void Root::ClearActorLightModel() +{ + this->dataPtr->modelLightOrActor = std::monostate{}; +} diff --git a/src/Root_TEST.cc b/src/Root_TEST.cc index 4a06de902..629d6b7e7 100644 --- a/src/Root_TEST.cc +++ b/src/Root_TEST.cc @@ -670,3 +670,45 @@ TEST(DOMRoot, WorldByName) ASSERT_TRUE(root.WorldNameExists("world2")); EXPECT_EQ("world2", root.WorldByName("world2")->Name()); } + +///////////////////////////////////////////////// +TEST(DOMRoot, ClearActorLightModel) +{ + sdf::Root root; + EXPECT_EQ(nullptr, root.Actor()); + EXPECT_EQ(nullptr, root.Light()); + EXPECT_EQ(nullptr, root.Model()); + + sdf::Actor actor1; + actor1.SetName("actor1"); + root.SetActor(actor1); + EXPECT_NE(nullptr, root.Actor()); + EXPECT_EQ(nullptr, root.Light()); + EXPECT_EQ(nullptr, root.Model()); + root.ClearActorLightModel(); + EXPECT_EQ(nullptr, root.Actor()); + EXPECT_EQ(nullptr, root.Light()); + EXPECT_EQ(nullptr, root.Model()); + + sdf::Light light1; + light1.SetName("light1"); + root.SetLight(light1); + EXPECT_EQ(nullptr, root.Actor()); + EXPECT_NE(nullptr, root.Light()); + EXPECT_EQ(nullptr, root.Model()); + root.ClearActorLightModel(); + EXPECT_EQ(nullptr, root.Actor()); + EXPECT_EQ(nullptr, root.Light()); + EXPECT_EQ(nullptr, root.Model()); + + sdf::Model model1; + model1.SetName("model1"); + root.SetModel(model1); + EXPECT_EQ(nullptr, root.Actor()); + EXPECT_EQ(nullptr, root.Light()); + EXPECT_NE(nullptr, root.Model()); + root.ClearActorLightModel(); + EXPECT_EQ(nullptr, root.Actor()); + EXPECT_EQ(nullptr, root.Light()); + EXPECT_EQ(nullptr, root.Model()); +}