From ec8d33d26bbbb76319a63f420fefea323f2332ad Mon Sep 17 00:00:00 2001 From: Frederick Roy Date: Tue, 9 Jun 2026 12:38:35 +0900 Subject: [PATCH 1/2] add a boolean to track bounding box value, and use this state at init to compute bbox (or not) --- .../Core/src/sofa/simulation/InitVisitor.cpp | 8 +++--- .../Core/src/sofa/simulation/Node.cpp | 7 ++++++ .../Core/src/sofa/simulation/Node.h | 3 ++- .../simulation/UpdateBoundingBoxVisitor.cpp | 25 +++++++++++++------ 4 files changed, 31 insertions(+), 12 deletions(-) diff --git a/Sofa/framework/Simulation/Core/src/sofa/simulation/InitVisitor.cpp b/Sofa/framework/Simulation/Core/src/sofa/simulation/InitVisitor.cpp index de84e195965..7d01708de01 100644 --- a/Sofa/framework/Simulation/Core/src/sofa/simulation/InitVisitor.cpp +++ b/Sofa/framework/Simulation/Core/src/sofa/simulation/InitVisitor.cpp @@ -37,14 +37,15 @@ Visitor::Result InitVisitor::processNodeTopDown(simulation::Node* node) node->initialize(); sofa::type::BoundingBox* nodeBBox = node->f_bbox.beginEdit(); - if(!node->f_bbox.isSet()) + if(!node->m_bboxIsFixed) nodeBBox->invalidate(); for(unsigned int i=0; iobject.size(); ++i) { node->object[i]->init(); node->object[i]->computeBBox(params, true); - nodeBBox->include(node->object[i]->f_bbox.getValue()); + if(!node->m_bboxIsFixed) + nodeBBox->include(node->object[i]->f_bbox.getValue()); } node->f_bbox.endEdit(); return RESULT_CONTINUE; @@ -60,7 +61,8 @@ void InitVisitor::processNodeBottomUp(simulation::Node* node) for(std::size_t i=node->object.size(); i>0; --i) { node->object[i-1]->bwdInit(); - nodeBBox->include(node->object[i-1]->f_bbox.getValue()); + if(!node->m_bboxIsFixed) + nodeBBox->include(node->object[i-1]->f_bbox.getValue()); } node->f_bbox.endEdit(); diff --git a/Sofa/framework/Simulation/Core/src/sofa/simulation/Node.cpp b/Sofa/framework/Simulation/Core/src/sofa/simulation/Node.cpp index bcc0dd329fa..70a0674af2f 100644 --- a/Sofa/framework/Simulation/Core/src/sofa/simulation/Node.cpp +++ b/Sofa/framework/Simulation/Core/src/sofa/simulation/Node.cpp @@ -191,6 +191,13 @@ void Node::parse( sofa::core::objectmodel::BaseObjectDescription* arg ) objDesc.setAttribute("displayFlags", oldFlags); sofa::core::objectmodel::BaseComponent::SPtr obj = sofa::core::ObjectFactory::CreateObject(this, &objDesc); } + + // BoundingBox state management + const char* bboxAttrStr = arg->getAttribute("bbox", nullptr); + if(bboxAttrStr != nullptr) + { + this->m_bboxIsFixed = true; + } } /// Initialize the components of this node and all the nodes which depend on it. diff --git a/Sofa/framework/Simulation/Core/src/sofa/simulation/Node.h b/Sofa/framework/Simulation/Core/src/sofa/simulation/Node.h index 11085a64378..d584dd8628b 100644 --- a/Sofa/framework/Simulation/Core/src/sofa/simulation/Node.h +++ b/Sofa/framework/Simulation/Core/src/sofa/simulation/Node.h @@ -555,7 +555,8 @@ class SOFA_SIMULATION_CORE_API Node : public sofa::core::objectmodel::BaseNode, /// return the smallest common parent between this and node2 (returns nullptr if separated sub-graphes) Node* findCommonParent( simulation::Node* node2 ); - + + bool m_bboxIsFixed{false}; protected: bool debug_; bool initialized; diff --git a/Sofa/framework/Simulation/Core/src/sofa/simulation/UpdateBoundingBoxVisitor.cpp b/Sofa/framework/Simulation/Core/src/sofa/simulation/UpdateBoundingBoxVisitor.cpp index 1732c0fd465..65ec313813a 100644 --- a/Sofa/framework/Simulation/Core/src/sofa/simulation/UpdateBoundingBoxVisitor.cpp +++ b/Sofa/framework/Simulation/Core/src/sofa/simulation/UpdateBoundingBoxVisitor.cpp @@ -41,7 +41,7 @@ Visitor::Result UpdateBoundingBoxVisitor::processNodeTopDown(Node* node) type::vector::iterator object; node->get(&objectList,BaseContext::Local); sofa::type::BoundingBox* nodeBBox = node->f_bbox.beginEdit(); - if(!node->f_bbox.isSet()) // bmarques: Without invalidating the bbox, the node's bbox will only be sized up, and never down with this visitor, to my understanding.. + if(!node->m_bboxIsFixed) // bmarques: Without invalidating the bbox, the node's bbox will only be sized up, and never down with this visitor, to my understanding.. nodeBBox->invalidate(); for ( object = objectList.begin(); object != objectList.end(); ++object) { @@ -53,8 +53,9 @@ Visitor::Result UpdateBoundingBoxVisitor::processNodeTopDown(Node* node) // if some objects does not participate to the bounding box where they should, // you should overload their computeBBox function to correct that (*object)->computeBBox(params, true); - - nodeBBox->include((*object)->f_bbox.getValue()); + + if(!node->m_bboxIsFixed) + nodeBBox->include((*object)->f_bbox.getValue()); } node->f_bbox.endEdit(); return RESULT_CONTINUE; @@ -62,13 +63,21 @@ Visitor::Result UpdateBoundingBoxVisitor::processNodeTopDown(Node* node) void UpdateBoundingBoxVisitor::processNodeBottomUp(simulation::Node* node) { - sofa::type::BoundingBox* nodeBBox = node->f_bbox.beginEdit(); - Node::ChildIterator childNode; - for( childNode = node->child.begin(); childNode!=node->child.end(); ++childNode) + if(!node->m_bboxIsFixed) { - nodeBBox->include((*childNode)->f_bbox.getValue()); + sofa::type::BoundingBox* nodeBBox = node->f_bbox.beginEdit(); + Node::ChildIterator childNode; + for( childNode = node->child.begin(); childNode!=node->child.end(); ++childNode) + { + nodeBBox->include((*childNode)->f_bbox.getValue()); + } + node->f_bbox.endEdit(); } - node->f_bbox.endEdit(); + else + { + // the node bounding box is supposed to be fixed + } + } } From fcae3d093976b7b235b8b9a555893953d4ceadde Mon Sep 17 00:00:00 2001 From: Frederick Roy Date: Tue, 9 Jun 2026 13:02:06 +0900 Subject: [PATCH 2/2] make it protected --- .../Simulation/Core/src/sofa/simulation/InitVisitor.cpp | 6 +++--- Sofa/framework/Simulation/Core/src/sofa/simulation/Node.h | 3 ++- .../Core/src/sofa/simulation/UpdateBoundingBoxVisitor.cpp | 6 +++--- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/Sofa/framework/Simulation/Core/src/sofa/simulation/InitVisitor.cpp b/Sofa/framework/Simulation/Core/src/sofa/simulation/InitVisitor.cpp index 7d01708de01..b6b0b6c02dc 100644 --- a/Sofa/framework/Simulation/Core/src/sofa/simulation/InitVisitor.cpp +++ b/Sofa/framework/Simulation/Core/src/sofa/simulation/InitVisitor.cpp @@ -37,14 +37,14 @@ Visitor::Result InitVisitor::processNodeTopDown(simulation::Node* node) node->initialize(); sofa::type::BoundingBox* nodeBBox = node->f_bbox.beginEdit(); - if(!node->m_bboxIsFixed) + if(!node->bboxIsFixed()) nodeBBox->invalidate(); for(unsigned int i=0; iobject.size(); ++i) { node->object[i]->init(); node->object[i]->computeBBox(params, true); - if(!node->m_bboxIsFixed) + if(!node->bboxIsFixed()) nodeBBox->include(node->object[i]->f_bbox.getValue()); } node->f_bbox.endEdit(); @@ -61,7 +61,7 @@ void InitVisitor::processNodeBottomUp(simulation::Node* node) for(std::size_t i=node->object.size(); i>0; --i) { node->object[i-1]->bwdInit(); - if(!node->m_bboxIsFixed) + if(!node->bboxIsFixed()) nodeBBox->include(node->object[i-1]->f_bbox.getValue()); } diff --git a/Sofa/framework/Simulation/Core/src/sofa/simulation/Node.h b/Sofa/framework/Simulation/Core/src/sofa/simulation/Node.h index d584dd8628b..9281a073629 100644 --- a/Sofa/framework/Simulation/Core/src/sofa/simulation/Node.h +++ b/Sofa/framework/Simulation/Core/src/sofa/simulation/Node.h @@ -556,10 +556,11 @@ class SOFA_SIMULATION_CORE_API Node : public sofa::core::objectmodel::BaseNode, /// return the smallest common parent between this and node2 (returns nullptr if separated sub-graphes) Node* findCommonParent( simulation::Node* node2 ); - bool m_bboxIsFixed{false}; + bool bboxIsFixed() const { return m_bboxIsFixed; } protected: bool debug_; bool initialized; + bool m_bboxIsFixed{false}; virtual bool doAddObject(sofa::core::objectmodel::BaseComponent::SPtr obj, sofa::core::objectmodel::TypeOfInsertion insertionLocation= sofa::core::objectmodel::TypeOfInsertion::AtEnd); virtual bool doRemoveObject(sofa::core::objectmodel::BaseComponent::SPtr obj); diff --git a/Sofa/framework/Simulation/Core/src/sofa/simulation/UpdateBoundingBoxVisitor.cpp b/Sofa/framework/Simulation/Core/src/sofa/simulation/UpdateBoundingBoxVisitor.cpp index 65ec313813a..6bc3d7048db 100644 --- a/Sofa/framework/Simulation/Core/src/sofa/simulation/UpdateBoundingBoxVisitor.cpp +++ b/Sofa/framework/Simulation/Core/src/sofa/simulation/UpdateBoundingBoxVisitor.cpp @@ -41,7 +41,7 @@ Visitor::Result UpdateBoundingBoxVisitor::processNodeTopDown(Node* node) type::vector::iterator object; node->get(&objectList,BaseContext::Local); sofa::type::BoundingBox* nodeBBox = node->f_bbox.beginEdit(); - if(!node->m_bboxIsFixed) // bmarques: Without invalidating the bbox, the node's bbox will only be sized up, and never down with this visitor, to my understanding.. + if(!node->bboxIsFixed()) // bmarques: Without invalidating the bbox, the node's bbox will only be sized up, and never down with this visitor, to my understanding.. nodeBBox->invalidate(); for ( object = objectList.begin(); object != objectList.end(); ++object) { @@ -54,7 +54,7 @@ Visitor::Result UpdateBoundingBoxVisitor::processNodeTopDown(Node* node) // you should overload their computeBBox function to correct that (*object)->computeBBox(params, true); - if(!node->m_bboxIsFixed) + if(!node->bboxIsFixed()) nodeBBox->include((*object)->f_bbox.getValue()); } node->f_bbox.endEdit(); @@ -63,7 +63,7 @@ Visitor::Result UpdateBoundingBoxVisitor::processNodeTopDown(Node* node) void UpdateBoundingBoxVisitor::processNodeBottomUp(simulation::Node* node) { - if(!node->m_bboxIsFixed) + if(!node->bboxIsFixed()) { sofa::type::BoundingBox* nodeBBox = node->f_bbox.beginEdit(); Node::ChildIterator childNode;