00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef SOFA_COMPONENT_CONSTRAINT_ATTACHCONSTRAINT_INL
00026 #define SOFA_COMPONENT_CONSTRAINT_ATTACHCONSTRAINT_INL
00027
00028 #include <sofa/core/componentmodel/behavior/PairInteractionConstraint.inl>
00029 #include <sofa/component/constraint/AttachConstraint.h>
00030 #include <sofa/helper/gl/template.h>
00031 #include <sofa/defaulttype/RigidTypes.h>
00032 #include <iostream>
00033
00034 #include <sofa/component/topology/PointSubset.h>
00035
00036 using std::cerr;
00037 using std::endl;
00038
00039 namespace sofa
00040 {
00041
00042 namespace component
00043 {
00044
00045 namespace constraint
00046 {
00047
00048 using namespace core::componentmodel::topology;
00049
00050 using namespace sofa::defaulttype;
00051 using namespace sofa::helper;
00052 using namespace sofa::core::componentmodel::behavior;
00053
00054 template<>
00055 inline void AttachConstraint<defaulttype::Rigid3dTypes>::projectPosition(Coord& x1, Coord& x2, bool freeRotations, unsigned index)
00056 {
00057 x2.getCenter() = x1.getCenter();
00058 if (!freeRotations)
00059 {
00060 if (!restRotations.empty())
00061 {
00062 if (index+1 >= lastDist.size() || activeFlags[index+1])
00063 x2.getOrientation() = x1.getOrientation()*restRotations[index];
00064 else
00065 {
00066 Real fact = -lastDist[index] / (lastDist[index+1]-lastDist[index]);
00067 Vector3 axis(restRotations[index][0], restRotations[index][1], restRotations[index][2]);
00068 Real angle = acos(restRotations[index][3])*2;
00069
00070 x2.getOrientation() = x1.getOrientation()*Quat(axis,angle*fact);
00071 }
00072 }
00073 else
00074 x2.getOrientation() = x1.getOrientation();
00075 }
00076 }
00077
00078 template<>
00079 inline void AttachConstraint<defaulttype::Rigid3fTypes>::projectPosition(Coord& x1, Coord& x2, bool freeRotations, unsigned )
00080 {
00081 x2.getCenter() = x1.getCenter();
00082 if (!freeRotations)
00083 x2.getOrientation() = x1.getOrientation();
00084 }
00085
00086 template<>
00087 inline void AttachConstraint<defaulttype::Rigid2dTypes>::projectPosition(Coord& x1, Coord& x2, bool freeRotations, unsigned )
00088 {
00089 x2.getCenter() = x1.getCenter();
00090 if (!freeRotations)
00091 x2.getOrientation() = x1.getOrientation();
00092 }
00093
00094 template<>
00095 inline void AttachConstraint<defaulttype::Rigid2fTypes>::projectPosition(Coord& x1, Coord& x2, bool freeRotations, unsigned )
00096 {
00097 x2.getCenter() = x1.getCenter();
00098 if (!freeRotations)
00099 x2.getOrientation() = x1.getOrientation();
00100 }
00101
00102 template<>
00103 inline void AttachConstraint<defaulttype::Rigid3dTypes>::projectVelocity(Deriv& x1, Deriv& x2, bool freeRotations, unsigned )
00104 {
00105 x2.getVCenter() = x1.getVCenter();
00106 if (!freeRotations)
00107 x2.getVOrientation() = x1.getVOrientation();
00108
00109 }
00110
00111 template<>
00112 inline void AttachConstraint<defaulttype::Rigid3fTypes>::projectVelocity(Deriv& x1, Deriv& x2, bool freeRotations, unsigned )
00113 {
00114 x2.getVCenter() = x1.getVCenter();
00115 if (!freeRotations)
00116 x2.getVOrientation() = x1.getVOrientation();
00117 }
00118
00119 template<>
00120 inline void AttachConstraint<defaulttype::Rigid2dTypes>::projectVelocity(Deriv& x1, Deriv& x2, bool freeRotations, unsigned )
00121 {
00122 x2.getVCenter() = x1.getVCenter();
00123 if (!freeRotations)
00124 x2.getVOrientation() = x1.getVOrientation();
00125 }
00126
00127 template<>
00128 inline void AttachConstraint<defaulttype::Rigid2fTypes>::projectVelocity(Deriv& x1, Deriv& x2, bool freeRotations, unsigned )
00129 {
00130 x2.getVCenter() = x1.getVCenter();
00131 if (!freeRotations)
00132 x2.getVOrientation() = x1.getVOrientation();
00133 }
00134
00135 template<>
00136 inline void AttachConstraint<defaulttype::Rigid3dTypes>::projectResponse(Deriv& dx1, Deriv& dx2, bool freeRotations, bool twoway, unsigned )
00137 {
00138 if (!twoway)
00139 {
00140 if (!freeRotations)
00141 dx2 = Deriv();
00142 else
00143 dx2.getVCenter().clear();
00144 }
00145 else
00146 {
00147 if (!freeRotations)
00148 {
00149 dx1 += dx2;
00150 dx2 = dx1;
00151 }
00152 else
00153 {
00154 dx1.getVCenter() += dx2.getVCenter();
00155 dx2.getVCenter() = dx1.getVCenter();
00156 }
00157 }
00158 }
00159
00160 template<>
00161 inline void AttachConstraint<defaulttype::Rigid3fTypes>::projectResponse(Deriv& dx1, Deriv& dx2, bool freeRotations, bool twoway, unsigned )
00162 {
00163 if (!twoway)
00164 {
00165 if (!freeRotations)
00166 dx2 = Deriv();
00167 else
00168 dx2.getVCenter().clear();
00169 }
00170 else
00171 {
00172 if (!freeRotations)
00173 {
00174 dx1 += dx2;
00175 dx2 = dx1;
00176 }
00177 else
00178 {
00179 dx1.getVCenter() += dx2.getVCenter();
00180 dx2.getVCenter() = dx1.getVCenter();
00181 }
00182 }
00183 }
00184
00185 template<>
00186 inline void AttachConstraint<defaulttype::Rigid2dTypes>::projectResponse(Deriv& dx1, Deriv& dx2, bool freeRotations, bool twoway, unsigned )
00187 {
00188 if (!twoway)
00189 {
00190 if (!freeRotations)
00191 dx2 = Deriv();
00192 else
00193 dx2.getVCenter().clear();
00194 }
00195 else
00196 {
00197 if (!freeRotations)
00198 {
00199 dx1 += dx2;
00200 dx2 = dx1;
00201 }
00202 else
00203 {
00204 dx1.getVCenter() += dx2.getVCenter();
00205 dx2.getVCenter() = dx1.getVCenter();
00206 }
00207 }
00208 }
00209
00210 template<>
00211 inline void AttachConstraint<defaulttype::Rigid2fTypes>::projectResponse(Deriv& dx1, Deriv& dx2, bool freeRotations, bool twoway, unsigned )
00212 {
00213 if (!twoway)
00214 {
00215 if (!freeRotations)
00216 dx2 = Deriv();
00217 else
00218 dx2.getVCenter().clear();
00219 }
00220 else
00221 {
00222 if (!freeRotations)
00223 {
00224 dx1 += dx2;
00225 dx2 = dx1;
00226 }
00227 else
00228 {
00229 dx1.getVCenter() += dx2.getVCenter();
00230 dx2.getVCenter() = dx1.getVCenter();
00231 }
00232 }
00233 }
00234
00235 template<>
00236 inline unsigned int AttachConstraint<defaulttype::Rigid3dTypes>::DerivConstrainedSize(bool freeRotations)
00237 {
00238 if (freeRotations)
00239 return Deriv::static_size;
00240 else
00241 return Deriv::size();
00242 }
00243
00244 template<>
00245 inline unsigned int AttachConstraint<defaulttype::Rigid3fTypes>::DerivConstrainedSize(bool freeRotations)
00246 {
00247 if (freeRotations)
00248 return Deriv::static_size;
00249 else
00250 return Deriv::size();
00251 }
00252
00253 template<>
00254 inline unsigned int AttachConstraint<defaulttype::Rigid2dTypes>::DerivConstrainedSize(bool freeRotations)
00255 {
00256 if (freeRotations)
00257 return Deriv::static_size;
00258 else
00259 return Deriv::size();
00260 }
00261
00262 template<>
00263 inline unsigned int AttachConstraint<defaulttype::Rigid2fTypes>::DerivConstrainedSize(bool freeRotations)
00264 {
00265 if (freeRotations)
00266 return Deriv::static_size;
00267 else
00268 return Deriv::size();
00269 }
00270
00271 #if 0
00272
00273 template< class DataTypes>
00274 bool AttachConstraint<DataTypes>::FCTestNewPointFunction(int , void* param, const sofa::helper::vector< unsigned int > &, const sofa::helper::vector< double >& )
00275 {
00276 AttachConstraint<DataTypes> *fc= (AttachConstraint<DataTypes> *)param;
00277 if (fc) {
00278 return true;
00279 }else{
00280 return false;
00281 }
00282 }
00283
00284
00285 template< class DataTypes>
00286 void AttachConstraint<DataTypes>::FCRemovalFunction(int pointIndex, void* param)
00287 {
00288 AttachConstraint<DataTypes> *fc= (AttachConstraint<DataTypes> *)param;
00289 if (fc) {
00290 fc->removeConstraint((unsigned int) pointIndex);
00291 }
00292 return;
00293 }
00294 #endif
00295
00296 template <class DataTypes>
00297 AttachConstraint<DataTypes>::AttachConstraint()
00298 : f_indices1( initData(&f_indices1,"indices1","Indices of the source points on the first model") )
00299 , f_indices2( initData(&f_indices2,"indices2","Indices of the fixed points on the second model") )
00300 , f_radius( initData(&f_radius,(Real)-1,"radius", "Radius to search corresponding fixed point if no indices are given") )
00301 , f_twoWay( initData(&f_twoWay,false,"twoWay", "true if forces should be projected back from model2 to model1") )
00302 , f_freeRotations( initData(&f_freeRotations,false,"freeRotations", "true to keep rotations free (only used for Rigid DOFs)") )
00303 , f_lastFreeRotation( initData(&f_lastFreeRotation,false,"lastFreeRotation", "true to keep rotation of the last attached point free (only used for Rigid DOFs)") )
00304 , f_restRotations( initData(&f_restRotations,false,"restRotations", "true to use rest rotations local offsets (only used for Rigid DOFs)") )
00305 , f_lastPos( initData(&f_lastPos,"lastPos", "position at which the attach constraint should become inactive") )
00306 , f_lastDir( initData(&f_lastDir,"lastDir", "direction from lastPos at which the attach coustraint should become inactive") )
00307 , f_clamp( initData(&f_clamp, false,"clamp", "true to clamp particles at lastPos instead of freeing them.") )
00308 {
00309
00310
00311
00312
00313
00314 }
00315
00316 #if 0
00317
00318 template <class DataTypes> void AttachConstraint<DataTypes>::handleTopologyChange()
00319 {
00320 std::list<const TopologyChange *>::const_iterator itBegin=topology->firstChange();
00321 std::list<const TopologyChange *>::const_iterator itEnd=topology->lastChange();
00322
00323 f_indices.beginEdit()->handleTopologyEvents(itBegin,itEnd,this->getMState()->getSize());
00324 }
00325 #endif
00326
00327 template <class DataTypes>
00328 AttachConstraint<DataTypes>::~AttachConstraint()
00329 {
00330 }
00331
00332 template <class DataTypes>
00333 void AttachConstraint<DataTypes>::clearConstraints()
00334 {
00335 f_indices1.beginEdit()->clear();
00336 f_indices1.endEdit();
00337 f_indices2.beginEdit()->clear();
00338 f_indices2.endEdit();
00339 }
00340
00341 template <class DataTypes>
00342 void AttachConstraint<DataTypes>::addConstraint(unsigned int index1, unsigned int index2)
00343 {
00344 f_indices1.beginEdit()->push_back(index1);
00345 f_indices1.endEdit();
00346 f_indices2.beginEdit()->push_back(index2);
00347 f_indices2.endEdit();
00348 }
00349
00350
00351
00352
00353 template <class DataTypes>
00354 void AttachConstraint<DataTypes>::init()
00355 {
00356 this->core::componentmodel::behavior::PairInteractionConstraint<DataTypes>::init();
00357
00358 topology = getContext()->getMeshTopology();
00359
00360 if (f_radius.getValue() >= 0 && f_indices1.getValue().size()==0 && f_indices2.getValue().size()==0 && this->mstate1 && this->mstate2)
00361 {
00362 const Real maxR = f_radius.getValue();
00363 VecCoord& x1 = *this->mstate1->getX();
00364 VecCoord& x2 = *this->mstate2->getX();
00365 for (unsigned int i2=0; i2<x2.size(); ++i2)
00366 {
00367 int best = -1;
00368 Real bestR = maxR;
00369 for (unsigned int i1=0; i1<x1.size(); ++i1)
00370 {
00371 Real r = (x2[i2]-x1[i1]).norm();
00372 if (r <= bestR)
00373 {
00374 best = i1;
00375 bestR = r;
00376 }
00377 }
00378 if (best >= 0)
00379 {
00380 addConstraint(best, i2);
00381 }
00382 }
00383 }
00384 #if 0
00385
00386 topology::PointSubset my_subset = f_indices.getValue();
00387
00388 my_subset.setTestFunction(FCTestNewPointFunction);
00389 my_subset.setRemovalFunction(FCRemovalFunction);
00390
00391 my_subset.setTestParameter( (void *) this );
00392 my_subset.setRemovalParameter( (void *) this );
00393 #endif
00394 activeFlags.resize(f_indices2.getValue().size());
00395 std::fill(activeFlags.begin(), activeFlags.end(), true);
00396 if (f_restRotations.getValue())
00397 calcRestRotations();
00398 }
00399
00400 template <class DataTypes>
00401 void AttachConstraint<DataTypes>::calcRestRotations()
00402 {
00403 }
00404
00405 template <>
00406 void AttachConstraint<Rigid3dTypes>::calcRestRotations()
00407 {
00408 const SetIndexArray & indices2 = f_indices2.getValue().getArray();
00409 const VecCoord& x0 = *this->mstate2->getX0();
00410 restRotations.resize(indices2.size());
00411 for (unsigned int i=0;i<indices2.size(); ++i)
00412 {
00413 Quat q(0,0,0,1);
00414 if (indices2[i] < x0.size()-1)
00415 {
00416 Vector3 dp0 = x0[indices2[i]].vectorToChild(x0[indices2[i]+1].getCenter()-x0[indices2[i]].getCenter());
00417 dp0.normalize();
00418 Vector3 y = cross(dp0, Vector3(1,0,0));
00419 y.normalize();
00420 double alpha = acos(dp0[0]);
00421 q = Quat(y,alpha);
00422 std::cout << "restRotations x2["<<indices2[i]<<"]="<<q<<" dp0="<<dp0<<" qx="<<q.rotate(Vector3(1,0,0))<<std::endl;
00423 }
00424 restRotations[i] = q;
00425 }
00426 }
00427
00428 template <class DataTypes>
00429 void AttachConstraint<DataTypes>::projectPosition(VecCoord& res1, VecCoord& res2)
00430 {
00431 const SetIndexArray & indices1 = f_indices1.getValue().getArray();
00432 const SetIndexArray & indices2 = f_indices2.getValue().getArray();
00433 const bool freeRotations = f_freeRotations.getValue();
00434 const bool lastFreeRotation = f_lastFreeRotation.getValue();
00435 const bool last = (f_lastDir.isSet() && f_lastDir.getValue().norm() > 1.0e-10);
00436 const bool clamp = f_clamp.getValue();
00437 const bool log = this->f_printLog.getValue();
00438
00439
00440 activeFlags.resize(indices2.size());
00441 if (last)
00442 lastDist.resize(indices2.size());
00443
00444
00445 for (unsigned int i=0;i<indices1.size() && i<indices2.size(); ++i)
00446 {
00447 bool active = true;
00448 if (last)
00449 {
00450 Coord p = res1[indices1[i]];
00451 Vec<3,Real> p3d;
00452 DataTypes::get(p3d[0],p3d[1],p3d[2],p);
00453 lastDist[i] = (Real)( (p3d-f_lastPos.getValue())*f_lastDir.getValue());
00454 if (lastDist[i] > 0.0)
00455 {
00456 if (clamp)
00457 {
00458 if (activeFlags[i])
00459 std::cout << "AttachConstraint: point "<<indices1[i]<<" stopped."<<std::endl;
00460
00461
00462 }
00463 else
00464 {
00465 if (activeFlags[i])
00466 std::cout << "AttachConstraint: point "<<indices1[i]<<" is free."<<std::endl;
00467 }
00468 active = false;
00469 }
00470 }
00471 activeFlags[i] = active;
00472 }
00473 for (unsigned int i=0;i<indices1.size() && i<indices2.size(); ++i)
00474 {
00475 Coord p = res1[indices1[i]];
00476 if (activeFlags[i])
00477 {
00478 if (log) std::cout << "AttachConstraint: x2["<<indices2[i]<<"] = x1["<<indices1[i]<<"]\n";
00479
00480 projectPosition(p, res2[indices2[i]], freeRotations || (lastFreeRotation && (i>=activeFlags.size() || !activeFlags[i+1])), i);
00481 }
00482 else if (clamp)
00483 {
00484 DataTypes::set(p,f_lastPos.getValue()[0],f_lastPos.getValue()[1],f_lastPos.getValue()[2]);
00485 if (log) std::cout << "AttachConstraint: x2["<<indices2[i]<<"] = lastPos\n";
00486 projectPosition(p, res2[indices2[i]], freeRotations, i);
00487 }
00488 }
00489 }
00490
00491 template <class DataTypes>
00492 void AttachConstraint<DataTypes>::projectVelocity(VecDeriv& res1, VecDeriv& res2)
00493 {
00494 const SetIndexArray & indices1 = f_indices1.getValue().getArray();
00495 const SetIndexArray & indices2 = f_indices2.getValue().getArray();
00496 const bool freeRotations = f_freeRotations.getValue();
00497 const bool lastFreeRotation = f_lastFreeRotation.getValue();
00498 const bool clamp = f_clamp.getValue();
00499 const bool log = this->f_printLog.getValue();
00500 for (unsigned int i=0;i<indices1.size() && i<indices2.size(); ++i)
00501 {
00502 bool active = true;
00503 if (i < activeFlags.size()) active = activeFlags[i];
00504
00505 if (active)
00506 {
00507 if (log) std::cout << "AttachConstraint: v2["<<indices2[i]<<"] = v1["<<indices1[i]<<"]\n";
00508 projectVelocity(res1[indices1[i]], res2[indices2[i]], freeRotations || (lastFreeRotation && (i>=activeFlags.size() || !activeFlags[i+1])), i);
00509 }
00510 else if (clamp)
00511 {
00512 if (log) std::cout << "AttachConstraint: v2["<<indices2[i]<<"] = 0\n";
00513 Deriv v = Deriv();
00514 projectVelocity(v, res2[indices2[i]], freeRotations, i);
00515 }
00516 }
00517 }
00518
00519 template <class DataTypes>
00520 void AttachConstraint<DataTypes>::projectResponse(VecDeriv& res1, VecDeriv& res2)
00521 {
00522 const SetIndexArray & indices1 = f_indices1.getValue().getArray();
00523 const SetIndexArray & indices2 = f_indices2.getValue().getArray();
00524 const bool twoway = f_twoWay.getValue();
00525 const bool freeRotations = f_freeRotations.getValue();
00526 const bool lastFreeRotation = f_lastFreeRotation.getValue();
00527 const bool clamp = f_clamp.getValue();
00528 const bool log = this->f_printLog.getValue();
00529 for (unsigned int i=0;i<indices1.size() && i<indices2.size(); ++i)
00530 {
00531 bool active = true;
00532 if (i < activeFlags.size()) active = activeFlags[i];
00533 if (active)
00534 {
00535 if (log)
00536 {
00537 if (twoway) std::cout << "AttachConstraint: r2["<<indices2[i]<<"] = r1["<<indices2[i]<<"] = (r2["<<indices2[i]<<"] + r2["<<indices2[i]<<"])\n";
00538 else std::cout << "AttachConstraint: r2["<<indices2[i]<<"] = 0\n";
00539 }
00540 projectResponse(res1[indices1[i]], res2[indices2[i]], freeRotations || (lastFreeRotation && (i>=activeFlags.size() || !activeFlags[i+1])), twoway, i);
00541
00542 if (log)
00543 std::cout << "AttachConstraint: final r2["<<indices2[i]<<"] = "<<res2[indices2[i]]<<"\n";
00544 }
00545 else if (clamp)
00546 {
00547 if (log) std::cout << "AttachConstraint: r2["<<indices2[i]<<"] = 0\n";
00548 Deriv v = Deriv();
00549 projectResponse(v, res2[indices2[i]], freeRotations, false, i);
00550 if (log)
00551 std::cout << "AttachConstraint: final r2["<<indices2[i]<<"] = "<<res2[indices2[i]]<<"\n";
00552 }
00553 }
00554 }
00555
00556
00557 template <class DataTypes>
00558 void AttachConstraint<DataTypes>::applyConstraint(defaulttype::BaseMatrix *mat, unsigned int &offset)
00559 {
00560
00561 const SetIndexArray & indices = f_indices2.getValue().getArray();
00562 const unsigned int N = Deriv::size();
00563 const unsigned int NC = DerivConstrainedSize(f_freeRotations.getValue());
00564 const unsigned int NCLast = DerivConstrainedSize(f_lastFreeRotation.getValue());
00565 unsigned int i=0;
00566 const bool clamp = f_clamp.getValue();
00567 const bool log = this->f_printLog.getValue();
00568 for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it, ++i)
00569 {
00570 if (!clamp && i < activeFlags.size() && !activeFlags[i]) continue;
00571 if (log) std::cout << "AttachConstraint: apply in matrix column/row "<<(*it)<<"\n";
00572 if (NCLast != NC && (i>=activeFlags.size() || !activeFlags[i+1]))
00573 {
00574
00575 for (unsigned int c=0;c<NCLast;++c)
00576 mat->clearRowCol(offset + N * (*it) + c);
00577
00578 for (unsigned int c=0;c<NCLast;++c)
00579 mat->set(offset + N * (*it) + c, offset + N * (*it) + c, 1.0);
00580 }
00581 else
00582 {
00583
00584 for (unsigned int c=0;c<NC;++c)
00585 mat->clearRowCol(offset + N * (*it) + c);
00586
00587 for (unsigned int c=0;c<NC;++c)
00588 mat->set(offset + N * (*it) + c, offset + N * (*it) + c, 1.0);
00589 }
00590 }
00591 }
00592
00593 template <class DataTypes>
00594 void AttachConstraint<DataTypes>::applyConstraint(defaulttype::BaseVector *vect, unsigned int &offset)
00595 {
00596 std::cout << "applyConstraint in Vector with offset = " << offset << std::endl;
00597
00598 const SetIndexArray & indices = f_indices2.getValue().getArray();
00599 const unsigned int N = Deriv::size();
00600 const unsigned int NC = DerivConstrainedSize(f_freeRotations.getValue());
00601 const unsigned int NCLast = DerivConstrainedSize(f_lastFreeRotation.getValue());
00602 unsigned int i=0;
00603 const bool clamp = f_clamp.getValue();
00604 for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it, ++i)
00605 {
00606 if (!clamp && i < activeFlags.size() && !activeFlags[i]) continue;
00607 if (NCLast != NC && (i>=activeFlags.size() || !activeFlags[i+1]))
00608 {
00609 for (unsigned int c=0;c<NCLast;++c)
00610 vect->clear(offset + N * (*it) + c);
00611 }
00612 else
00613 {
00614 for (unsigned int c=0;c<NC;++c)
00615 vect->clear(offset + N * (*it) + c);
00616 }
00617 }
00618 }
00619
00620
00621 template <class DataTypes>
00622 void AttachConstraint<DataTypes>::draw()
00623 {
00624 if (!getContext()->
00625 getShowBehaviorModels()) return;
00626 const SetIndexArray & indices1 = f_indices1.getValue().getArray();
00627 const SetIndexArray & indices2 = f_indices2.getValue().getArray();
00628 VecCoord& x1 = *this->mstate1->getX();
00629 VecCoord& x2 = *this->mstate2->getX();
00630 glDisable (GL_LIGHTING);
00631 glPointSize(10);
00632 glColor4f (1,0.5,0.5,1);
00633 glBegin (GL_POINTS);
00634 for (unsigned int i=0;i<indices1.size() && i<indices2.size(); ++i)
00635 {
00636 if (activeFlags.size() > i && !activeFlags[i]) continue;
00637 gl::glVertexT(x2[indices2[i]]);
00638 }
00639 glEnd();
00640 glPointSize(1);
00641 glColor4f (1,0.5,0.5,1);
00642 glBegin (GL_LINES);
00643 for (unsigned int i=0;i<indices1.size() && i<indices2.size(); ++i)
00644 {
00645 if (activeFlags.size() > i && !activeFlags[i]) continue;
00646 gl::glVertexT(x1[indices1[i]]);
00647 gl::glVertexT(x2[indices2[i]]);
00648 }
00649 glEnd();
00650 }
00651
00652 }
00653
00654 }
00655
00656 }
00657
00658 #endif