@@ -20,6 +20,8 @@ SimulationModel::SimulationModel()
2020 m_solid_poissonRatio = 0 .3f ;
2121 m_solid_normalizeShear = false ;
2222 m_solid_normalizeStretch = false ;
23+
24+ m_groupsInitialized = false ;
2325}
2426
2527SimulationModel::~SimulationModel (void )
@@ -86,6 +88,11 @@ SimulationModel::ConstraintVector & SimulationModel::getConstraints()
8688 return m_constraints;
8789}
8890
91+ SimulationModel::ConstraintGroupVector & SimulationModel::getConstraintGroups ()
92+ {
93+ return m_constraintGroups;
94+ }
95+
8996void SimulationModel::updateConstraints ()
9097{
9198 for (unsigned int i = 0 ; i < m_constraints.size (); i++)
@@ -98,7 +105,10 @@ bool SimulationModel::addBallJoint(const unsigned int rbIndex1, const unsigned i
98105 BallJoint *bj = new BallJoint ();
99106 const bool res = bj->initConstraint (*this , rbIndex1, rbIndex2, pos);
100107 if (res)
108+ {
101109 m_constraints.push_back (bj);
110+ m_groupsInitialized = false ;
111+ }
102112 return res;
103113}
104114
@@ -107,7 +117,10 @@ bool SimulationModel::addBallOnLineJoint(const unsigned int rbIndex1, const unsi
107117 BallOnLineJoint *bj = new BallOnLineJoint ();
108118 const bool res = bj->initConstraint (*this , rbIndex1, rbIndex2, pos, dir);
109119 if (res)
120+ {
110121 m_constraints.push_back (bj);
122+ m_groupsInitialized = false ;
123+ }
111124 return res;
112125}
113126
@@ -116,7 +129,10 @@ bool SimulationModel::addHingeJoint(const unsigned int rbIndex1, const unsigned
116129 HingeJoint *hj = new HingeJoint ();
117130 const bool res = hj->initConstraint (*this , rbIndex1, rbIndex2, pos, axis);
118131 if (res)
132+ {
119133 m_constraints.push_back (hj);
134+ m_groupsInitialized = false ;
135+ }
120136 return res;
121137}
122138
@@ -125,7 +141,10 @@ bool SimulationModel::addUniversalJoint(const unsigned int rbIndex1, const unsig
125141 UniversalJoint *uj = new UniversalJoint ();
126142 const bool res = uj->initConstraint (*this , rbIndex1, rbIndex2, pos, axis1, axis2);
127143 if (res)
144+ {
128145 m_constraints.push_back (uj);
146+ m_groupsInitialized = false ;
147+ }
129148 return res;
130149}
131150
@@ -135,7 +154,10 @@ bool SimulationModel::addRigidBodyParticleBallJoint(const unsigned int rbIndex,
135154 RigidBodyParticleBallJoint *bj = new RigidBodyParticleBallJoint ();
136155 const bool res = bj->initConstraint (*this , rbIndex, particleIndex);
137156 if (res)
157+ {
138158 m_constraints.push_back (bj);
159+ m_groupsInitialized = false ;
160+ }
139161 return res;
140162}
141163
@@ -144,7 +166,10 @@ bool SimulationModel::addDistanceConstraint(const unsigned int particle1, const
144166 DistanceConstraint *c = new DistanceConstraint ();
145167 const bool res = c->initConstraint (*this , particle1, particle2);
146168 if (res)
169+ {
147170 m_constraints.push_back (c);
171+ m_groupsInitialized = false ;
172+ }
148173 return res;
149174}
150175
@@ -154,7 +179,10 @@ bool SimulationModel::addDihedralConstraint(const unsigned int particle1, const
154179 DihedralConstraint *c = new DihedralConstraint ();
155180 const bool res = c->initConstraint (*this , particle1, particle2, particle3, particle4);
156181 if (res)
182+ {
157183 m_constraints.push_back (c);
184+ m_groupsInitialized = false ;
185+ }
158186 return res;
159187}
160188
@@ -164,7 +192,10 @@ bool SimulationModel::addIsometricBendingConstraint(const unsigned int particle1
164192 IsometricBendingConstraint *c = new IsometricBendingConstraint ();
165193 const bool res = c->initConstraint (*this , particle1, particle2, particle3, particle4);
166194 if (res)
195+ {
167196 m_constraints.push_back (c);
197+ m_groupsInitialized = false ;
198+ }
168199 return res;
169200}
170201
@@ -174,7 +205,10 @@ bool SimulationModel::addFEMTriangleConstraint(const unsigned int particle1, con
174205 FEMTriangleConstraint *c = new FEMTriangleConstraint ();
175206 const bool res = c->initConstraint (*this , particle1, particle2, particle3);
176207 if (res)
208+ {
177209 m_constraints.push_back (c);
210+ m_groupsInitialized = false ;
211+ }
178212 return res;
179213}
180214
@@ -184,7 +218,10 @@ bool SimulationModel::addStrainTriangleConstraint(const unsigned int particle1,
184218 StrainTriangleConstraint *c = new StrainTriangleConstraint ();
185219 const bool res = c->initConstraint (*this , particle1, particle2, particle3);
186220 if (res)
221+ {
187222 m_constraints.push_back (c);
223+ m_groupsInitialized = false ;
224+ }
188225 return res;
189226}
190227
@@ -194,7 +231,10 @@ bool SimulationModel::addVolumeConstraint(const unsigned int particle1, const un
194231 VolumeConstraint *c = new VolumeConstraint ();
195232 const bool res = c->initConstraint (*this , particle1, particle2, particle3, particle4);
196233 if (res)
234+ {
197235 m_constraints.push_back (c);
236+ m_groupsInitialized = false ;
237+ }
198238 return res;
199239}
200240
@@ -204,7 +244,10 @@ bool SimulationModel::addFEMTetConstraint(const unsigned int particle1, const un
204244 FEMTetConstraint *c = new FEMTetConstraint ();
205245 const bool res = c->initConstraint (*this , particle1, particle2, particle3, particle4);
206246 if (res)
247+ {
207248 m_constraints.push_back (c);
249+ m_groupsInitialized = false ;
250+ }
208251 return res;
209252}
210253
@@ -214,7 +257,10 @@ bool SimulationModel::addStrainTetConstraint(const unsigned int particle1, const
214257 StrainTetConstraint *c = new StrainTetConstraint ();
215258 const bool res = c->initConstraint (*this , particle1, particle2, particle3, particle4);
216259 if (res)
260+ {
217261 m_constraints.push_back (c);
262+ m_groupsInitialized = false ;
263+ }
218264 return res;
219265}
220266
@@ -223,7 +269,10 @@ bool SimulationModel::addShapeMatchingConstraint(const unsigned int numberOfPart
223269 ShapeMatchingConstraint *c = new ShapeMatchingConstraint (numberOfParticles);
224270 const bool res = c->initConstraint (*this , particleIndices, numClusters);
225271 if (res)
272+ {
226273 m_constraints.push_back (c);
274+ m_groupsInitialized = false ;
275+ }
227276 return res;
228277}
229278
@@ -270,3 +319,66 @@ void SimulationModel::addTetModel(
270319}
271320
272321
322+
323+ void SimulationModel::initConstraintGroups ()
324+ {
325+ if (m_groupsInitialized)
326+ return ;
327+
328+ const unsigned int numConstraints = (unsigned int ) m_constraints.size ();
329+ const unsigned int numParticles = (unsigned int ) m_particles.size ();
330+ const unsigned int numRigidBodies = (unsigned int ) m_rigidBodies.size ();
331+ const unsigned int numBodies = numParticles + numRigidBodies;
332+ m_constraintGroups.clear ();
333+
334+ // Maps in which group a particle is or 0 if not yet mapped
335+ std::vector<unsigned char *> mapping;
336+
337+ for (unsigned int i = 0 ; i < numConstraints; i++)
338+ {
339+ Constraint *constraint = m_constraints[i];
340+
341+ bool addToNewGroup = true ;
342+ for (unsigned int j = 0 ; j < m_constraintGroups.size (); j++)
343+ {
344+ bool addToThisGroup = true ;
345+
346+ for (unsigned int k = 0 ; k < constraint->m_numberOfBodies ; k++)
347+ {
348+ if (mapping[j][constraint->m_bodies [k]] != 0 )
349+ {
350+ addToThisGroup = false ;
351+ break ;
352+ }
353+ }
354+
355+ if (addToThisGroup)
356+ {
357+ m_constraintGroups[j].push_back (i);
358+
359+ for (unsigned int k = 0 ; k < constraint->m_numberOfBodies ; k++)
360+ mapping[j][constraint->m_bodies [k]] = 1 ;
361+
362+ addToNewGroup = false ;
363+ break ;
364+ }
365+ }
366+ if (addToNewGroup)
367+ {
368+ mapping.push_back (new unsigned char [numBodies]);
369+ memset (mapping[mapping.size () - 1 ], 0 , sizeof (unsigned char )*numBodies);
370+ m_constraintGroups.resize (m_constraintGroups.size () + 1 );
371+ m_constraintGroups[m_constraintGroups.size ()-1 ].push_back (i);
372+ for (unsigned int k = 0 ; k < constraint->m_numberOfBodies ; k++)
373+ mapping[m_constraintGroups.size () - 1 ][constraint->m_bodies [k]] = 1 ;
374+ }
375+ }
376+
377+ for (unsigned int i = 0 ; i < mapping.size (); i++)
378+ {
379+ delete[] mapping[i];
380+ }
381+ mapping.clear ();
382+
383+ m_groupsInitialized = true ;
384+ }
0 commit comments