opynsim
Unofficial C++ Documentation
Loading...
Searching...
No Matches
open_sim_helpers.h
Go to the documentation of this file.
1#pragma once
2
10#include <OpenSim/Common/ComponentPath.h>
11#include <SimTKcommon/internal/Transform.h>
12
13#include <algorithm>
14#include <concepts>
15#include <cstddef>
16#include <filesystem>
17#include <functional>
18#include <iosfwd>
19#include <iterator>
20#include <memory>
21#include <optional>
22#include <span>
23#include <stdexcept>
24#include <string_view>
25#include <string>
26#include <type_traits>
27#include <unordered_map>
28#include <utility>
29#include <vector>
30
31namespace OpenSim { class AbstractOutput; }
32namespace OpenSim { class AbstractPathPoint; }
33namespace OpenSim { class AbstractProperty; }
34namespace OpenSim { class AbstractSocket; }
35namespace OpenSim { class Appearance; }
36namespace OpenSim { template<typename> class Array; }
37namespace OpenSim { template<typename> class ArrayPtrs; }
38namespace OpenSim { class Body; }
39namespace OpenSim { class Component; }
40namespace OpenSim { class ComponentPath; }
41namespace OpenSim { class Constraint; }
42namespace OpenSim { class Coordinate; }
43namespace OpenSim { class ExternalForce; }
44namespace OpenSim { class Frame; }
45namespace OpenSim { class Geometry; }
46namespace OpenSim { class GeometryPath; }
47namespace OpenSim { class HuntCrossleyForce; }
48namespace OpenSim { class Joint; }
49namespace OpenSim { class Marker; }
50namespace OpenSim { class Mesh; }
51namespace OpenSim { class Model; }
52namespace OpenSim { class ModelComponent; }
53namespace OpenSim { class Muscle; }
54namespace OpenSim { class Object; }
55namespace OpenSim { template<typename> class Property; }
56namespace OpenSim { template<typename> class ObjectProperty; }
57namespace OpenSim { class PhysicalFrame; }
58namespace OpenSim { class PhysicalOffsetFrame; }
59namespace OpenSim { template<typename, typename> class Set; }
60namespace OpenSim { template<typename> class SimpleProperty; }
61namespace OpenSim { class Storage; }
62namespace OpenSim { class WrapObject; }
63namespace SimTK { class State; }
64namespace SimTK { class SimbodyMatterSubsystem; }
65
66// OpenSimHelpers: a collection of various helper functions that are used by `osc`
67namespace opyn
68{
69 // Is satisfied if `T` has a `.clone()` member method that returns a raw `T*` pointer.
70 template<typename T>
71 concept ClonesToRawPointer = requires(const T& v) {
72 { v.clone() } -> std::same_as<T*>;
73 };
74
75 // Returns the number of elements in `s` (see: `std::size`).
76 template<
77 std::derived_from<OpenSim::Object> T,
78 std::derived_from<OpenSim::Object> C = OpenSim::Object
79 >
80 size_t size(const OpenSim::Set<T, C>& s)
81 {
82 return static_cast<size_t>(s.getSize());
83 }
84
85 // Returns the number of elements in `s` as a signed integer (see: `std::ssize`).
86 template<
87 std::derived_from<OpenSim::Object> T,
88 std::derived_from<OpenSim::Object> C = OpenSim::Object
89 >
90 ptrdiff_t ssize(const OpenSim::Set<T, C>& s)
91 {
92 return static_cast<ptrdiff_t>(s.getSize());
93 }
94
95 // Returns the number of elements in `ary` (see: `std::size`).
96 template<typename T>
97 size_t size(const OpenSim::ArrayPtrs<T>& ary)
98 {
99 return static_cast<size_t>(ary.getSize());
100 }
101
102 // Returns the number of elements in `ary` (see: `std::size`).
103 template<typename T>
104 size_t size(const OpenSim::Array<T>& ary)
105 {
106 return static_cast<size_t>(ary.getSize());
107 }
108
109 // Returns the number of elements in `p` (see `std::size`).
110 template<typename T>
111 size_t size(const OpenSim::Property<T>& p)
112 {
113 return static_cast<size_t>(p.size());
114 }
115
116 // Returns an iterator to the beginning of `ary` (see: `std::begin`, `std::ranges::begin`).
117 template<typename T>
118 const T* begin(const OpenSim::Array<T>& ary)
119 {
120 return size(ary) != 0 ? std::addressof(ary[0]) : nullptr;
121 }
122
123 // Returns an iterator to the beginning of `ary` (see: `std::begin`, `std::ranges::begin`).
124 template<typename T>
126 {
127 return size(ary) != 0 ? std::addressof(ary[0]) : nullptr;
128 }
129
130 // Returns an iterator to the end (i.e. the element after the last element) of `ary` (see: `std::end`, `std::ranges::end`)
131 template<typename T>
132 const T* end(const OpenSim::Array<T>& ary)
133 {
134 return begin(ary) + size(ary);
135 }
136
137 // Returns an iterator to the end (i.e. the element after the last element) of `ary` (see: `std::end`, `std::ranges::end`)
138 template<typename T>
140 {
141 return begin(ary) + ary.size();
142 }
143
144 // Returns whether `s` is empty (see: `std::empty`)
145 template<
146 std::derived_from<OpenSim::Object> T,
147 std::derived_from<OpenSim::Object> C = OpenSim::Object
148 >
149 [[nodiscard]] bool empty(const OpenSim::Set<T, C>& s)
150 {
151 return size(s) <= 0;
152 }
153
154 // Returns a reference to the element of `ary` at location `pos`, with bounds checking.
155 template<typename T>
156 T& At(OpenSim::ArrayPtrs<T>& ary, size_t pos)
157 {
158 if (pos >= size(ary)) {
159 throw std::out_of_range{"out of bounds access to an OpenSim::ArrayPtrs detected"};
160 }
161
162 if (T* el = ary.get(static_cast<int>(pos))) {
163 return *el;
164 }
165 else {
166 throw std::runtime_error{"attempted to access null element of ArrayPtrs"};
167 }
168 }
169
170 // Returns a reference to the element of `ary` at location `pos`, with bounds checking.
171 template<typename T>
172 const T& At(const OpenSim::Array<T>& ary, size_t pos)
173 {
174 if (pos >= size(ary)) {
175 throw std::out_of_range{"out of bounds access to an OpenSim::ArrayPtrs detected"};
176 }
177 return ary.get(static_cast<int>(pos));
178 }
179
180 // Returns a reference to the element of `s` at location `pos`, with bounds checking.
181 template<
182 std::derived_from<OpenSim::Object> T,
183 std::derived_from<OpenSim::Object> C = OpenSim::Object
184 >
185 const T& At(const OpenSim::Set<T, C>& s, size_t pos)
186 {
187 if (pos >= size(s)) {
188 throw std::out_of_range{"out of bounds access to an OpenSim::Set detected"};
189 }
190 return s.get(static_cast<int>(pos));
191 }
192
193 // Returns a reference to the element of `s` at location `pos`, with bounds checking.
194 template<
195 std::derived_from<OpenSim::Object> T,
196 std::derived_from<OpenSim::Object> C = OpenSim::Object
197 >
198 T& At(OpenSim::Set<T, C>& s, size_t pos)
199 {
200 if (pos >= size(s)) {
201 throw std::out_of_range{"out of bounds access to an OpenSim::Set detected"};
202 }
203 s.get(static_cast<int>(pos)); // force an OpenSim-based null check
204 return s[static_cast<int>(pos)];
205 }
206
207 // Returns a reference to the element of `p` at location `pos`, with bounds checking.
208 template<typename T>
209 const T& At(const OpenSim::Property<T>& p, size_t pos)
210 {
211 return p[static_cast<int>(pos)]; // the implementation is already bounds-checked
212 }
213
214 template<
215 std::derived_from<OpenSim::Object> T,
216 std::derived_from<OpenSim::Object> C = OpenSim::Object
217 >
218 bool EraseAt(OpenSim::Set<T, C>& s, size_t i)
219 {
220 return s.remove(static_cast<int>(i));
221 }
222
223 // Returns whether all elements in `v` are not equal to any other element in `v`.
224 template<typename T>
225 requires (std::strict_weak_order<std::ranges::less, T, T> and std::equality_comparable<T>)
227 {
228 std::vector<std::reference_wrapper<const T>> buffer;
229 buffer.reserve(v.size());
230 std::ranges::copy(begin(v), end(v), std::back_inserter(buffer));
231 std::ranges::sort(buffer, std::less<T>{});
232 return std::ranges::adjacent_find(buffer, std::ranges::equal_to{}, [](const auto& wrapper) { return wrapper.get(); }) == buffer.end();
233 }
234
235 // returns true if the first argument has a lexicographically lower class name
237 const OpenSim::Component&,
238 const OpenSim::Component&
239 );
240
241 // returns true if the first argument points to a component that has a lexicographically lower class
242 // name than the component pointed to by second argument
243 //
244 // (it's a helper method that's handy for use with pointers, unique_ptr, shared_ptr, etc.)
245 template<osc::DereferencesTo<const OpenSim::Component&> ComponentPtrLike>
247 const ComponentPtrLike& a,
248 const ComponentPtrLike& b)
249 {
251 }
252
254 const OpenSim::Component&,
255 const OpenSim::Component&
256 );
257
258 template<osc::DereferencesTo<const OpenSim::Component&> Ptr>
260 const Ptr& a,
261 const Ptr& b)
262 {
263 return IsNameLexographicallyLowerThan(*a, *b);
264 }
265
266 template<osc::DereferencesTo<const OpenSim::Component&> Ptr>
268 const Ptr& a,
269 const Ptr& b)
270 {
271 return !IsNameLexographicallyLowerThan<Ptr>(a, b);
272 }
273
274 // returns a mutable pointer to the owner (if it exists)
275 OpenSim::Component* UpdOwner(OpenSim::Component& root, const OpenSim::Component&);
276 OpenSim::Component& UpdOwnerOrThrow(OpenSim::Component& root, const OpenSim::Component&);
277
278 template<std::derived_from<OpenSim::Component> T>
279 T& UpdOwnerOrThrow(OpenSim::Component& root, const OpenSim::Component& c)
280 {
281 return dynamic_cast<T&>(UpdOwnerOrThrow(root, c));
282 }
283
284 template<std::derived_from<OpenSim::Component> T>
285 T* UpdOwner(OpenSim::Component& root, const OpenSim::Component& c)
286 {
287 return dynamic_cast<T*>(UpdOwner(root, c));
288 }
289
290 // returns a pointer to the owner (if it exists)
291 const OpenSim::Component& GetOwnerOrThrow(const OpenSim::AbstractOutput&);
292 const OpenSim::Component& GetOwnerOrThrow(const OpenSim::Component&);
293 const OpenSim::Component& GetOwnerOr(const OpenSim::Component&, const OpenSim::Component& fallback);
294 const OpenSim::Component* GetOwner(const OpenSim::Component&);
295
296 template<std::derived_from<OpenSim::Component> T>
297 const T* GetOwner(const OpenSim::Component& c)
298 {
299 return dynamic_cast<const T*>(GetOwner(c));
300 }
301
302 template<std::derived_from<OpenSim::Component> T>
303 bool OwnerIs(const OpenSim::Component& c)
304 {
305 return GetOwner<T>(c) != nullptr;
306 }
307
308 std::optional<std::string> TryGetOwnerName(const OpenSim::Component&);
309
310 // returns the distance between the given `Component` and the component that is at the root of the component tree
311 size_t DistanceFromRoot(const OpenSim::Component&);
312
313 // returns a reference to a global instance of a path that points to the root of a model (i.e. "/")
314 OpenSim::ComponentPath GetRootComponentPath();
315
316 // returns `true` if the given `ComponentPath` is an empty path
317 bool IsEmpty(const OpenSim::ComponentPath&);
318
319 // clears the given component path
320 void Clear(OpenSim::ComponentPath&);
321
322 // returns all components between the root (element 0) and the given component (element n-1) inclusive
323 std::vector<const OpenSim::Component*> GetPathElements(const OpenSim::Component&);
324
325 // calls the given function with each subcomponent of the given component
326 void ForEachComponent(const OpenSim::Component&, const std::function<void(const OpenSim::Component&)>&);
327
328 // calls the given function with the provided component and each of its subcomponents
329 void ForEachComponentInclusive(const OpenSim::Component&, const std::function<void(const OpenSim::Component&)>&);
330
331 // returns the number of children (recursive) of type T under the given component
332 template<std::derived_from<OpenSim::Component> T>
333 size_t GetNumChildren(const OpenSim::Component& c)
334 {
335 size_t i = 0;
336 ForEachComponent(c, [&i](const OpenSim::Component& c)
337 {
338 if (dynamic_cast<const T*>(&c)) {
339 ++i;
340 }
341 });
342 return i;
343 }
344
345 // returns the number of direct children that the component owns
346 size_t GetNumChildren(const OpenSim::Component&);
347
348 // returns `true` if `c == parent` or `c` is a descendant of `parent`
350 const OpenSim::Component* parent,
351 const OpenSim::Component* c
352 );
353
354 // returns the first parent in `parents` that appears to be an inclusive parent of `c`
355 //
356 // returns `nullptr` if no element in `parents` is an inclusive parent of `c`
357 const OpenSim::Component* IsInclusiveChildOf(
358 std::span<const OpenSim::Component*> parents,
359 const OpenSim::Component* c
360 );
361
362 // returns the first ancestor of `c` for which the given predicate returns `true`
363 const OpenSim::Component* FindFirstAncestorInclusive(
364 const OpenSim::Component*,
365 bool(*pred)(const OpenSim::Component*)
366 );
367
368 // returns the first ancestor of `c` that has type `T`
369 template<std::derived_from<OpenSim::Component> T>
370 const T* FindAncestorWithType(const OpenSim::Component* c)
371 {
372 const OpenSim::Component* rv = FindFirstAncestorInclusive(c, [](const OpenSim::Component* el)
373 {
374 return dynamic_cast<const T*>(el) != nullptr;
375 });
376
377 return dynamic_cast<const T*>(rv);
378 }
379
380 // returns `true` if `c` is a child of a component that derives from `T`
381 template<std::derived_from<OpenSim::Component> T>
382 bool IsChildOfA(const OpenSim::Component& c)
383 {
384 return FindAncestorWithType<T>(&c) != nullptr;
385 }
386
387 // returns the first descendant (including `component`) that satisfies `predicate(descendant);`
388 const OpenSim::Component* FindFirstDescendentInclusive(
389 const OpenSim::Component& component,
390 bool(*predicate)(const OpenSim::Component&)
391 );
392
393 // returns the first descendant of `component` that satisfies `predicate(descendant)`
394 const OpenSim::Component* FindFirstDescendent(
395 const OpenSim::Component& component,
396 bool(*predicate)(const OpenSim::Component&)
397 );
398
399 // returns the first descendant of `component` that satisfies `predicate(descendant)`
400 OpenSim::Component* FindFirstDescendentMut(
401 OpenSim::Component& component,
402 bool(*predicate)(const OpenSim::Component&)
403 );
404
405 // returns the first direct descendant of `component` that has type `T`, or
406 // `nullptr` if no such descendant exists
407 template<std::derived_from<OpenSim::Component> T>
408 const T* FindFirstDescendentOfType(const OpenSim::Component& c)
409 {
410 const OpenSim::Component* rv = FindFirstDescendent(c, [](const OpenSim::Component& el)
411 {
412 return dynamic_cast<const T*>(&el) != nullptr;
413 });
414 return dynamic_cast<const T*>(rv);
415 }
416
417 // returns the first direct descendant of `component` that has type `T`, or
418 // `nullptr` if no such descendant exists
419 template<std::derived_from<OpenSim::Component> T>
420 T* FindFirstDescendentOfTypeMut(OpenSim::Component& c)
421 {
422 OpenSim::Component* rv = FindFirstDescendentMut(c, [](const OpenSim::Component& el)
423 {
424 return dynamic_cast<const T*>(&el) != nullptr;
425 });
426 return dynamic_cast<T*>(rv);
427 }
428
429 // returns a vector containing pointers to all user-editable coordinates in the model
430 std::vector<const OpenSim::Coordinate*> GetCoordinatesInModel(const OpenSim::Model&);
431
432 // fills the given vector with all user-editable coordinates in the model
434 const OpenSim::Model&,
435 std::vector<const OpenSim::Coordinate*>&
436 );
437
438 // returns a vector containing mutable pointers to all default-locked coordinates in the model
439 std::vector<OpenSim::Coordinate*> UpdDefaultLockedCoordinatesInModel(OpenSim::Model&);
440
441 // returns the user-facing display value (i.e. degrees) for a coordinate
442 float ConvertCoordValueToDisplayValue(const OpenSim::Coordinate&, double v);
443
444 // returns the storage-facing value (i.e. radians) for a coordinate
445 double ConvertCoordDisplayValueToStorageValue(const OpenSim::Coordinate&, float v);
446
447 // returns a user-facing string that describes a coordinate's units
449
450 // returns the names of a component's sockets
451 std::vector<std::string> GetSocketNames(const OpenSim::Component&);
452
453 // returns all sockets that are directly attached to the given component
454 std::vector<const OpenSim::AbstractSocket*> GetAllSockets(const OpenSim::Component&);
455
456 // returns all (mutable) sockets that are directly attached to the given component
457 std::vector<OpenSim::AbstractSocket*> UpdAllSockets(OpenSim::Component&);
458
459 // writes the given component's (recursive) topology graph to the output stream as a
460 // dotviz `digraph`
462 const OpenSim::Component&,
463 std::ostream&
464 );
465
466 // writes the given model's multi-body system (i.e. kinematic chain) to the output stream
467 // as a dotviz `digraph`
469 const OpenSim::Model&,
470 std::ostream&
471 );
472
473 // returns a pointer if the given path resolves a component relative to root
474 const OpenSim::Component* FindComponent(const OpenSim::Component& root, const OpenSim::ComponentPath&);
475 const OpenSim::Component* FindComponent(const OpenSim::Model&, const std::string& absPath);
476 const OpenSim::Component* FindComponent(const OpenSim::Model&, const osc::StringName& absPath);
477
478 // return non-nullptr if the given path resolves a component of type T relative to root
479 template<std::derived_from<OpenSim::Component> T>
480 const T* FindComponent(const OpenSim::Component& root, const OpenSim::ComponentPath& cp)
481 {
482 return dynamic_cast<const T*>(FindComponent(root, cp));
483 }
484
485 template<std::derived_from<OpenSim::Component> T>
486 const T* FindComponent(const OpenSim::Model& root, const std::string& cp)
487 {
488 return dynamic_cast<const T*>(FindComponent(root, cp));
489 }
490
491 template<std::derived_from<OpenSim::Component> T>
492 const T* FindComponent(const OpenSim::Model& root, const osc::StringName& cp)
493 {
494 return dynamic_cast<const T*>(FindComponent(root, cp));
495 }
496
497 // returns a mutable pointer if the given path resolves a component relative to root
498 OpenSim::Component* FindComponentMut(
499 OpenSim::Component& root,
500 const OpenSim::ComponentPath&
501 );
502
503 // returns non-nullptr if the given path resolves a component of type T relative to root
504 template<std::derived_from<OpenSim::Component> T>
506 OpenSim::Component& root,
507 const OpenSim::ComponentPath& cp)
508 {
509 return dynamic_cast<T*>(FindComponentMut(root, cp));
510 }
511
512 // returns true if the path resolves to a component within `root`
514 const OpenSim::Component& root,
515 const OpenSim::ComponentPath&
516 );
517
518 // returns non-nullptr if a socket with the given name is found within the given component
519 const OpenSim::AbstractSocket* FindSocket(
520 const OpenSim::Component&,
521 const std::string& socketName
522 );
523
524 // returns non-nullptr if a socket with the given name is found within the given component
525 OpenSim::AbstractSocket* FindSocketMut(
526 OpenSim::Component&,
527 const std::string& socketName
528 );
529
530 // returns `true` if the socket is connected to the component
532 const OpenSim::AbstractSocket&,
533 const OpenSim::Component&
534 );
535
536 // returns true if the socket is able to connect to the component
538 const OpenSim::AbstractSocket&,
539 const OpenSim::Component&
540 );
541
542 // recursively traverses all components within `root` and reassigns any sockets
543 // pointing to `from` to instead point to `to`
544 //
545 // note: must be called on a component that already has finalized connections
547 OpenSim::Component& root,
548 const OpenSim::Component& from,
549 const OpenSim::Component& to
550 );
551
553 public:
555 const OpenSim::Component& source,
556 const OpenSim::Component& target,
557 std::string socketName) :
558
559 m_Source{&source},
560 m_Target{&target},
561 m_SocketName{std::move(socketName)}
562 {}
563
564 friend bool operator==(const ComponentConnectionView&, const ComponentConnectionView&) = default;
565
566 const OpenSim::Component& source() const { return *m_Source; }
567 const OpenSim::Component& target() const { return *m_Target; }
568 osc::CStringView socketName() const { return m_SocketName; }
569 private:
570 const OpenSim::Component* m_Source;
571 const OpenSim::Component* m_Target;
572 std::string m_SocketName;
573 };
574 std::ostream& operator<<(std::ostream&, const ComponentConnectionView&);
575
576 // Returns a generator that yields `ComponentConnectionView` for each socket of each component
577 // in `root` that points to `c`.
579 const OpenSim::Component* root,
580 const OpenSim::Component* c,
581 std::function<bool(const OpenSim::Component&)> filter = [](const OpenSim::Component&){ return true; }
582 );
583
584 // returns a pointer to the property if the component has a property with the given name
585 OpenSim::AbstractProperty* FindPropertyMut(
586 OpenSim::Component&,
587 const std::string&
588 );
589
590 // returns a pointer to the property if the component has a simple property with the given name and type
591 template<typename T>
593 OpenSim::Component& c,
594 const std::string& name)
595 {
596 return dynamic_cast<OpenSim::SimpleProperty<T>*>(FindPropertyMut(c, name));
597 }
598
599 // returns non-nullptr if an `AbstractOutput` with the given name is attached to the given component
600 const OpenSim::AbstractOutput* FindOutput(
601 const OpenSim::Component&,
602 const std::string& outputName
603 );
604
605 // returns non-nullptr if an `AbstractOutput` with the given name is attached to a component located at the given path relative to the root
606 const OpenSim::AbstractOutput* FindOutput(
607 const OpenSim::Component& root,
608 const OpenSim::ComponentPath&,
609 const std::string& outputName
610 );
611
612 // returns true if the given model has an input file name (not empty, or "Unassigned")
613 bool HasInputFileName(const OpenSim::Model&);
614
615 // returns a non-empty path if the given model has an input file name that exists on the user's filesystem
616 //
617 // otherwise, returns an empty path
618 std::optional<std::filesystem::path> TryFindInputFile(const OpenSim::Model&);
619
620 // returns the recommended name of the provided model file, e.g. for suggesting a name for users
621 std::string RecommendedDocumentName(const OpenSim::Model&);
622
623 // returns the absolute path to the given mesh component, if found (otherwise, std::nullptr)
624 std::optional<std::filesystem::path> FindGeometryFileAbsPath(
625 const OpenSim::Model&,
626 const OpenSim::Mesh&
627 );
628
629 // returns the filename part of the `mesh_file` property (e.g. `C:\Users\adam\mesh.obj` returns `mesh.obj`)
630 std::string GetMeshFileName(const OpenSim::Mesh&);
631
632 // returns `true` if the component should be shown in the UI
633 //
634 // this uses heuristics to determine whether the component is something the UI should be
635 // "revealed" to the user
636 bool ShouldShowInUI(const OpenSim::Component&);
637
638 // *tries* to delete the supplied component from the model
639 //
640 // returns `true` if the implementation was able to delete the component; otherwise, `false`
641 bool TryDeleteComponentFromModel(OpenSim::Model&, OpenSim::Component&);
642
643 // copy common joint properties from a `src` to `dest`
644 //
645 // e.g. names, coordinate names, etc.
646 void CopyCommonJointProperties(const OpenSim::Joint& src, OpenSim::Joint& dest);
647
648 // de-activates all wrap objects in the given model
649 //
650 // returns `true` if any modification was made to the model
651 bool DeactivateAllWrapObjectsIn(OpenSim::Model&);
652
653 // activates all wrap objects in the given model
654 //
655 // returns `true` if any modification was made to the model
656 bool ActivateAllWrapObjectsIn(OpenSim::Model&);
657
658 // returns pointers to all wrap objects that are referenced by the given `GeometryPath`
659 std::vector<const OpenSim::WrapObject*> GetAllWrapObjectsReferencedBy(const OpenSim::GeometryPath&);
660
661 // Returns `true` if `path` has a supported model file extension.
662 bool HasModelFileExtension(const std::filesystem::path& path);
663
664 // returns a pointer to a not-yet-initialized model, loaded via an osim file at the given path
665 std::unique_ptr<OpenSim::Model> LoadModel(const std::filesystem::path&);
666
667 // fully initialize an OpenSim model (clear connections, finalize properties, remake SimTK::System)
668 void InitializeModel(OpenSim::Model&);
669
670 // Tries to equilibrate the muscles in the given model for the given state, or logs a warning
671 // message if the muscles cannot be equilibriated.
672 //
673 // This should be used in the UI in cases where the user may load or edit a model that contains
674 // invalid/incorrect muscles. Some OpenSim models can have this problem, and it shouldn't be
675 // treated as a fatal error (opensim-creator/#1070).
676 void TryEquilibrateMusclesOrLogWarning(OpenSim::Model&, SimTK::State&);
677
678 // fully initalize an OpenSim model's working state
679 SimTK::State& InitializeState(OpenSim::Model&);
680
681 // calls `model.finalizeFromProperties()`
682 //
683 // (mostly here to match the style of osc's initialization methods)
684 void FinalizeFromProperties(OpenSim::Model&);
685
686 // finalize any socket connections in the model
687 //
688 // care:
689 //
690 // - it will _first_ finalize any properties in the model
691 // - then it will finalize each socket recursively
692 // - finalizing a socket causes the socket's pointer to write an updated
693 // component path to the socket's path property (for later serialization)
694 void FinalizeConnections(OpenSim::Model&);
695
696 // returns optional{index} if joint is found in parent jointset (otherwise: std::nullopt)
697 std::optional<size_t> FindJointInParentJointSet(const OpenSim::Joint&);
698
699 // returns user-visible (basic) name of geometry, or underlying file name
700 std::string GetDisplayName(const OpenSim::Geometry&);
701
702 // returns a user-visible string for a coordinate's motion type
703 osc::CStringView GetMotionTypeDisplayName(const OpenSim::Coordinate&);
704
705 // returns a pointer to the component's appearance property, or `nullptr` if it doesn't have one
706 const OpenSim::Appearance* TryGetAppearance(const OpenSim::Component&);
707 OpenSim::Appearance* TryUpdAppearance(OpenSim::Component&);
708
709 // tries to set the given component's appearance property's visibility field to the given bool
710 //
711 // returns `false` if the component doesn't have an appearance property, `true` if it does (and
712 // the value was set)
713 bool TrySetAppearancePropertyIsVisibleTo(OpenSim::Component&, bool);
714
715 // returns the color part of the `OpenSim::Appearance` as an `osc::Color`
716 osc::Color to_color(const OpenSim::Appearance&);
717
718 osc::Color GetSuggestedBoneColor(); // best guess, based on shaders etc.
719
720 // returns `true` if the given model's display properties asks to show frames
721 bool IsShowingFrames(const OpenSim::Model&);
722
723 // toggles the model's "show frames" display property and returns the new value
724 bool ToggleShowingFrames(OpenSim::Model&);
725
726 // returns `true` if the given model's display properties ask to show markers
727 bool IsShowingMarkers(const OpenSim::Model&);
728
729 // toggles the model's "show markers" display property and returns the new value
730 bool ToggleShowingMarkers(OpenSim::Model&);
731
732 // returns `true` if the given model's display properties asks to show wrap geometry
733 bool IsShowingWrapGeometry(const OpenSim::Model&);
734
735 // toggles the model's "show wrap geometry" display property and returns the new value
736 bool ToggleShowingWrapGeometry(OpenSim::Model&);
737
738 // returns `true` if the given model's display properties asks to show contact geometry
739 bool IsShowingContactGeometry(const OpenSim::Model&);
740
741 // returns `true` if the given model's display properties asks to show forces
742 bool IsShowingForces(const OpenSim::Model&);
743
744 // toggles the model's "show contact geometry" display property and returns the new value
745 bool ToggleShowingContactGeometry(OpenSim::Model&);
746
747 // toggles the model's "show forces" display property and returns the new value
748 bool ToggleShowingForces(OpenSim::Model&);
749
750 // returns/assigns the absolute path to a component within its hierarchy (e.g. /jointset/joint/somejoint)
751 //
752 // (custom OSC version that may be faster than OpenSim::Component::getAbsolutePathString)
753 void GetAbsolutePathString(const OpenSim::Component&, std::string&);
754 std::string GetAbsolutePathString(const OpenSim::Component&);
755 osc::StringName GetAbsolutePathStringName(const OpenSim::Component&);
756
757 // returns the absolute path to a component within its hierarchy (e.g. /jointset/joint/somejoint)
758 //
759 // (custom OSC version that may be faster than OpenSim::Component::getAbsolutePath)
760 OpenSim::ComponentPath GetAbsolutePath(const OpenSim::Component&);
761
762 // if non-nullptr, returns/assigns the absolute path to the component within its hierarchy (e.g. /jointset/joint/somejoint)
763 //
764 // (custom OSC version that may be faster than OpenSim::Component::getAbsolutePath)
765 OpenSim::ComponentPath GetAbsolutePathOrEmpty(const OpenSim::Component*);
766
767 // muscle lines of action
768 //
769 // helper functions for computing the "line of action" of a muscle. These algorithms were
770 // adapted from: https://github.com/modenaxe/MuscleForceDirection/
771 //
772 // the reason they return `optional` is to handle edge-cases like the path containing an
773 // insufficient number of points (shouldn't happen, but you never know)
778 std::optional<LinesOfAction> GetEffectiveLinesOfActionInGround(const OpenSim::Muscle&, const SimTK::State&);
779 std::optional<LinesOfAction> GetAnatomicalLinesOfActionInGround(const OpenSim::Muscle&, const SimTK::State&);
780
781 // contact forces
782 //
783 // helper functions for pulling contact forces out of the model (e.g. for rendering)
788 std::optional<ForcePoint> TryGetContactForceInGround(
789 const OpenSim::Model&,
790 const SimTK::State&,
791 const OpenSim::HuntCrossleyForce&
792 );
793
794 // force vectors
795 //
796 // helper functions for pulling force vectors out of components in the model
797 const OpenSim::PhysicalFrame& GetFrameUsingExternalForceLookupHeuristic(
798 const OpenSim::Model&,
799 const std::string& bodyNameOrPath
800 );
801
802 // point info
803 //
804 // extract point-like information from generic OpenSim components
805 struct PointInfo final {
807 osc::Vector3 location_,
808 OpenSim::ComponentPath frameAbsPath_) :
809
810 location{location_},
811 frameAbsPath{std::move(frameAbsPath_)}
812 {}
813
815 OpenSim::ComponentPath frameAbsPath;
816 };
817 bool CanExtractPointInfoFrom(const OpenSim::Component&, const SimTK::State&);
818 std::optional<PointInfo> TryExtractPointInfo(const OpenSim::Component&, const SimTK::State&);
819
820 // adds a component to an appropriate location in the model (e.g. joint-set for a joint) and
821 // returns a reference to the placed component
822 OpenSim::Component& AddComponentToAppropriateSet(OpenSim::Model&, std::unique_ptr<OpenSim::Component>);
823
824 // adds a model component to the component set of a model and returns a reference to the component
825 OpenSim::ModelComponent& AddModelComponent(OpenSim::Model&, std::unique_ptr<OpenSim::ModelComponent>&&);
826
827 // adds a specific (T) model component to the component set of the model and returns a reference to the component
828 template<std::derived_from<OpenSim::ModelComponent> T>
829 T& AddModelComponent(OpenSim::Model& model, std::unique_ptr<T> p)
830 {
831 return static_cast<T&>(AddModelComponent(model, static_cast<std::unique_ptr<OpenSim::ModelComponent>&&>(std::move(p))));
832 }
833
834 // constructs a specific (T) model component in the component set of the model and returns a reference to the component
835 template<std::derived_from<OpenSim::ModelComponent> T, typename... Args>
836 requires std::constructible_from<T, Args&&...>
837 T& AddModelComponent(OpenSim::Model& model, Args&&... args)
838 {
839 return AddModelComponent(model, std::make_unique<T>(std::forward<Args>(args)...));
840 }
841
842 // adds a new component to the component set of the component and returns a reference to the new component
843 OpenSim::Component& AddComponent(OpenSim::Component&, std::unique_ptr<OpenSim::Component>&&);
844
845 template<std::derived_from<OpenSim::Component> T>
846 T& AddComponent(OpenSim::Component& c, std::unique_ptr<T> p)
847 {
848 return static_cast<T&>(AddComponent(c, static_cast<std::unique_ptr<OpenSim::Component>&&>(std::move(p))));
849 }
850
851 template<std::derived_from<OpenSim::Component> T>
852 T& AddComponent(OpenSim::Component& host)
853 {
854 return AddComponent(host, std::make_unique<T>());
855 }
856
857 template<std::derived_from<OpenSim::Component> T, typename... Args>
858 requires std::constructible_from<T, Args&&...>
859 T& AddComponent(OpenSim::Component& host, Args&&...args)
860 {
861 return AddComponent(host, std::make_unique<T>(std::forward<Args>(args)...));
862 }
863
864 OpenSim::Body& AddBody(OpenSim::Model&, std::unique_ptr<OpenSim::Body>);
865
866 template<typename... Args>
867 requires std::constructible_from<OpenSim::Body, Args&&...>
868 OpenSim::Body& AddBody(OpenSim::Model& model, Args&&... args)
869 {
870 auto p = std::make_unique<OpenSim::Body>(std::forward<Args>(args)...);
871 return AddBody(model, std::move(p));
872 }
873
874 OpenSim::Joint& AddJoint(OpenSim::Model&, std::unique_ptr<OpenSim::Joint>);
875
876 template<std::derived_from<OpenSim::Joint> T, typename... Args>
877 requires std::constructible_from<T, Args&&...>
878 T& AddJoint(OpenSim::Model& model, Args&&... args)
879 {
880 auto p = std::make_unique<T>(std::forward<Args>(args)...);
881 return static_cast<T&>(AddJoint(model, std::move(p)));
882 }
883
884 OpenSim::Constraint& AddConstraint(OpenSim::Model&, std::unique_ptr<OpenSim::Constraint>);
885
886 template<std::derived_from<OpenSim::Constraint> T, typename... Args>
887 requires std::constructible_from<T, Args&&...>
888 T& AddConstraint(OpenSim::Model& model, Args&&... args)
889 {
890 auto p = std::make_unique<T>(std::forward<Args>(args)...);
891 return static_cast<T&>(AddConstraint(model, std::move(p)));
892 }
893
894 OpenSim::Marker& AddMarker(OpenSim::Model&, std::unique_ptr<OpenSim::Marker>);
895
896 template<typename... Args>
897 requires std::constructible_from<OpenSim::Marker, Args&&...>
898 OpenSim::Marker& AddMarker(OpenSim::Model& model, Args&&... args)
899 {
900 auto p = std::make_unique<OpenSim::Marker>(std::forward<Args>(args)...);
901 return AddMarker(model, std::move(p));
902 }
903
904 OpenSim::Geometry& AttachGeometry(OpenSim::Frame&, std::unique_ptr<OpenSim::Geometry>);
905
906 template<std::derived_from<OpenSim::Geometry> T, typename... Args>
907 requires std::constructible_from<T, Args&&...>
908 T& AttachGeometry(OpenSim::Frame& frame, Args&&... args)
909 {
910 auto p = std::make_unique<T>(std::forward<Args>(args)...);
911 return static_cast<T&>(AttachGeometry(frame, std::move(p)));
912 }
913
914 // Tries to overwride `oldGeometry` in the given `model` with `newGeometry`.
915 //
916 // This is useful when transforming geometry (e.g. TPS warping) and overwriting it
917 // in a model.
919 OpenSim::Model&,
920 OpenSim::Geometry& oldGeometry,
921 std::unique_ptr<OpenSim::Geometry> newGeometry
922 );
923
924 OpenSim::PhysicalOffsetFrame& AddFrame(OpenSim::Joint&, std::unique_ptr<OpenSim::PhysicalOffsetFrame>);
925
926 OpenSim::WrapObject& AddWrapObject(OpenSim::PhysicalFrame&, std::unique_ptr<OpenSim::WrapObject>);
927
928 template<std::derived_from<OpenSim::WrapObject> T, typename... Args>
929 requires std::constructible_from<T, Args&&...>
930 T& AddWrapObject(OpenSim::PhysicalFrame& physFrame, Args&&... args)
931 {
932 return static_cast<T&>(AddWrapObject(physFrame, std::make_unique<T>(std::forward<Args>(args)...)));
933 }
934
935 template<ClonesToRawPointer T>
936 std::unique_ptr<T> Clone(const T& obj)
937 {
938 return std::unique_ptr<T>(obj.clone());
939 }
940
941 template<std::derived_from<OpenSim::Component> T>
942 void Append(OpenSim::ObjectProperty<T>& prop, const T& c)
943 {
944 prop.adoptAndAppendValue(Clone(c).release());
945 }
946
947 template<
948 std::derived_from<OpenSim::Object> T,
949 std::derived_from<OpenSim::Object> C = OpenSim::Object
950 >
951 std::optional<size_t> IndexOf(const OpenSim::Set<T, C>& set, const T& el)
952 {
953 for (size_t i = 0; i < size(set); ++i) {
954 if (&At(set, i) == &el) {
955 return i;
956 }
957 }
958 return std::nullopt;
959 }
960
961 template<
962 std::derived_from<OpenSim::Object> T,
963 std::derived_from<T> U,
964 std::derived_from<OpenSim::Object> C = OpenSim::Object
965 >
966 void Append(OpenSim::Set<T, C>& set, std::unique_ptr<U> el)
967 {
968 set.adoptAndAppend(el.release());
969 }
970
971 template<
972 std::derived_from<OpenSim::Object> T,
973 std::derived_from<T> U,
974 std::derived_from<OpenSim::Object> C = OpenSim::Object
975 >
976 U& Assign(OpenSim::Set<T, C>& set, size_t index, std::unique_ptr<U> el)
977 {
978 if (index >= size(set)) {
979 throw std::out_of_range{"out of bounds access to an OpenSim::Set detected"};
980 }
981
982 U& rv = *el;
983 set.set(static_cast<int>(index), el.release());
984 return rv;
985 }
986
987 template<
988 std::derived_from<OpenSim::Object> T,
989 std::derived_from<T> U,
990 std::derived_from<OpenSim::Object> C = OpenSim::Object
991 >
992 U& Assign(OpenSim::Set<T, C>& set, T& oldElement, std::unique_ptr<U> newElement)
993 {
994 auto idx = IndexOf(set, oldElement);
995 if (not idx) {
996 throw std::runtime_error{"cannot find the requested element in the set"};
997 }
998 return Assign(set, *idx, std::move(newElement));
999 }
1000
1001 template<
1002 std::derived_from<OpenSim::Object> T,
1003 std::derived_from<T> U,
1004 std::derived_from<OpenSim::Object> C = OpenSim::Object
1005 >
1006 U& Assign(OpenSim::Set<T, C>& set, size_t index, const U& el)
1007 {
1008 return Assign(set, index, Clone(el));
1009 }
1010
1011 // Tries to delete an item from an `OpenSim::Set`.
1012 //
1013 // Returns `true` if the item was found and deleted; otherwise, returns `false`.
1014 template<
1015 std::derived_from<OpenSim::Object> T,
1016 std::derived_from<T> U,
1017 std::derived_from<OpenSim::Object> C
1018 >
1020 {
1021 for (size_t i = 0; i < size(set); ++i) {
1022 if (&At(set, i) == item) {
1023 return EraseAt(set, i);
1024 }
1025 }
1026 return false;
1027 }
1028
1029 // tries to get the "parent" frame of the given component (if available)
1030 //
1031 // e.g. in OpenSim, this is usually acquired with `getParentFrame()`
1032 // but that API isn't exposed generically via virtual methods
1033 const OpenSim::PhysicalFrame* TryGetParentToGroundFrame(const OpenSim::Component&);
1034
1035 // tries to get the "parent" transform of the given component (if available)
1036 //
1037 // e.g. in OpenSim, this is usually acquired with `getParentFrame().getTransformInGround(State const&)`
1038 // but that API isn't exposed generically via virtual methods
1039 std::optional<SimTK::Transform> TryGetParentToGroundTransform(const OpenSim::Component&, const SimTK::State&);
1040
1041 // tries to get the name of the "positional" property of the given component
1042 //
1043 // e.g. the positional property of an `OpenSim::Station` is "location", whereas the
1044 // positional property of an `OpenSim::PhysicalOffsetFrame` is "translation"
1045 std::optional<std::string> TryGetPositionalPropertyName(const OpenSim::Component&);
1046
1047 // tries to get the name of the "orientational" property of the given component
1048 //
1049 // e.g. the orientational property of an `OpenSim::PhysicalOffsetFrame` is "orientation",
1050 // whereas `OpenSim::Station` has no orientation, so this returns `std::nullopt`
1051 std::optional<std::string> TryGetOrientationalPropertyName(const OpenSim::Component&);
1052
1053 // tries to return the "parent" of the given frame, if applicable (e.g. if the frame is an
1054 // `OffsetFrame<T>` that has a logical parent
1055 const OpenSim::Frame* TryGetParentFrame(const OpenSim::Frame&);
1056
1057 // packages up the various useful parts that describe how a component is spatially represented
1058 //
1059 // see also (component functions):
1060 //
1061 // - TryGetParentToGroundTransform
1062 // - TryGetPositionalPropertyName
1063 // - TryGetOrientationalPropertyName
1065 SimTK::Transform parentToGround;
1067 std::optional<std::string> maybeOrientationVec3EulersPropertyName;
1068 };
1069
1070 // tries to get the "spatial" representation of a component
1071 std::optional<ComponentSpatialRepresentation> TryGetSpatialRepresentation(
1072 const OpenSim::Component&,
1073 const SimTK::State&
1074 );
1075
1076 // returns `true` if the given character is permitted to appear within the name
1077 // of an `OpenSim::Component`
1079
1080 // returns a sanitized form of the given string that OpenSim would (probably) accept
1081 // as a component name
1082 std::string SanitizeToOpenSimComponentName(std::string_view);
1083
1086 std::optional<double> resampleToFrequency = std::nullopt;
1087 };
1088
1089 // returns an `OpenSim::Storage` with the given parameters
1090 //
1091 // (a `Model` is required because its `Coordinate`s are used to figure out which columns
1092 // might be rotational)
1093 std::unique_ptr<OpenSim::Storage> LoadStorage(
1094 const OpenSim::Model&,
1095 const std::filesystem::path&,
1096 const StorageLoadingParameters& = {}
1097 );
1098
1099 // Represents the result of trying to map columns in an `OpenSim::Storage` to state
1100 // variables in an `OpenSim::Model`.
1102 std::unordered_map<int, int> storageIndexToModelStatevarIndex;
1103 std::vector<std::string> stateVariablesMissingInStorage;
1104 };
1105
1107 const OpenSim::Model&,
1108 const OpenSim::Storage&
1109 );
1110
1112 const OpenSim::Model&,
1113 const OpenSim::Storage&
1114 );
1115
1117 OpenSim::Model&,
1118 SimTK::State&,
1119 const std::unordered_map<int, int>& columnIndexToModelStateVarIndex,
1120 const OpenSim::Storage&,
1121 int row
1122 );
1123
1125 OpenSim::Model&,
1126 SimTK::State&,
1127 const std::unordered_map<int, int>& columnIndexToModelStateVarIndex,
1128 const OpenSim::Storage&,
1129 double time
1130 );
1131
1132 std::string WriteObjectXMLToString(const OpenSim::Object&);
1133
1134 // Scales the masses of all bodies in `model` such that its total mass
1135 // becomes equal to `newMass`, while preserving the relative distribution
1136 // of masses of the model.
1137 //
1138 // Note: this edits the body mass (properties), but doesn't re-initialize
1139 // `model` or `state`.
1141 OpenSim::Model& model,
1142 const SimTK::State& state,
1143 double newMass
1144 );
1145}
Definition open_sim_helpers.h:37
Definition open_sim_helpers.h:36
Definition open_sim_helpers.h:56
Definition open_sim_helpers.h:55
Definition open_sim_helpers.h:59
Definition open_sim_helpers.h:60
Definition open_sim_helpers.h:552
friend bool operator==(const ComponentConnectionView &, const ComponentConnectionView &)=default
const OpenSim::Component & source() const
Definition open_sim_helpers.h:566
ComponentConnectionView(const OpenSim::Component &source, const OpenSim::Component &target, std::string socketName)
Definition open_sim_helpers.h:554
const OpenSim::Component & target() const
Definition open_sim_helpers.h:567
osc::CStringView socketName() const
Definition open_sim_helpers.h:568
Definition c_string_view.h:12
Definition string_name.h:14
Definition generator.h:32
Definition open_sim_helpers.h:71
Definition static_component_registries.h:3
Definition custom_decoration_generator.h:6
Definition component_registry.h:14
const OpenSim::Component * FindComponent(const OpenSim::Component &root, const OpenSim::ComponentPath &)
size_t GetNumChildren(const OpenSim::Component &c)
Definition open_sim_helpers.h:333
bool IsShowingMarkers(const OpenSim::Model &)
std::string SanitizeToOpenSimComponentName(std::string_view)
bool IsConcreteClassNameLexicographicallyLowerThan(const OpenSim::Component &, const OpenSim::Component &)
bool CanExtractPointInfoFrom(const OpenSim::Component &, const SimTK::State &)
osc::CStringView GetCoordDisplayValueUnitsString(const OpenSim::Coordinate &)
OpenSim::WrapObject & AddWrapObject(OpenSim::PhysicalFrame &, std::unique_ptr< OpenSim::WrapObject >)
const ComponentRegistryEntry< T > & At(const ComponentRegistry< T > &registry, size_t i)
Definition component_registry.h:59
std::string WriteObjectXMLToString(const OpenSim::Object &)
OpenSim::Component & UpdOwnerOrThrow(OpenSim::Component &root, const OpenSim::Component &)
std::unique_ptr< OpenSim::Model > LoadModel(const std::filesystem::path &)
const OpenSim::Component * FindFirstDescendentInclusive(const OpenSim::Component &component, bool(*predicate)(const OpenSim::Component &))
OpenSim::Component & AddComponent(OpenSim::Component &, std::unique_ptr< OpenSim::Component > &&)
bool IsShowingFrames(const OpenSim::Model &)
osc::cpp23::generator< ComponentConnectionView > ForEachInboundConnection(const OpenSim::Component *root, const OpenSim::Component *c, std::function< bool(const OpenSim::Component &)> filter=[](const OpenSim::Component &){ return true;})
void WriteModelMultibodySystemGraphAsDotViz(const OpenSim::Model &, std::ostream &)
const T * FindAncestorWithType(const OpenSim::Component *c)
Definition open_sim_helpers.h:370
void InitializeModel(OpenSim::Model &)
bool HasInputFileName(const OpenSim::Model &)
bool IsInclusiveChildOf(const OpenSim::Component *parent, const OpenSim::Component *c)
std::vector< const OpenSim::Component * > GetPathElements(const OpenSim::Component &)
OpenSim::AbstractSocket * FindSocketMut(OpenSim::Component &, const std::string &socketName)
const OpenSim::Appearance * TryGetAppearance(const OpenSim::Component &)
StorageIndexToModelStateVarMappingResult CreateStorageIndexToModelStatevarMapping(const OpenSim::Model &, const OpenSim::Storage &)
bool ActivateAllWrapObjectsIn(OpenSim::Model &)
U & Assign(OpenSim::Set< T, C > &set, size_t index, std::unique_ptr< U > el)
Definition open_sim_helpers.h:976
bool IsAbleToConnectTo(const OpenSim::AbstractSocket &, const OpenSim::Component &)
bool ToggleShowingContactGeometry(OpenSim::Model &)
void Append(OpenSim::ObjectProperty< T > &prop, const T &c)
Definition open_sim_helpers.h:942
const OpenSim::PhysicalFrame & GetFrameUsingExternalForceLookupHeuristic(const OpenSim::Model &, const std::string &bodyNameOrPath)
std::optional< size_t > IndexOf(const ComponentRegistryBase &, std::string_view componentClassName)
std::vector< OpenSim::AbstractSocket * > UpdAllSockets(OpenSim::Component &)
void UpdateStateVariablesFromStorageRow(OpenSim::Model &, SimTK::State &, const std::unordered_map< int, int > &columnIndexToModelStateVarIndex, const OpenSim::Storage &, int row)
std::vector< OpenSim::Coordinate * > UpdDefaultLockedCoordinatesInModel(OpenSim::Model &)
OpenSim::Appearance * TryUpdAppearance(OpenSim::Component &)
void ScaleModelMassPreserveMassDistribution(OpenSim::Model &model, const SimTK::State &state, double newMass)
std::optional< std::filesystem::path > TryFindInputFile(const OpenSim::Model &)
T * FindFirstDescendentOfTypeMut(OpenSim::Component &c)
Definition open_sim_helpers.h:420
void UpdateStateFromStorageTime(OpenSim::Model &, SimTK::State &, const std::unordered_map< int, int > &columnIndexToModelStateVarIndex, const OpenSim::Storage &, double time)
const OpenSim::Component * GetOwner(const OpenSim::Component &)
std::optional< PointInfo > TryExtractPointInfo(const OpenSim::Component &, const SimTK::State &)
bool ShouldShowInUI(const OpenSim::Component &)
const OpenSim::Component & GetOwnerOrThrow(const OpenSim::AbstractOutput &)
OpenSim::Component * FindComponentMut(OpenSim::Component &root, const OpenSim::ComponentPath &)
const T * end(const OpenSim::Array< T > &ary)
Definition open_sim_helpers.h:132
bool IsAllElementsUnique(const OpenSim::Array< T > &v)
Definition open_sim_helpers.h:226
bool OwnerIs(const OpenSim::Component &c)
Definition open_sim_helpers.h:303
osc::Color GetSuggestedBoneColor()
float ConvertCoordValueToDisplayValue(const OpenSim::Coordinate &, double v)
bool IsShowingWrapGeometry(const OpenSim::Model &)
bool ContainsComponent(const OpenSim::Component &root, const OpenSim::ComponentPath &)
OpenSim::Component * FindFirstDescendentMut(OpenSim::Component &component, bool(*predicate)(const OpenSim::Component &))
OpenSim::ComponentPath GetAbsolutePath(const OpenSim::Component &)
std::unordered_map< int, int > CreateStorageIndexToModelStatevarMappingWithWarnings(const OpenSim::Model &, const OpenSim::Storage &)
ptrdiff_t ssize(const OpenSim::Set< T, C > &s)
Definition open_sim_helpers.h:90
std::unique_ptr< T > Clone(const T &obj)
Definition open_sim_helpers.h:936
std::unique_ptr< OpenSim::Storage > LoadStorage(const OpenSim::Model &, const std::filesystem::path &, const StorageLoadingParameters &={})
std::optional< ForcePoint > TryGetContactForceInGround(const OpenSim::Model &, const SimTK::State &, const OpenSim::HuntCrossleyForce &)
std::optional< std::string > TryGetOrientationalPropertyName(const OpenSim::Component &)
bool TryDeleteComponentFromModel(OpenSim::Model &, OpenSim::Component &)
std::string GetMeshFileName(const OpenSim::Mesh &)
size_t DistanceFromRoot(const OpenSim::Component &)
OpenSim::PhysicalOffsetFrame & AddFrame(OpenSim::Joint &, std::unique_ptr< OpenSim::PhysicalOffsetFrame >)
const OpenSim::Frame * TryGetParentFrame(const OpenSim::Frame &)
bool TryDeleteItemFromSet(OpenSim::Set< T, C > &set, const U *item)
Definition open_sim_helpers.h:1019
std::optional< std::filesystem::path > FindGeometryFileAbsPath(const OpenSim::Model &, const OpenSim::Mesh &)
OpenSim::Geometry & AttachGeometry(OpenSim::Frame &, std::unique_ptr< OpenSim::Geometry >)
std::string RecommendedDocumentName(const OpenSim::Model &)
void TryEquilibrateMusclesOrLogWarning(OpenSim::Model &, SimTK::State &)
OpenSim::Constraint & AddConstraint(OpenSim::Model &, std::unique_ptr< OpenSim::Constraint >)
bool IsValidOpenSimComponentNameCharacter(char)
bool ToggleShowingFrames(OpenSim::Model &)
std::optional< LinesOfAction > GetEffectiveLinesOfActionInGround(const OpenSim::Muscle &, const SimTK::State &)
OpenSim::Joint & AddJoint(OpenSim::Model &, std::unique_ptr< OpenSim::Joint >)
bool IsNameLexographicallyLowerThan(const OpenSim::Component &, const OpenSim::Component &)
bool IsEmpty(const OpenSim::ComponentPath &)
std::optional< SimTK::Transform > TryGetParentToGroundTransform(const OpenSim::Component &, const SimTK::State &)
const OpenSim::AbstractSocket * FindSocket(const OpenSim::Component &, const std::string &socketName)
void ForEachComponentInclusive(const OpenSim::Component &, const std::function< void(const OpenSim::Component &)> &)
const OpenSim::Component & GetOwnerOr(const OpenSim::Component &, const OpenSim::Component &fallback)
const OpenSim::PhysicalFrame * TryGetParentToGroundFrame(const OpenSim::Component &)
std::vector< std::string > GetSocketNames(const OpenSim::Component &)
std::optional< LinesOfAction > GetAnatomicalLinesOfActionInGround(const OpenSim::Muscle &, const SimTK::State &)
void GetAbsolutePathString(const OpenSim::Component &, std::string &)
std::optional< ComponentSpatialRepresentation > TryGetSpatialRepresentation(const OpenSim::Component &, const SimTK::State &)
bool empty(const OpenSim::Set< T, C > &s)
Definition open_sim_helpers.h:149
OpenSim::Component * UpdOwner(OpenSim::Component &root, const OpenSim::Component &)
OpenSim::ComponentPath GetAbsolutePathOrEmpty(const OpenSim::Component *)
std::optional< std::string > TryGetOwnerName(const OpenSim::Component &)
std::ostream & operator<<(std::ostream &out, const DataFrame &data_frame)
Writes a pretty-printed representation of data_frame to out.
OpenSim::AbstractProperty * FindPropertyMut(OpenSim::Component &, const std::string &)
bool ToggleShowingForces(OpenSim::Model &)
const T * FindFirstDescendentOfType(const OpenSim::Component &c)
Definition open_sim_helpers.h:408
OpenSim::ModelComponent & AddModelComponent(OpenSim::Model &, std::unique_ptr< OpenSim::ModelComponent > &&)
bool IsChildOfA(const OpenSim::Component &c)
Definition open_sim_helpers.h:382
OpenSim::Marker & AddMarker(OpenSim::Model &, std::unique_ptr< OpenSim::Marker >)
void ForEachComponent(const OpenSim::Component &, const std::function< void(const OpenSim::Component &)> &)
SimTK::State & InitializeState(OpenSim::Model &)
osc::Color to_color(const OpenSim::Appearance &)
const OpenSim::Component * FindFirstAncestorInclusive(const OpenSim::Component *, bool(*pred)(const OpenSim::Component *))
bool IsConnectedTo(const OpenSim::AbstractSocket &, const OpenSim::Component &)
std::vector< const OpenSim::WrapObject * > GetAllWrapObjectsReferencedBy(const OpenSim::GeometryPath &)
OpenSim::Component & AddComponentToAppropriateSet(OpenSim::Model &, std::unique_ptr< OpenSim::Component >)
bool DeactivateAllWrapObjectsIn(OpenSim::Model &)
OpenSim::Body & AddBody(OpenSim::Model &, std::unique_ptr< OpenSim::Body >)
std::string GetDisplayName(const OpenSim::Geometry &)
const T * begin(const OpenSim::Array< T > &ary)
Definition open_sim_helpers.h:118
std::optional< size_t > FindJointInParentJointSet(const OpenSim::Joint &)
void WriteComponentTopologyGraphAsDotViz(const OpenSim::Component &, std::ostream &)
bool EraseAt(OpenSim::Set< T, C > &s, size_t i)
Definition open_sim_helpers.h:218
std::optional< std::string > TryGetPositionalPropertyName(const OpenSim::Component &)
bool IsShowingForces(const OpenSim::Model &)
void CopyCommonJointProperties(const OpenSim::Joint &src, OpenSim::Joint &dest)
osc::CStringView GetMotionTypeDisplayName(const OpenSim::Coordinate &)
const OpenSim::Component * FindFirstDescendent(const OpenSim::Component &component, bool(*predicate)(const OpenSim::Component &))
bool HasModelFileExtension(const std::filesystem::path &path)
void OverwriteGeometry(OpenSim::Model &, OpenSim::Geometry &oldGeometry, std::unique_ptr< OpenSim::Geometry > newGeometry)
const OpenSim::AbstractOutput * FindOutput(const OpenSim::Component &, const std::string &outputName)
osc::StringName GetAbsolutePathStringName(const OpenSim::Component &)
bool IsShowingContactGeometry(const OpenSim::Model &)
std::vector< const OpenSim::AbstractSocket * > GetAllSockets(const OpenSim::Component &)
std::vector< const OpenSim::Coordinate * > GetCoordinatesInModel(const OpenSim::Model &)
bool IsNameLexographicallyGreaterThan(const Ptr &a, const Ptr &b)
Definition open_sim_helpers.h:267
void RecursivelyReassignAllSockets(OpenSim::Component &root, const OpenSim::Component &from, const OpenSim::Component &to)
OpenSim::ComponentPath GetRootComponentPath()
double ConvertCoordDisplayValueToStorageValue(const OpenSim::Coordinate &, float v)
void FinalizeFromProperties(OpenSim::Model &)
size_t size(const OpenSim::Set< T, C > &s)
Definition open_sim_helpers.h:80
void FinalizeConnections(OpenSim::Model &)
OpenSim::SimpleProperty< T > * FindSimplePropertyMut(OpenSim::Component &c, const std::string &name)
Definition open_sim_helpers.h:592
bool ToggleShowingMarkers(OpenSim::Model &)
bool TrySetAppearancePropertyIsVisibleTo(OpenSim::Component &, bool)
void Clear(OpenSim::ComponentPath &)
bool ToggleShowingWrapGeometry(OpenSim::Model &)
Definition open_sim_helpers.h:1064
std::string locationVec3PropertyName
Definition open_sim_helpers.h:1066
SimTK::Transform parentToGround
Definition open_sim_helpers.h:1065
std::optional< std::string > maybeOrientationVec3EulersPropertyName
Definition open_sim_helpers.h:1067
Definition open_sim_helpers.h:784
osc::Vector3 force
Definition open_sim_helpers.h:785
osc::Vector3 point
Definition open_sim_helpers.h:786
Definition open_sim_helpers.h:774
osc::Ray origin
Definition open_sim_helpers.h:775
osc::Ray insertion
Definition open_sim_helpers.h:776
Definition open_sim_helpers.h:805
osc::Vector3 location
Definition open_sim_helpers.h:814
PointInfo(osc::Vector3 location_, OpenSim::ComponentPath frameAbsPath_)
Definition open_sim_helpers.h:806
OpenSim::ComponentPath frameAbsPath
Definition open_sim_helpers.h:815
Definition open_sim_helpers.h:1101
std::vector< std::string > stateVariablesMissingInStorage
Definition open_sim_helpers.h:1103
std::unordered_map< int, int > storageIndexToModelStatevarIndex
Definition open_sim_helpers.h:1102
Definition open_sim_helpers.h:1084
bool convertRotationalValuesToRadians
Definition open_sim_helpers.h:1085
std::optional< double > resampleToFrequency
Definition open_sim_helpers.h:1086
Definition ray.h:13