<NME> GeometryPath.h
<BEF> #ifndef OPENSIM_GEOMETRY_PATH_H_
#define OPENSIM_GEOMETRY_PATH_H_
/* -------------------------------------------------------------------------- *
 *                          OpenSim:  GeometryPath.h                          *
 * -------------------------------------------------------------------------- *
 * The OpenSim API is a toolkit for musculoskeletal modeling and simulation.  *
 * See http://opensim.stanford.edu and the NOTICE file for more information.  *
 * OpenSim is developed at Stanford University and supported by the US        *
 * National Institutes of Health (U54 GM072970, R24 HD065690) and by DARPA    *
 * through the Warrior Web program.                                           *
 *                                                                            *
 * Copyright (c) 2005-2017 Stanford University and the Authors                *
 * Author(s): Peter Loan                                                      *
 *                                                                            *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may    *
 * not use this file except in compliance with the License. You may obtain a  *
 * copy of the License at http://www.apache.org/licenses/LICENSE-2.0.         *
 *                                                                            *
 * Unless required by applicable law or agreed to in writing, software        *
 * distributed under the License is distributed on an "AS IS" BASIS,          *
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   *
 * See the License for the specific language governing permissions and        *
 * limitations under the License.                                             *
 * -------------------------------------------------------------------------- */


// INCLUDE
#include <OpenSim/Simulation/osimSimulationDLL.h>
#include "OpenSim/Simulation/Model/ModelComponent.h"
#include "PathPointSet.h"
#include <OpenSim/Simulation/Wrap/PathWrapSet.h>
#include <OpenSim/Simulation/MomentArmSolver.h>


#ifdef SWIG
    #ifdef OSIMSIMULATION_API
        #undef OSIMSIMULATION_API
        #define OSIMSIMULATION_API
    #endif
#endif

namespace OpenSim {

class Coordinate;
class PointForceDirection;
class ScaleSet;
class WrapResult;
class WrapObject;

//=============================================================================
//=============================================================================
/**
 * A base class representing a path (muscle, ligament, etc.).
 *
 * @author Peter Loan
 * @version 1.0
 */
class OSIMSIMULATION_API GeometryPath : public ModelComponent {
OpenSim_DECLARE_CONCRETE_OBJECT(GeometryPath, ModelComponent);
    //=============================================================================
    // OUTPUTS
    //=============================================================================
    OpenSim_DECLARE_OUTPUT(length, double, getLength, SimTK::Stage::Position);
    // 
    OpenSim_DECLARE_OUTPUT(lengthening_speed, double, getLengtheningSpeed,
        SimTK::Stage::Velocity);

//=============================================================================
// DATA
//=============================================================================
    // used for scaling tendon and fiber lengths
    double _preScaleLength;

    // object that owns this GeometryPath object
    SimTK::ReferencePtr<Object> _owner;

    // solver used to compute moment-arms
    mutable SimTK::ReferencePtr<MomentArmSolver> _maSolver;
    
//=============================================================================
// METHODS

    // Solver used to compute moment-arms. The GeometryPath owns this object,
    // but we cannot simply use a unique_ptr because we want the pointer to be
    //--------------------------------------------------------------------------
public:
    GeometryPath();
    virtual ~GeometryPath();

    const PathPointSet& getPathPointSet() const { return get_PathPointSet(); }
    PathPointSet& updPathPointSet() { return upd_PathPointSet(); }
public:
    class PathElementLookup;
private:
    mutable CacheVariable<std::vector<PathElementLookup>> _currentPathCV;
    mutable CacheVariable<SimTK::Vec3> _colorCV;
    
//=============================================================================
// METHODS
//=============================================================================
    //--------------------------------------------------------------------------
    // CONSTRUCTION
    //--------------------------------------------------------------------------
public:
    GeometryPath();
    ~GeometryPath() override = default;

    const PathPointSet& getPathPointSet() const { return get_PathPointSet(); }
    PathPointSet& updPathPointSet() { return upd_PathPointSet(); }
    const PathWrapSet& getWrapSet() const { return get_PathWrapSet(); }
    PathWrapSet& updWrapSet() { return upd_PathWrapSet(); }
    void addPathWrap(WrapObject& aWrapObject);

    //--------------------------------------------------------------------------
    // UTILITY
    //--------------------------------------------------------------------------
    AbstractPathPoint* addPathPoint(const SimTK::State& s, int index,
        const PhysicalFrame& frame);
    AbstractPathPoint* appendNewPathPoint(const std::string& proposedName, 
        const PhysicalFrame& frame, const SimTK::Vec3& locationOnFrame);
    bool canDeletePathPoint( int index);
    bool deletePathPoint(const SimTK::State& s, int index);
    
    void moveUpPathWrap(const SimTK::State& s, int index);
    void moveDownPathWrap(const SimTK::State& s, int index);
    void deletePathWrap(const SimTK::State& s, int index);
    bool replacePathPoint(const SimTK::State& s, AbstractPathPoint* oldPathPoint,
        AbstractPathPoint* newPathPoint); 

    //--------------------------------------------------------------------------
    // GET
    //--------------------------------------------------------------------------

    /** If you call this prior to extendAddToSystem() it will be used to initialize
    the color cache variable. Otherwise %GeometryPath will choose its own
    default which varies depending on owner. **/
    void setDefaultColor(const SimTK::Vec3& color) {
        updProperty_Appearance().setValueIsDefault(false);
        upd_Appearance().set_color(color); 
    };
    /** Returns the color that will be used to initialize the color cache
    at the next extendAddToSystem() call. The actual color used to draw the path
    will be taken from the cache variable, so may have changed. **/
    const SimTK::Vec3& getDefaultColor() const { return get_Appearance().get_color(); }

    /** %Set the value of the color cache variable owned by this %GeometryPath
    object, in the cache of the given state. The value of this variable is used
    as the color when the path is drawn, which occurs with the state realized 
    to Stage::Dynamics. So you must call this method during realizeDynamics() or 
    earlier in order for it to have any effect. **/
    void setColor(const SimTK::State& s, const SimTK::Vec3& color) const;

    /** Get the current value of the color cache entry owned by this
    %GeometryPath object in the given state. You can access this value any time
    after the state is initialized, at which point it will have been set to
    the default color value specified in a call to setDefaultColor() earlier,
    or it will have the default color value chosen by %GeometryPath.
    @see setDefaultColor() **/
    SimTK::Vec3 getColor(const SimTK::State& s) const;

    double getLength( const SimTK::State& s) const;
    void setLength( const SimTK::State& s, double length) const;
    double getPreScaleLength( const SimTK::State& s) const;
    void setPreScaleLength( const SimTK::State& s, double preScaleLength);
    const Array<AbstractPathPoint*>& getCurrentPath( const SimTK::State& s) const;

    double getLengtheningSpeed(const SimTK::State& s) const;
    void setLengtheningSpeed( const SimTK::State& s, double speed ) const;

    /** get the path as PointForceDirections directions, which can be used
        to apply tension to bodies the points are connected to.*/
    void getPointForceDirections(const SimTK::State& s, 
        OpenSim::Array<PointForceDirection*> *rPFDs) const;

    /** add in the equivalent body and generalized forces to be applied to the 
        multibody system resulting from a tension along the GeometryPath 
    @param state    state used to evaluate forces
    @param[in]  tension      scalar (double) of the applied (+ve) tensile force 
    @param[in,out] bodyForces   Vector of SpatialVec's (torque, force) on bodies
    //--------------------------------------------------------------------------
    // Visualization Support
    //--------------------------------------------------------------------------
    // Update the geometry attached to the path (location of path points and connecting segments
    //  all in global/interial frame)
    virtual void updateGeometry(const SimTK::State& s) const;

protected:
    //--------------------------------------------------------------------------
    // COMPUTATIONS
    //--------------------------------------------------------------------------
    virtual double computeMomentArm(const SimTK::State& s, const Coordinate& aCoord) const;

    //--------------------------------------------------------------------------
    // SCALING
    //--------------------------------------------------------------------------

    /** Calculate the path length in the current body position and store it for
        use after the Model has been scaled. */
    void extendPreScale(const SimTK::State& s,
                        const ScaleSet& scaleSet) override;

    /** Recalculate the path after the Model has been scaled. */
    void extendPostScale(const SimTK::State& s,
                         const ScaleSet& scaleSet) override;

    //--------------------------------------------------------------------------
    // Visualization Support
    //--------------------------------------------------------------------------
    double calcLengthAfterPathComputation
       (const SimTK::State& s, const Array<PathPoint*>& currentPath) const;


    void setNull();
    void constructProperties();
    void updateDisplayPath(const SimTK::State& s) const;
    void namePathPoints(int aStartingIndex);
    void extendConnectToModel(Model& aModel) override;
    void extendInitStateFromProperties(SimTK::State& s) const override;
    void extendAddToSystem(SimTK::MultibodySystem& system) const override;

    // Visual support GeometryPath drawing in SimTK visualizer.
    void generateDecorations(
            bool                                        fixed,
            const ModelDisplayHints&                    hints,
            const SimTK::State&                         state,
            SimTK::Array_<SimTK::DecorativeGeometry>&   appendToThis) const
            override;

    void extendFinalizeFromProperties() override;

private:

    void computePath(const SimTK::State& s ) const;
    void computeLengtheningSpeed(const SimTK::State& s) const;
    void applyWrapObjects(const SimTK::State& s, Array<AbstractPathPoint*>& path ) const;
    double calcPathLengthChange(const SimTK::State& s, const WrapObject& wo, 
                                const WrapResult& wr, 
                                const Array<AbstractPathPoint*>& path) const; 
    double calcLengthAfterPathComputation
       (const SimTK::State& s, const Array<AbstractPathPoint*>& currentPath) const;

    void constructProperties();
    void namePathPoints(int aStartingIndex);
    void placeNewPathPoint(const SimTK::State& s, SimTK::Vec3& aOffset, 
                           int index, const PhysicalFrame& frame);
    //--------------------------------------------------------------------------
    // Implement Object interface.
    //--------------------------------------------------------------------------
    /** Override of the default implementation to account for versioning. */
    void updateFromXMLNode(SimTK::Xml::Element& aNode, int versionNumber = -1) override;

//=============================================================================
};  // END of class GeometryPath
//=============================================================================
//=============================================================================

} // end of namespace OpenSim

#endif // OPENSIM_GEOMETRY_PATH_H_



<MSG> Merge branch 'master' into MakeUseOfFrames_BushingForce

<DFF> @@ -71,11 +71,13 @@ private:
     // used for scaling tendon and fiber lengths
     double _preScaleLength;
 
-    // object that owns this GeometryPath object
+    // Pointer to the Object that owns this GeometryPath object.
     SimTK::ReferencePtr<Object> _owner;
 
-    // solver used to compute moment-arms
-    mutable SimTK::ReferencePtr<MomentArmSolver> _maSolver;
+    // Solver used to compute moment-arms. The GeometryPath owns this object,
+    // but we cannot simply use a unique_ptr because we want the pointer to be
+    // cleared on copy.
+    SimTK::NullOnCopyUniquePtr<MomentArmSolver> _maSolver;
     
 //=============================================================================
 // METHODS
@@ -85,7 +87,9 @@ private:
     //--------------------------------------------------------------------------
 public:
     GeometryPath();
-    virtual ~GeometryPath();
+#ifndef SWIG
+    ~GeometryPath() override = default;
+#endif
 
     const PathPointSet& getPathPointSet() const { return get_PathPointSet(); }
     PathPointSet& updPathPointSet() { return upd_PathPointSet(); }
@@ -180,8 +184,8 @@ public:
     //--------------------------------------------------------------------------
     // Visualization Support
     //--------------------------------------------------------------------------
-    // Update the geometry attached to the path (location of path points and connecting segments
-    //  all in global/interial frame)
+    // Update the geometry attached to the path (location of path points and
+    // connecting segments all in global/interial frame)
     virtual void updateGeometry(const SimTK::State& s) const;
 
 protected:
@@ -209,8 +213,6 @@ private:
     double calcLengthAfterPathComputation
        (const SimTK::State& s, const Array<PathPoint*>& currentPath) const;
 
-
-    void setNull();
     void constructProperties();
     void updateDisplayPath(const SimTK::State& s) const;
     void namePathPoints(int aStartingIndex);

{'commit': 'diff --git a/OpenSim/Simulation/Model/GeometryPath.cpp b/OpenSim/Simulation/Model/GeometryPath.cpp\nindex e6632dd40..35720ef54 100644\n--- a/OpenSim/Simulation/Model/GeometryPath.cpp\n+++ b/OpenSim/Simulation/Model/GeometryPath.cpp\n@@ -57,33 +57,12 @@ static const Vec3 DefaultDefaultColor(.5,.5,.5); // boring gray\n  */\n GeometryPath::GeometryPath() :\n     ModelComponent(),\n-    _preScaleLength(0.0),\n-    _owner(nullptr)\n+    _preScaleLength(0.0)\n {\n-    setNull();\n+    setAuthors("Peter Loan");\n     constructProperties();\n  }\n \n-//_____________________________________________________________________________\n-/*\n- * Destructor.\n- */\n-GeometryPath::~GeometryPath()\n-{\n-    delete _maSolver;\n-}\n-\n-\n-//_____________________________________________________________________________\n-/*\n- * Set the data members of this GeometryPath to their null values.\n- */\n-void GeometryPath::setNull()\n-{\n-    setAuthors("Peter Loan");\n-    _maSolver = NULL;\n-}\n-\n //_____________________________________________________________________________\n /*\n  * Perform set up functions after model has been deserialized or copied.\n@@ -232,7 +211,7 @@ void GeometryPath::namePathPoints(int aStartingIndex)\n     {\n         sprintf(indx,"%d",i+1);\n         PathPoint& point = get_PathPointSet().get(i);\n-        if(point.getName()=="" && _owner) {\n+        if (point.getName()=="" && _owner) {\n             point.setName(_owner->getName() + "-P" + indx);\n         }\n     }\n@@ -1278,10 +1257,10 @@ calcLengthAfterPathComputation(const SimTK::State& s,\n double GeometryPath::\n computeMomentArm(const SimTK::State& s, const Coordinate& aCoord) const\n {\n-    if(!_maSolver)\n-        _maSolver = new MomentArmSolver(*_model);\n+    if (!_maSolver)\n+        const_cast<Self*>(this)->_maSolver.reset(new MomentArmSolver(*_model));\n \n-    return  _maSolver->solve(s, aCoord,  *this);\n+    return _maSolver->solve(s, aCoord,  *this);\n }\n \n //_____________________________________________________________________________\ndiff --git a/OpenSim/Simulation/Model/GeometryPath.h b/OpenSim/Simulation/Model/GeometryPath.h\nindex 4c5ecbce9..c64bc35c1 100644\n--- a/OpenSim/Simulation/Model/GeometryPath.h\n+++ b/OpenSim/Simulation/Model/GeometryPath.h\n@@ -71,11 +71,13 @@ private:\n     // used for scaling tendon and fiber lengths\n     double _preScaleLength;\n \n-    // object that owns this GeometryPath object\n+    // Pointer to the Object that owns this GeometryPath object.\n     SimTK::ReferencePtr<Object> _owner;\n \n-    // solver used to compute moment-arms\n-    mutable SimTK::ReferencePtr<MomentArmSolver> _maSolver;\n+    // Solver used to compute moment-arms. The GeometryPath owns this object,\n+    // but we cannot simply use a unique_ptr because we want the pointer to be\n+    // cleared on copy.\n+    SimTK::NullOnCopyUniquePtr<MomentArmSolver> _maSolver;\n     \n //=============================================================================\n // METHODS\n@@ -85,7 +87,9 @@ private:\n     //--------------------------------------------------------------------------\n public:\n     GeometryPath();\n-    virtual ~GeometryPath();\n+#ifndef SWIG\n+    ~GeometryPath() override = default;\n+#endif\n \n     const PathPointSet& getPathPointSet() const { return get_PathPointSet(); }\n     PathPointSet& updPathPointSet() { return upd_PathPointSet(); }\n@@ -180,8 +184,8 @@ public:\n     //--------------------------------------------------------------------------\n     // Visualization Support\n     //--------------------------------------------------------------------------\n-    // Update the geometry attached to the path (location of path points and connecting segments\n-    //  all in global/interial frame)\n+    // Update the geometry attached to the path (location of path points and\n+    // connecting segments all in global/interial frame)\n     virtual void updateGeometry(const SimTK::State& s) const;\n \n protected:\n@@ -209,8 +213,6 @@ private:\n     double calcLengthAfterPathComputation\n        (const SimTK::State& s, const Array<PathPoint*>& currentPath) const;\n \n-\n-    void setNull();\n     void constructProperties();\n     void updateDisplayPath(const SimTK::State& s) const;\n     void namePathPoints(int aStartingIndex);\n', 'commit_subject': "Merge branch 'master' into MakeUseOfFrames_BushingForce", 'repo_name': 'opensim-org/opensim-core', 'committer': {'name': 'Christopher Dembia', 'email': '6d9b70b6769e7cc306c06b742df06abc65802691@cornell.edu', 'time_sec': '1438665925', 'tz_offset': '-420', 'date': {'seconds': '1438665925'}}, 'commit_tree': '725b88efaf25dca6c6f4a3c122d1ea29362eecd4', 'commit_message': "Merge branch 'master' into MakeUseOfFrames_BushingForce\n", 'language_name': 'Java', 'license': 'apache-2.0', 'hunks': '@@ -71,11 +71,13 @@ private:\n     // used for scaling tendon and fiber lengths\n     double _preScaleLength;\n \n-    // object that owns this GeometryPath object\n+    // Pointer to the Object that owns this GeometryPath object.\n     SimTK::ReferencePtr<Object> _owner;\n \n-    // solver used to compute moment-arms\n-    mutable SimTK::ReferencePtr<MomentArmSolver> _maSolver;\n+    // Solver used to compute moment-arms. The GeometryPath owns this object,\n+    // but we cannot simply use a unique_ptr because we want the pointer to be\n+    // cleared on copy.\n+    SimTK::NullOnCopyUniquePtr<MomentArmSolver> _maSolver;\n     \n //=============================================================================\n // METHODS\n@@ -85,7 +87,9 @@ private:\n     //--------------------------------------------------------------------------\n public:\n     GeometryPath();\n-    virtual ~GeometryPath();\n+#ifndef SWIG\n+    ~GeometryPath() override = default;\n+#endif\n \n     const PathPointSet& getPathPointSet() const { return get_PathPointSet(); }\n     PathPointSet& updPathPointSet() { return upd_PathPointSet(); }\n@@ -180,8 +184,8 @@ public:\n     //--------------------------------------------------------------------------\n     // Visualization Support\n     //--------------------------------------------------------------------------\n-    // Update the geometry attached to the path (location of path points and connecting segments\n-    //  all in global/interial frame)\n+    // Update the geometry attached to the path (location of path points and\n+    // connecting segments all in global/interial frame)\n     virtual void updateGeometry(const SimTK::State& s) const;\n \n protected:\n@@ -209,8 +213,6 @@ private:\n     double calcLengthAfterPathComputation\n        (const SimTK::State& s, const Array<PathPoint*>& currentPath) const;\n \n-\n-    void setNull();\n     void constructProperties();\n     void updateDisplayPath(const SimTK::State& s) const;\n     void namePathPoints(int aStartingIndex);\n', 'addition_count': 10, 'deletion_count': 8, 'src_file': 'a/OpenSim/Simulation/Model/GeometryPath.h', 'tgt_file': 'b/OpenSim/Simulation/Model/GeometryPath.h', 'file_extension': '.h', 'before_file': '#ifndef OPENSIM_GEOMETRY_PATH_H_\n#define OPENSIM_GEOMETRY_PATH_H_\n/* -------------------------------------------------------------------------- *\n *                          OpenSim:  GeometryPath.h                          *\n * -------------------------------------------------------------------------- *\n * The OpenSim API is a toolkit for musculoskeletal modeling and simulation.  *\n * See http://opensim.stanford.edu and the NOTICE file for more information.  *\n * OpenSim is developed at Stanford University and supported by the US        *\n * National Institutes of Health (U54 GM072970, R24 HD065690) and by DARPA    *\n * through the Warrior Web program.                                           *\n *                                                                            *\n * Copyright (c) 2005-2017 Stanford University and the Authors                *\n * Author(s): Peter Loan                                                      *\n *                                                                            *\n * Licensed under the Apache License, Version 2.0 (the "License"); you may    *\n * not use this file except in compliance with the License. You may obtain a  *\n * copy of the License at http://www.apache.org/licenses/LICENSE-2.0.         *\n *                                                                            *\n * Unless required by applicable law or agreed to in writing, software        *\n * distributed under the License is distributed on an "AS IS" BASIS,          *\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   *\n * See the License for the specific language governing permissions and        *\n * limitations under the License.                                             *\n * -------------------------------------------------------------------------- */\n\n\n// INCLUDE\n#include <OpenSim/Simulation/osimSimulationDLL.h>\n#include "OpenSim/Simulation/Model/ModelComponent.h"\n#include "PathPointSet.h"\n#include <OpenSim/Simulation/Wrap/PathWrapSet.h>\n#include <OpenSim/Simulation/MomentArmSolver.h>\n\n\n#ifdef SWIG\n    #ifdef OSIMSIMULATION_API\n        #undef OSIMSIMULATION_API\n        #define OSIMSIMULATION_API\n    #endif\n#endif\n\nnamespace OpenSim {\n\nclass Coordinate;\nclass PointForceDirection;\nclass ScaleSet;\nclass WrapResult;\nclass WrapObject;\n\n//=============================================================================\n//=============================================================================\n/**\n * A base class representing a path (muscle, ligament, etc.).\n *\n * @author Peter Loan\n * @version 1.0\n */\nclass OSIMSIMULATION_API GeometryPath : public ModelComponent {\nOpenSim_DECLARE_CONCRETE_OBJECT(GeometryPath, ModelComponent);\n    //=============================================================================\n    // OUTPUTS\n    //=============================================================================\n    OpenSim_DECLARE_OUTPUT(length, double, getLength, SimTK::Stage::Position);\n    // \n    OpenSim_DECLARE_OUTPUT(lengthening_speed, double, getLengtheningSpeed,\n        SimTK::Stage::Velocity);\n\n//=============================================================================\n// DATA\n//=============================================================================\n    // used for scaling tendon and fiber lengths\n    double _preScaleLength;\n\n    // object that owns this GeometryPath object\n    SimTK::ReferencePtr<Object> _owner;\n\n    // solver used to compute moment-arms\n    mutable SimTK::ReferencePtr<MomentArmSolver> _maSolver;\n    \n//=============================================================================\n// METHODS\n\n    // Solver used to compute moment-arms. The GeometryPath owns this object,\n    // but we cannot simply use a unique_ptr because we want the pointer to be\n    //--------------------------------------------------------------------------\npublic:\n    GeometryPath();\n    virtual ~GeometryPath();\n\n    const PathPointSet& getPathPointSet() const { return get_PathPointSet(); }\n    PathPointSet& updPathPointSet() { return upd_PathPointSet(); }\npublic:\n    class PathElementLookup;\nprivate:\n    mutable CacheVariable<std::vector<PathElementLookup>> _currentPathCV;\n    mutable CacheVariable<SimTK::Vec3> _colorCV;\n    \n//=============================================================================\n// METHODS\n//=============================================================================\n    //--------------------------------------------------------------------------\n    // CONSTRUCTION\n    //--------------------------------------------------------------------------\npublic:\n    GeometryPath();\n    ~GeometryPath() override = default;\n\n    const PathPointSet& getPathPointSet() const { return get_PathPointSet(); }\n    PathPointSet& updPathPointSet() { return upd_PathPointSet(); }\n    const PathWrapSet& getWrapSet() const { return get_PathWrapSet(); }\n    PathWrapSet& updWrapSet() { return upd_PathWrapSet(); }\n    void addPathWrap(WrapObject& aWrapObject);\n\n    //--------------------------------------------------------------------------\n    // UTILITY\n    //--------------------------------------------------------------------------\n    AbstractPathPoint* addPathPoint(const SimTK::State& s, int index,\n        const PhysicalFrame& frame);\n    AbstractPathPoint* appendNewPathPoint(const std::string& proposedName, \n        const PhysicalFrame& frame, const SimTK::Vec3& locationOnFrame);\n    bool canDeletePathPoint( int index);\n    bool deletePathPoint(const SimTK::State& s, int index);\n    \n    void moveUpPathWrap(const SimTK::State& s, int index);\n    void moveDownPathWrap(const SimTK::State& s, int index);\n    void deletePathWrap(const SimTK::State& s, int index);\n    bool replacePathPoint(const SimTK::State& s, AbstractPathPoint* oldPathPoint,\n        AbstractPathPoint* newPathPoint); \n\n    //--------------------------------------------------------------------------\n    // GET\n    //--------------------------------------------------------------------------\n\n    /** If you call this prior to extendAddToSystem() it will be used to initialize\n    the color cache variable. Otherwise %GeometryPath will choose its own\n    default which varies depending on owner. **/\n    void setDefaultColor(const SimTK::Vec3& color) {\n        updProperty_Appearance().setValueIsDefault(false);\n        upd_Appearance().set_color(color); \n    };\n    /** Returns the color that will be used to initialize the color cache\n    at the next extendAddToSystem() call. The actual color used to draw the path\n    will be taken from the cache variable, so may have changed. **/\n    const SimTK::Vec3& getDefaultColor() const { return get_Appearance().get_color(); }\n\n    /** %Set the value of the color cache variable owned by this %GeometryPath\n    object, in the cache of the given state. The value of this variable is used\n    as the color when the path is drawn, which occurs with the state realized \n    to Stage::Dynamics. So you must call this method during realizeDynamics() or \n    earlier in order for it to have any effect. **/\n    void setColor(const SimTK::State& s, const SimTK::Vec3& color) const;\n\n    /** Get the current value of the color cache entry owned by this\n    %GeometryPath object in the given state. You can access this value any time\n    after the state is initialized, at which point it will have been set to\n    the default color value specified in a call to setDefaultColor() earlier,\n    or it will have the default color value chosen by %GeometryPath.\n    @see setDefaultColor() **/\n    SimTK::Vec3 getColor(const SimTK::State& s) const;\n\n    double getLength( const SimTK::State& s) const;\n    void setLength( const SimTK::State& s, double length) const;\n    double getPreScaleLength( const SimTK::State& s) const;\n    void setPreScaleLength( const SimTK::State& s, double preScaleLength);\n    const Array<AbstractPathPoint*>& getCurrentPath( const SimTK::State& s) const;\n\n    double getLengtheningSpeed(const SimTK::State& s) const;\n    void setLengtheningSpeed( const SimTK::State& s, double speed ) const;\n\n    /** get the path as PointForceDirections directions, which can be used\n        to apply tension to bodies the points are connected to.*/\n    void getPointForceDirections(const SimTK::State& s, \n        OpenSim::Array<PointForceDirection*> *rPFDs) const;\n\n    /** add in the equivalent body and generalized forces to be applied to the \n        multibody system resulting from a tension along the GeometryPath \n    @param state    state used to evaluate forces\n    @param[in]  tension      scalar (double) of the applied (+ve) tensile force \n    @param[in,out] bodyForces   Vector of SpatialVec\'s (torque, force) on bodies\n    //--------------------------------------------------------------------------\n    // Visualization Support\n    //--------------------------------------------------------------------------\n    // Update the geometry attached to the path (location of path points and connecting segments\n    //  all in global/interial frame)\n    virtual void updateGeometry(const SimTK::State& s) const;\n\nprotected:\n    //--------------------------------------------------------------------------\n    // COMPUTATIONS\n    //--------------------------------------------------------------------------\n    virtual double computeMomentArm(const SimTK::State& s, const Coordinate& aCoord) const;\n\n    //--------------------------------------------------------------------------\n    // SCALING\n    //--------------------------------------------------------------------------\n\n    /** Calculate the path length in the current body position and store it for\n        use after the Model has been scaled. */\n    void extendPreScale(const SimTK::State& s,\n                        const ScaleSet& scaleSet) override;\n\n    /** Recalculate the path after the Model has been scaled. */\n    void extendPostScale(const SimTK::State& s,\n                         const ScaleSet& scaleSet) override;\n\n    //--------------------------------------------------------------------------\n    // Visualization Support\n    //--------------------------------------------------------------------------\n    double calcLengthAfterPathComputation\n       (const SimTK::State& s, const Array<PathPoint*>& currentPath) const;\n\n\n    void setNull();\n    void constructProperties();\n    void updateDisplayPath(const SimTK::State& s) const;\n    void namePathPoints(int aStartingIndex);\n    void extendConnectToModel(Model& aModel) override;\n    void extendInitStateFromProperties(SimTK::State& s) const override;\n    void extendAddToSystem(SimTK::MultibodySystem& system) const override;\n\n    // Visual support GeometryPath drawing in SimTK visualizer.\n    void generateDecorations(\n            bool                                        fixed,\n            const ModelDisplayHints&                    hints,\n            const SimTK::State&                         state,\n            SimTK::Array_<SimTK::DecorativeGeometry>&   appendToThis) const\n            override;\n\n    void extendFinalizeFromProperties() override;\n\nprivate:\n\n    void computePath(const SimTK::State& s ) const;\n    void computeLengtheningSpeed(const SimTK::State& s) const;\n    void applyWrapObjects(const SimTK::State& s, Array<AbstractPathPoint*>& path ) const;\n    double calcPathLengthChange(const SimTK::State& s, const WrapObject& wo, \n                                const WrapResult& wr, \n                                const Array<AbstractPathPoint*>& path) const; \n    double calcLengthAfterPathComputation\n       (const SimTK::State& s, const Array<AbstractPathPoint*>& currentPath) const;\n\n    void constructProperties();\n    void namePathPoints(int aStartingIndex);\n    void placeNewPathPoint(const SimTK::State& s, SimTK::Vec3& aOffset, \n                           int index, const PhysicalFrame& frame);\n    //--------------------------------------------------------------------------\n    // Implement Object interface.\n    //--------------------------------------------------------------------------\n    /** Override of the default implementation to account for versioning. */\n    void updateFromXMLNode(SimTK::Xml::Element& aNode, int versionNumber = -1) override;\n\n//=============================================================================\n};  // END of class GeometryPath\n//=============================================================================\n//=============================================================================\n\n} // end of namespace OpenSim\n\n#endif // OPENSIM_GEOMETRY_PATH_H_\n\n\n', 'message': "Merge branch 'master' into MakeUseOfFrames_BushingForce\n", 'author_name': 'Christopher Dembia', 'lang': 'h'}