void UniformDistribution::redistributeUniformly() { ParticleBoundingBox* boundingBox=dynamic_cast<ParticleBoundingBox*>(_boundingBoxAttributeRef); if (boundingBox==0) return; const gmVector3 & minC=boundingBox->min; const gmVector3 & maxC=boundingBox->max; const unsigned int nbParticles = ps->size(); const unsigned int nbWanted=_nbParticles[0]*_nbParticles[1]*_nbParticles[2]; if (nbParticles<nbWanted) { for (unsigned int i=0;i<nbWanted-nbParticles;++i) { ps->addParticle(); } } else if (nbParticles>nbWanted) { //remove all the last particles, until the size is ok //this is the way it is supposed to work... although //I do personnally not like the fact that when you delete //a particle in the middle, the indices change for (unsigned int i=0;i<nbParticles-nbWanted;++i) ps->removeParticle(nbParticles-i-1); } assert(ps->size()==nbWanted); gmVector3 offset; if (_sampleMaxBorder) { offset = gmVector3( (maxC[0]-minC[0])/(_nbParticles[0]-1), (maxC[1]-minC[1])/(_nbParticles[1]-1), (maxC[2]-minC[2])/(_nbParticles[2]-1) ); } else { offset = gmVector3( (maxC[0]-minC[0])/(_nbParticles[0]), (maxC[1]-minC[1])/(_nbParticles[1]), (maxC[2]-minC[2])/(_nbParticles[2]) ); } for (unsigned int z=0;z<(unsigned int) _nbParticles[2];++z) for (unsigned int y=0;y<(unsigned int) _nbParticles[1];++y) for (unsigned int x=0;x<(unsigned int) _nbParticles[0];++x) { _thisPosition->setPosition( x+_nbParticles[0]*y+_nbParticles[0]*_nbParticles[1]*z, minC+gmVector3(offset[0]*x,offset[1]*y,offset[2]*z) ); } }
gmVector3 ParticleMesh::getPosition(unsigned int i) { ParticleOpenMesh::VertexHandle vh(i); if (vh.is_valid()) { ParticleOpenMesh::Point p(mesh.point(vh)); return gmVector3(p[0],p[1],p[2]); } return gmVector3(); }
void ITKImplicit::init(void) { //init from surface //Via dynamic cast we test whether the surface type allows for a transformation //into an ITKImplicit if (!surface) return; //init default image, this can still be overwritten myImage = ImageType::New(); SurfaceMesh * mesh=dynamic_cast<SurfaceMesh*>(surface); if (mesh) { mesh->computeBoundingBox(); gmVector3 maxV(mesh->bbox_max[0], mesh->bbox_max[1], mesh->bbox_max[2]); gmVector3 minV(mesh->bbox_min[0], mesh->bbox_min[1], mesh->bbox_min[2]); initScalingAndOriginFromBoundingBox(minV,maxV); //we have a special surface, a mesh surface initFromSurfaceMesh(mesh); } //surface could be an implicit Implicit * imp=dynamic_cast<Implicit*>(surface); if (imp) { //if we have an implicit we want to check whether the particle bounding box is set. //if so, we adjust the image if (bbox) { //we have a bounding box, so we use it to evaluate the //values. initScalingAndOriginFromBoundingBox(bbox->min, bbox->max); } else { initScalingAndOriginFromBoundingBox(gmVector3(-0.5,-0.5,-0.5), gmVector3(0.5,0.5,0.5)); } initFromImplicit(imp); } originalSpacing = myImage->GetSpacing(); originalOrigin = myImage->GetOrigin(); //we apply eventual transformations //and init the spline interpolator //we refit the particles bounding box applyParameterChanges(); }
/** Computed via product rule: grad(grad f . v) = Hf v + 0 (since grad v = 0) */ gmVector3 DirectionalDerivative::grad(const gmVector3 & x) { if (m_f) return m_f->hess(x) * m_v; else return gmVector3(); }
/** * Transforms (multiplies) a gmVector3 by the current matrix. * @param v The gmVector3 to multiply. * @return A new vector reflecting v * the first three columns of M. */ gmVector3 gmMatrix4::transform(const gmVector3& v) const { return gmVector3( v[0] * m_[0][0] + v[1] * m_[1][0] + v[2] * m_[2][0] + m_[3][0], v[0] * m_[0][1] + v[1] * m_[1][1] + v[2] * m_[2][1] + m_[3][1], v[0] * m_[0][2] + v[1] * m_[1][2] + v[2] * m_[2][2] + m_[3][2]); }
gmVector3 SPHPressure::dW_spiky(gmVector3 &r) { double r2 = dot(r, r); if ( sqrt(r2) < 1e-6*pressure_kernel || r2 > h2 ) return gmVector3(0,0,0); double x = sqrt(r2) / pressure_kernel; return (-coeff*pressure_kernel*(1-x)*(1-x)/x)*r; }
InterfaceRBF::InterfaceRBF(void) :RBF() { new SurfAttrRefParam(this,(ParticleAttribute **)&zeroConstraints,"ZeroConstraints","zeroPos","ZeroCons", "Particle positions used as zero constraints."); new SurfParamButton(this, new InterpolateParticlesWithRBF(this),"interpolate particles","fit RBF", "find RBF corresponding to particle positions and values"); //I do not really like this kind of construction //but as it is done everywhere I stick to it... new SurfParamComboBox(this,new RBFBasicFunctionSelector(this, &_phiFunction), "RBFSelect","RBFSelector", "The selection decides which basic functions to use during creation and evaluation. Note: The creation choice does not fix the evaluation choice."); new SurfParamString(this,&_filename,"","fn","filename","Load/Save filename (including location)"); new SurfParamButton(this, new LoadRBFCallback(this),"loadRBF", "load solution", "loadRBF from file"); new SurfParamButton(this, new SaveRBFCallback(this), "saveRBF", "save solution", "saveRBF to file"); //Init with default RBF centers.resize(7); centers[0] = RBFPoint(gmVector3(1.0,0.0,0.0),0); centers[1] = RBFPoint(gmVector3(-1.0,0.0,0.0),0); centers[2] = RBFPoint(gmVector3(0.0,1.0,0.0),0); centers[3] = RBFPoint(gmVector3(0.0,-1.0,0.0),0); centers[4] = RBFPoint(gmVector3(0.0,0.0,1.0),0); centers[5] = RBFPoint(gmVector3(0.0,0.0,-1.0),0); centers[6] = RBFPoint(gmVector3(0.0,0.0,0.0),-1); updateRBF(); }
ShaderSpecularContour::ShaderSpecularContour(Particles *ps) :ShaderContour(ps,std::string("ShaderSpecularContour")) { new PSParamDouble(this,&shine,0.9,"shine","size of specular", "The arccos of this number determines the specular shadow curve size"); new Attached<LightPosition>(this,&light); brushColorf = gmVector3(1.0,1.0,1.0); }
/** * Evaluates the gradient of a sphere. * @param x Point at which to evaluate gradient. * @returns Gradient vector. */ gmVector3 Sphere::grad(const gmVector3 & x) { gmVector3 g = x - m_x; double l = g.lengthSquared(); if (gmIsZero(l)) return gmVector3(0.0,0.0,0.0); else return (g / sqrt(l)); }
ViewDependence::ViewDependence(Particles *ps, const std::string& name):ParticleAttribute(ps,name) { mCameraPosition = new gmVector3(0.0,0.0,0.0); new PSParamgmVector3(this,mCameraPosition,gmVector3(0,0,0), "camera","camera position","Position of camera used for visibility computation."); new PSParamBool(this, &mFixCam, false,"fixCam","fix view","fixes the current viewpoint"); new PSParamButton(this,new ViewDependenceJumpToFixCamCallback(this),"jumpBTN","jump to fix position","Place the camera at the fixed/current position"); } // end ViewDependence::ViewDependence()
gmVector3 DistanceField::grad(const gmVector3 & x) { Vector3d interpolated_vector(-0.1,-0.1,-0.1); Vector3d test_point(x[0],x[1],x[2]); if(sparse_lattice->ContainsPoint(test_point)) interpolated_vector = sparse_lattice->InterpNormal(test_point); return gmVector3(interpolated_vector[0],interpolated_vector[1],interpolated_vector[2]); }
/** Gradient of the sum of radial basis functions * phi = r^3 * dphi = 3 r^2 * Gradient is just magnitude r in the unitized direction of x. * grad phi = 3r x (since x = r x/||x||) */ gmVector3 InterfaceRBF::grad(const gmVector3 & x) { gmVector3 g(0.0,0.0,0.0); for (unsigned int i = 0; i < centers.size(); i++) g += centers[i].w * _phiFunction->gradphi(x - centers[i].c); g += gmVector3(m_p[1],m_p[2],m_p[3]); return g; }
gmVector3 CSGUnion::grad(const gmVector3 & x) { if ((m_f!=NULL) && (m_g!=NULL)) { double fx = m_f->proc(x); double gx = m_g->proc(x); return hf(fx,gx) * m_f->grad(x) + hg(fx,gx) * m_g->grad(x); } else return gmVector3(); }
gmVector3 ImplicitInterrogator::normal(unsigned int i)const { //copied from implicit gmVector3 n = grad(i); if (gmIsZero(n.length())) n = gmVector3(1.0,0.0,0.0); else n.normalize(); return n; }
void SPHPressure::applyForce() { unsigned int i, k; int j; gmVector3 rij; // vector between particle i and j double sqr_ph = pressure_kernel * pressure_kernel; // h2 double total; gmVector3 pressure; std::vector<unsigned int> neighbors; // plocality->queryRadius=pressure_kernel; plocality->queryRadius=pressure_kernel*2; // compute pressure gradient force for all particles for(i=0; i<ps->size(); i++) { pressure = gmVector3(0.0, 0.0, 0.0); double pre; neighbors.clear(); plocality->getNeighbors(i, neighbors); std::cout << "#neighbor: " << neighbors.size() << std::endl; for (k = 0; k < neighbors.size(); k++) { j = neighbors[k]; // for(j=0; j<ps->size(); j++) // { if (i==j) continue; // shouldn't consider itself rij = position->getPosition(i) - position->getPosition(j); pre = mass * gasC * (density->den[i] + density->den[j] - 2.0*density_rest) / (2.0*density->den[j]); pressure -= pre * dW_spiky(rij); } acceleration->acc[i] += pressure / density->den[i]; } }
gmVector3 ITKImplicit::grad(const gmVector3 & x) { ImageType::PointType myPoint; myPoint[0]=x[0]; myPoint[1]=x[1]; myPoint[2]=x[2]; if(myInterpFunc && myInterpFunc->IsInsideBuffer(myPoint)) { itk::CovariantVector<double> v(myInterpFunc->EvaluateDerivative(myPoint)); //before it was dependent on the scaling, but I see no reason for it... return gmVector3(v[0], v[1], v[2]); } else { //we return a grad which is like one on the sphere to attract particles to the center... ImageType::SpacingType spacing = myImage->GetSpacing(); ImageType::SizeType size = myImage->GetLargestPossibleRegion().GetSize(); gmVector3 scaling; scaling[0] = 1.0/(spacing[0]*size[0]/2.0); scaling[1] = 1.0/(spacing[1]*size[1]/2.0); scaling[2] = 1.0/(spacing[2]*size[2]/2.0); scaling=scaling.normalize(); gmVector3 ellipse=(x-center); ellipse[0]*=scaling[0]; ellipse[1]*=scaling[1]; ellipse[2]*=scaling[2]; return (ellipse).normalize(); } }
/** * Creates a sphere with radius r at the origin. */ Sphere::Sphere(double r) : Geometric() { init(gmVector3(0.0,0.0,0.0),r); }
/** * Creates the default sphere of radius 1 at the origin. */ Sphere::Sphere() : Geometric() { init(gmVector3(0.0,0.0,0.0),1.0); }
void Bitmap::Draw(X3DDrawContext* pDC, X3DTextureNodeImplImpl* textureNode) { ASSERT(0); #if 0 if (true) { if (textureNode) { // TODO //CLMovieTexture* pMovieTexture = static_cast<CLMovieTexture*>(textureNode); //ILVideoMediaType* videoMediaType = pMovieTexture->m_pVideoFilter->m_pInput->m_mediaType; //if (videoMediaType) { long imageWidth = textureNode->GetWidth(); long imageHeight = textureNode->GetHeight(); //videoMediaType->GetWidth(&imageWidth); //videoMediaType->GetHeight(&imageHeight); if (imageWidth > 0 && imageHeight > 0) { float destWidth; float destHeight; if (m_scale->m_value[0] == -1) { destWidth = imageWidth; } else { destWidth = imageWidth * m_scale->m_value[0]; } if (m_scale->m_value[1] == -1) { destHeight = imageHeight; } else { destHeight = imageHeight * m_scale->m_value[1]; } //if (textureNode->m_pVideoFilter->m_pInput->m_pSample) //{ pDC->m_pGraphics3D->glBegin(GL_QUADS); pDC->m_pGraphics3D->glTexCoordf(0, 0); pDC->m_pGraphics3D->glVertexf(-destWidth/2, destHeight/2, 0); pDC->m_pGraphics3D->glTexCoordf(1, 0); pDC->m_pGraphics3D->glVertexf(destWidth/2, destHeight/2, 0); pDC->m_pGraphics3D->glTexCoordf(1, 1); pDC->m_pGraphics3D->glVertexf(destWidth/2, -destHeight/2, 0); pDC->m_pGraphics3D->glTexCoordf(0, 1); pDC->m_pGraphics3D->glVertexf(-destWidth/2, -destHeight/2, 0); pDC->m_pGraphics3D->glEnd(); #if 0 void* pixels = textureNode->GetData();//pMovieTexture->m_pVideoFilter->m_pInput->m_pSample->m_bits; if (pixels) { glRasterPos2f(0.0f, 0.0f); // TODO ?? ASSERT(glGetError() == GL_NO_ERROR); //destWidth *= 4; //destHeight *= 4; glPixelZoom(destWidth / imageWidth, destHeight / imageHeight); ASSERT(glGetError() == GL_NO_ERROR); glDrawPixels(imageWidth, imageHeight, GL_RGB, GL_UNSIGNED_BYTE, pixels); ASSERT(glGetError() == GL_NO_ERROR); } #endif } } } } else { } #if 0 glRectf( -m_size->m_value[0]/2, -m_size->m_value[1]/2, m_size->m_value[0]/2, m_size->m_value[1]/2); #endif #if 0 glBegin(GL_QUADS); SFVec3f* size = static_cast<SFVec3f*>(m_size->m_value); gmVector3 s = size->m_v; // front (cw) /* glVertex3d(-m_boxSize[0]/2, -m_boxSize[1]/2, m_boxSize[2]/2); glVertex3d(m_boxSize[0]/2, -m_boxSize[1]/2, m_boxSize[2]/2); glVertex3d(m_boxSize[0]/2, m_boxSize[1]/2, m_boxSize[2]/2); glVertex3d(-m_boxSize[0]/2, m_boxSize[1]/2, m_boxSize[2]/2); */ // front (ccw) lglNormal( gmVector3(-s[0]/2, -s[1]/2, s[2]/2), gmVector3(-s[0]/2, s[1]/2, s[2]/2), gmVector3(s[0]/2, s[1]/2, s[2]/2)); glVertex3d(-s[0]/2, -s[1]/2, s[2]/2); glVertex3d(-s[0]/2, s[1]/2, s[2]/2); glVertex3d(s[0]/2, s[1]/2, s[2]/2); glVertex3d(s[0]/2, -s[1]/2, s[2]/2); // left side lglNormal( gmVector3(-s[0]/2, -s[1]/2, s[2]/2), gmVector3(-s[0]/2, -s[1]/2, -s[2]/2), gmVector3(-s[0]/2, s[1]/2, -s[2]/2)); glVertex3d(-s[0]/2, -s[1]/2, s[2]/2); glVertex3d(-s[0]/2, -s[1]/2, -s[2]/2); glVertex3d(-s[0]/2, s[1]/2, -s[2]/2); glVertex3d(-s[0]/2, s[1]/2, s[2]/2); glEnd(); #endif #endif }
void FeatureDetector::particleAdded() { lastN.push_back(gmVector3()); flips.push_back(0); }
LRESULT CLX3DViewer::OnMouseMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { CPoint point; point.x = (short)LOWORD(lParam); point.y = (short)HIWORD(lParam); if (m_dragging == 1) { m_slider.OnMouseMove(point); UpdateWindow(); double position = m_slider.GetPos(); CComQIPtr<ILMediaSeeking> seeking = m_filterGraph; seeking->Seek(position); } #if 0 if (m_dragging) { CPoint offset = point - m_startpoint; if (m_dragging == 1) // change XY position { CLViewpoint* pViewpoint = static_cast<CLViewpoint*>(m_viewpointStack[0]); CLSFRotation* orientation = static_cast<CLSFRotation*>(pViewpoint->m_orientation); CLSFVec3f* position = static_cast<CLSFVec3f*>(pViewpoint->m_position); double moveY = (double)-offset.y/20; double moveX = (double)offset.x/20; gmMatrix4 repos = gmMatrix4::identity(); repos *= gmMatrix4::rotate(gmDegrees(orientation->m_value.m_a), -orientation->m_value.m_v); repos *= gmMatrix4::translate(moveX, moveY, 0); repos *= gmMatrix4::rotate(gmDegrees(orientation->m_value.m_a), -orientation->m_value.m_v).inverse(); position->m_value = repos.transform(m_initialPosition); FireViewChange(); } else if (m_dragging == 2) // change XZ position { CLViewpoint* pViewpoint = static_cast<CLViewpoint*>(m_viewpointStack[0]); CLSFRotation* orientation = static_cast<CLSFRotation*>(pViewpoint->m_orientation); CLSFVec3f* position = static_cast<CLSFVec3f*>(pViewpoint->m_position); double moveX = (double)offset.x/20; double moveZ = (double)offset.y/20; gmMatrix4 repos = gmMatrix4::identity(); repos *= gmMatrix4::rotate(gmDegrees(orientation->m_value.m_a), -orientation->m_value.m_v); repos *= gmMatrix4::translate(moveX, 0, moveZ); repos *= gmMatrix4::rotate(gmDegrees(orientation->m_value.m_a), -orientation->m_value.m_v).inverse(); position->m_value = repos.transform(m_initialPosition); FireViewChange(); } else if (m_dragging == 3) { double r = 600; // 360 double rotateY = (double)offset.x*360/r; double rotateX = (double)offset.y*360/r; CLViewpoint* pViewpoint = static_cast<CLViewpoint*>(m_viewpointStack[0]); CLSFRotation* orientation = static_cast<CLSFRotation*>(pViewpoint->m_orientation); CLSFVec3f* position = static_cast<CLSFVec3f*>(pViewpoint->m_position); // Orientation if (rotateY != 0 || rotateX != 0) { /* float x = m_initialOrientation.m_v[0]; float y = m_initialOrientation.m_v[1]; float z = m_initialOrientation.m_v[2]; float angle = m_initialOrientation.m_a; */ Quat4d q = m_initialOrientation.AxisAngleToQuaternion(/*x, y, z, angle*/); q.CombineQuaternion(/*x, y, z, angle,*/ 0, gmRadians(rotateY), gmRadians(rotateX)); orientation->m_value = q.QuaternionToAxisAngle();//Quat4d(x, y, z, angle)); /* orientation->m_value.m_v[0] = x; orientation->m_value.m_v[1] = y; orientation->m_value.m_v[2] = z; orientation->m_value.m_a = angle; */ orientation->m_value.m_v.normalize(); } // Position { // Rotate position around centerOfRotation gmMatrix4 repos = gmMatrix4::identity(); repos *= gmMatrix4::rotate(gmDegrees(orientation->m_value.m_a), -orientation->m_value.m_v); repos *= gmMatrix4::rotate(rotateY, gmVector3(0,1,0)); repos *= gmMatrix4::rotate(gmDegrees(orientation->m_value.m_a), -orientation->m_value.m_v).inverse(); position->m_value = repos.transform(m_initialPosition); } // Position { // Rotate position around centerOfRotation gmMatrix4 repos = gmMatrix4::identity(); repos *= gmMatrix4::rotate(gmDegrees(orientation->m_value.m_a), -orientation->m_value.m_v); repos *= gmMatrix4::rotate(rotateX, gmVector3(1,0,0)); repos *= gmMatrix4::rotate(rotateY, gmVector3(0,1,0)); repos *= gmMatrix4::rotate(gmDegrees(orientation->m_value.m_a), -orientation->m_value.m_v).inverse(); position->m_value = repos.transform(m_initialPosition); } FireViewChange(); } } else { CRect client; GetClientRect(&client); int w = client.right; int h = client.bottom; // wglMakeCurrent(hdc, m_hrc); double winx = point.x; double winy = client.bottom-point.y-1; GLint viewport[4] = { 0, 0, w, h }; GLuint selectBuf[512]; glSelectBuffer(512, selectBuf); glRenderMode(GL_SELECT); glInitNames(); glPushName(0); { CLViewpoint* pViewpoint = NULL; if (m_viewpointStack.GetSize() > 0) { pViewpoint = static_cast<CLViewpoint*>(m_viewpointStack[0]); } else { // hmm... } // glViewport(m_viewR[view].left, m_viewR[view].top, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPickMatrix(winx, winy, 3, 3, viewport); // glLoadMatrixd(projm); // double fov; if (pViewpoint) { CLSFFloat* fieldOfView = static_cast<CLSFFloat*>(pViewpoint->m_fieldOfView); fov = fieldOfView->m_value; } else { fov = M_PI/4; } gluPerspective(gmDegrees(fov), (GLfloat)w / (GLfloat)h, 1.0, 10000.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); //glLoadMatrixf((float*)modelm); CX3DDrawContext xdc; #if 0 // NavigationInfo { BOOL headlight; if (m_navigationinfoStack.GetSize() > 0) { CLNavigationInfo* pNavigationInfo = static_cast<CLNavigationInfo*>(m_navigationinfoStack[0]); headlight = static_cast<CLSFBool*>(pNavigationInfo->m_headlight)->m_v; } else { // Default values headlight = TRUE; } glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); if (TRUE)//TRUE/*bAnyLights*/) { } if (headlight) { GLfloat light_direction[4] = { 0, 0, 1, 0}; // directional GLfloat color[4] = {1, 1, 1, 1}; GLfloat ambient[4] = {0, 0, 0, 1}; glEnable(GL_LIGHT0+xdc.m_nLight); glLightfv(GL_LIGHT0+xdc.m_nLight, GL_POSITION, light_direction); glLightfv(GL_LIGHT0+xdc.m_nLight, GL_AMBIENT, ambient); glLightfv(GL_LIGHT0+xdc.m_nLight, GL_DIFFUSE, color); glLightfv(GL_LIGHT0+xdc.m_nLight, GL_SPECULAR , color); xdc.m_nLight++; } } #endif if (pViewpoint) { CLSFRotation* orientation = static_cast<CLSFRotation*>(pViewpoint->m_orientation); CLSFVec3f* position = static_cast<CLSFVec3f*>(pViewpoint->m_position); gmVector3t<float> norientation = orientation->m_value.m_v; norientation.normalize(); glRotate(gmDegrees(orientation->m_value.m_a), -norientation); glTranslate(-position->m_value); } else { // TODO glTranslatef(0, 0, -180); } glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); if (m_scene) { CComQIPtr<CLRenderImplImpl> render = static_cast<CLSAIScene*>(m_scene)->m_root; if (render) { render->Draw(&xdc); } } glFlush(); } GLint hits = glRenderMode(GL_RENDER); if (hits > 0) { MessageBeep(-1); GLuint* ptr = selectBuf; GLuint names = *ptr++; float z1 = *ptr++ / 0x7fffffff; float z2 = *ptr++ / 0x7fffffff; double winz = z2; double modelMatrix[16]; double projMatrix[16]; glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix); glGetDoublev(GL_PROJECTION_MATRIX, projMatrix); double objx, objy, objz; gluUnProject(winx, winy, winz, modelMatrix, projMatrix, viewport, &objx, &objy, &objz); for (int n = 0; n < names; n++) { } } } #endif return 0; }
gmVector3 Algebraic::grad(const gmVector3 & v) { return gmVector3(dx(v), dy(v), dz(v)); }
ITKImplicit::ITKImplicit(void) { new SurfParamString(this,&dirFile,"","fileDir", "Input file or dicom directory"); new SurfParamButton(this,new LoadButtonCallback(this),"load","","load a dicom or imagetype file (extension .vtk suggested)"); new SurfParamButton(this,new SaveButtonCallback(this),"save","","save a dicom or imagetype file (extension .vtk suggested)"); new SurfParamDouble(this,&threshold,0,"Threshold", "CT Number"); new SurfParamDouble(this,&scale,1.0,"Scale", "Volume Scaling Factor"); new SurfParamgmVector3(this,&tr,gmVector3(0,0,0),"Translation","Volume Translation"); new SurfParamButton(this, new ApplyParameterChangesCallback(this),"Apply","Apply parameter changes", "apply parameter changes: Namely translation, scaling," "and spline order"); new SurfSurfRefParam(this, &surface,"<invalid/optional>","Surf(opt.)","SurfaceReference(optional)", "The ITK Volume can also be initialized using a" "surface. In the case of an implicit the bounding box should be meaningful." "If no bounding box is provided a unit cube centered at the origin is assumed." "The implicit is sampled inside of this bounding box." "In the case of a surface mesh, the behavior is special:" "a distance field is calculated inside of ITS bounding box"); new SurfParamInt(this,&(voxelRes[0]),64,"sizeX", "NbX", "Nb of gridcells along x-Axis"); new SurfParamInt(this,&(voxelRes[1]),64,"sizeY","nbY", "Nb of gridcells along y-Axis"); new SurfParamInt(this,&(voxelRes[2]),64,"sizeZ","nbZ", "Nb of gridcells along z-Axis"); new SurfParamDouble(this, &boundingBoxScaling, 1.3,"scale","scalebb", "Scaling of the bounding box to make it slightly bigger"); new SurfAttrRefParam(this,(ParticleAttribute **)&bbox,"invalid:ParticleBoundingBox","bbox","box", "Particle bounding box attribute (it is advised to provide one for implicit surfaces)."); new SurfParamButton(this, new SetITKImplicit(this),"initImp","Initialize ITK implicit","set ITK imp"); new SurfParamInt(this,&order,3,"Order","Spline Order"); //DICOM reader dicomIO = ImageIOType::New(); reader = ReaderType::New(); reader->SetImageIO( dicomIO ); nameGenerator = NamesGeneratorType::New(); //now we initialize a simple default image //and all the rest of this constructor is just to do this... //...I love the ITK interface ... lol //init default image, this can still be overwritten myImage = ImageType::New(); ImageType::SpacingType spacing; spacing[0]=0.1; spacing[1]=0.1;; spacing[2]=0.1;; myImage->SetSpacing(spacing); //we set the origin such that center lies at (0,0,0) ImageType::PointType origin; origin[0]=-0.05; origin[1]=-0.05; origin[2]=-0.05; myImage->SetOrigin(origin); //we want an image with voxelRes voxels ImageType::IndexType start; start[0]=0; start[1]=0; start[2]=0; ImageType::SizeType size; size[0]=1; size[1]=1; size[2]=1; ImageType::RegionType region; region.SetIndex(start); region.SetSize(size); myImage->SetRegions(region); //allocate memory myImage->Allocate(); //interpolating function myInterpFunc = InterpFunc::New(); myInterpFunc->SetSplineOrder((unsigned int) 0); myInterpFunc->SetInputImage(myImage); }
gmMatrix3 ITKImplicit::hess(const gmVector3 & x) { ImageType::PointType myPoint; myPoint[0]=x[0]; myPoint[1]=x[1]; myPoint[2]=x[2]; if(myInterpFunc && myInterpFunc->IsInsideBuffer(myPoint)) { itk::CovariantVector<double> grad(myInterpFunc->EvaluateDerivative(myPoint)); ImageType::PointType myPointxEps(myPoint); myPointxEps[0]+=m_epsilon; itk::CovariantVector<double> gradxEps; if (myInterpFunc->IsInsideBuffer(myPointxEps)) gradxEps=(myInterpFunc->EvaluateDerivative(myPointxEps)); else return gmMatrix3(1,0,0, 0,1,0, 0,0,1); gmVector3 gradx=(gmVector3(gradxEps[0], gradxEps[1],gradxEps[2])-gmVector3(grad[0],grad[1],grad[2]))/m_epsilon; ImageType::PointType myPointyEps(myPoint); myPointyEps[1]+=m_epsilon; itk::CovariantVector<double> gradyEps; if (myInterpFunc->IsInsideBuffer(myPointyEps)) gradyEps=(myInterpFunc->EvaluateDerivative(myPointyEps)); else return gmMatrix3(1,0,0, 0,1,0, 0,0,1); gmVector3 grady=(gmVector3(gradyEps[0], gradyEps[1],gradyEps[2])-gmVector3(grad[0],grad[1],grad[2]))/m_epsilon; ImageType::PointType myPointzEps(myPoint); myPointzEps[2]+=m_epsilon; itk::CovariantVector<double> gradzEps; if (myInterpFunc->IsInsideBuffer(myPointyEps)) gradzEps=(myInterpFunc->EvaluateDerivative(myPointzEps)); else return gmMatrix3(1,0,0, 0,1,0, 0,0,1); gmVector3 gradz=(gmVector3(gradzEps[0], gradzEps[1],gradzEps[2])-gmVector3(grad[0],grad[1],grad[2]))/m_epsilon; const double fxx=gradx[0], fxy=(grady[0]+gradx[1])/2.0, fxz=(gradz[0]+gradx[2])/2.0, fyy=grady[1], fyz=(grady[2]+gradz[1])/2.0, fzz=gradz[2]; return gmMatrix3(fxx,fxy,fxz,fxy,fyy,fyz,fxz,fyz,fzz); } else { //we return a hessian which is like one on the sphere to attract particles to the center... return gmMatrix3(1,0,0, 0,1,0, 0,0,1); } }
/** * Add a normal corresponding to the new particle. * @param i Index of the new particle. */ void ParticlePosition::particleAdded() { x.push_back(gmVector3(psRandom(),psRandom(),psRandom())); changed = true; }