Develop with Sofa

Credit: Pengfei Xie
Minor modified: Wenqiang Xu

  • pre-built

    • 不推荐利用预编译进行开发。
    • 预编译版本以zip格式分发, lib 里面的一些软链接经过一番archive,基本上都损坏了,变成了pure txt。如果想修复这些软链接,可以利用下面提供的命令:
    •  find . -type f -size -40c -name 'lib*' | while read f; do ln -sf "$(cat $f)" "$f" done 
      
    • 还有一些别的地方的软链接也损坏了,需要自行修复。(踩了很多坑)
  • 自行编译

    • 选择一个合适的路径,给sofa安家
    • mkdir sofa
      git clone -b v22.06 https://github.com/sofa-framework/sofa sofa/src --depth=1
      
    • 接着,建立一个 build 文件夹并生成Makefile。此处,我们以sofa/build为例。
    • mkdir sofa/build && cd sofa/build
      cmake ../src
      
    • 此时有可能提示找不到glew: sudo apt install libglew-dev
    • 开始愉快的编译(自行修改thread数)
    • make -j8
      
    • 编译完之后,可以在sofa/build里看到编译好的东西。但此时还不能用,需要自行生成一个release(这里也踩了很多坑)。 此处索性直接防在sofa/build内:
    • cmake --install .
      
    • 此时可以看到出现了新的目录sofa/build/install。该目录大致长这个样子:
    • .
      ├── Authors.txt
      ├── bin
      ├── CHANGELOG.md
      ├── collections
      ├── config
      ├── etc
      ├── git-info.txt
      ├── include
      ├── lib
      ├── LICENSE.LGPL.txt
      ├── plugins
      ├── README.md
      ├── screenshots
      └── share
      
    • 其中,bin目录下包括了启动文件runSofainclude则包括了一些.h的header。
    • 此处还有个问题,先解决以防后患:sofa会尝试去找collections/SofaGui/bin/runSofa-22.06.00,然而编译过程中并没有把runSofa link过去,需要手动链接一下。
      install/collections/SofaGui先创建一个bin,cd bin,再:
    • ln -s ../../../bin/runSofa-22.06.00 runSofa-22.06.00
      
  • 项目目录配置

    • 此处以sofa_test为例。
    • CMakeLists.txt

      • list(APPEND CMAKE_PREFIX_PATH path_to/sofa/build/install/lib/cmake)
        include_directories(path_to/sofa/build/install/include)
        
        project(SofaTest)
        find_package(Sofa.Core)
        sofa_find_package(Sofa.Framework)
        sofa_find_package(Sofa.Simulation.Common)
        sofa_find_package(Sofa.Component)
        sofa_find_package(SofaGui)
        sofa_find_package(Sofa.GL.Component)
        sofa_find_package(Sofa.Simulation.Graph)
        
        
        add_executable(${PROJECT_NAME} Main.cpp)
        target_link_libraries(${PROJECT_NAME} Sofa.Core Sofa.Framework Sofa.Simulation.Common Sofa.Component Sofa.Simulation.Graph SofaGui Sofa.GL.Component)
        
      • 需要自行修改前两行的路径。
      • sofa经过了重构,以前的SofaComponentAll似乎不再起作用。引入Sofa.Core后,可以通过sofa_find_package引入别的包。
      • PS: find_package有时候能找到,有时候找不到,不知道为什么。索性全部用sofa_find_package
    • 插件

      • runSofa启动时会读取环境变量SOFA_PLUGIN_PATH SOFA_DATA_PATH GUI_DATA_PATH,如果没有设置环境变量,则默认为${pwd}/collections, …
      • 因此,我写了一个conf.env(或者改叫.profile可能更好)。
      • unset SOFA_PLUGIN_PATH SOFA_DATA_PATH GUI_DATA_PATH
        SOFA_PLUGIN_PATH=path_to/sofa/build/install/plugins:path_to/sofa/build/install/collections:path_to/sofa/build/install/lib
        SOFA_DATA_PATH=path_to/sofa/build/install/share:path_to/sofa/build/install/share/sofa:path_to/sofa/build/install/share/sofa/examples:path_to/sofa/build
        GUI_DATA_PATH=path_to/sofa/applications/projects/runSofa/resources:path_to/sofa/build:path_to/sofa/Sofa/GUI/Qt/src/sofa/gui/qt/resources
        export SOFA_PLUGIN_PATH SOFA_DATA_PATH GUI_DATA_PATH
        
        
      • 运行runSofa前,需要先source conf.env
        - 如果你用的是clion,在bash里对环境变量的改变对它无效,以上环境变量可以在代码里通过PluginRepository.addFirstPath(xxx)DataRepository.addFirstPath(xxx), GuiDataRepository.addFirstPath(xxx)的方式加入。
    • meshLoader

      • 还需修改meshLoader的path。getFile的第一个arg代表文件名,第二个arg代表文件所在路径。
      •     // MeshOBJLoader
            MeshOBJLoader::SPtr link1Loader = New<MeshOBJLoader>();
            link1Loader->setName("loader");
            link1Loader->setFilename(DataRepository.getFile(
                "link1.obj",
                "path_to/sofa_test/"
                "05c57920-0e3c-11ed-9d37-ec2e98c7e246/part_meshes"));
            link1Loader->d_handleSeams.setValue(1);
            link1Loader->load();
            link1->addObject(link1Loader);
        
  • 最后

    • 以上这些配置全是自己摸索的,有些环境变量的配置可能不太对,只是在我的机器上能跑了。