1 /* -------------------------------------------------------------------------- *
2 * OpenSim: ObjectGroup.cpp *
3 * -------------------------------------------------------------------------- *
4 * The OpenSim API is a toolkit for musculoskeletal modeling and simulation. *
5 * See http://opensim.stanford.edu and the NOTICE file for more information. *
6 * OpenSim is developed at Stanford University and supported by the US *
7 * National Institutes of Health (U54 GM072970, R24 HD065690) and by DARPA *
8 * through the Warrior Web program. *
9 * *
10 * Copyright (c) 2005-2017 Stanford University and the Authors *
11 * Author(s): Peter Loan *
12 * *
13 * Licensed under the Apache License, Version 2.0 (the "License"); you may *
14 * not use this file except in compliance with the License. You may obtain a *
15 * copy of the License at http://www.apache.org/licenses/LICENSE-2.0. *
16 * *
17 * Unless required by applicable law or agreed to in writing, software *
18 * distributed under the License is distributed on an "AS IS" BASIS, *
19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
20 * See the License for the specific language governing permissions and *
21 * limitations under the License. *
22 * -------------------------------------------------------------------------- */
23
24 //=============================================================================
25 // INCLUDES
26 //=============================================================================
27 #include "ObjectGroup.h"
28
29 //=============================================================================
30 // STATICS
31 //=============================================================================
32 using namespace std;
33 using namespace OpenSim;
34
35 //=============================================================================
36 // CONSTRUCTOR(S) AND DESTRUCTOR
37 //=============================================================================
38 //_____________________________________________________________________________
39 /**
40 * Default constructor.
41 */
ObjectGroup()42 ObjectGroup::ObjectGroup() :
43 Object(),
44 _memberNames(_memberNamesProp.getValueStrArray())
45 {
46 setNull();
47 setupProperties();
48 }
49
50 //_____________________________________________________________________________
51 /**
52 * Constructor taking the group name but no member names.
53 */
ObjectGroup(const string & aName)54 ObjectGroup::ObjectGroup(const string& aName) :
55 Object(),
56 _memberNames(_memberNamesProp.getValueStrArray())
57 {
58 setName(aName);
59 setNull();
60 setupProperties();
61 }
62
63 //_____________________________________________________________________________
64 /**
65 * Destructor.
66 */
~ObjectGroup()67 ObjectGroup::~ObjectGroup()
68 {
69 }
70
71 //_____________________________________________________________________________
72 /**
73 * Copy constructor.
74 *
75 * @param aGroup Group to be copied.
76 */
ObjectGroup(const ObjectGroup & aGroup)77 ObjectGroup::ObjectGroup(const ObjectGroup &aGroup) :
78 Object(aGroup),
79 _memberNames(_memberNamesProp.getValueStrArray())
80 {
81 setupProperties();
82 copyData(aGroup);
83 }
84
85 //=============================================================================
86 // CONSTRUCTION METHODS
87 //=============================================================================
88 //_____________________________________________________________________________
89 /**
90 * Copy data members from one ObjectGroup to another.
91 *
92 * @param aGroup ObjectGroup to be copied.
93 */
copyData(const ObjectGroup & aGroup)94 void ObjectGroup::copyData(const ObjectGroup &aGroup)
95 {
96 _memberNames = aGroup._memberNames;
97 _memberObjects = aGroup._memberObjects; // TODO: this copies pointers... but as long as call setup afterwards it should be okay
98 }
99
100 //_____________________________________________________________________________
101 /**
102 * Set the data members of this ObjectGroup to their null values.
103 */
setNull()104 void ObjectGroup::setNull()
105 {
106 _memberObjects.setSize(0);
107 }
108
109 //_____________________________________________________________________________
110 /**
111 * Connect properties to local pointers.
112 */
setupProperties()113 void ObjectGroup::setupProperties()
114 {
115 _memberNamesProp.setName("members");
116 _propertySet.append(&_memberNamesProp);
117 }
118
119 //=============================================================================
120 // OPERATORS
121 //=============================================================================
122 //_____________________________________________________________________________
123 /**
124 * Assignment operator.
125 *
126 * @return Reference to this object.
127 */
operator =(const ObjectGroup & aGroup)128 ObjectGroup& ObjectGroup::operator=(const ObjectGroup &aGroup)
129 {
130 // BASE CLASS
131 Object::operator=(aGroup);
132
133 copyData(aGroup);
134
135 return(*this);
136 }
137
138 //_____________________________________________________________________________
139 /**
140 * Check if the group contains an object with a certain name.
141 *
142 * @param aName the name of the object.
143 * @return Boolean indicating whether or not the group contains the object.
144 */
contains(const string & aName) const145 bool ObjectGroup::contains(const string& aName) const
146 {
147 for(int i=0; i<_memberObjects.getSize(); i++)
148 if(_memberObjects[i] && _memberObjects[i]->getName()==aName)
149 return true;
150 return false;
151 }
152
153 //_____________________________________________________________________________
154 /**
155 * Add an object to the group.
156 *
157 * @param aObject pointer to the object.
158 */
add(const Object * aObject)159 void ObjectGroup::add(const Object* aObject)
160 {
161 if (aObject != NULL) {
162 // check if object is already a member of this group
163 if (_memberObjects.findIndex(aObject) != -1) return;
164
165 _memberObjects.append(aObject);
166 _memberNames.append(aObject->getName());
167 }
168 }
169
170 //_____________________________________________________________________________
171 /**
172 * Remove an object from the group.
173 *
174 * @param aObject pointer to the object.
175 */
remove(const Object * aObject)176 void ObjectGroup::remove(const Object* aObject)
177 {
178 if (aObject != NULL)
179 {
180 int index = _memberObjects.findIndex(const_cast<Object*>(aObject));
181 if(index >= 0) {
182 _memberObjects.remove(index);
183 _memberNames.remove(index);
184 }
185 }
186 }
187
188 //_____________________________________________________________________________
189 /**
190 * Replace an object in the group with another object.
191 *
192 * @param aOldObject pointer to the old object.
193 * @param aNewObject pointer to the new object.
194 */
replace(const Object * aOldObject,const Object * aNewObject)195 void ObjectGroup::replace(const Object* aOldObject, const Object* aNewObject)
196 {
197 if (aOldObject != NULL && aNewObject != NULL)
198 {
199 int index = _memberObjects.findIndex(const_cast<Object*>(aOldObject));
200 if(index >= 0) {
201 _memberObjects.updElt(index) = aNewObject;
202 _memberNames.updElt(index) = aNewObject->getName();
203 }
204 }
205 }
206
207 //_____________________________________________________________________________
208 /**
209 * Set up the group, after the member names have been deserialized.
210 * For each member name, if the name is the name of an object in
211 * aObject (the objects in the set that this group belongs to), then
212 * store a pointer to the object in the same index in _memberObjects
213 * as the name is in _memberNames. If the member name does not correspond
214 * to an object in aObjects, remove the name from _memberNames.
215 *
216 * @param aObjects list of objects that are in the set that this group belongs to.
217 */
setupGroup(ArrayPtrs<Object> & aObjects)218 void ObjectGroup::setupGroup(ArrayPtrs<Object>& aObjects)
219 {
220 _memberObjects.setSize(0); // clear existing contents
221 for (int i=0; i<_memberNames.getSize();) {
222 int index = aObjects.getIndex(_memberNames.get(i));
223 if (index > -1) {
224 _memberObjects.insert(i, aObjects.get(index));
225 i++;
226 } else {
227 _memberNames.remove(i);
228 }
229 }
230 }
231