|
27 | 27 | #include <OpenSim/Simulation/Model/ModelComponent.h> |
28 | 28 | #include <OpenSim/Simulation/Model/Appearance.h> |
29 | 29 |
|
| 30 | +#include <functional> |
| 31 | +#include <vector> |
| 32 | + |
30 | 33 | #ifdef SWIG |
31 | 34 | #ifdef OSIMSIMULATION_API |
32 | 35 | #undef OSIMSIMULATION_API |
@@ -229,8 +232,86 @@ OpenSim_DECLARE_ABSTRACT_OBJECT(AbstractGeometryPath, ModelComponent); |
229 | 232 | */ |
230 | 233 | double getPreScaleLength(const SimTK::State& s) const; |
231 | 234 | void setPreScaleLength(const SimTK::State& s, double preScaleLength); |
232 | | - |
| 235 | + |
| 236 | + /** |
| 237 | + * Represents a decorative (i.e. visualization-only) point of an |
| 238 | + * `AbstractGeometryPath`. Can be used by UI implementations to |
| 239 | + * display the path. |
| 240 | + */ |
| 241 | + class DecorativePathPoint final { |
| 242 | + public: |
| 243 | + explicit DecorativePathPoint( |
| 244 | + const SimTK::Vec3& locationInGround, |
| 245 | + const Component* associatedComponent = nullptr) : |
| 246 | + m_locationInGround{locationInGround}, |
| 247 | + m_maybeAssociatedComponent{associatedComponent} |
| 248 | + {} |
| 249 | + |
| 250 | + SimTK::Vec3 getLocationInGround() const { return m_locationInGround; } |
| 251 | + void setLocationInGround(const SimTK::Vec3& p) { |
| 252 | + m_locationInGround = p; |
| 253 | + } |
| 254 | + const Component* getAssociatedComponent() const { |
| 255 | + return m_maybeAssociatedComponent; |
| 256 | + } |
| 257 | + private: |
| 258 | + SimTK::Vec3 m_locationInGround; |
| 259 | + const Component* m_maybeAssociatedComponent; |
| 260 | + }; |
| 261 | + |
| 262 | + /** |
| 263 | + * Calls `callback` with each point of a decorative representation of the |
| 264 | + * path, if such a representation is available. |
| 265 | + * |
| 266 | + * @param s Current simulation state, used to read the state of this |
| 267 | + * path. |
| 268 | + * @param callback A callback that should be called with each point of the |
| 269 | + * decorative path. |
| 270 | + */ |
| 271 | + void forEachDecorativePathPoint(const SimTK::State& state, |
| 272 | + const std::function<void(const DecorativePathPoint&)>& callback) const; |
| 273 | + |
| 274 | + /** |
| 275 | + * Get a vector of decorative path points. |
| 276 | + * |
| 277 | + * @param s Current simulation state, used to read the state of this path. |
| 278 | + */ |
| 279 | + std::vector<DecorativePathPoint> getDecorativePathPoints( |
| 280 | + const SimTK::State& s) const; |
| 281 | + |
| 282 | +protected: |
| 283 | + /** |
| 284 | + * Generates default decorations for this `AbstractGeometryPath`, based on |
| 285 | + * the decorative points emitted by `implForEachDecorativePathPoint`. |
| 286 | + * |
| 287 | + * Derived classes may override this to provide different display behavior |
| 288 | + * for the path. |
| 289 | + */ |
| 290 | + void generateDecorations(bool fixed, const ModelDisplayHints&, |
| 291 | + const SimTK::State&, |
| 292 | + SimTK::Array_<SimTK::DecorativeGeometry>&) const override; |
| 293 | + |
233 | 294 | private: |
| 295 | + /** |
| 296 | + * Implementors should call `callback` with each point of a decorative |
| 297 | + * representation of the path. |
| 298 | + * |
| 299 | + * The decorative representation does not necessarily need to be the same |
| 300 | + * as the computational representation: it only needs to be a "suitable" |
| 301 | + * visual representation of the path (if any). |
| 302 | + * |
| 303 | + * @param s Current simulation state, used to read the state of this |
| 304 | + * path. |
| 305 | + * @param callback A callback that should be called with each point of the |
| 306 | + * decorative path. |
| 307 | + */ |
| 308 | + virtual void implForEachDecorativePathPoint(const SimTK::State& s, |
| 309 | + const std::function<void(const DecorativePathPoint&)>& callback) const |
| 310 | + { |
| 311 | + // No-op: implementations are also permitted to provide no decorative |
| 312 | + // point representation at all. |
| 313 | + } |
| 314 | + |
234 | 315 | // Used by `(get|set)PreLengthScale`. Used during `extend(Pre|Post)Scale` by |
235 | 316 | // downstream users of AbstractGeometryPath to cache the length of the path |
236 | 317 | // before scaling. |
|
0 commit comments