From 913dc8f5d1f47151e65cd88b61c4297e6c391bf2 Mon Sep 17 00:00:00 2001 From: BehnamBinesh Date: Mon, 22 Apr 2024 17:28:01 +0330 Subject: [PATCH 01/13] [Modeler] :: Compatible Modeler Project With master branch. TODO :: test to find bug --- .../Qt/src/sofa/gui/qt/SofaSceneGraphWidget.h | 2 +- .../src/sofa/core/objectmodel/AspectPool.cpp | 13 +- .../Core/src/sofa/core/objectmodel/Base.cpp | 36 ++++-- .../src/sofa/core/objectmodel/BaseClass.cpp | 13 +- .../src/sofa/core/objectmodel/BaseData.cpp | 24 +++- .../Core/src/sofa/core/objectmodel/BaseData.h | 2 +- .../src/sofa/core/objectmodel/BaseNode.cpp | 24 +++- .../src/sofa/core/objectmodel/BaseObject.cpp | 25 +++- .../src/sofa/core/objectmodel/BaseObject.h | 12 +- .../src/sofa/core/objectmodel/ClassInfo.cpp | 13 +- .../sofa/core/objectmodel/ComponentState.cpp | 12 +- .../core/objectmodel/ConfigurationSetting.cpp | 15 ++- .../Core/src/sofa/core/objectmodel/Data.cpp | 13 +- .../sofa/core/objectmodel/DeprecatedData.cpp | 2 + .../sofa/core/objectmodel/DetachNodeEvent.cpp | 13 +- applications/projects/Modeler/CMakeLists.txt | 2 +- .../projects/Modeler/exec/CMakeLists.txt | 107 +++++++++++++++-- applications/projects/Modeler/exec/Main.cpp | 111 ++++++++++++++++-- .../projects/Modeler/lib/CMakeLists.txt | 2 +- .../projects/Modeler/lib/GraphModeler.cpp | 86 +++++++++++--- .../projects/Modeler/lib/GraphModeler.h | 8 +- .../projects/Modeler/lib/SofaModeler.cpp | 95 +++++++++------ .../Modeler/lib/SofaTutorialManager.cpp | 3 +- .../projects/Modeler/lib/TutorialSelector.h | 5 +- 24 files changed, 495 insertions(+), 143 deletions(-) diff --git a/Sofa/GUI/Qt/src/sofa/gui/qt/SofaSceneGraphWidget.h b/Sofa/GUI/Qt/src/sofa/gui/qt/SofaSceneGraphWidget.h index 9eda652c557..84e0675c52a 100644 --- a/Sofa/GUI/Qt/src/sofa/gui/qt/SofaSceneGraphWidget.h +++ b/Sofa/GUI/Qt/src/sofa/gui/qt/SofaSceneGraphWidget.h @@ -112,7 +112,7 @@ class SOFA_GUI_QT_API SofaSceneGraphWidget : public QTreeWidget /// This can happen if the graph has been freezed (i.e. not graphically updated) for performance /// reason while simulating complex scenes. bool m_isDirty; - bool m_isLocked; + bool m_isLocked = false; }; } //namespace sofa::gui::qt diff --git a/Sofa/framework/Core/src/sofa/core/objectmodel/AspectPool.cpp b/Sofa/framework/Core/src/sofa/core/objectmodel/AspectPool.cpp index a973c544b7b..ad313e4e4da 100644 --- a/Sofa/framework/Core/src/sofa/core/objectmodel/AspectPool.cpp +++ b/Sofa/framework/Core/src/sofa/core/objectmodel/AspectPool.cpp @@ -24,8 +24,13 @@ #include #include +namespace sofa +{ + +namespace core +{ -namespace sofa::core::objectmodel +namespace objectmodel { /** @@ -220,8 +225,8 @@ bool AspectBuffer::pop(AspectRef& id) return true; } -} // namespace sofa::core::objectmodel - - +} // namespace objectmodel +} // namespace core +} // namespace sofa diff --git a/Sofa/framework/Core/src/sofa/core/objectmodel/Base.cpp b/Sofa/framework/Core/src/sofa/core/objectmodel/Base.cpp index df738d145a1..6d00c6f20ff 100644 --- a/Sofa/framework/Core/src/sofa/core/objectmodel/Base.cpp +++ b/Sofa/framework/Core/src/sofa/core/objectmodel/Base.cpp @@ -637,17 +637,31 @@ void Base::writeDatas (std::ostream& out, const std::string& separator) for(VecData::const_iterator iData = m_vecData.begin(); iData != m_vecData.end(); ++iData) { const BaseData* field = *iData; - if (!field->getLinkPath().empty() ) + std::string linkPath = field->getLinkPath(); + std::cerr << __FUNCTION__ << ": Link Path From Data :: " << linkPath << std::endl; +// if (!field->getLinkPath().empty() ) +// { +// out << separator << field->getName() << "=\""<< xmlencode(field->getLinkPath()) << "\" "; +// } +// else { - out << separator << field->getName() << "=\""<< xmlencode(field->getLinkPath()) << "\" "; - } - else - { - if(field->isPersistent() && field->isSet()) + std::string val = field->getValueString(); + std::string fieldname = field->getName(); +// bool isPer = field->isPersistent(); + bool isFullTrim = false; + bool isset = field->isSet(); + if(/*isPer &&*/ isset && fieldname != "parents") { - std::string val = field->getValueString(); - if (!val.empty()) - out << separator << field->getName() << "=\""<< xmlencode(val) << "\" "; + std::string checkSpace = field->getValueString(); + checkSpace.erase(remove_if(checkSpace.begin(), checkSpace.end(), isspace), checkSpace.end()); + if(checkSpace.empty()) + { + isFullTrim = true; + } + if (!val.empty() && !isFullTrim) + { + out << separator << fieldname << "=\""<< xmlencode(val) << "\" "; + } } } } @@ -657,8 +671,10 @@ void Base::writeDatas (std::ostream& out, const std::string& separator) if(link->storePath()) { std::string val = link->getValueString(); - if (!val.empty()) + if (!val.empty() && link->getName() != "parents") + { out << separator << link->getName() << "=\""<< xmlencode(val) << "\" "; + } } } } diff --git a/Sofa/framework/Core/src/sofa/core/objectmodel/BaseClass.cpp b/Sofa/framework/Core/src/sofa/core/objectmodel/BaseClass.cpp index e05f2d9b5c4..aa4b374e0b3 100644 --- a/Sofa/framework/Core/src/sofa/core/objectmodel/BaseClass.cpp +++ b/Sofa/framework/Core/src/sofa/core/objectmodel/BaseClass.cpp @@ -21,8 +21,13 @@ ******************************************************************************/ #include +namespace sofa +{ + +namespace core +{ -namespace sofa::core::objectmodel +namespace objectmodel { BaseClass* DeprecatedBaseClass::GetSingleton() @@ -49,9 +54,9 @@ DeprecatedBaseClass::DeprecatedBaseClass() } -} // namespace sofa::core::objectmodel - - +} // namespace objectmodel +} // namespace core +} // namespace sofa diff --git a/Sofa/framework/Core/src/sofa/core/objectmodel/BaseData.cpp b/Sofa/framework/Core/src/sofa/core/objectmodel/BaseData.cpp index 3d16511118f..d687316f655 100644 --- a/Sofa/framework/Core/src/sofa/core/objectmodel/BaseData.cpp +++ b/Sofa/framework/Core/src/sofa/core/objectmodel/BaseData.cpp @@ -137,8 +137,20 @@ bool BaseData::setParent(BaseData* parent, const std::string& path) std::string BaseData::getLinkPath() const { - if(m_owner) - return "@"+m_owner->getPathName()+"."+getName(); + std::string ownerPathName = m_owner->getPathName(); + bool isStrFine = false; + for(unsigned int i=0 ; i < ownerPathName.length() ; i++) + { + if(ownerPathName[i] != '/') + { + isStrFine = true; + } + } + if(m_owner && ownerPathName != "/") + { + std::string linkPathStr = "@"+m_owner->getPathName()+"."+getName(); + return linkPathStr; + } return ""; } @@ -158,9 +170,9 @@ void BaseData::doDelInput(DDGNode* n) void BaseData::update() { cleanDirty(); - for (DDGNode* input : inputs) + for(DDGLinkIterator it=inputs.begin(); it!=inputs.end(); ++it) { - input->updateIfDirty(); + (*it)->updateIfDirty(); } /// Check if there is a parent (so a predecessor in the DDG), if so @@ -168,6 +180,10 @@ void BaseData::update() const auto parent = parentData.resolvePathAndGetTarget(); if (parent) { +#ifdef SOFA_DDG_TRACE + if (m_owner) + dmsg_warning(m_owner) << "Data " << m_name << ": update from parent " << parentBaseData->m_name; +#endif updateValueFromLink(parent); // If the value is dirty clean it if(this->isDirty()) diff --git a/Sofa/framework/Core/src/sofa/core/objectmodel/BaseData.h b/Sofa/framework/Core/src/sofa/core/objectmodel/BaseData.h index aaef1b3abe3..d784e3c7b96 100644 --- a/Sofa/framework/Core/src/sofa/core/objectmodel/BaseData.h +++ b/Sofa/framework/Core/src/sofa/core/objectmodel/BaseData.h @@ -272,7 +272,7 @@ class SOFA_CORE_API BaseData : public DDGNode /// True if this %Data is set, i.e. its value is different from the default value bool m_isSet; /// Flags indicating the purpose and behaviour of this %Data - DataFlags m_dataFlags; + DataFlags m_dataFlags = FLAG_PERSISTENT; /// Return the Base component owning this %Data Base* m_owner {nullptr}; /// Data name within the Base component diff --git a/Sofa/framework/Core/src/sofa/core/objectmodel/BaseNode.cpp b/Sofa/framework/Core/src/sofa/core/objectmodel/BaseNode.cpp index 91d4001ec10..f2491fe06fe 100644 --- a/Sofa/framework/Core/src/sofa/core/objectmodel/BaseNode.cpp +++ b/Sofa/framework/Core/src/sofa/core/objectmodel/BaseNode.cpp @@ -26,8 +26,13 @@ #include #include +namespace sofa +{ + +namespace core +{ -namespace sofa::core::objectmodel +namespace objectmodel { BaseNode::BaseNode() @@ -94,7 +99,16 @@ std::string BaseNode::internalGetPathName() const { // no smarter choice without breaking the "Node" heritage str = parents[0]->internalGetPathName(); str += '/'; - str += getName(); + bool strIsFine = false; + for(unsigned int i=0 ; i < str.length() ; i++) + { + if(str[i] != '/') + { + strIsFine = true; + } + } + if(strIsFine) + str += getName(); } return str; } @@ -116,8 +130,8 @@ std::string BaseNode::getRootPath() const { return str; } -} // namespace sofa::core::objectmodel - - +} // namespace objectmodel +} // namespace core +} // namespace sofa diff --git a/Sofa/framework/Core/src/sofa/core/objectmodel/BaseObject.cpp b/Sofa/framework/Core/src/sofa/core/objectmodel/BaseObject.cpp index c0d94dff970..a5ed2ff398a 100644 --- a/Sofa/framework/Core/src/sofa/core/objectmodel/BaseObject.cpp +++ b/Sofa/framework/Core/src/sofa/core/objectmodel/BaseObject.cpp @@ -29,7 +29,13 @@ #include -namespace sofa::core::objectmodel +namespace sofa +{ + +namespace core +{ + +namespace objectmodel { BaseObject::BaseObject() @@ -363,13 +369,22 @@ std::string BaseObject::getPathName() const { } } - result += getName(); + bool strIsFine = false; + for(unsigned int i=0 ; i < result.length() ; i++) + { + if(result[i] != '/') + { + strIsFine = true; + } + } + if(strIsFine) + result += getName(); return result; } -} // namespace sofa::core::objectmodel - - +} // namespace objectmodel +} // namespace core +} // namespace sofa diff --git a/Sofa/framework/Core/src/sofa/core/objectmodel/BaseObject.h b/Sofa/framework/Core/src/sofa/core/objectmodel/BaseObject.h index 95d2b11babd..192283812ad 100644 --- a/Sofa/framework/Core/src/sofa/core/objectmodel/BaseObject.h +++ b/Sofa/framework/Core/src/sofa/core/objectmodel/BaseObject.h @@ -211,14 +211,14 @@ class SOFA_CORE_API BaseObject : public virtual Base public: - /// the component can insert itself directly in the right sequence in the Node - /// so the Node does not have to test its type against all known types - /// \returns true if the component was inserted + /// the component can insert itseft direclty in the right sequence in the Node + /// so the Node does not have to test its type against every known types. + /// \returns true iff the component was inserted virtual bool insertInNode( BaseNode* /*node*/ ) { return false; } - /// the component can remove itself directly in the right sequence in the Node - /// so the Node does not have to test its type against all known types - /// \returns true if the component was removed + /// the component can remove itseft direclty in the right sequence in the Node + /// so the Node does not have to test its type against every known types. + /// \returns true iff the component was removed virtual bool removeInNode( BaseNode* /*node*/ ) { return false; } }; diff --git a/Sofa/framework/Core/src/sofa/core/objectmodel/ClassInfo.cpp b/Sofa/framework/Core/src/sofa/core/objectmodel/ClassInfo.cpp index d234fbdda42..1c7459b6bb4 100644 --- a/Sofa/framework/Core/src/sofa/core/objectmodel/ClassInfo.cpp +++ b/Sofa/framework/Core/src/sofa/core/objectmodel/ClassInfo.cpp @@ -21,8 +21,13 @@ ******************************************************************************/ #include +namespace sofa +{ + +namespace core +{ -namespace sofa::core::objectmodel +namespace objectmodel { std::map ClassInfo::classes; @@ -38,9 +43,9 @@ ClassInfo::~ClassInfo() } -} // namespace sofa::core::objectmodel - - +} // namespace objectmodel +} // namespace core +} // namespace sofa diff --git a/Sofa/framework/Core/src/sofa/core/objectmodel/ComponentState.cpp b/Sofa/framework/Core/src/sofa/core/objectmodel/ComponentState.cpp index 6b96a6765a2..6a0277b9b21 100644 --- a/Sofa/framework/Core/src/sofa/core/objectmodel/ComponentState.cpp +++ b/Sofa/framework/Core/src/sofa/core/objectmodel/ComponentState.cpp @@ -24,8 +24,11 @@ #include #include - -namespace sofa::core::objectmodel +namespace sofa +{ +namespace core +{ +namespace objectmodel { @@ -60,5 +63,8 @@ std::istream& operator>>(std::istream& i, ComponentState& s) return i; } -} +} /// namespace objectmodel +} /// namespace core +} /// namespace sofa + diff --git a/Sofa/framework/Core/src/sofa/core/objectmodel/ConfigurationSetting.cpp b/Sofa/framework/Core/src/sofa/core/objectmodel/ConfigurationSetting.cpp index 7080c02c1fc..f39f2bdabfe 100644 --- a/Sofa/framework/Core/src/sofa/core/objectmodel/ConfigurationSetting.cpp +++ b/Sofa/framework/Core/src/sofa/core/objectmodel/ConfigurationSetting.cpp @@ -23,8 +23,13 @@ #include #include +namespace sofa +{ + +namespace core +{ -namespace sofa::core::objectmodel +namespace objectmodel { ConfigurationSetting::ConfigurationSetting() @@ -41,8 +46,6 @@ ConfigurationSetting::~ConfigurationSetting() void ConfigurationSetting::init() { - Inherit1::init(); - //Set all the Data in read only mode: for (VecData::const_iterator it = m_vecData.begin(); it!=m_vecData.end(); ++it) { @@ -67,8 +70,8 @@ bool ConfigurationSetting::removeInNode( objectmodel::BaseNode* node ) } -} // namespace sofa::core::objectmodel - - +} // namespace objectmodel +} // namespace core +} // namespace sofa diff --git a/Sofa/framework/Core/src/sofa/core/objectmodel/Data.cpp b/Sofa/framework/Core/src/sofa/core/objectmodel/Data.cpp index cde0424eefa..32de378a748 100644 --- a/Sofa/framework/Core/src/sofa/core/objectmodel/Data.cpp +++ b/Sofa/framework/Core/src/sofa/core/objectmodel/Data.cpp @@ -23,8 +23,13 @@ #include +namespace sofa +{ + +namespace core +{ -namespace sofa::core::objectmodel +namespace objectmodel { /// Specialization for reading strings @@ -59,6 +64,10 @@ template class SOFA_CORE_API Data< sofa::type::vector >; template class SOFA_CORE_API Data< bool >; template class SOFA_CORE_API Data< sofa::type::vector >; -} +} // objectmodel + +} // core + +} // sofa diff --git a/Sofa/framework/Core/src/sofa/core/objectmodel/DeprecatedData.cpp b/Sofa/framework/Core/src/sofa/core/objectmodel/DeprecatedData.cpp index 5b1f42517be..139b7a14508 100644 --- a/Sofa/framework/Core/src/sofa/core/objectmodel/DeprecatedData.cpp +++ b/Sofa/framework/Core/src/sofa/core/objectmodel/DeprecatedData.cpp @@ -19,6 +19,8 @@ * * * Contact information: contact@sofa-framework.org * ******************************************************************************/ +#pragma once + #include #include #include diff --git a/Sofa/framework/Core/src/sofa/core/objectmodel/DetachNodeEvent.cpp b/Sofa/framework/Core/src/sofa/core/objectmodel/DetachNodeEvent.cpp index a69cdb05310..4cdfe3f9aae 100644 --- a/Sofa/framework/Core/src/sofa/core/objectmodel/DetachNodeEvent.cpp +++ b/Sofa/framework/Core/src/sofa/core/objectmodel/DetachNodeEvent.cpp @@ -21,8 +21,13 @@ ******************************************************************************/ #include +namespace sofa +{ + +namespace core +{ -namespace sofa::core::objectmodel +namespace objectmodel { SOFA_EVENT_CPP( DetachNodeEvent ) @@ -55,8 +60,8 @@ bool DetachNodeEvent::contains(BaseObject* o) const return contains(o->getContext()->toBaseNode()); } -} // namespace sofa::core::objectmodel - - +} // namespace objectmodel +} // namespace core +} // namespace sofa diff --git a/applications/projects/Modeler/CMakeLists.txt b/applications/projects/Modeler/CMakeLists.txt index 2e1570f39e3..026972a526f 100644 --- a/applications/projects/Modeler/CMakeLists.txt +++ b/applications/projects/Modeler/CMakeLists.txt @@ -1,4 +1,4 @@ -message(DEPRECATION "Modeler project is deprecated") +#message(DEPRECATION "Modeler project is deprecated") add_subdirectory("lib") add_subdirectory("exec") diff --git a/applications/projects/Modeler/exec/CMakeLists.txt b/applications/projects/Modeler/exec/CMakeLists.txt index d302149da79..6169b8103fe 100644 --- a/applications/projects/Modeler/exec/CMakeLists.txt +++ b/applications/projects/Modeler/exec/CMakeLists.txt @@ -1,22 +1,107 @@ -cmake_minimum_required(VERSION 3.22) +cmake_minimum_required(VERSION 3.12) project(Modeler) +################################### +# Generate plugin_list.conf.default +#include(cmake/GeneratePluginConfig.cmake) +if(MSVC) + # plugins are located in bin/ + set(_pluginLocation "bin") +else() + # plugins are located in lib/ + set(_pluginLocation "lib") +endif() +set(_configPluginFileName plugin_list.conf) +set(_defaultConfigPluginFileName "${_configPluginFileName}.default") +set(_defaultConfigPluginFilePath "${CMAKE_BINARY_DIR}/${_pluginLocation}/${_defaultConfigPluginFileName}") +#sofa_generate_plugin_config(${_defaultConfigPluginFilePath}) +message("Write Plugin list at ${_defaultConfigPluginFilePath}") +configure_file(${_defaultConfigPluginFilePath} ${PROJECT_BINARY_DIR}/${_defaultConfigPluginFileName} COPYONLY) +install(FILES "${_defaultConfigPluginFilePath}" DESTINATION ${_pluginLocation}/ COMPONENT applications) +################################### +set(QT_TARGETS "") + +sofa_find_package(Sofa.Component.Playback QUIET) +sofa_find_package(Sofa.Simulation.Graph REQUIRED) +sofa_find_package(Sofa.GUI.Common REQUIRED) +sofa_find_package(Sofa.GUI.Batch REQUIRED) +sofa_find_package(SceneChecking REQUIRED) +sofa_find_package(SofaComponentAll REQUIRED) + +find_package(Qt5 COMPONENTS Core QUIET) +if (NOT Qt5Core_FOUND) + if(${CMAKE_VERSION} VERSION_GREATER "3.16.0") + find_package(Qt6 COMPONENTS Core CoreTools QUIET) + endif() +endif() + +if (Qt5Core_FOUND) + message("${PROJECT_NAME}: will use Qt5") + sofa_find_package(Qt5 COMPONENTS Core Gui OpenGL REQUIRED) + set(QT_TARGETS ${QT_TARGETS} Qt5::Core Qt5::Gui Qt5::OpenGL) +elseif (Qt6Core_FOUND) + message("${PROJECT_NAME}: will use Qt6 (beta)") + sofa_find_package(Qt6 COMPONENTS Gui GuiTools Widgets WidgetsTools OpenGLWidgets REQUIRED) + set(QT_TARGETS ${QT_TARGETS} Qt::Core Qt::Gui Qt::Widgets Qt::OpenGLWidgets ) +else() + message(SEND_ERROR "${PROJECT_NAME}: Could not find either Qt5 or Qt6.") +endif() +set(SOURCE_FILES + Main.cpp + ) + +set(RESOURCE_FILES + resources/docs/runsofa.html + ${PROJECT_BINARY_DIR}/${_defaultConfigPluginFileName} + ) if(APPLE) - set(RC_FILES "../Modeler.icns") + set(RC_FILES "../${CMAKE_CURRENT_SOURCE_DIR}/Modeler.icns") + set_source_files_properties(${RC_FILES} PROPERTIES MACOSX_PACKAGE_LOCATION "Resources") else() - set(RC_FILES "sofa.rc") + set(RC_FILES "${CMAKE_CURRENT_SOURCE_DIR}/sofa.rc") endif() -sofa_find_package(Qt5 COMPONENTS Core REQUIRED) -sofa_find_package(SofaComponentAll REQUIRED) +if(APPLE AND SOFA_BUILD_APP_BUNDLE) + add_executable(${PROJECT_NAME} MACOSX_BUNDLE ${RC_FILES} ${RESOURCE_FILES} ${HEADER_FILES} ${SOURCE_FILES}) + set_target_properties(${PROJECT_NAME} PROPERTIES MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/Modeler.plist") +else() + add_executable(${PROJECT_NAME} ${RC_FILES} ${RESOURCE_FILES} ${HEADER_FILES} ${SOURCE_FILES}) +endif() + +target_compile_definitions(${PROJECT_NAME} PUBLIC "CONFIG_PLUGIN_FILENAME=${_configPluginFileName}") +target_compile_definitions(${PROJECT_NAME} PUBLIC "DEFAULT_CONFIG_PLUGIN_FILENAME=${_defaultConfigPluginFileName}") -if(Qt5Core_FOUND) - message("Modeler executable: Using Qt5") - qt5_add_resources(RESOURCE_FILES "${CMAKE_SOURCE_DIR}/share/textures/modeler/icons.qrc") +target_link_libraries(${PROJECT_NAME} Sofa.Simulation.Graph) +target_link_libraries(${PROJECT_NAME} Sofa.GUI.Common) +target_link_libraries(${PROJECT_NAME} Sofa.GUI.Batch) +target_link_libraries(${PROJECT_NAME} SceneChecking) +target_link_libraries(${PROJECT_NAME} SofaComponentAll) +target_link_libraries(${PROJECT_NAME} SofaModeler) +target_link_libraries(${PROJECT_NAME} ${QT_TARGETS}) + +if(Sofa.Component.Playback_FOUND) + target_link_libraries(${PROJECT_NAME} Sofa.Component.Playback) +else() + message(WARNING "Modeler: Sofa.Component.Playback not found, disabling validation feature.") endif() -add_executable(${PROJECT_NAME} Main.cpp ${RC_FILES} ${RESOURCE_FILES}) -target_link_libraries(${PROJECT_NAME} SofaModeler SofaComponentAll SofaSimulationGraph) +#if(SOFA_BUILD_TESTS) +# add_subdirectory(runSofa_test) +#endif() + +# Create build and install versions of .ini file for resources finding +set(RESOURCES_DIR "${CMAKE_CURRENT_SOURCE_DIR}/resources") +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/etc/${PROJECT_NAME}.ini.in" "${CMAKE_BINARY_DIR}/etc/${PROJECT_NAME}.ini") +set(RESOURCES_DIR "../share/sofa/gui/runSofa") +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/etc/${PROJECT_NAME}.ini.in" "${CMAKE_BINARY_DIR}/etc/installed${PROJECT_NAME}.ini") +install(FILES "${CMAKE_BINARY_DIR}/etc/installed${PROJECT_NAME}.ini" DESTINATION etc RENAME ${PROJECT_NAME}.ini COMPONENT applications) + +install(DIRECTORY "resources/" DESTINATION "share/sofa/gui/runSofa" COMPONENT resources) -sofa_install_targets(SofaModeler Modeler "Modeler") +sofa_add_targets_to_package( + PACKAGE_NAME Sofa.GUI + TARGETS ${PROJECT_NAME} AUTO_SET_TARGET_PROPERTIES + INCLUDE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}" + INCLUDE_INSTALL_DIR "Sofa.GUI/Modeler" + ) diff --git a/applications/projects/Modeler/exec/Main.cpp b/applications/projects/Modeler/exec/Main.cpp index f55716f2c7b..0faf940eb42 100644 --- a/applications/projects/Modeler/exec/Main.cpp +++ b/applications/projects/Modeler/exec/Main.cpp @@ -25,8 +25,11 @@ #include #include #include +#include +#include +#include -#include +#include #include @@ -36,9 +39,30 @@ #include #include - +#include +#include +#include +#include +#include +#include + +using sofa::gui::common::BaseGUI; +using sofa::helper::logging::MainPerComponentLoggingMessageHandler; +using sofa::helper::logging::ConsoleMessageHandler; +using sofa::helper::logging::MessageDispatcher; +using sofa::gui::common::GuiDataRepository; using sofa::helper::system::FileSystem; using sofa::helper::Utils; +using sofa::gui::common::GUIManager; +using sofa::core::ExecParams ; +using sofa::simulation::graph::DAGSimulation; +using sofa::helper::system::SetDirectory; +using sofa::core::objectmodel::BaseNode ; +using sofa::helper::system::DataRepository; +using sofa::helper::system::PluginRepository; +using sofa::helper::system::PluginManager; +using namespace std; + // --------------------------------------------------------------------- // --- @@ -46,19 +70,86 @@ using sofa::helper::Utils; int main(int argc, char** argv) { - sofa::component::initSofaComponentAll(); - // TODO: create additionnal handlers depending on command-line parameters + // Add resources dir to GuiDataRepository + const std::string runSofaIniFilePath = Utils::getSofaPathTo("/etc/runSofa.ini"); + std::map iniFileValues = Utils::readBasicIniFile(runSofaIniFilePath); + if (iniFileValues.find("RESOURCES_DIR") != iniFileValues.end()) + { + std::string dir = iniFileValues["RESOURCES_DIR"]; + dir = SetDirectory::GetRelativeFromProcess(dir.c_str()); + if(FileSystem::isDirectory(dir)) + { + sofa::gui::common::GuiDataRepository.addFirstPath(dir); + } + } + +#if defined(SOFA_HAVE_DAG) + string simulationType = "dag"; +#else + string simulationType = "tree"; +#endif + + vector plugins; + vector files; + + string gui_help = "choose the UI ("; + gui_help += GUIManager::ListSupportedGUI('|'); + gui_help += ")"; + + sofa::simulation::common::init(); + sofa::simulation::graph::init(); + + MessageDispatcher::clearHandlers() ; + MessageDispatcher::addHandler( new ConsoleMessageHandler() ) ; + MessageDispatcher::addHandler(&MainPerComponentLoggingMessageHandler::getInstance()) ; +#ifdef TRACY_ENABLE + MessageDispatcher::addHandler(&sofa::helper::logging::MainTracyMessageHandler::getInstance()); +#endif + + // Output FileRepositories + msg_info("runSofa") << "PluginRepository paths = " << PluginRepository.getPathsJoined(); + msg_info("runSofa") << "DataRepository paths = " << DataRepository.getPathsJoined(); + msg_info("runSofa") << "GuiDataRepository paths = " << GuiDataRepository.getPathsJoined(); + + // Initialise paths + BaseGUI::setConfigDirectoryPath(Utils::getSofaPathPrefix() + "/config", true); + BaseGUI::setScreenshotDirectoryPath(Utils::getSofaPathPrefix() + "/screenshots", true); + + // Add Batch GUI (runSofa without any GUIs wont be useful) + sofa::gui::batch::init(); + + for (unsigned int i=0; isetMainWidget(sofaModeler); +// application->setMainWidget(sofaModeler); sofaModeler->show(); std::string binaryName=argv[0]; @@ -68,6 +159,8 @@ int main(int argc, char** argv) #endif if (!binaryName.empty() && binaryName[binaryName.size()-1] == 'd') sofaModeler->setDebugBinary(true); + std::cerr << "DataRep :: " << sofa::helper::system::DataRepository.getFirstPath() <setWindowIcon(QIcon(pathIcon)); @@ -79,5 +172,7 @@ int main(int argc, char** argv) if (argc <= 1 ) sofaModeler->newTab(); int appReturnCode = application->exec(); + delete application; + application = nullptr; return appReturnCode; } diff --git a/applications/projects/Modeler/lib/CMakeLists.txt b/applications/projects/Modeler/lib/CMakeLists.txt index fa26182ad40..642174019ec 100644 --- a/applications/projects/Modeler/lib/CMakeLists.txt +++ b/applications/projects/Modeler/lib/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.22) +cmake_minimum_required(VERSION 3.12) project(SofaModeler VERSION 0.1) find_package(TinyXML2 REQUIRED) diff --git a/applications/projects/Modeler/lib/GraphModeler.cpp b/applications/projects/Modeler/lib/GraphModeler.cpp index 6566804c01c..bcdc8710f4b 100644 --- a/applications/projects/Modeler/lib/GraphModeler.cpp +++ b/applications/projects/Modeler/lib/GraphModeler.cpp @@ -33,10 +33,10 @@ #include #include -#include -#include -#include -#include +#include +#include +#include +#include #include #include @@ -69,6 +69,7 @@ GraphModeler::GraphModeler(QWidget* parent, const char* name, Qt::WindowFlags f) setWindowFlags(f); graphListener = new GraphListenerQListView(this); + graphListener->widget->unLock(); //addColumn("Graph"); header()->hide(); setSortingEnabled(false); @@ -97,7 +98,7 @@ GraphModeler::GraphModeler(QWidget* parent, const char* name, Qt::WindowFlags f) GraphModeler::~GraphModeler() { delete historyManager; - simulation::getSimulation()->unload(getRoot()); + simulation::node::unload(getRoot()); //delete getRoot(); graphRoot.reset(); delete graphListener; @@ -126,7 +127,10 @@ Node::SPtr GraphModeler::addNode(Node::SPtr parent, Node::SPtr child, bool saveH { std::ostringstream oss; oss << Node::shortName(child.get()) << numNode++; - child = Node::create(oss.str() ); + sofa::core::objectmodel::BaseObjectDescription arg; + arg.setName(oss.str()); + child = Node::create(parent.get(),&arg); +// child = Node::create(oss.str() ); if (!parent) child->setName("Root"); } @@ -134,6 +138,7 @@ Node::SPtr GraphModeler::addNode(Node::SPtr parent, Node::SPtr child, bool saveH if (parent != nullptr) { parent->addChild(child); + graphListener->onBeginAddChild(parent.get(),child.get()); if (saveHistory) { @@ -146,7 +151,8 @@ Node::SPtr GraphModeler::addNode(Node::SPtr parent, Node::SPtr child, bool saveH { graphListener->onBeginAddChild(nullptr, child.get()); //Set up the root - this->topLevelItem(0)->setExpanded(true); + if(this->topLevelItem(0) != nullptr) + this->topLevelItem(0)->setExpanded(true); if (saveHistory) historyManager->graphClean(); graphRoot = child; @@ -283,15 +289,27 @@ void GraphModeler::dropEvent(QDropEvent* event) if (text == QString("ComponentCreation")) { BaseObject::SPtr newComponent = addComponent(getNode(event->pos()), lastSelectedComponent.second, lastSelectedComponent.first ); + graphListener->onBeginAddObject(getNode(event->pos()),newComponent.get()); if (newComponent) { -// QTreeWidgetItem *after = graphListener->items[newComponent.get()]; + std::cerr << __FUNCTION__ << ":newComponent name : " << newComponent->getName() << std::endl; + QTreeWidgetItem *after = graphListener->items[newComponent.get()]; + for(std::map ::const_iterator cit = graphListener->items.begin() ; cit != graphListener->items.end() ; cit++) + { + core::objectmodel::Base* bNode = cit->first; + QTreeWidgetItem* bItem = cit->second; + if(bNode && bItem) + { + std::cerr << __FUNCTION__ << ":Base Node Name : " << bNode->getName() << std::endl; + std::cerr << __FUNCTION__ << ":item name : " << bItem->text(0).toStdString() << std::endl; + } + } -// std::ostringstream oss; -// oss << newComponent->getClassName() << " " << newComponent->getName(); -// after->setText(0, QString(oss.str().c_str())); -// QTreeWidgetItem *item = itemAt(event->pos()); -// if (getObject(item)) initItem(after, item); + std::ostringstream oss; + oss << newComponent->getClassName() << " " << newComponent->getName(); + after->setText(0, QString(oss.str().c_str())); + QTreeWidgetItem *item = itemAt(event->pos()); + if (getObject(item)) initItem(after, item); } } else @@ -299,15 +317,33 @@ void GraphModeler::dropEvent(QDropEvent* event) if (text == QString("Node")) { Node* node=getNode(event->pos()); - + std::cerr << __FUNCTION__ << ":event pos node name : " << node->getName() << std::endl; if (node) { Node::SPtr newNode=addNode(node); + std::cerr << __FUNCTION__ << ":newNode name : " << newNode->getName() << std::endl; if (newNode) { QTreeWidgetItem *after = graphListener->items[newNode.get()]; QTreeWidgetItem *item = itemAt(event->pos()); - if (getObject(item)) initItem(after,item); + + for(std::map ::const_iterator cit = graphListener->items.begin() ; cit != graphListener->items.end() ; cit++) + { + core::objectmodel::Base* bNode = cit->first; + QTreeWidgetItem* bItem = cit->second; + if(bNode && bItem) + { + std::cerr << __FUNCTION__ << ":Base Node Name : " << bNode->getName() << std::endl; + std::cerr << __FUNCTION__ << ":item name : " << bItem->text(0).toStdString() << std::endl; + } + } + + if(after) + std::cerr << __FUNCTION__ << ":after name : " << after->text(0).toStdString() << std::endl; + if(item) + std::cerr << __FUNCTION__ << ":item name : " << item->text(0).toStdString() << std::endl; + if (getObject(item)) + initItem(after,item); } } } @@ -315,6 +351,8 @@ void GraphModeler::dropEvent(QDropEvent* event) } + + Base* GraphModeler::getComponent(QTreeWidgetItem *item) const { if (!item) return nullptr; @@ -332,7 +370,12 @@ Base* GraphModeler::getComponent(QTreeWidgetItem *item) const BaseObject *GraphModeler::getObject(QTreeWidgetItem *item) const { Base* component=getComponent(item); - return dynamic_cast(component); + std::cerr << "Component Class Name :: " << component->getClassName() << std::endl; + std::cerr << "Component Name :: " << component->getName() << std::endl; + std::cerr << "Component Template Name :: " << component->getTemplateName() << std::endl; + std::cerr << "Component Type Name :: " << component->getTypeName() << std::endl; + BaseObject* ComponentBaseObject = component->toBaseObject(); + return ComponentBaseObject; } @@ -678,7 +721,10 @@ void GraphModeler::linkComponent() Node::SPtr GraphModeler::buildNodeFromBaseElement(Node::SPtr node,xml::BaseElement *elem, bool saveHistory) { const bool displayWarning=true; - Node::SPtr newNode = Node::create(""); + sofa::core::objectmodel::BaseObjectDescription arg; + arg.setName(""); + Node::SPtr newNode = Node::create(node.get(),&arg); +// Node::SPtr newNode = Node::create(""); //Configure the new Node configureElement(newNode.get(), elem); @@ -913,7 +959,7 @@ bool GraphModeler::getSaveFilename(std::string &filename) void GraphModeler::save(const std::string &filename) { Node *node = getNode(this->topLevelItem(0)); - simulation::getSimulation()->exportXML(node, filename.c_str()); + simulation::node::exportInXML(node, filename.c_str()); emit graphClean(); } @@ -968,6 +1014,7 @@ void GraphModeler::deleteComponent(QTreeWidgetItem* item, bool saveHistory) } getNode(item)->removeObject(getObject(item)); + graphListener->onBeginRemoveObject(parent,object); } else { @@ -985,7 +1032,10 @@ void GraphModeler::deleteComponent(QTreeWidgetItem* item, bool saveHistory) if (!parent) graphListener->onBeginRemoveChild(parent, node); else + { parent->removeChild(dynamic_cast(node)); + graphListener->onBeginRemoveChild(nullptr,node); + } if (!parent && this->children().size() == 0) addNode(nullptr); } diff --git a/applications/projects/Modeler/lib/GraphModeler.h b/applications/projects/Modeler/lib/GraphModeler.h index 4ef7d664b00..276d6a11304 100644 --- a/applications/projects/Modeler/lib/GraphModeler.h +++ b/applications/projects/Modeler/lib/GraphModeler.h @@ -34,7 +34,7 @@ #include #include #include -#include +#include #include #include @@ -48,6 +48,8 @@ #include + + namespace sofa { @@ -72,7 +74,7 @@ class GraphModeler : public SofaSceneGraphWidget friend class LinkComponent; Q_OBJECT public: - GraphModeler( QWidget* parent=0, const char* name=0, Qt::WindowFlags f = 0 ); + GraphModeler( QWidget* parent=0, const char* name=0, Qt::WindowFlags f = Qt::WindowFlags() ); ~GraphModeler() override; /// Set the Sofa Resources: intern library to get the creators of the elements @@ -178,6 +180,8 @@ class GraphModeler : public SofaSceneGraphWidget /// Used to know what component is about to be created by a drag&drop void setLastSelectedComponent( const std::string& templateName, ClassEntry::SPtr entry) {lastSelectedComponent = std::make_pair(templateName, entry);} + GraphListenerQListView *getGraphListener(){return graphListener;} + signals: void fileOpen(const QString&); diff --git a/applications/projects/Modeler/lib/SofaModeler.cpp b/applications/projects/Modeler/lib/SofaModeler.cpp index 429c0ff48ce..551b6d2b226 100644 --- a/applications/projects/Modeler/lib/SofaModeler.cpp +++ b/applications/projects/Modeler/lib/SofaModeler.cpp @@ -28,7 +28,8 @@ #include #include -#include +//#include +#include #include #include #include @@ -51,6 +52,7 @@ #include #include #include +#include using namespace sofa::core; @@ -71,23 +73,25 @@ using sofa::helper::Utils; void SofaModeler::createActions() { - newTabAction = new QAction(QIcon(":/image0.png"), "New &Tab", this); + QString pathIcon=(sofa::helper::system::DataRepository.getFirstPath() + std::string( "/textures/modeler" )).c_str(); + + newTabAction = new QAction(QIcon(pathIcon+"/image0.png"), "New &Tab", this); newTabAction->setShortcut(QString("Ctrl+T")); connect(newTabAction, SIGNAL(triggered()), this, SLOT(newTab())); - closeTabAction = new QAction(QIcon(":/imageClose.png"), "&Close Tab", this); + closeTabAction = new QAction(QIcon(pathIcon+"/imageClose.png"), "&Close Tab", this); closeTabAction->setShortcut(QString("Ctrl+W")); connect(closeTabAction, SIGNAL(triggered()), this, SLOT(closeTab())); - clearTabAction = new QAction(QIcon(":/image0.png"), "Clear", this); + clearTabAction = new QAction(QIcon(pathIcon+"/image0.png"), "Clear", this); clearTabAction->setShortcut(QString("Ctrl+N")); connect(clearTabAction, SIGNAL(triggered()), this, SLOT(clearTab())); - openAction = new QAction(QIcon(":/image1.png"), "&Open...", this); + openAction = new QAction(QIcon(pathIcon+"/image1.png"), "&Open...", this); openAction->setShortcut(QString("Ctrl+O")); connect(openAction, SIGNAL(triggered()), this, SLOT(fileOpen())); - saveAction = new QAction(QIcon(":/image3.png"), "&Save", this); + saveAction = new QAction(QIcon(pathIcon+"/image3.png"), "&Save", this); saveAction->setShortcut(QString("Ctrl+S")); connect(saveAction, SIGNAL(triggered()), this, SLOT(fileSave())); @@ -100,25 +104,25 @@ void SofaModeler::createActions() exitAction = new QAction("E&xit", this); connect(exitAction, SIGNAL(triggered()), this, SLOT(exit())); - undoAction = new QAction(QIcon(":/image5.png"), "&Undo", this); + undoAction = new QAction(QIcon(pathIcon+"/image5.png"), "&Undo", this); undoAction->setEnabled(false); undoAction->setShortcut(QString("Ctrl+Z")); connect(undoAction, SIGNAL(triggered()), this, SLOT(undo())); - redoAction = new QAction(QIcon(":/image6.png"), "&Redo", this); + redoAction = new QAction(QIcon(pathIcon+"/image6.png"), "&Redo", this); redoAction->setEnabled(false); redoAction->setShortcut(QString("Ctrl+Y")); connect(redoAction, SIGNAL(triggered()), this, SLOT(redo())); - cutAction = new QAction(QIcon(":/image7.png"), "&Cut", this); + cutAction = new QAction(QIcon(pathIcon+"/image7.png"), "&Cut", this); cutAction->setShortcut(QString("Ctrl+X")); connect(cutAction, SIGNAL(triggered()), this, SLOT(cut())); - copyAction = new QAction(QIcon(":/image8.png"), "C&opy", this); + copyAction = new QAction(QIcon(pathIcon+"/image8.png"), "C&opy", this); copyAction->setShortcut(QString("Ctrl+C")); connect(copyAction, SIGNAL(triggered()), this, SLOT(copy())); - pasteAction = new QAction(QIcon(":/image9.png"), "&Paste", this); + pasteAction = new QAction(QIcon(pathIcon+"/image9.png"), "&Paste", this); pasteAction->setEnabled(false); pasteAction->setShortcut(QString("Ctrl+V")); connect(pasteAction, SIGNAL(triggered()), this, SLOT(paste())); @@ -126,11 +130,11 @@ void SofaModeler::createActions() openPluginManagerAction = new QAction("Plugin Manager", this); connect(openPluginManagerAction, SIGNAL(triggered()), this, SLOT(showPluginManager())); - runInSofaAction = new QAction(QIcon(":/image2.png"), "&Run in SOFA", this); + runInSofaAction = new QAction(QIcon(pathIcon+"/image2.png"), "&Run in SOFA", this); runInSofaAction->setShortcut(QString("Ctrl+R")); connect(runInSofaAction, SIGNAL(triggered()), this, SLOT(runInSofa())); - openTutorialsAction = new QAction(QIcon(":/image11.png"), "Launch the &Tutorials" ,this); + openTutorialsAction = new QAction(QIcon(pathIcon+"/image11.png"), "Launch the &Tutorials" ,this); connect(openTutorialsAction, SIGNAL(triggered()), this, SLOT(openTutorial())); exportSofaClassesAction = new QAction("Export Sofa Classes", this); @@ -572,7 +576,8 @@ void SofaModeler::createTab() graph = modelerGraph; graph->setAcceptDrops(true); - currentTabLayout->addWidget(graph,0,0); + graph->getGraphListener()->widget->unLock(); + currentTabLayout->addWidget(graph); graph->setSofaLibrary(library); graph->setPropertyWidget(propertyWidget); @@ -613,7 +618,7 @@ bool SofaModeler::closeTab(QWidget *curTab, bool forceClose) else if (response == QMessageBox::Ok) { if (mod->getFilename().empty()) fileSaveAs(); - else simulation::getSimulation()->exportXML(mod->getRoot(), mod->getFilename().c_str()); + else simulation::node::exportInXML(mod->getRoot(), mod->getFilename().c_str()); } } //If the scene has been launch in Sofa @@ -625,7 +630,7 @@ bool SofaModeler::closeTab(QWidget *curTab, bool forceClose) range=mapSofa.equal_range(curTab); for (multimapIterator it=range.first; it!=range.second; ++it) { - removeTemporaryFiles(it->second->objectName().toStdString()); +// removeTemporaryFiles(it->second->objectName().toStdString()); it->second->kill(); } mapSofa.erase(range.first, range.second); @@ -675,14 +680,17 @@ void SofaModeler::fileOpen(const QUrl &u) void SofaModeler::fileOpen(std::string filename) { + std::cerr << __FUNCTION__ << ": input file name = " << filename << std::endl; if ( sofa::helper::system::DataRepository.findFile ( filename ) ) { filename = sofa::helper::system::DataRepository.getFile ( filename ); openPath = sofa::helper::system::SetDirectory::GetParentDir(filename.c_str()); - Node::SPtr root = NULL; - root = down_cast( sofa::simulation::getSimulation()->load(filename.c_str()).get() ); + std::cerr << __FUNCTION__ << ": openPath = " << openPath << std::endl; + std::cerr << __FUNCTION__ << ": filename = " << filename << std::endl; + Node::SPtr root = sofa::simulation::node::load(filename.c_str()).get(); if (root) { + sofa::simulation::node::initRoot(root.get()); createTab(); fileNew(root.get()); sceneTab->setCurrentIndex(sceneTab->count()-1); @@ -697,6 +705,7 @@ void SofaModeler::fileOpen(std::string filename) } } displayHelpModeler(); + std::cerr << __FUNCTION__ << " -> Finished" << std::endl; } void SofaModeler::fileRecentlyOpened(QAction* act) @@ -826,7 +835,7 @@ void SofaModeler::exportSofaClasses() } } - getSimulation()->exportXML(root.get(), filename.toStdString().c_str()); + sofa::simulation::node::exportInXML(root.get(), filename.toStdString().c_str()); std::cout << "Sofa classes have been XML exported in: " << filename.toStdString() << std::endl << std::endl; } @@ -951,7 +960,7 @@ void SofaModeler::componentDraggedReception( std::string description, std::strin mimedata->setText("ComponentCreation"); dragging->setMimeData(mimedata); dragging->exec(Qt::CopyAction | Qt::MoveAction); - //dragging->dragCopy(); +// dragging->dragCopy(); } void SofaModeler::changeComponent(const std::string &description) @@ -966,7 +975,6 @@ void SofaModeler::newGNode() QMimeData* mimedata = new QMimeData(); mimedata->setText("Node"); dragging->setMimeData(mimedata); - //dragging->dragCopy(); dragging->exec(Qt::CopyAction | Qt::MoveAction); } @@ -1079,6 +1087,7 @@ void SofaModeler::runInSofa() { if (sceneTab->count() == 0) return; Node* root=graph->getRoot(); + std::cerr << __FUNCTION__ << ": Graph File Name :: " << graph->getFilename() << std::endl; runInSofa(graph->getFilename(), root); } void SofaModeler::runInSofa( const std::string &sceneFilename, Node* root) @@ -1093,8 +1102,8 @@ void SofaModeler::runInSofa( const std::string &sceneFilename, Node* root) else path = sofa::helper::system::SetDirectory::GetParentDir(sceneFilename.c_str())+std::string("/"); - std::string filename=path + std::string("temp") + (++count) + std::string(".scn"); - simulation::getSimulation()->exportXML(root,filename.c_str()); + std::string filename=/*path + std::string("temp") + (++count) + std::string(".scn")*/sceneFilename; +// sofa::simulation::node::exportInXML(root,filename.c_str()); //Make a copy of the .view if it exists for the current viewer const std::string &extension=sofa::helper::system::SetDirectory::GetExtension(sceneFilename.c_str()); @@ -1167,25 +1176,27 @@ void SofaModeler::runInSofa( const std::string &sceneFilename, Node* root) #endif } - argv << QString(filename.c_str()); + messageLaunch = QString("Use command: ") + QString(sofaBinary.c_str()) + QString(" "); //Setting the GUI - for (unsigned int i=0; iisChecked()) - { - if (std::string(listActionGUI[i]->text().toStdString()) != "default") - { - argv << "-g" << listActionGUI[i]->text(); - messageLaunch += QString("-g ") + QString(listActionGUI[i]->text()); - } - break; - } - } + argv << "-g" << "qt"; + messageLaunch += QString("-g ") + QString("qt"); +// for (unsigned int i=0; iisChecked()) +// { +// if (std::string(listActionGUI[i]->text().toStdString()) != "default") +// { +// argv << "-g" << listActionGUI[i]->text(); +// messageLaunch += QString("-g ") + QString(listActionGUI[i]->text()); +// } +// break; +// } +// } //retrive plugins typedef sofa::helper::system::PluginManager::PluginMap PluginMap; @@ -1195,11 +1206,17 @@ void SofaModeler::runInSofa( const std::string &sceneFilename, Node* root) for( it = pluginMap.begin(); it != pluginMap.end(); ++it ) { argv << "-l" << QString((it->first).c_str()) << " "; - messageLaunch += QString("-l ") + QString((it->first).c_str()); + messageLaunch += QString(" -l ") + QString((it->first).c_str()); } - argv << "-t"; +// argv << "-t"; + + argv << QString(filename.c_str()); + + std::cerr << __FUNCTION__ << ": messageLaunch :: " << messageLaunch.toStdString() << std::endl; + + qDebug() << "argv :: " << argv; QProcess *p = new QProcess(this); @@ -1257,7 +1274,7 @@ void SofaModeler::sofaExited(int exitCode, QProcess::ExitStatus existStatus) programName = p->objectName().toStdString(); - removeTemporaryFiles(programName); +// removeTemporaryFiles(programName); if (existStatus == QProcess::NormalExit ) { p->closeWriteChannel(); diff --git a/applications/projects/Modeler/lib/SofaTutorialManager.cpp b/applications/projects/Modeler/lib/SofaTutorialManager.cpp index 090455931e0..030cc2196e7 100644 --- a/applications/projects/Modeler/lib/SofaTutorialManager.cpp +++ b/applications/projects/Modeler/lib/SofaTutorialManager.cpp @@ -26,8 +26,7 @@ #include #include -#include - +#include #include #include #include diff --git a/applications/projects/Modeler/lib/TutorialSelector.h b/applications/projects/Modeler/lib/TutorialSelector.h index bb41e8e7c03..0d73ade8935 100644 --- a/applications/projects/Modeler/lib/TutorialSelector.h +++ b/applications/projects/Modeler/lib/TutorialSelector.h @@ -25,13 +25,14 @@ #include #include #include +#include #include #include // Forward declarations -class tinyxml2::XMLNode; -class tinyxml2::XMLElement; +//class tinyxml2::XMLNode; +//class tinyxml2::XMLElement; #include From 73bc5c6e139e7ded0f0521bfb0e9aed3a4b7e228 Mon Sep 17 00:00:00 2001 From: BehnamBinesh Date: Sun, 28 Apr 2024 16:54:11 +0330 Subject: [PATCH 02/13] [Modeler] :: Modeler project cmake set ON --- applications/projects/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/projects/CMakeLists.txt b/applications/projects/CMakeLists.txt index 0c85f91879a..1a858184d25 100644 --- a/applications/projects/CMakeLists.txt +++ b/applications/projects/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.22) sofa_add_subdirectory(application SceneChecking SceneChecking ON) -sofa_add_subdirectory(application Modeler Modeler OFF) +sofa_add_subdirectory(application Modeler Modeler ON) sofa_add_subdirectory(application getDeprecatedComponents getDeprecatedComponents OFF) From 1fc653c6f1659940faba2af477ecd4f2bb57f861 Mon Sep 17 00:00:00 2001 From: BehnamBinesh Date: Sun, 28 Apr 2024 16:55:05 +0330 Subject: [PATCH 03/13] [Modeler] :: warning and cout cleaned. deprecated function removed --- .../Simulation/Core/src/sofa/simulation/Node.cpp | 8 ++++++-- Sofa/framework/Simulation/Core/src/sofa/simulation/Node.h | 3 +-- applications/projects/Modeler/exec/Main.cpp | 2 +- applications/projects/Modeler/lib/GraphHistoryManager.cpp | 4 ++-- applications/projects/Modeler/lib/GraphModeler.cpp | 4 ++-- applications/projects/Modeler/lib/SofaModeler.cpp | 4 ---- 6 files changed, 12 insertions(+), 13 deletions(-) diff --git a/Sofa/framework/Simulation/Core/src/sofa/simulation/Node.cpp b/Sofa/framework/Simulation/Core/src/sofa/simulation/Node.cpp index f3c4f3d34ec..ccf220b1857 100644 --- a/Sofa/framework/Simulation/Core/src/sofa/simulation/Node.cpp +++ b/Sofa/framework/Simulation/Core/src/sofa/simulation/Node.cpp @@ -833,6 +833,8 @@ void Node::setDefaultVisualContextValue() */ } + + void Node::initialize() { initialized = true; // flag telling is the node is initialized @@ -1001,11 +1003,13 @@ void Node::printComponents() msg_info() << sstream.str(); } -Node::SPtr Node::create( const std::string& name ) +Node::SPtr Node::create(core::objectmodel::BaseObjectDescription *arg) { if (Simulation* simulation = getSimulation()) { - return simulation->createNewNode(name); + Node::SPtr obj = simulation->createNewNode(arg->getName()); + obj->parse(arg); + return obj; } return nullptr; } diff --git a/Sofa/framework/Simulation/Core/src/sofa/simulation/Node.h b/Sofa/framework/Simulation/Core/src/sofa/simulation/Node.h index 271c83e4892..5f1ad9ac083 100644 --- a/Sofa/framework/Simulation/Core/src/sofa/simulation/Node.h +++ b/Sofa/framework/Simulation/Core/src/sofa/simulation/Node.h @@ -515,8 +515,7 @@ class SOFA_SIMULATION_CORE_API Node : public sofa::core::objectmodel::BaseNode, template static Node::SPtr create(RealObject*, sofa::core::objectmodel::BaseObjectDescription* arg); - SOFA_ATTRIBUTE_DISABLED_NODECREATENODE() - static Node::SPtr create( const std::string& name ); + static Node::SPtr create(sofa::core::objectmodel::BaseObjectDescription* arg); /// return the smallest common parent between this and node2 (returns nullptr if separated sub-graphes) virtual Node* findCommonParent( simulation::Node* node2 ) = 0; diff --git a/applications/projects/Modeler/exec/Main.cpp b/applications/projects/Modeler/exec/Main.cpp index 0faf940eb42..10ba75c74a4 100644 --- a/applications/projects/Modeler/exec/Main.cpp +++ b/applications/projects/Modeler/exec/Main.cpp @@ -159,7 +159,7 @@ int main(int argc, char** argv) #endif if (!binaryName.empty() && binaryName[binaryName.size()-1] == 'd') sofaModeler->setDebugBinary(true); - std::cerr << "DataRep :: " << sofa::helper::system::DataRepository.getFirstPath() <setWindowIcon(QIcon(pathIcon)); diff --git a/applications/projects/Modeler/lib/GraphHistoryManager.cpp b/applications/projects/Modeler/lib/GraphHistoryManager.cpp index 3530069c1e8..6bd76418fd5 100644 --- a/applications/projects/Modeler/lib/GraphHistoryManager.cpp +++ b/applications/projects/Modeler/lib/GraphHistoryManager.cpp @@ -248,7 +248,7 @@ void GraphHistoryManager::clearHistory() else if (historyOperation[i].ID == Operation::DELETE_Node) { Node *n=down_cast(historyOperation[i].sofaComponent->toBaseNode()); - simulation::getSimulation()->unload(n); + sofa::simulation::node::unload(n); historyOperation[i].sofaComponent.reset(); } } @@ -267,7 +267,7 @@ void GraphHistoryManager::clearHistoryUndo() else if (historyUndoOperation[i].ID == Operation::DELETE_Node) { Node *n=down_cast(historyUndoOperation[i].sofaComponent->toBaseNode()); - simulation::getSimulation()->unload(n); + sofa::simulation::node::unload(n); historyUndoOperation[i].sofaComponent.reset(); } } diff --git a/applications/projects/Modeler/lib/GraphModeler.cpp b/applications/projects/Modeler/lib/GraphModeler.cpp index bcdc8710f4b..d878156a682 100644 --- a/applications/projects/Modeler/lib/GraphModeler.cpp +++ b/applications/projects/Modeler/lib/GraphModeler.cpp @@ -129,7 +129,7 @@ Node::SPtr GraphModeler::addNode(Node::SPtr parent, Node::SPtr child, bool saveH oss << Node::shortName(child.get()) << numNode++; sofa::core::objectmodel::BaseObjectDescription arg; arg.setName(oss.str()); - child = Node::create(parent.get(),&arg); + child = Node::create(&arg); // child = Node::create(oss.str() ); if (!parent) child->setName("Root"); @@ -723,7 +723,7 @@ Node::SPtr GraphModeler::buildNodeFromBaseElement(Node::SPtr node,xml::BaseEleme const bool displayWarning=true; sofa::core::objectmodel::BaseObjectDescription arg; arg.setName(""); - Node::SPtr newNode = Node::create(node.get(),&arg); + Node::SPtr newNode = Node::create(&arg); // Node::SPtr newNode = Node::create(""); //Configure the new Node configureElement(newNode.get(), elem); diff --git a/applications/projects/Modeler/lib/SofaModeler.cpp b/applications/projects/Modeler/lib/SofaModeler.cpp index 551b6d2b226..8ce93e3b2cd 100644 --- a/applications/projects/Modeler/lib/SofaModeler.cpp +++ b/applications/projects/Modeler/lib/SofaModeler.cpp @@ -680,13 +680,10 @@ void SofaModeler::fileOpen(const QUrl &u) void SofaModeler::fileOpen(std::string filename) { - std::cerr << __FUNCTION__ << ": input file name = " << filename << std::endl; if ( sofa::helper::system::DataRepository.findFile ( filename ) ) { filename = sofa::helper::system::DataRepository.getFile ( filename ); openPath = sofa::helper::system::SetDirectory::GetParentDir(filename.c_str()); - std::cerr << __FUNCTION__ << ": openPath = " << openPath << std::endl; - std::cerr << __FUNCTION__ << ": filename = " << filename << std::endl; Node::SPtr root = sofa::simulation::node::load(filename.c_str()).get(); if (root) { @@ -705,7 +702,6 @@ void SofaModeler::fileOpen(std::string filename) } } displayHelpModeler(); - std::cerr << __FUNCTION__ << " -> Finished" << std::endl; } void SofaModeler::fileRecentlyOpened(QAction* act) From 834e824831a7eb82148d68509d9ee08492510652 Mon Sep 17 00:00:00 2001 From: BehnamBinesh Date: Tue, 30 Apr 2024 09:57:17 +0330 Subject: [PATCH 04/13] [Modeler] :: Modeler.ini and other config files added --- .../projects/Modeler/exec/Modeler.plist | 32 +++++++++++++++++++ .../projects/Modeler/exec/etc/Modeler.ini.in | 1 + .../Modeler/exec/resources/docs/runsofa.html | 16 ++++++++++ 3 files changed, 49 insertions(+) create mode 100644 applications/projects/Modeler/exec/Modeler.plist create mode 100644 applications/projects/Modeler/exec/etc/Modeler.ini.in create mode 100644 applications/projects/Modeler/exec/resources/docs/runsofa.html diff --git a/applications/projects/Modeler/exec/Modeler.plist b/applications/projects/Modeler/exec/Modeler.plist new file mode 100644 index 00000000000..c59e246bd0c --- /dev/null +++ b/applications/projects/Modeler/exec/Modeler.plist @@ -0,0 +1,32 @@ + + + + + CFBundlePackageType + APPL + CFBundleDevelopmentRegion + en_US + CFBundleExecutable + bin/runSofa + CFBundleGetInfoString + Created by the SOFA Team + CFBundleIconFile + runSofa.icns + CFBundleIdentifier + org.sofa-framework.runsofa + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + runSOFA + CFBundleDisplayName + SOFA Framework - Real-time multi-physics simulation + CFBundleVersion + @Sofa_VERSION@ + CFBundleShortVersionString + v@Sofa_VERSION@ + NSHumanReadableCopyright + LGPL + GPL + CSResourcesFileMapped + + + diff --git a/applications/projects/Modeler/exec/etc/Modeler.ini.in b/applications/projects/Modeler/exec/etc/Modeler.ini.in new file mode 100644 index 00000000000..1a9c6a74899 --- /dev/null +++ b/applications/projects/Modeler/exec/etc/Modeler.ini.in @@ -0,0 +1 @@ +RESOURCES_DIR=@RESOURCES_DIR@ diff --git a/applications/projects/Modeler/exec/resources/docs/runsofa.html b/applications/projects/Modeler/exec/resources/docs/runsofa.html new file mode 100644 index 00000000000..c6c274b2494 --- /dev/null +++ b/applications/projects/Modeler/exec/resources/docs/runsofa.html @@ -0,0 +1,16 @@ + + + + +runSofa 1.0. +
+Welcome in runSofa, a simple way to execute and debug Sofa scene. This tool is part of the Sofa framework +for simulation. + +You can try the following examples: +
    + Caduceus +
+ + + From bb1250a9125e05c4180cdc77c803b397e270dcda Mon Sep 17 00:00:00 2001 From: BehnamBinesh Date: Tue, 30 Apr 2024 10:18:42 +0330 Subject: [PATCH 05/13] [Modeler] :: cmake generate plugin config file fixed . add plugin config generation cmake file (#4673) --- .../projects/Modeler/exec/CMakeLists.txt | 5 +- .../exec/cmake/GeneratePluginConfig.cmake | 52 +++++++++++++++++++ 2 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 applications/projects/Modeler/exec/cmake/GeneratePluginConfig.cmake diff --git a/applications/projects/Modeler/exec/CMakeLists.txt b/applications/projects/Modeler/exec/CMakeLists.txt index 6169b8103fe..614f46a27cb 100644 --- a/applications/projects/Modeler/exec/CMakeLists.txt +++ b/applications/projects/Modeler/exec/CMakeLists.txt @@ -3,7 +3,7 @@ project(Modeler) ################################### # Generate plugin_list.conf.default -#include(cmake/GeneratePluginConfig.cmake) +include(cmake/GeneratePluginConfig.cmake) if(MSVC) # plugins are located in bin/ set(_pluginLocation "bin") @@ -14,10 +14,11 @@ endif() set(_configPluginFileName plugin_list.conf) set(_defaultConfigPluginFileName "${_configPluginFileName}.default") set(_defaultConfigPluginFilePath "${CMAKE_BINARY_DIR}/${_pluginLocation}/${_defaultConfigPluginFileName}") -#sofa_generate_plugin_config(${_defaultConfigPluginFilePath}) +sofa_generate_plugin_config(${_defaultConfigPluginFilePath}) message("Write Plugin list at ${_defaultConfigPluginFilePath}") configure_file(${_defaultConfigPluginFilePath} ${PROJECT_BINARY_DIR}/${_defaultConfigPluginFileName} COPYONLY) install(FILES "${_defaultConfigPluginFilePath}" DESTINATION ${_pluginLocation}/ COMPONENT applications) + ################################### set(QT_TARGETS "") diff --git a/applications/projects/Modeler/exec/cmake/GeneratePluginConfig.cmake b/applications/projects/Modeler/exec/cmake/GeneratePluginConfig.cmake new file mode 100644 index 00000000000..dc75641fdd4 --- /dev/null +++ b/applications/projects/Modeler/exec/cmake/GeneratePluginConfig.cmake @@ -0,0 +1,52 @@ +cmake_minimum_required(VERSION 3.22) + +include_guard(GLOBAL) + +macro(sofa_generate_plugin_config config_filename) + # Generate default list of plugins (according to the options) + get_property(_allTargets GLOBAL PROPERTY __GlobalTargetList__) + get_property(_allTargetNames GLOBAL PROPERTY __GlobalTargetNameList__) + + list(LENGTH _allTargets nbTargets) + + # do the generation only if there is any plugin + if (NOT ${nbTargets} EQUAL 0) + math(EXPR len "${nbTargets} - 1") + + set(_modulePrefix "MODULE") + set(_pluginPrefix "PLUGIN") + foreach(counter RANGE ${len}) + list(GET _allTargets ${counter} _target) + list(GET _allTargetNames ${counter} _targetName) + + string(SUBSTRING "${_targetName}" 0 6 _testPlugin) + if(${_testPlugin} MATCHES "${_modulePrefix}.*" OR ${_testPlugin} MATCHES "${_pluginPrefix}.*") + if(${${_targetName}}) + get_target_property(_version ${_target} VERSION ) + if(${_version} MATCHES ".*NOTFOUND") + set(_version "NO_VERSION") + endif() + + set(_target_filename ${_target}) + get_target_property(target_output_name ${_target} OUTPUT_NAME) + if(target_output_name) + set(_target_filename ${target_output_name}) + endif() + + string(CONCAT _pluginConfig "${_pluginConfig}\n${_target_filename} ${_version}") + endif() + endif() + endforeach() + FILE(WRITE ${config_filename} ${_pluginConfig}) + + # only useful for devs working directly with a build version (not installed) + # With Win/MVSC, we can only know $CONFIG at build time + if (MSVC) + add_custom_target(do_always ALL + COMMAND if exist "${CMAKE_BINARY_DIR}/bin/$/" # does not exist if using MSVC without Visual Studio IDE + "${CMAKE_COMMAND}" -E copy "${config_filename}" "${CMAKE_BINARY_DIR}/bin/$/" + ) + endif(MSVC) + endif() + +endmacro() From 3852ca02bf14a1f29de4d98c0e70fc8a1d4bec4a Mon Sep 17 00:00:00 2001 From: BehnamBinesh Date: Tue, 30 Apr 2024 10:30:01 +0330 Subject: [PATCH 06/13] [Modeler] :: add custom target removed from Modeler project and execute in runSofa --- .../Modeler/exec/cmake/GeneratePluginConfig.cmake | 8 -------- 1 file changed, 8 deletions(-) diff --git a/applications/projects/Modeler/exec/cmake/GeneratePluginConfig.cmake b/applications/projects/Modeler/exec/cmake/GeneratePluginConfig.cmake index dc75641fdd4..4c81141a32d 100644 --- a/applications/projects/Modeler/exec/cmake/GeneratePluginConfig.cmake +++ b/applications/projects/Modeler/exec/cmake/GeneratePluginConfig.cmake @@ -39,14 +39,6 @@ macro(sofa_generate_plugin_config config_filename) endforeach() FILE(WRITE ${config_filename} ${_pluginConfig}) - # only useful for devs working directly with a build version (not installed) - # With Win/MVSC, we can only know $CONFIG at build time - if (MSVC) - add_custom_target(do_always ALL - COMMAND if exist "${CMAKE_BINARY_DIR}/bin/$/" # does not exist if using MSVC without Visual Studio IDE - "${CMAKE_COMMAND}" -E copy "${config_filename}" "${CMAKE_BINARY_DIR}/bin/$/" - ) - endif(MSVC) endif() endmacro() From dc61268db7f5d0c54fe570012014809f5be190ed Mon Sep 17 00:00:00 2001 From: BehnamBinesh Date: Tue, 30 Apr 2024 10:37:40 +0330 Subject: [PATCH 07/13] [Modeler] :: Added modeler icons for macos --- applications/projects/Modeler/exec/Modeler.icns | Bin 0 -> 65531 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 applications/projects/Modeler/exec/Modeler.icns diff --git a/applications/projects/Modeler/exec/Modeler.icns b/applications/projects/Modeler/exec/Modeler.icns new file mode 100644 index 0000000000000000000000000000000000000000..79da865c78abd41595c3c142cd2958172ee21bf8 GIT binary patch literal 65531 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 literal 0 HcmV?d00001 From 2d9f03da80aea3d1701f8f20b1b41d72644b8be3 Mon Sep 17 00:00:00 2001 From: BehnamBinesh Date: Tue, 30 Apr 2024 10:42:40 +0330 Subject: [PATCH 08/13] [Modeler] :: Added ispc format for modeler resource in macos --- applications/projects/Modeler/Modeler.ispc | Bin 0 -> 65531 bytes .../projects/Modeler/exec/CMakeLists.txt | 2 +- applications/projects/Modeler/exec/Modeler.ispc | Bin 0 -> 65531 bytes 3 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 applications/projects/Modeler/Modeler.ispc create mode 100644 applications/projects/Modeler/exec/Modeler.ispc diff --git a/applications/projects/Modeler/Modeler.ispc b/applications/projects/Modeler/Modeler.ispc new file mode 100644 index 0000000000000000000000000000000000000000..79da865c78abd41595c3c142cd2958172ee21bf8 GIT binary patch literal 65531 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 literal 0 HcmV?d00001 diff --git a/applications/projects/Modeler/exec/CMakeLists.txt b/applications/projects/Modeler/exec/CMakeLists.txt index 614f46a27cb..ef124f3bb5e 100644 --- a/applications/projects/Modeler/exec/CMakeLists.txt +++ b/applications/projects/Modeler/exec/CMakeLists.txt @@ -57,7 +57,7 @@ set(RESOURCE_FILES ${PROJECT_BINARY_DIR}/${_defaultConfigPluginFileName} ) if(APPLE) - set(RC_FILES "../${CMAKE_CURRENT_SOURCE_DIR}/Modeler.icns") + set(RC_FILES "../${CMAKE_CURRENT_SOURCE_DIR}/Modeler.ispc") set_source_files_properties(${RC_FILES} PROPERTIES MACOSX_PACKAGE_LOCATION "Resources") else() set(RC_FILES "${CMAKE_CURRENT_SOURCE_DIR}/sofa.rc") diff --git a/applications/projects/Modeler/exec/Modeler.ispc b/applications/projects/Modeler/exec/Modeler.ispc new file mode 100644 index 0000000000000000000000000000000000000000..79da865c78abd41595c3c142cd2958172ee21bf8 GIT binary patch literal 65531 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 literal 0 HcmV?d00001 From 66024d7de0a6ab22e52dc25e4908923682afee19 Mon Sep 17 00:00:00 2001 From: BehnamBinesh Date: Tue, 30 Apr 2024 10:47:16 +0330 Subject: [PATCH 09/13] [Modeler] :: Modeler rc files for icons disabled in macos --- applications/projects/Modeler/exec/CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/applications/projects/Modeler/exec/CMakeLists.txt b/applications/projects/Modeler/exec/CMakeLists.txt index ef124f3bb5e..9740ef4a56e 100644 --- a/applications/projects/Modeler/exec/CMakeLists.txt +++ b/applications/projects/Modeler/exec/CMakeLists.txt @@ -57,8 +57,8 @@ set(RESOURCE_FILES ${PROJECT_BINARY_DIR}/${_defaultConfigPluginFileName} ) if(APPLE) - set(RC_FILES "../${CMAKE_CURRENT_SOURCE_DIR}/Modeler.ispc") - set_source_files_properties(${RC_FILES} PROPERTIES MACOSX_PACKAGE_LOCATION "Resources") + #set(RC_FILES "../${CMAKE_CURRENT_SOURCE_DIR}/Modeler.ispc") + #set_source_files_properties(${RC_FILES} PROPERTIES MACOSX_PACKAGE_LOCATION "Resources") else() set(RC_FILES "${CMAKE_CURRENT_SOURCE_DIR}/sofa.rc") endif() @@ -67,7 +67,7 @@ if(APPLE AND SOFA_BUILD_APP_BUNDLE) add_executable(${PROJECT_NAME} MACOSX_BUNDLE ${RC_FILES} ${RESOURCE_FILES} ${HEADER_FILES} ${SOURCE_FILES}) set_target_properties(${PROJECT_NAME} PROPERTIES MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/Modeler.plist") else() - add_executable(${PROJECT_NAME} ${RC_FILES} ${RESOURCE_FILES} ${HEADER_FILES} ${SOURCE_FILES}) + add_executable(${PROJECT_NAME} ${RESOURCE_FILES} ${HEADER_FILES} ${SOURCE_FILES}) endif() target_compile_definitions(${PROJECT_NAME} PUBLIC "CONFIG_PLUGIN_FILENAME=${_configPluginFileName}") From f898523ce9b30b6c0f28c53e5574aa0324371b89 Mon Sep 17 00:00:00 2001 From: BehnamBinesh Date: Wed, 1 May 2024 14:40:28 +0330 Subject: [PATCH 10/13] [Modeler] :: Unused log cleaned.Fink path bug fixed --- Sofa/GUI/Qt/src/sofa/gui/qt/DataWidget.cpp | 23 +++++++++++-------- .../Core/src/sofa/core/objectmodel/Base.cpp | 19 +++++++-------- .../src/sofa/core/objectmodel/BaseData.cpp | 20 ++++++++-------- .../src/sofa/core/objectmodel/BaseNode.cpp | 20 ++++++++-------- .../src/sofa/core/objectmodel/BaseObject.cpp | 20 ++++++++-------- .../projects/Modeler/lib/GraphModeler.cpp | 4 ---- .../projects/Modeler/lib/SofaModeler.cpp | 9 ++++---- 7 files changed, 59 insertions(+), 56 deletions(-) diff --git a/Sofa/GUI/Qt/src/sofa/gui/qt/DataWidget.cpp b/Sofa/GUI/Qt/src/sofa/gui/qt/DataWidget.cpp index c51dbb3040f..8b66300d7ee 100644 --- a/Sofa/GUI/Qt/src/sofa/gui/qt/DataWidget.cpp +++ b/Sofa/GUI/Qt/src/sofa/gui/qt/DataWidget.cpp @@ -52,6 +52,8 @@ DataWidget::DataWidget(QWidget* parent,const char* name, MyData* d) , m_toFill(false) { this->setObjectName(name); + + } DataWidget::~DataWidget() @@ -211,23 +213,26 @@ QDisplayDataInfoWidget::QDisplayDataInfoWidget(QWidget* parent, const std::strin if (!ownerClass.empty()) helper_button->setToolTip( ("Data from "+ownerClass).c_str()); } + + linkpath_edit = new QLineEdit(this); + linkpath_edit->setContentsMargins(2, 0, 0, 0); + linkpath_edit->setReadOnly(!modifiable); + layout->addWidget(linkpath_edit); + if(modifyObjectFlags.PROPERTY_WIDGET_FLAG) + connect(linkpath_edit, &QLineEdit::textChanged, [=](){ WidgetDirty(); }); + else + connect(linkpath_edit, &QLineEdit::editingFinished, this, &QDisplayDataInfoWidget::linkEdited); + if(data->getParent()) { const std::string linkvalue = data->getParent()->getLinkPath(); - linkpath_edit = new QLineEdit(this); - linkpath_edit->setContentsMargins(2, 0, 0, 0); linkpath_edit->setText(QString(linkvalue.c_str())); - linkpath_edit->setReadOnly(!modifiable); - layout->addWidget(linkpath_edit); linkpath_edit->setVisible(!linkvalue.empty()); - if(modifyObjectFlags.PROPERTY_WIDGET_FLAG) - connect(linkpath_edit, &QLineEdit::textChanged, [=](){ WidgetDirty(); }); - else - connect(linkpath_edit, &QLineEdit::editingFinished, this, &QDisplayDataInfoWidget::linkEdited); } else { - linkpath_edit=nullptr; + linkpath_edit->setText(""); + linkpath_edit->setVisible(false); } } diff --git a/Sofa/framework/Core/src/sofa/core/objectmodel/Base.cpp b/Sofa/framework/Core/src/sofa/core/objectmodel/Base.cpp index 6d00c6f20ff..6c9983e165f 100644 --- a/Sofa/framework/Core/src/sofa/core/objectmodel/Base.cpp +++ b/Sofa/framework/Core/src/sofa/core/objectmodel/Base.cpp @@ -637,20 +637,21 @@ void Base::writeDatas (std::ostream& out, const std::string& separator) for(VecData::const_iterator iData = m_vecData.begin(); iData != m_vecData.end(); ++iData) { const BaseData* field = *iData; - std::string linkPath = field->getLinkPath(); - std::cerr << __FUNCTION__ << ": Link Path From Data :: " << linkPath << std::endl; -// if (!field->getLinkPath().empty() ) -// { -// out << separator << field->getName() << "=\""<< xmlencode(field->getLinkPath()) << "\" "; -// } -// else + + if (field->getParent()) + { +// out << separator << field->getName() << "=\"" << xmlencode(field->getLinkPath()) << "\" "; + std::string linkPath = field->getParent()->getLinkPath(); + if(!linkPath.empty()) + out << separator << field->getName() << "=\"" << xmlencode(linkPath) << "\" "; + } + else { std::string val = field->getValueString(); std::string fieldname = field->getName(); -// bool isPer = field->isPersistent(); bool isFullTrim = false; bool isset = field->isSet(); - if(/*isPer &&*/ isset && fieldname != "parents") + if(isset && fieldname != "parents") { std::string checkSpace = field->getValueString(); checkSpace.erase(remove_if(checkSpace.begin(), checkSpace.end(), isspace), checkSpace.end()); diff --git a/Sofa/framework/Core/src/sofa/core/objectmodel/BaseData.cpp b/Sofa/framework/Core/src/sofa/core/objectmodel/BaseData.cpp index d687316f655..0a4f2890807 100644 --- a/Sofa/framework/Core/src/sofa/core/objectmodel/BaseData.cpp +++ b/Sofa/framework/Core/src/sofa/core/objectmodel/BaseData.cpp @@ -137,16 +137,16 @@ bool BaseData::setParent(BaseData* parent, const std::string& path) std::string BaseData::getLinkPath() const { - std::string ownerPathName = m_owner->getPathName(); - bool isStrFine = false; - for(unsigned int i=0 ; i < ownerPathName.length() ; i++) - { - if(ownerPathName[i] != '/') - { - isStrFine = true; - } - } - if(m_owner && ownerPathName != "/") +// std::string ownerPathName = m_owner->getPathName(); +// bool isStrFine = false; +// for(unsigned int i=0 ; i < ownerPathName.length() ; i++) +// { +// if(ownerPathName[i] != '/') +// { +// isStrFine = true; +// } +// } + if(m_owner /*&& ownerPathName != "/"*/) { std::string linkPathStr = "@"+m_owner->getPathName()+"."+getName(); return linkPathStr; diff --git a/Sofa/framework/Core/src/sofa/core/objectmodel/BaseNode.cpp b/Sofa/framework/Core/src/sofa/core/objectmodel/BaseNode.cpp index f2491fe06fe..70068215d21 100644 --- a/Sofa/framework/Core/src/sofa/core/objectmodel/BaseNode.cpp +++ b/Sofa/framework/Core/src/sofa/core/objectmodel/BaseNode.cpp @@ -99,16 +99,16 @@ std::string BaseNode::internalGetPathName() const { // no smarter choice without breaking the "Node" heritage str = parents[0]->internalGetPathName(); str += '/'; - bool strIsFine = false; - for(unsigned int i=0 ; i < str.length() ; i++) - { - if(str[i] != '/') - { - strIsFine = true; - } - } - if(strIsFine) - str += getName(); +// bool strIsFine = false; +// for(unsigned int i=0 ; i < str.length() ; i++) +// { +// if(str[i] != '/') +// { +// strIsFine = true; +// } +// } +// if(strIsFine) + str += getName(); } return str; } diff --git a/Sofa/framework/Core/src/sofa/core/objectmodel/BaseObject.cpp b/Sofa/framework/Core/src/sofa/core/objectmodel/BaseObject.cpp index a5ed2ff398a..c0b62abab22 100644 --- a/Sofa/framework/Core/src/sofa/core/objectmodel/BaseObject.cpp +++ b/Sofa/framework/Core/src/sofa/core/objectmodel/BaseObject.cpp @@ -369,16 +369,16 @@ std::string BaseObject::getPathName() const { } } - bool strIsFine = false; - for(unsigned int i=0 ; i < result.length() ; i++) - { - if(result[i] != '/') - { - strIsFine = true; - } - } - if(strIsFine) - result += getName(); +// bool strIsFine = false; +// for(unsigned int i=0 ; i < result.length() ; i++) +// { +// if(result[i] != '/') +// { +// strIsFine = true; +// } +// } +// if(strIsFine) + result += getName(); return result; } diff --git a/applications/projects/Modeler/lib/GraphModeler.cpp b/applications/projects/Modeler/lib/GraphModeler.cpp index d878156a682..788c8b29a0f 100644 --- a/applications/projects/Modeler/lib/GraphModeler.cpp +++ b/applications/projects/Modeler/lib/GraphModeler.cpp @@ -370,10 +370,6 @@ Base* GraphModeler::getComponent(QTreeWidgetItem *item) const BaseObject *GraphModeler::getObject(QTreeWidgetItem *item) const { Base* component=getComponent(item); - std::cerr << "Component Class Name :: " << component->getClassName() << std::endl; - std::cerr << "Component Name :: " << component->getName() << std::endl; - std::cerr << "Component Template Name :: " << component->getTemplateName() << std::endl; - std::cerr << "Component Type Name :: " << component->getTypeName() << std::endl; BaseObject* ComponentBaseObject = component->toBaseObject(); return ComponentBaseObject; } diff --git a/applications/projects/Modeler/lib/SofaModeler.cpp b/applications/projects/Modeler/lib/SofaModeler.cpp index 8ce93e3b2cd..5ab9b66060c 100644 --- a/applications/projects/Modeler/lib/SofaModeler.cpp +++ b/applications/projects/Modeler/lib/SofaModeler.cpp @@ -687,7 +687,7 @@ void SofaModeler::fileOpen(std::string filename) Node::SPtr root = sofa::simulation::node::load(filename.c_str()).get(); if (root) { - sofa::simulation::node::initRoot(root.get()); +// sofa::simulation::node::initRoot(root.get()); createTab(); fileNew(root.get()); sceneTab->setCurrentIndex(sceneTab->count()-1); @@ -1208,11 +1208,13 @@ void SofaModeler::runInSofa( const std::string &sceneFilename, Node* root) // argv << "-t"; - argv << QString(filename.c_str()); + argv << QString::fromStdString(filename); + + messageLaunch += (" "+QString(filename.c_str())); std::cerr << __FUNCTION__ << ": messageLaunch :: " << messageLaunch.toStdString() << std::endl; - qDebug() << "argv :: " << argv; +// qDebug() << "argv :: " << argv; QProcess *p = new QProcess(this); @@ -1223,7 +1225,6 @@ void SofaModeler::runInSofa( const std::string &sceneFilename, Node* root) connect(p, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(sofaExited(int, QProcess::ExitStatus))); - QDir dir(QString(sofa::helper::system::SetDirectory::GetParentDir(sceneFilename.c_str()).c_str())); connect(p, SIGNAL( readyReadStandardOutput () ), this , SLOT ( redirectStdout() ) ); connect(p, SIGNAL( readyReadStandardError () ), this , SLOT ( redirectStderr() ) ); From 87e865cdb1e8821ae57b138660bd615f97904e5a Mon Sep 17 00:00:00 2001 From: BehnamBinesh Date: Wed, 8 May 2024 10:35:41 +0330 Subject: [PATCH 11/13] [Constraint] :: Check mstate pointer validation in "checkIndices" function --- .../constraint/projective/FixedProjectiveConstraint.inl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedProjectiveConstraint.inl b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedProjectiveConstraint.inl index 78bd3636d2e..ed6ba6c2411 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedProjectiveConstraint.inl +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedProjectiveConstraint.inl @@ -131,6 +131,11 @@ template void FixedProjectiveConstraint::checkIndices() { // Check value of given indices + if (!this->mstate.get()) + { + msg_warning() << "Missing mstate, cannot check indices .!"; + return; + } Index maxIndex=this->mstate->getSize(); const SetIndexArray & indices = d_indices.getValue(); From 87adeb244fa74b0c121c0b806356564e8a46ac0a Mon Sep 17 00:00:00 2001 From: BehnamBinesh Date: Wed, 8 May 2024 10:36:24 +0330 Subject: [PATCH 12/13] [Modeler] :: Set initialize value in constructor --- Sofa/GUI/Qt/src/sofa/gui/qt/SofaSceneGraphWidget.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Sofa/GUI/Qt/src/sofa/gui/qt/SofaSceneGraphWidget.h b/Sofa/GUI/Qt/src/sofa/gui/qt/SofaSceneGraphWidget.h index 84e0675c52a..74aa191fe8b 100644 --- a/Sofa/GUI/Qt/src/sofa/gui/qt/SofaSceneGraphWidget.h +++ b/Sofa/GUI/Qt/src/sofa/gui/qt/SofaSceneGraphWidget.h @@ -81,7 +81,10 @@ class SOFA_GUI_QT_API SofaSceneGraphWidget : public QTreeWidget { Q_OBJECT public: - SofaSceneGraphWidget(QWidget* parent) : QTreeWidget(parent){} + SofaSceneGraphWidget(QWidget* parent) : QTreeWidget(parent) + { + m_isLocked = false; + } ~SofaSceneGraphWidget(){} void lock(); @@ -112,7 +115,7 @@ class SOFA_GUI_QT_API SofaSceneGraphWidget : public QTreeWidget /// This can happen if the graph has been freezed (i.e. not graphically updated) for performance /// reason while simulating complex scenes. bool m_isDirty; - bool m_isLocked = false; + bool m_isLocked; }; } //namespace sofa::gui::qt From 091268b0be8f2cfa235e9283db4ec22dcfe3b5c0 Mon Sep 17 00:00:00 2001 From: BehnamBinesh Date: Wed, 8 May 2024 10:37:00 +0330 Subject: [PATCH 13/13] [Modeler] :: Unused code and comment line deleted --- applications/projects/Modeler/exec/Main.cpp | 17 +++----- .../projects/Modeler/lib/GraphModeler.cpp | 30 -------------- .../projects/Modeler/lib/SofaModeler.cpp | 41 ++++++------------- 3 files changed, 19 insertions(+), 69 deletions(-) diff --git a/applications/projects/Modeler/exec/Main.cpp b/applications/projects/Modeler/exec/Main.cpp index 10ba75c74a4..91811cc1f51 100644 --- a/applications/projects/Modeler/exec/Main.cpp +++ b/applications/projects/Modeler/exec/Main.cpp @@ -108,9 +108,9 @@ int main(int argc, char** argv) #endif // Output FileRepositories - msg_info("runSofa") << "PluginRepository paths = " << PluginRepository.getPathsJoined(); - msg_info("runSofa") << "DataRepository paths = " << DataRepository.getPathsJoined(); - msg_info("runSofa") << "GuiDataRepository paths = " << GuiDataRepository.getPathsJoined(); + msg_info("Modeler") << "PluginRepository paths = " << PluginRepository.getPathsJoined(); + msg_info("Modeler") << "DataRepository paths = " << DataRepository.getPathsJoined(); + msg_info("Modeler") << "GuiDataRepository paths = " << GuiDataRepository.getPathsJoined(); // Initialise paths BaseGUI::setConfigDirectoryPath(Utils::getSofaPathPrefix() + "/config", true); @@ -127,17 +127,17 @@ int main(int argc, char** argv) if (PluginRepository.findFile(configPluginPath, "", nullptr)) { - msg_info("runSofa") << "Loading automatically plugin list in " << configPluginPath; + msg_info("Modeler") << "Loading automatically plugin list in " << configPluginPath; PluginManager::getInstance().readFromIniFile(configPluginPath); } else if (PluginRepository.findFile(defaultConfigPluginPath, "", nullptr)) { - msg_info("runSofa") << "Loading automatically plugin list in " << defaultConfigPluginPath; + msg_info("Modeler") << "Loading automatically plugin list in " << defaultConfigPluginPath; PluginManager::getInstance().readFromIniFile(defaultConfigPluginPath); } else { - msg_info("runSofa") << "No plugin list found. No plugin will be automatically loaded."; + msg_info("Modeler") << "No plugin list found. No plugin will be automatically loaded."; } PluginManager::getInstance().init(); @@ -146,10 +146,8 @@ int main(int argc, char** argv) QApplication* application = new QApplication(argc, argv); (void)application; -// Q_INIT_RESOURCE(icons); sofa::gui::qt::SofaModeler* sofaModeler = new sofa::gui::qt::SofaModeler(); -// application->setMainWidget(sofaModeler); sofaModeler->show(); std::string binaryName=argv[0]; @@ -159,8 +157,6 @@ int main(int argc, char** argv) #endif if (!binaryName.empty() && binaryName[binaryName.size()-1] == 'd') sofaModeler->setDebugBinary(true); -// std::cerr << "DataRep :: " << sofa::helper::system::DataRepository.getFirstPath() <setWindowIcon(QIcon(pathIcon)); @@ -173,6 +169,5 @@ int main(int argc, char** argv) int appReturnCode = application->exec(); delete application; - application = nullptr; return appReturnCode; } diff --git a/applications/projects/Modeler/lib/GraphModeler.cpp b/applications/projects/Modeler/lib/GraphModeler.cpp index 788c8b29a0f..3b20969af1a 100644 --- a/applications/projects/Modeler/lib/GraphModeler.cpp +++ b/applications/projects/Modeler/lib/GraphModeler.cpp @@ -292,19 +292,7 @@ void GraphModeler::dropEvent(QDropEvent* event) graphListener->onBeginAddObject(getNode(event->pos()),newComponent.get()); if (newComponent) { - std::cerr << __FUNCTION__ << ":newComponent name : " << newComponent->getName() << std::endl; QTreeWidgetItem *after = graphListener->items[newComponent.get()]; - for(std::map ::const_iterator cit = graphListener->items.begin() ; cit != graphListener->items.end() ; cit++) - { - core::objectmodel::Base* bNode = cit->first; - QTreeWidgetItem* bItem = cit->second; - if(bNode && bItem) - { - std::cerr << __FUNCTION__ << ":Base Node Name : " << bNode->getName() << std::endl; - std::cerr << __FUNCTION__ << ":item name : " << bItem->text(0).toStdString() << std::endl; - } - } - std::ostringstream oss; oss << newComponent->getClassName() << " " << newComponent->getName(); after->setText(0, QString(oss.str().c_str())); @@ -317,31 +305,13 @@ void GraphModeler::dropEvent(QDropEvent* event) if (text == QString("Node")) { Node* node=getNode(event->pos()); - std::cerr << __FUNCTION__ << ":event pos node name : " << node->getName() << std::endl; if (node) { Node::SPtr newNode=addNode(node); - std::cerr << __FUNCTION__ << ":newNode name : " << newNode->getName() << std::endl; if (newNode) { QTreeWidgetItem *after = graphListener->items[newNode.get()]; QTreeWidgetItem *item = itemAt(event->pos()); - - for(std::map ::const_iterator cit = graphListener->items.begin() ; cit != graphListener->items.end() ; cit++) - { - core::objectmodel::Base* bNode = cit->first; - QTreeWidgetItem* bItem = cit->second; - if(bNode && bItem) - { - std::cerr << __FUNCTION__ << ":Base Node Name : " << bNode->getName() << std::endl; - std::cerr << __FUNCTION__ << ":item name : " << bItem->text(0).toStdString() << std::endl; - } - } - - if(after) - std::cerr << __FUNCTION__ << ":after name : " << after->text(0).toStdString() << std::endl; - if(item) - std::cerr << __FUNCTION__ << ":item name : " << item->text(0).toStdString() << std::endl; if (getObject(item)) initItem(after,item); } diff --git a/applications/projects/Modeler/lib/SofaModeler.cpp b/applications/projects/Modeler/lib/SofaModeler.cpp index 5ab9b66060c..c5d37faefe2 100644 --- a/applications/projects/Modeler/lib/SofaModeler.cpp +++ b/applications/projects/Modeler/lib/SofaModeler.cpp @@ -1083,7 +1083,6 @@ void SofaModeler::runInSofa() { if (sceneTab->count() == 0) return; Node* root=graph->getRoot(); - std::cerr << __FUNCTION__ << ": Graph File Name :: " << graph->getFilename() << std::endl; runInSofa(graph->getFilename(), root); } void SofaModeler::runInSofa( const std::string &sceneFilename, Node* root) @@ -1092,14 +1091,12 @@ void SofaModeler::runInSofa( const std::string &sceneFilename, Node* root) // Init the scene sofa::gui::common::GUIManager::Init("Modeler"); - //Saving the scene in a temporary file ==> doesn't modify the current Node of the simulation std::string path; if (sceneFilename.empty()) path=presetPath; else path = sofa::helper::system::SetDirectory::GetParentDir(sceneFilename.c_str())+std::string("/"); - std::string filename=/*path + std::string("temp") + (++count) + std::string(".scn")*/sceneFilename; -// sofa::simulation::node::exportInXML(root,filename.c_str()); + std::string filename=sceneFilename; //Make a copy of the .view if it exists for the current viewer const std::string &extension=sofa::helper::system::SetDirectory::GetExtension(sceneFilename.c_str()); @@ -1139,7 +1136,6 @@ void SofaModeler::runInSofa( const std::string &sceneFilename, Node* root) viewerExtension = ".view"; } - // msg_error("SofaModeler") << "viewFile = " << viewFile ; if ( sofa::helper::system::DataRepository.findFile ( viewFile ) ) { std::ifstream originalViewFile(viewFile.c_str()); @@ -1179,20 +1175,18 @@ void SofaModeler::runInSofa( const std::string &sceneFilename, Node* root) + QString(" "); //Setting the GUI - argv << "-g" << "qt"; - messageLaunch += QString("-g ") + QString("qt"); -// for (unsigned int i=0; iisChecked()) -// { -// if (std::string(listActionGUI[i]->text().toStdString()) != "default") -// { -// argv << "-g" << listActionGUI[i]->text(); -// messageLaunch += QString("-g ") + QString(listActionGUI[i]->text()); -// } -// break; -// } -// } + for (unsigned int i=0; iisChecked()) + { + if (std::string(listActionGUI[i]->text().toStdString()) != "default") + { + argv << "-g" << listActionGUI[i]->text(); + messageLaunch += QString("-g ") + QString(listActionGUI[i]->text()); + } + break; + } + } //retrive plugins typedef sofa::helper::system::PluginManager::PluginMap PluginMap; @@ -1205,21 +1199,12 @@ void SofaModeler::runInSofa( const std::string &sceneFilename, Node* root) messageLaunch += QString(" -l ") + QString((it->first).c_str()); } - -// argv << "-t"; - argv << QString::fromStdString(filename); messageLaunch += (" "+QString(filename.c_str())); - std::cerr << __FUNCTION__ << ": messageLaunch :: " << messageLaunch.toStdString() << std::endl; - -// qDebug() << "argv :: " << argv; - - QProcess *p = new QProcess(this); - p->setWorkingDirectory(QString(binPath.c_str()) ); p->setObjectName(QString(filename.c_str()) );