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 #include <sofa/component/topology/RegularGridTopology.h>
00026 #include <sofa/core/ObjectFactory.h>
00027
00028 namespace sofa
00029 {
00030
00031 namespace component
00032 {
00033
00034 namespace topology
00035 {
00036
00037 using namespace sofa::defaulttype;
00038 using std::cout;
00039 using std::endl;
00040
00041 void RegularGridTopology::parse(core::objectmodel::BaseObjectDescription* arg)
00042 {
00043 float scale=1.0f;
00044 if (arg->getAttribute("scale")!=NULL) {
00045 scale = (float)atof(arg->getAttribute("scale"));
00046 }
00047
00048 this->GridTopology::parse(arg);
00049 if (arg->getAttribute("xmin") != NULL &&
00050 arg->getAttribute("ymin") != NULL &&
00051 arg->getAttribute("zmin") != NULL &&
00052 arg->getAttribute("xmax") != NULL &&
00053 arg->getAttribute("ymax") != NULL &&
00054 arg->getAttribute("zmax") != NULL )
00055 {
00056 const char* xmin = arg->getAttribute("xmin");
00057 const char* ymin = arg->getAttribute("ymin");
00058 const char* zmin = arg->getAttribute("zmin");
00059 const char* xmax = arg->getAttribute("xmax");
00060 const char* ymax = arg->getAttribute("ymax");
00061 const char* zmax = arg->getAttribute("zmax");
00062 min.setValue(Vector3((SReal)atof(xmin)*scale, (SReal)atof(ymin)*scale, (SReal)atof(zmin)*scale));
00063 max.setValue(Vector3((SReal)atof(xmax)*scale, (SReal)atof(ymax)*scale, (SReal)atof(zmax)*scale));
00064 }
00065 this->setPos(min.getValue()[0],max.getValue()[0],min.getValue()[1],max.getValue()[1],min.getValue()[2],max.getValue()[2]);
00066
00067 }
00068
00069 SOFA_DECL_CLASS(RegularGridTopology)
00070
00071 int RegularGridTopologyClass = core::RegisterObject("Regular grid in 3D")
00072 .addAlias("RegularGrid")
00073 .add< RegularGridTopology >()
00074 ;
00075
00076 RegularGridTopology::RegularGridTopology(int nx, int ny, int nz)
00077 : GridTopology(nx, ny, nz),
00078 min(initData(&min,Vector3(0.0f,0.0f,0.0f),"min", "Min")),
00079 max(initData(&max,Vector3(1.0f,1.0f,1.0f),"max", "Max")),
00080 p0(initData(&p0,Vector3(0.0f,0.0f,0.0f),"p0", "p0"))
00081 {
00082 }
00083
00084 RegularGridTopology::RegularGridTopology()
00085 : min(initData(&min,Vector3(0.0f,0.0f,0.0f),"min", "Min")),
00086 max(initData(&max,Vector3(1.0f,1.0f,1.0f),"max", "Max")),
00087 p0(initData(&p0,Vector3(0.0f,0.0f,0.0f),"p0", "p0"))
00088 {
00089 }
00090
00091 void RegularGridTopology::setPos(SReal xmin, SReal xmax, SReal ymin, SReal ymax, SReal zmin, SReal zmax)
00092 {
00093 min.setValue(Vector3(xmin,ymin,zmin));
00094 max.setValue(Vector3(xmax,ymax,zmax));
00095 if (!p0.isSet())
00096 setP0(Vector3(xmin,ymin,zmin));
00097 if (n.getValue()[0]>1)
00098 setDx(Vector3((xmax-xmin)/(n.getValue()[0]-1),0,0));
00099 else
00100 setDx(Vector3(0,0,0));
00101 if (n.getValue()[1]>1)
00102 setDy(Vector3(0,(ymax-ymin)/(n.getValue()[1]-1),0));
00103 else
00104 setDy(Vector3(0,0,0));
00105 if (n.getValue()[2]>1)
00106 setDz(Vector3(0,0,(zmax-zmin)/(n.getValue()[2]-1)));
00107 else
00108 setDz(Vector3(0,0,0));
00109 }
00110
00111 unsigned RegularGridTopology::getIndex( int i, int j, int k ) const
00112 {
00113 return n.getValue()[0]* ( n.getValue()[1]*k + j ) + i;
00114 }
00115
00116
00117 Vector3 RegularGridTopology::getPoint(int i) const
00118 {
00119 int x = i%n.getValue()[0]; i/=n.getValue()[0];
00120 int y = i%n.getValue()[1]; i/=n.getValue()[1];
00121 int z = i;
00122 return getPoint(x,y,z);
00123 }
00124
00125 Vector3 RegularGridTopology::getPoint(int x, int y, int z) const
00126 {
00127 return p0.getValue()+dx*x+dy*y+dz*z;
00128 }
00129
00131 int RegularGridTopology::findCube(const Vector3& pos)
00132 {
00133 if (n.getValue()[0]<2 || n.getValue()[1]<2 || n.getValue()[2]<2)
00134 return -1;
00135 Vector3 p = pos-p0.getValue();
00136 SReal x = p*dx*inv_dx2;
00137 SReal y = p*dy*inv_dy2;
00138 SReal z = p*dz*inv_dz2;
00139 int ix = int(x+1000000)-1000000;
00140 int iy = int(y+1000000)-1000000;
00141 int iz = int(z+1000000)-1000000;
00142 if ( (unsigned)ix <= (unsigned)n.getValue()[0]-2
00143 && (unsigned)iy <= (unsigned)n.getValue()[1]-2
00144 && (unsigned)iz <= (unsigned)n.getValue()[2]-2 )
00145 {
00146 return cube(ix,iy,iz);
00147 }
00148 else
00149 {
00150 return -1;
00151 }
00152 }
00153
00155 int RegularGridTopology::findNearestCube(const Vector3& pos)
00156 {
00157 if (n.getValue()[0]<2 || n.getValue()[1]<2 || n.getValue()[2]<2) return -1;
00158 Vector3 p = pos-p0.getValue();
00159 SReal x = p*dx*inv_dx2;
00160 SReal y = p*dy*inv_dy2;
00161 SReal z = p*dz*inv_dz2;
00162 int ix = int(x+1000000)-1000000;
00163 int iy = int(y+1000000)-1000000;
00164 int iz = int(z+1000000)-1000000;
00165 if (ix<0) ix=0; else if (ix>n.getValue()[0]-2) ix=n.getValue()[0]-2;
00166 if (iy<0) iy=0; else if (iy>n.getValue()[1]-2) iy=n.getValue()[1]-2;
00167 if (iz<0) iz=0; else if (iz>n.getValue()[2]-2) iz=n.getValue()[2]-2;
00168 return cube(ix,iy,iz);
00169 }
00170
00173 int RegularGridTopology::findCube(const Vector3& pos, SReal& fx, SReal &fy, SReal &fz)
00174 {
00175 if (n.getValue()[0]<2 || n.getValue()[1]<2 || n.getValue()[2]<2) return -1;
00176 Vector3 p = pos-p0.getValue();
00177
00178 SReal x = p*dx*inv_dx2;
00179 SReal y = p*dy*inv_dy2;
00180 SReal z = p*dz*inv_dz2;
00181
00182 int ix = int(x+1000000)-1000000;
00183 int iy = int(y+1000000)-1000000;
00184 int iz = int(z+1000000)-1000000;
00185 if ((unsigned)ix<=(unsigned)n.getValue()[0]-2 && (unsigned)iy<=(unsigned)n.getValue()[1]-2 && (unsigned)iz<=(unsigned)n.getValue()[2]-2)
00186 {
00187 fx = x-ix;
00188 fy = y-iy;
00189 fz = z-iz;
00190 return cube(ix,iy,iz);
00191 }
00192 else
00193 {
00194 return -1;
00195 }
00196 }
00197
00200 int RegularGridTopology::findNearestCube(const Vector3& pos, SReal& fx, SReal &fy, SReal &fz)
00201 {
00202 if (n.getValue()[0]<2 || n.getValue()[1]<2 || n.getValue()[2]<2) return -1;
00203 Vector3 p = pos-p0.getValue();
00204 SReal x = p*dx*inv_dx2;
00205 SReal y = p*dy*inv_dy2;
00206 SReal z = p*dz*inv_dz2;
00207 int ix = int(x+1000000)-1000000;
00208 int iy = int(y+1000000)-1000000;
00209 int iz = int(z+1000000)-1000000;
00210 if (ix<0) ix=0; else if (ix>n.getValue()[0]-2) ix=n.getValue()[0]-2;
00211 if (iy<0) iy=0; else if (iy>n.getValue()[1]-2) iy=n.getValue()[1]-2;
00212 if (iz<0) iz=0; else if (iz>n.getValue()[2]-2) iz=n.getValue()[2]-2;
00213 fx = x-ix;
00214 fy = y-iy;
00215 fz = z-iz;
00216 return cube(ix,iy,iz);
00217 }
00218
00219
00220 unsigned RegularGridTopology::getCubeIndex( int i, int j, int k ) const
00221 {
00222 return (n.getValue()[0]-1)* ( (n.getValue()[1]-1)*k + j ) + i;
00223 }
00224
00225 Vector3 RegularGridTopology::getCubeCoordinate(int i) const
00226 {
00227 Vector3 result;
00228 result[0] = (SReal)(i%(n.getValue()[0]-1)); i/=(n.getValue()[0]-1);
00229 result[1] = (SReal)(i%(n.getValue()[1]-1)); i/=(n.getValue()[1]-1);
00230 result[2] = (SReal)i;
00231 return result;
00232 }
00233
00234
00235 }
00236
00237 }
00238
00239 }
00240