diff --git a/.github/workflows/continuous_integration.yml b/.github/workflows/continuous_integration.yml index 0da626a3fb..c8242285ed 100644 --- a/.github/workflows/continuous_integration.yml +++ b/.github/workflows/continuous_integration.yml @@ -31,11 +31,16 @@ jobs: echo "$env:GITHUB_WORKSPACE\\doxygen" >> $GITHUB_PATH - name: Install Python packages - # Need numpy to use SWIG numpy typemaps. + uses: actions/setup-python@v2 + with: + python-version: '3.7' + + - name: Install numpy + #Need numpy to use SWIG numpy typemaps. run: python -m pip install numpy - name: Install SWIG - run: choco install swig --version 3.0.12 --yes --limit-output + run: choco install swig --version 4.0.0 --yes --limit-output - name: Cache dependencies id: cache-dependencies @@ -157,7 +162,7 @@ jobs: - name: Install Homebrew packages # Save the gfortran version to a file so we can use it in the cache key. run: | - brew install cmake pkgconfig autoconf libtool automake wget pcre doxygen + brew install cmake pkgconfig autoconf libtool automake wget pcre doxygen python@3.7 brew reinstall gcc pip3 install numpy gfortran -v @@ -172,11 +177,11 @@ jobs: key: ${{ runner.os }}-swig - name: Install SWIG - if: steps.cache-swig.outputs.cache-hit != 'true' + # if: steps.cache-swig.outputs.cache-hit != 'true' run: | mkdir ~/swig-source && cd ~/swig-source - wget https://github.com/swig/swig/archive/rel-3.0.12.tar.gz - tar xzf rel-3.0.12.tar.gz && cd swig-rel-3.0.12 + wget https://github.com/swig/swig/archive/refs/tags/rel-4.0.2.tar.gz + tar xzf rel-4.0.2.tar.gz && cd swig-rel-4.0.2 sh autogen.sh && ./configure --prefix=$HOME/swig --disable-ccache make && make -j4 install @@ -300,8 +305,16 @@ jobs: - uses: actions/checkout@v1 - name: Install packages - run: sudo apt-get update && sudo apt-get install --yes build-essential libtool autoconf pkg-config gfortran libopenblas-dev liblapack-dev freeglut3-dev libxi-dev libxmu-dev doxygen python3 python3-dev python3-numpy python3-setuptools swig + run: sudo apt-get update && sudo apt-get install --yes build-essential libtool autoconf pkg-config gfortran libopenblas-dev liblapack-dev freeglut3-dev libxi-dev libxmu-dev doxygen python3 python3-dev python3-numpy python3-setuptools + - name: Install SWIG + # if: steps.cache-swig.outputs.cache-hit != 'true' + run: | + mkdir ~/swig-source && cd ~/swig-source + wget https://github.com/swig/swig/archive/refs/tags/rel-4.0.2.tar.gz + tar xzf rel-4.0.2.tar.gz && cd swig-rel-4.0.2 + sh autogen.sh && ./configure --prefix=$HOME/swig --disable-ccache + make && make -j4 install - name: Cache dependencies id: cache-dependencies uses: actions/cache@v1 @@ -333,6 +346,8 @@ jobs: OSIM_CMAKE_ARGS+=(-DOPENSIM_DEPENDENCIES_DIR=~/opensim_dependencies_install) OSIM_CMAKE_ARGS+=(-DOPENSIM_C3D_PARSER=ezc3d) OSIM_CMAKE_ARGS+=(-DBUILD_PYTHON_WRAPPING=on -DBUILD_JAVA_WRAPPING=on) + OSIM_CMAKE_ARGS+=(-DSWIG_DIR=~/swig/share/swig) + OSIM_CMAKE_ARGS+=(-DSWIG_EXECUTABLE=~/swig/bin/swig) OSIM_CMAKE_ARGS+=(-DOPENSIM_INSTALL_UNIX_FHS=OFF) OSIM_CMAKE_ARGS+=(-DOPENSIM_DOXYGEN_USE_MATHJAX=off) # TODO: Update to simbody.github.io/latest diff --git a/Bindings/CMakeLists.txt b/Bindings/CMakeLists.txt index 7b45eb2e5e..7395f83908 100644 --- a/Bindings/CMakeLists.txt +++ b/Bindings/CMakeLists.txt @@ -1,11 +1,5 @@ if(BUILD_PYTHON_WRAPPING OR BUILD_JAVA_WRAPPING) - # We require 3.0.8 for the reason mentioned here (for Python 3): - # https://github.com/tensorflow/tensorflow/issues/830 - find_package(SWIG 3.0.8 REQUIRED) - if(NOT (SWIG_VERSION VERSION_LESS "4.0.0") AND BUILD_JAVA_WRAPPING) - message(FATAL_ERROR - "SWIG version 4.0.0 and greater not yet supported for Java bindings.") - endif() + find_package(SWIG 4.0.0 REQUIRED) endif() # Flags are both Python and Java bindings will use. diff --git a/Bindings/Java/OpenSimJNI/CMakeLists.txt b/Bindings/Java/OpenSimJNI/CMakeLists.txt index e5c4d516b2..03dfe937cf 100644 --- a/Bindings/Java/OpenSimJNI/CMakeLists.txt +++ b/Bindings/Java/OpenSimJNI/CMakeLists.txt @@ -11,7 +11,7 @@ set_directory_properties(PROPERTIES COMPILE_OPTIONS "") function(OpenSimGenerateJavaWrapper NAME INPUT_INTERFACE_FILE OUTPUT_CXX_FILE OUTPUT_H_FILE) - set(_swig_common_args -c++ -java + set(_swig_common_args -c++ -java -doxygen -package ${OPENSIM_JAVA_WRAPPING_PACKAGE} -I${OpenSim_SOURCE_DIR} -I${OpenSim_SOURCE_DIR}/Bindings diff --git a/Bindings/Python/CMakeLists.txt b/Bindings/Python/CMakeLists.txt index 940f1aa66d..c9d402f4ce 100644 --- a/Bindings/Python/CMakeLists.txt +++ b/Bindings/Python/CMakeLists.txt @@ -73,7 +73,7 @@ macro(OpenSimAddPythonModule) # We run swig once to get dependencies and then again to actually generate # the wrappers. This variable holds the parts of the swig command that # are shared between both invocations. - set(_swig_common_args -c++ -python + set(_swig_common_args -c++ -python -doxygen -I${OpenSim_SOURCE_DIR} -I${OpenSim_SOURCE_DIR}/Bindings/ -I${Simbody_INCLUDE_DIR} @@ -95,6 +95,7 @@ macro(OpenSimAddPythonModule) #-debug-tmused # Which typemaps were used? -v # verbose -o ${_output_cxx_file} + -doxygen -outdir "${CMAKE_CURRENT_BINARY_DIR}" ${_swig_common_args} DEPENDS ${_${OSIMSWIGPY_MODULE}_dependencies} diff --git a/Bindings/SWIGSimTK/Rotation.h b/Bindings/SWIGSimTK/Rotation.h index 4c4da361ec..c177546f9b 100644 --- a/Bindings/SWIGSimTK/Rotation.h +++ b/Bindings/SWIGSimTK/Rotation.h @@ -518,10 +518,10 @@ class Rotation_ : public Mat<3, 3, P> { /// Theory: calculate qdot=N_P(q)*w_PB using multiplyByBodyXYZ_N_P(). /// @see multiplyByBodyXYZ_N_P() static Vec3 convertAngVelInParentToBodyXYZDot - (const Vec2& cosxy, ///< cos(qx), cos(qy) - const Vec2& sinxy, ///< sin(qx), sin(qy) - P oocosy, ///< 1/cos(qy) - const Vec3& w_PB) ///< angular velocity of B in P, exp. in P + (const Vec2& cosxy, //< cos(qx), cos(qy) + const Vec2& sinxy, //< sin(qx), sin(qy) + P oocosy, //< 1/cos(qy) + const Vec3& w_PB) //< angular velocity of B in P, exp. in P { return multiplyByBodyXYZ_N_P(cosxy,sinxy,oocosy,w_PB); } @@ -538,11 +538,11 @@ class Rotation_ : public Mat<3, 3, P> { /// efficiently. The second term is just an acceleration remainder term /// quadratic in qdot. static Vec3 convertAngAccInParentToBodyXYZDotDot - (const Vec2& cosxy, ///< cos(qx), cos(qy) - const Vec2& sinxy, ///< sin(qx), sin(qy) - P oocosy, ///< 1/cos(qy) - const Vec3& qdot, ///< previously calculated BodyXYZDot - const Vec3& b_PB) ///< angular acceleration, a.k.a. wdot_PB + (const Vec2& cosxy, //< cos(qx), cos(qy) + const Vec2& sinxy, //< sin(qx), sin(qy) + P oocosy, //< 1/cos(qy) + const Vec3& qdot, //< previously calculated BodyXYZDot + const Vec3& b_PB) //< angular acceleration, a.k.a. wdot_PB { const P s1 = sinxy[1], c1 = cosxy[1]; const P q0 = qdot[0], q1 = qdot[1], q2 = qdot[2]; @@ -1088,14 +1088,14 @@ class InverseRotation_ : public Mat<3,3,P>::TransposeType { #endif Rotation_

& operator~() { return updInvert(); } //@} - +#ifndef SWIG /// Access individual rows and columns of this InverseRotation; no cost or /// copying since suitably-cast references to the actual data are returned. /// There are no writable versions of these methods since changing a single /// row or column would violate the contract that these are always legitimate /// rotation matrices. //@{ -#ifndef SWIG + const RowType& row( int i ) const { return reinterpret_cast(asMat33()[i]); } const ColType& col( int j ) const { return reinterpret_cast(asMat33()(j)); } const ColType& x() const { return col(0); } @@ -1111,8 +1111,8 @@ class InverseRotation_ : public Mat<3,3,P>::TransposeType { //@{ const BaseMat& asMat33() const { return *static_cast(this); } BaseMat toMat33() const { return asMat33(); } -#endif //@} +#endif }; #ifndef SWIG diff --git a/Bindings/common.i b/Bindings/common.i index 0286dcc228..059ae953ea 100644 --- a/Bindings/common.i +++ b/Bindings/common.i @@ -133,19 +133,19 @@ namespace OpenSim { %shared_ptr(OpenSim::DataTable_); %shared_ptr(OpenSim::DataTable_); %shared_ptr(OpenSim::DataTable_); -%shared_ptr(OpenSim::DataTable_>); +%shared_ptr(OpenSim::DataTable_ >); %shared_ptr(OpenSim::DataTable_); %shared_ptr(OpenSim::DataTable_); %shared_ptr(OpenSim::DataTable_); -%shared_ptr(OpenSim::DataTable_>); +%shared_ptr(OpenSim::DataTable_ >); %shared_ptr(OpenSim::TimeSeriesTable_); %shared_ptr(OpenSim::TimeSeriesTable_); %shared_ptr(OpenSim::TimeSeriesTable_); -%shared_ptr(OpenSim::TimeSeriesTable_>); +%shared_ptr(OpenSim::TimeSeriesTable_ >); %shared_ptr(OpenSim::TimeSeriesTable_); %shared_ptr(OpenSim::TimeSeriesTable_); %shared_ptr(OpenSim::TimeSeriesTable_); -%shared_ptr(OpenSim::TimeSeriesTable_>); +%shared_ptr(OpenSim::TimeSeriesTable_ >); %ignore OpenSim::AbstractDataTable::clone; %ignore OpenSim::AbstractDataTable::getTableMetaData; %ignore OpenSim::AbstractDataTable::updTableMetaData; @@ -155,7 +155,7 @@ namespace OpenSim { %ignore OpenSim::AbstractDataTable::setDependentsMetaData; %ignore OpenSim::AbstractDataTable::setColumnLabels( const std::initializer_list&); -%template(StdVectorMatrix) std::vector>; +%template(StdVectorMatrix) std::vector >; %extend OpenSim::AbstractDataTable { void setColumnLabels(const std::vector& columnLabels) { $self->setColumnLabels(columnLabels); @@ -345,28 +345,27 @@ DATATABLE_CLONE(double, SimTK::Rotation_) %template(DataTable) OpenSim::DataTable_; %template(DataTableVec3) OpenSim::DataTable_; %template(DataTableUnitVec3) OpenSim::DataTable_; -%template(DataTableQuaternion) OpenSim::DataTable_>; +%template(DataTableQuaternion) OpenSim::DataTable_ >; %template(DataTableVec6) OpenSim::DataTable_; %template(DataTableSpatialVec) OpenSim::DataTable_; %template(DataTableMat33) OpenSim::DataTable_; -%template(DataTableRotation) OpenSim::DataTable_>; +%template(DataTableRotation) OpenSim::DataTable_ >; %template(TimeSeriesTable) OpenSim::TimeSeriesTable_; %template(TimeSeriesTableVec3) OpenSim::TimeSeriesTable_; %template(TimeSeriesTableUnitVec3) OpenSim::TimeSeriesTable_; %template(TimeSeriesTableQuaternion) - OpenSim::TimeSeriesTable_>; + OpenSim::TimeSeriesTable_ >; %template(TimeSeriesTableVec6) OpenSim::TimeSeriesTable_; %template(TimeSeriesTableSpatialVec) OpenSim::TimeSeriesTable_; %template(TimeSeriesTableMat33) OpenSim::TimeSeriesTable_; -%template(TimeSeriesTableRotation) OpenSim::TimeSeriesTable_>; +%template(TimeSeriesTableRotation) OpenSim::TimeSeriesTable_ >; %include %template(StdVectorEvent) std::vector; -%template(StdMapStringTimeSeriesTableVec3) - std::map>>; +%shared_ptr(OpenSim::TimeSeriesTableVec3) + %shared_ptr(OpenSim::DataAdapter) %shared_ptr(OpenSim::FileAdapter) %shared_ptr(OpenSim::DelimFileAdapter) @@ -383,9 +382,13 @@ DATATABLE_CLONE(double, SimTK::Rotation_) %shared_ptr(OpenSim::TRCFileAdapter) %shared_ptr(OpenSim::C3DFileAdapter) %template(StdMapStringDataAdapter) - std::map>; + std::map >; %template(StdMapStringAbstractDataTable) - std::map>; + std::map >; +//%template(StdMapStringTimeSeriesTableVec3) +// std::map > >; + + %include %include %include diff --git a/Bindings/simulation.i b/Bindings/simulation.i index 6ba6669e79..ec138f186c 100644 --- a/Bindings/simulation.i +++ b/Bindings/simulation.i @@ -269,12 +269,42 @@ OpenSim::ModelComponentSet; %template(ActuatorList) OpenSim::ComponentList; %template(ActuatorIterator) OpenSim::ComponentListIterator; -%template(getFrameList) OpenSim::Model::getComponentList; -%template(getBodyList) OpenSim::Model::getComponentList; -%template(getMuscleList) OpenSim::Model::getComponentList; -%template(getModelComponentList) OpenSim::Model::getComponentList; -%template(getJointList) OpenSim::Model::getComponentList; -%template(getActuatorList) OpenSim::Model::getComponentList; +%template(Thelen2003MuscleList) + OpenSim::ComponentList; +%template(Thelen2003MuscleIterator) + OpenSim::ComponentListIterator; + +%template(Millard2012EquilibriumMuscleList) + OpenSim::ComponentList; +%template(Millard2012EquilibriumMuscleIterator) + OpenSim::ComponentListIterator; + +%extend OpenSim::Model { + OpenSim::ComponentList getFrameList(){ + return $self->getComponentList(); + } + OpenSim::ComponentList getBodyList(){ + return $self->getComponentList(); + } + OpenSim::ComponentList getMuscleList(){ + return $self->getComponentList(); + } + OpenSim::ComponentList getJointList(){ + return $self->getComponentList(); + } + OpenSim::ComponentList getActuatorList(){ + return $self->getComponentList(); + } + OpenSim::ComponentList getModelComponentList(){ + return $self->getComponentList(); + } + OpenSim::ComponentList getThelen2003MuscleList(){ + return $self->getComponentList(); + } + OpenSim::ComponentList getMillard2012EquilibriumMuscleList(){ + return $self->getComponentList(); + } +} %include %include @@ -289,20 +319,6 @@ OpenSim::ModelComponentSet; %include %include -%template(Thelen2003MuscleList) - OpenSim::ComponentList; -%template(Thelen2003MuscleIterator) - OpenSim::ComponentListIterator; - -%template(Millard2012EquilibriumMuscleList) - OpenSim::ComponentList; -%template(Millard2012EquilibriumMuscleIterator) - OpenSim::ComponentListIterator; - -%template(getThelen2003MuscleList) - OpenSim::Model::getComponentList; -%template(getMillard2012EquilibriumMuscleList) - OpenSim::Model::getComponentList; // Compensate for insufficient C++11 support in SWIG // ================================================= diff --git a/OpenSim/Actuators/ModelFactory.h b/OpenSim/Actuators/ModelFactory.h index b18c8ce2f9..c680841710 100644 --- a/OpenSim/Actuators/ModelFactory.h +++ b/OpenSim/Actuators/ModelFactory.h @@ -19,7 +19,6 @@ * -------------------------------------------------------------------------- */ #include "osimActuatorsDLL.h" - #include namespace OpenSim { @@ -91,7 +90,6 @@ class OSIMACTUATORS_API ModelFactory { double bound = SimTK::NaN, bool skipCoordinatesWithExistingActuators = true); - /// @} }; } // namespace OpenSim diff --git a/OpenSim/Common/C3DFileAdapter.cpp b/OpenSim/Common/C3DFileAdapter.cpp index 4aaf377e2c..bf8fe6afdc 100644 --- a/OpenSim/Common/C3DFileAdapter.cpp +++ b/OpenSim/Common/C3DFileAdapter.cpp @@ -80,8 +80,8 @@ C3DFileAdapter::clone() const { return new C3DFileAdapter{*this}; } -void -C3DFileAdapter::write(const C3DFileAdapter::Tables& tables, +void C3DFileAdapter::write( + const C3DFileAdapter::Tables& tables, const std::string& fileName) { OPENSIM_THROW(Exception, "Writing C3D not supported yet."); } diff --git a/OpenSim/Common/C3DFileAdapter.h b/OpenSim/Common/C3DFileAdapter.h index f31cfc6050..fed6fbd5ed 100644 --- a/OpenSim/Common/C3DFileAdapter.h +++ b/OpenSim/Common/C3DFileAdapter.h @@ -117,13 +117,17 @@ class OSIMCOMMON_API C3DFileAdapter : public FileAdapter { return _location; } +#ifndef SWIG static void write(const Tables& markerTable, const std::string& fileName); +#endif + /** Retrieve the TimeSeriesTableVec3 of Markers */ std::shared_ptr getMarkersTable(DataAdapter::OutputTables& tables) { std::shared_ptr& adt = tables.at("markers"); return std::dynamic_pointer_cast(adt); } + /** Retrieve the TimeSeriesTableVec3 of Forces */ std::shared_ptr getForcesTable(DataAdapter::OutputTables& tables) { std::shared_ptr& adt = tables.at("forces"); diff --git a/OpenSim/Common/Property.h b/OpenSim/Common/Property.h index 33994001f8..7a5122214e 100644 --- a/OpenSim/Common/Property.h +++ b/OpenSim/Common/Property.h @@ -577,7 +577,9 @@ class Property : public AbstractProperty { Property(Property&&) = default; Property& operator=(const Property&) = default; Property& operator=(Property&&) = default; - /** @cond **/ // Hide from Doxygen. +#ifndef SWIG + /** @cond **/ + // Hide from Doxygen. // This is the interface that SimpleProperty and ObjectProperty must // implement. // Base class verifies that 0 <= index < size(), and for append operations @@ -588,6 +590,7 @@ class Property : public AbstractProperty { virtual int appendValueVirtual(const T& value) = 0; virtual int adoptAndAppendValueVirtual(T* value) = 0; /** @endcond **/ +#endif }; diff --git a/OpenSim/Moco/MocoStudyFactory.h b/OpenSim/Moco/MocoStudyFactory.h index 99b92f7479..fd854f5de7 100644 --- a/OpenSim/Moco/MocoStudyFactory.h +++ b/OpenSim/Moco/MocoStudyFactory.h @@ -32,8 +32,8 @@ class OSIMMOCO_API MocoStudyFactory { /// LinearTangentFinalSpeed. This function is intended for use in testing. /// This problem has an analytical solution, and /// is described in Section 2.4 of Bryson and Ho [1]. Bryson, A. E., Ho, - /// Y.‐C., Applied Optimal Control, Optimization, Estimation, and Control. - /// New York‐London‐Sydney‐Toronto. John Wiley & Sons. 1975. + /// Y.C., Applied Optimal Control, Optimization, Estimation, and Control. + /// New York London Sydney Toronto. John Wiley & Sons. 1975. static MocoStudy createLinearTangentSteeringStudy( double acceleration, double finalTime, double finalHeight); }; diff --git a/OpenSim/Simulation/StatesTrajectory.h b/OpenSim/Simulation/StatesTrajectory.h index 69195660b5..7be03edf04 100644 --- a/OpenSim/Simulation/StatesTrajectory.h +++ b/OpenSim/Simulation/StatesTrajectory.h @@ -476,7 +476,6 @@ class OSIMSIMULATION_API StatesTrajectory { * default values for `allowMissingColumns` and `allowExtraColumns`. */ static StatesTrajectory createFromStatesStorage(const Model& model, const std::string& filepath); - /// @} }; } // namespace diff --git a/OpenSim/Tools/InverseKinematicsTool.h b/OpenSim/Tools/InverseKinematicsTool.h index f8ed9c3159..e0530d7ef5 100644 --- a/OpenSim/Tools/InverseKinematicsTool.h +++ b/OpenSim/Tools/InverseKinematicsTool.h @@ -106,15 +106,17 @@ class OSIMTOOLS_API InverseKinematicsTool : public InverseKinematicsToolBase { // INTERFACE //-------------------------------------------------------------------------- bool run() override SWIG_DECLARE_EXCEPTION; - +#ifndef SWIG /** @cond **/ // hide from Doxygen +#endif // For testing/debugging it is necessary to know exactly what are the // MarkersReference (set of marker trajectories and their weights) and // CoordinateReferences that are being used by the InverseKinematicsSolver. void populateReferences(MarkersReference& markersReference, SimTK::Array_&coordinateReferences) const; +#ifndef SWIG /** @endcond **/ - +#endif private: void constructProperties();