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_BOXSTIFFSPRINGFORCEFIELD_INL
00026 #define SOFA_COMPONENT_FORCEFIELD_BOXSTIFFSPRINGFORCEFIELD_INL
00027
00028 #if !defined(__GNUC__) || (__GNUC__ > 3 || (_GNUC__ == 3 && __GNUC_MINOR__ > 3))
00029 #pragma once
00030 #endif
00031
00032 #include <sofa/component/forcefield/BoxStiffSpringForceField.h>
00033 #include <sofa/helper/gl/template.h>
00034 #include <sofa/defaulttype/Vec.h>
00035 #include <sofa/helper/vector.h>
00036 #include <map>
00037
00038
00039 namespace sofa
00040 {
00041
00042 namespace component
00043 {
00044
00045 namespace forcefield
00046 {
00047
00048 template <class DataTypes>
00049 BoxStiffSpringForceField<DataTypes>::BoxStiffSpringForceField(MechanicalState* object1, MechanicalState* object2, double ks, double kd)
00050 : StiffSpringForceField<DataTypes>(object1, object2, ks, kd),
00051 box_object1( initData( &box_object1, Vec6(0,0,0,1,1,1), "box_object1", "Box for the object1 where springs will be attached") ),
00052 box_object2( initData( &box_object2, Vec6(0,0,0,1,1,1), "box_object2", "Box for the object2 where springs will be attached") )
00053
00054 {
00055 }
00056
00057 template <class DataTypes>
00058 BoxStiffSpringForceField<DataTypes>::BoxStiffSpringForceField(double ks, double kd)
00059 : StiffSpringForceField<DataTypes>(ks, kd),
00060 box_object1( initData( &box_object1, Vec6(0,0,0,1,1,1), "box_object1", "Box for the object1 where springs will be attached") ),
00061 box_object2( initData( &box_object2, Vec6(0,0,0,1,1,1), "box_object2", "Box for the object2 where springs will be attached") )
00062 {
00063 }
00064
00065 template <class DataTypes>
00066 void BoxStiffSpringForceField<DataTypes>::bwdInit()
00067 {
00068 Inherit::bwdInit();
00069 sofa::helper::vector <unsigned int> indices1;
00070 const Vec6& b1=box_object1.getValue();
00071 this->mstate1->getIndicesInSpace( indices1, b1[0],b1[3],b1[1],b1[4],b1[2],b1[5] );
00072
00073 sofa::helper::vector <unsigned int> indices2;
00074 const Vec6& b2=box_object2.getValue();
00075 this->mstate2->getIndicesInSpace( indices2, b2[0],b2[3],b2[1],b2[4],b2[2],b2[5] );
00076
00077
00078 const VecCoord& x1 = *this->mstate1->getX();
00079 const VecCoord& x2 = *this->mstate2->getX();
00080
00081
00082 Real min_dist=0;
00083 if (indices1.size() < indices2.size())
00084 {
00085 sofa::helper::vector< std::map<Real, unsigned int> > distance_spring(indices1.size());
00086 for(unsigned int i = 0; i < indices1.size(); ++i)
00087 {
00088 for(unsigned int j = 0; j < indices2.size(); ++j)
00089 {
00090 distance_spring[i][(Real)sqrt((x1[indices1[i]] - x2[indices2[j]]).norm2())] = j;
00091 }
00092 if (i==0 || min_dist> distance_spring[i].begin()->first) min_dist = distance_spring[i].begin()->first;
00093
00094 }
00095 sofa::helper::vector< bool > indice_unused(indices2.size(),true);
00096
00097 for(unsigned int i = 0; i<indices1.size(); ++i)
00098 {
00099 typename std::map<Real, unsigned int>::const_iterator it = distance_spring[i].begin();
00100 for (;it!=distance_spring[i].end();it++)
00101 {
00102 if (indice_unused[it->second])
00103 {
00104 indice_unused[it->second] = false;
00105 this->addSpring(indices1[i], indices2[it->second], this->getStiffness()*it->first/min_dist, this->getDamping(), it->first );
00106 break;
00107 }
00108 }
00109 }
00110 }
00111 else
00112 {
00113 sofa::helper::vector< std::map<Real, unsigned int> > distance_spring(indices2.size());
00114 for(unsigned int i = 0; i < indices2.size(); ++i)
00115 {
00116 for(unsigned int j = 0; j < indices1.size(); ++j)
00117 {
00118 distance_spring[i][(Real)sqrt((x1[indices1[j]] - x2[indices2[i]]).norm2())] = j;
00119 }
00120
00121 if (i==0 || min_dist> distance_spring[i].begin()->first) min_dist = distance_spring[i].begin()->first;
00122 }
00123 sofa::helper::vector< bool > indice_unused(indices1.size(),true);
00124
00125 for(unsigned int i = 0; i<indices2.size(); ++i)
00126 {
00127 typename std::map<Real, unsigned int>::const_iterator it = distance_spring[i].begin();
00128 for (;it!=distance_spring[i].end();it++)
00129 {
00130 if (indice_unused[it->second])
00131 {
00132 indice_unused[it->second] = false;
00133 this->addSpring( indices1[it->second], indices2[i], this->getStiffness()*it->first/min_dist, this->getDamping(), it->first );
00134 break;
00135 }
00136 }
00137 }
00138 }
00139 }
00140
00141
00142
00143 template <class DataTypes>
00144 void BoxStiffSpringForceField<DataTypes>::draw()
00145 {
00146 if (!this->getContext()->getShowInteractionForceFields())
00147 return;
00148
00149 Inherit::draw();
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00165 const Vec6& b1=box_object1.getValue();
00166 const Real& Xmin1=b1[0];
00167 const Real& Xmax1=b1[3];
00168 const Real& Ymin1=b1[1];
00169 const Real& Ymax1=b1[4];
00170 const Real& Zmin1=b1[2];
00171 const Real& Zmax1=b1[5];
00172
00173 const Vec6& b2=box_object2.getValue();
00174 const Real& Xmin2=b2[0];
00175 const Real& Xmax2=b2[3];
00176 const Real& Ymin2=b2[1];
00177 const Real& Ymax2=b2[4];
00178 const Real& Zmin2=b2[2];
00179 const Real& Zmax2=b2[5];
00180
00181
00182 glBegin(GL_LINES);
00183
00184
00185 glColor4f (0,0.5,0.5,1);
00186 glVertex3d(Xmin1,Ymin1,Zmin1);
00187 glVertex3d(Xmin1,Ymin1,Zmax1);
00188 glVertex3d(Xmin1,Ymin1,Zmin1);
00189 glVertex3d(Xmax1,Ymin1,Zmin1);
00190 glVertex3d(Xmin1,Ymin1,Zmin1);
00191 glVertex3d(Xmin1,Ymax1,Zmin1);
00192 glVertex3d(Xmin1,Ymax1,Zmin1);
00193 glVertex3d(Xmax1,Ymax1,Zmin1);
00194 glVertex3d(Xmin1,Ymax1,Zmin1);
00195 glVertex3d(Xmin1,Ymax1,Zmax1);
00196 glVertex3d(Xmin1,Ymax1,Zmax1);
00197 glVertex3d(Xmin1,Ymin1,Zmax1);
00198 glVertex3d(Xmin1,Ymin1,Zmax1);
00199 glVertex3d(Xmax1,Ymin1,Zmax1);
00200 glVertex3d(Xmax1,Ymin1,Zmax1);
00201 glVertex3d(Xmax1,Ymax1,Zmax1);
00202 glVertex3d(Xmax1,Ymin1,Zmax1);
00203 glVertex3d(Xmax1,Ymin1,Zmin1);
00204 glVertex3d(Xmin1,Ymax1,Zmax1);
00205 glVertex3d(Xmax1,Ymax1,Zmax1);
00206 glVertex3d(Xmax1,Ymax1,Zmin1);
00207 glVertex3d(Xmax1,Ymin1,Zmin1);
00208 glVertex3d(Xmax1,Ymax1,Zmin1);
00209 glVertex3d(Xmax1,Ymax1,Zmax1);
00210
00211 glColor4f (0.5,0.5,0,1);
00212
00213 glVertex3d(Xmin2,Ymin2,Zmin2);
00214 glVertex3d(Xmin2,Ymin2,Zmax2);
00215 glVertex3d(Xmin2,Ymin2,Zmin2);
00216 glVertex3d(Xmax2,Ymin2,Zmin2);
00217 glVertex3d(Xmin2,Ymin2,Zmin2);
00218 glVertex3d(Xmin2,Ymax2,Zmin2);
00219 glVertex3d(Xmin2,Ymax2,Zmin2);
00220 glVertex3d(Xmax2,Ymax2,Zmin2);
00221 glVertex3d(Xmin2,Ymax2,Zmin2);
00222 glVertex3d(Xmin2,Ymax2,Zmax2);
00223 glVertex3d(Xmin2,Ymax2,Zmax2);
00224 glVertex3d(Xmin2,Ymin2,Zmax2);
00225 glVertex3d(Xmin2,Ymin2,Zmax2);
00226 glVertex3d(Xmax2,Ymin2,Zmax2);
00227 glVertex3d(Xmax2,Ymin2,Zmax2);
00228 glVertex3d(Xmax2,Ymax2,Zmax2);
00229 glVertex3d(Xmax2,Ymin2,Zmax2);
00230 glVertex3d(Xmax2,Ymin2,Zmin2);
00231 glVertex3d(Xmin2,Ymax2,Zmax2);
00232 glVertex3d(Xmax2,Ymax2,Zmax2);
00233 glVertex3d(Xmax2,Ymax2,Zmin2);
00234 glVertex3d(Xmax2,Ymin2,Zmin2);
00235 glVertex3d(Xmax2,Ymax2,Zmin2);
00236 glVertex3d(Xmax2,Ymax2,Zmax2);
00237
00238 glEnd();
00239 }
00240
00241
00242 }
00243
00244 }
00245
00246 }
00247
00248 #endif