float BSDF::Pdf(const Vector &woW, const Vector &wiW, BxDFType flags) const { if (nBxDFs == 0.) return 0.; Vector wo = WorldToLocal(woW), wi = WorldToLocal(wiW); float pdf = 0.f; int matchingComps = 0; for (int i = 0; i < nBxDFs; ++i) if (bxdfs[i]->MatchesFlags(flags)) { ++matchingComps; pdf += bxdfs[i]->Pdf(wo, wi); } return matchingComps > 0 ? pdf / matchingComps : 0.f; }
// BSDF Method Definitions Spectrum BSDF::f(const Vector3f &woW, const Vector3f &wiW, BxDFType flags) const { ProfilePhase pp(Prof::BSDFEvaluation); Vector3f wi = WorldToLocal(wiW), wo = WorldToLocal(woW); bool reflect = Dot(wiW, ng) * Dot(woW, ng) > 0; Spectrum f(0.f); for (int i = 0; i < nBxDFs; ++i) if (bxdfs[i]->MatchesFlags(flags) && ((reflect && (bxdfs[i]->type & BSDF_REFLECTION)) || (!reflect && (bxdfs[i]->type & BSDF_TRANSMISSION)))) f += bxdfs[i]->f(wo, wi); return f; }
Float BSDF::Pdf(const Vector3f &woWorld, const Vector3f &wiWorld, BxDFType flags) const { if (nBxDFs == 0.f) return 0.f; Vector3f wo = WorldToLocal(woWorld), wi = WorldToLocal(wiWorld); Float pdf = 0.f; int matchingComps = 0; for (int i = 0; i < nBxDFs; ++i) if (bxdfs[i]->MatchesFlags(flags)) { ++matchingComps; pdf += bxdfs[i]->Pdf(wo, wi); } Float v = matchingComps > 0 ? pdf / matchingComps : 0.f; return v; }
float BSDF::Pdf(const Vector &woWorld, const Vector &wiWorld, BxDFType flags) const { if (mNumBxdf == 0) return 0; Vector wo = WorldToLocal(woWorld), wi = WorldToLocal(wiWorld); float pdf = 0.0f; int matchingComps = 0; for (int i = 0; i < mNumBxdf; ++i) if (mBxdfs[i]->MatchesFlag(flags)) { ++matchingComps; pdf += mBxdfs[i]->Pdf(wo, wi); } float v = matchingComps > 0 ? pdf / matchingComps : 0.f; return v; }
Spectrum BSDF::f(const Vector &woW, const Vector &wiW, BxDFType flags) const { Vector wi = WorldToLocal(wiW), wo = WorldToLocal(woW); if (Dot(wiW, ng) * Dot(woW, ng) > 0) // ignore BTDFs flags = BxDFType(flags & ~BSDF_TRANSMISSION); else // ignore BRDFs flags = BxDFType(flags & ~BSDF_REFLECTION); Spectrum f = 0.; for (int i = 0; i < nBxDFs; ++i) if (bxdfs[i]->MatchesFlags(flags)) f += bxdfs[i]->f(wo, wi); return f; }
RGB BSDF::f(const Vector &woWorld, const Vector &wiWorld, BxDFType flags) const { Vector wo = WorldToLocal(woWorld); Vector wi = WorldToLocal(wiWorld); if (Dot(woWorld, mNG) * Dot(wiWorld, mNG) > 0) { //相乘大于零说明在同一半球 flags = BxDFType(flags & ~BSDF_TRANSMISSION); //去除折射 } else { flags = BxDFType(flags & ~BSDF_REFLECTION); //去除反射 } RGB f = 0; for (int i = 0; i < mNumBxdf; ++i) { if (mBxdfs[i]->MatchesFlag(flags)) { f += mBxdfs[i]->f(wo, wi); } } return f; }
void CPhysicsObject::ApplyForceOffset(const Vector& forceVector, const Vector& worldPosition) { Vector local; WorldToLocal(&local, worldPosition); btVector3 force, offset; ConvertForceImpulseToBull(forceVector, force); ConvertPosToBull(local, offset); m_pObject->applyForce(force, offset); }
Spectrum BSDF::Sample_f(const Vector3f &woWorld, Vector3f *wiWorld, const Point2f &u, Float *pdf, BxDFType type, BxDFType *sampledType) const { ProfilePhase pp(Prof::BSDFEvaluation); // Choose which _BxDF_ to sample int matchingComps = NumComponents(type); if (matchingComps == 0) { *pdf = 0; if (sampledType) *sampledType = BxDFType(0); return Spectrum(0); } int comp = std::min((int)std::floor(u[0] * matchingComps), matchingComps - 1); // Get _BxDF_ pointer for chosen component BxDF *bxdf = nullptr; int count = comp; for (int i = 0; i < nBxDFs; ++i) if (bxdfs[i]->MatchesFlags(type) && count-- == 0) { bxdf = bxdfs[i]; break; } Assert(bxdf); // Remap _BxDF_ sample _u_ to $[0,1)^2$ Point2f uRemapped(u[0] * matchingComps - comp, u[1]); // Sample chosen _BxDF_ Vector3f wi, wo = WorldToLocal(woWorld); *pdf = 0; if (sampledType) *sampledType = bxdf->type; Spectrum f = bxdf->Sample_f(wo, &wi, uRemapped, pdf, sampledType); if (*pdf == 0) { if (sampledType) *sampledType = BxDFType(0); return 0; } *wiWorld = LocalToWorld(wi); // Compute overall PDF with all matching _BxDF_s if (!(bxdf->type & BSDF_SPECULAR) && matchingComps > 1) for (int i = 0; i < nBxDFs; ++i) if (bxdfs[i] != bxdf && bxdfs[i]->MatchesFlags(type)) *pdf += bxdfs[i]->Pdf(wo, wi); if (matchingComps > 1) *pdf /= matchingComps; // Compute value of BSDF for sampled direction if (!(bxdf->type & BSDF_SPECULAR) && matchingComps > 1) { bool reflect = Dot(*wiWorld, ng) * Dot(woWorld, ng) > 0; f = 0.; for (int i = 0; i < nBxDFs; ++i) if (bxdfs[i]->MatchesFlags(type) && ((reflect && (bxdfs[i]->type & BSDF_REFLECTION)) || (!reflect && (bxdfs[i]->type & BSDF_TRANSMISSION)))) f += bxdfs[i]->f(wo, wi); } return f; }
void CPhysicsObject::GetVelocityAtPoint(const Vector &worldPosition, Vector *pVelocity) const { if (!pVelocity) return; Vector localPos; WorldToLocal(&localPos, worldPosition); btVector3 vec; ConvertPosToBull(localPos, vec); ConvertPosToHL(m_pObject->getVelocityInLocalPoint(vec), *pVelocity); }
Spectrum BSDF::Sample_f(const Vector &woW, Vector *wiW, float u1, float u2, float u3, float *pdf, BxDFType flags, BxDFType *sampledType) const { // Choose which _BxDF_ to sample int matchingComps = NumComponents(flags); if (matchingComps == 0) { *pdf = 0.f; return Spectrum(0.f); } int which = min(Floor2Int(u3 * matchingComps), matchingComps-1); BxDF *bxdf = NULL; int count = which; for (int i = 0; i < nBxDFs; ++i) if (bxdfs[i]->MatchesFlags(flags)) if (count-- == 0) { bxdf = bxdfs[i]; break; } Assert(bxdf); // NOBOOK // Sample chosen _BxDF_ Vector wi; Vector wo = WorldToLocal(woW); *pdf = 0.f; Spectrum f = bxdf->Sample_f(wo, &wi, u1, u2, pdf); if (*pdf == 0.f) return 0.f; if (sampledType) *sampledType = bxdf->type; *wiW = LocalToWorld(wi); // Compute overall PDF with all matching _BxDF_s if (!(bxdf->type & BSDF_SPECULAR) && matchingComps > 1) { for (int i = 0; i < nBxDFs; ++i) { if (bxdfs[i] != bxdf && bxdfs[i]->MatchesFlags(flags)) *pdf += bxdfs[i]->Pdf(wo, wi); } } if (matchingComps > 1) *pdf /= matchingComps; // Compute value of BSDF for sampled direction if (!(bxdf->type & BSDF_SPECULAR)) { f = 0.; if (Dot(*wiW, ng) * Dot(woW, ng) > 0) // ignore BTDFs flags = BxDFType(flags & ~BSDF_TRANSMISSION); else // ignore BRDFs flags = BxDFType(flags & ~BSDF_REFLECTION); for (int i = 0; i < nBxDFs; ++i) if (bxdfs[i]->MatchesFlags(flags)) f += bxdfs[i]->f(wo, wi); } return f; }
void CPhysicsObject::ApplyForceOffset(const Vector &forceVector, const Vector &worldPosition) { if (!IsMoveable() || !IsMotionEnabled()) { return; } Wake(); Vector local; WorldToLocal(&local, worldPosition); btVector3 force, offset; ConvertForceImpulseToBull(forceVector, force); ConvertPosToBull(local, offset); m_pObject->applyImpulse(force, offset); Wake(); }
//Move the active image slice by the specified amount void WITVolumeViz::MoveActiveImage(int amount) { if(!_vol) return; uint dim[4]; _vol->getDimension(dim[0], dim[1], dim[2], dim[3]); DTIVoxel lPos = DTIVoxel(3); WorldToLocal(_vol->getTransformMatrix(), _vPos, dim, lPos); DTISceneActorID i = ActiveImage(); if(i >=0 && i < 3) { lPos[i] += amount; // see if the new position exceeds the dimensions // since both are unsigned, a value of -1 will be mapped to 0xfffffff which is greater than dim[i] if(lPos[i] >= dim[i]) lPos[i] = (amount > 0) ? dim[i]-1 : 0; Vector3d vPos; LocalToWorld(_vol->getTransformMatrix(), lPos, vPos.v); SetPosition(vPos); } }
bool OBB::Intersects(const Ray &ray, float *dNear, float *dFar) const { AABB aabb(float3(0,0,0), float3(Size())); Ray r = WorldToLocal() * ray; return aabb.Intersects(ray, dNear, dFar); }
RGB BSDF::Sample_f(const Vector &woWorld, Vector *wiWorld, const BSDFSample &bsdfSample, float *pdf, BxDFType flags, BxDFType *sampledType) const { int numComp = NumComponents(flags); if (numComp == 0) { *pdf = 0; if (sampledType) *sampledType = BxDFType(0); return 0; } int whichComp = min(Floor2Int(bsdfSample.uComponent * numComp), numComp - 1); int count = whichComp; BxDF *bxdf = nullptr; //被选中的Bxdf for (int i = 0; i < mNumBxdf; ++i) { if (mBxdfs[i]->MatchesFlag(flags) && count-- == 0) { //这技巧 GOOD bxdf = mBxdfs[i]; break; } } Vector wo = WorldToLocal(woWorld); //获得局部坐标下的wo Vector wi; *pdf = 0.f; RGB f = bxdf->Sample_f(wo, &wi, bsdfSample.uDir[0], bsdfSample.uDir[1], pdf); //这里的主要作用是采样出射方向 if (*pdf == 0) { if (sampledType) *sampledType = BxDFType(0); return 0; } if (sampledType) *sampledType = bxdf->type; *wiWorld = LocalToWorld(wi); //获得世界坐标系下的wi //计算pdf if (!(bxdf->type & BSDF_SPECULAR) && numComp > 1) { for (int i = 0; i < mNumBxdf; ++i) { if (bxdf != mBxdfs[i] && mBxdfs[i]->MatchesFlag(flags)) { *pdf += mBxdfs[i]->Pdf(wo, wi); } } } if (numComp > 1) { *pdf /= numComp; } //开始计算BRDF系数 if (!(bxdf->type & BSDF_SPECULAR)) { f=0;//因为不是镜面反射 所以重新计算BRDF if (Dot(*wiWorld, mNG) * Dot(woWorld, mNG) > 0) //反射 flags = BxDFType(flags & ~BSDF_TRANSMISSION); else//折射 flags = BxDFType(flags & ~BSDF_REFLECTION); for (int i = 0; i < mNumBxdf; ++i) if (mBxdfs[i]->MatchesFlag(flags)) f += mBxdfs[i]->f(wo, wi); } return f; }
bool OBB::Intersects(const Line &line, float &dNear, float &dFar) const { AABB aabb(POINT_VEC_SCALAR(0.f), Size()); Line l = WorldToLocal() * line; return aabb.Intersects(l, dNear, dFar); }
bool OBB::Intersects(const Line &line) const { AABB aabb(POINT_VEC_SCALAR(0.f), Size()); Line l = WorldToLocal() * line; return aabb.Intersects(l); }
bool OBB::Intersects(const Triangle &triangle) const { AABB aabb(POINT_VEC_SCALAR(0.f), Size()); Triangle t = WorldToLocal() * triangle; return t.Intersects(aabb); }
CVec2 CControl::CalcSizeFromMouse(float x, float y, EHitTestResult hitPos) { CVec2 anchor = m_vec2Anchor; WorldToLocal(x, y); CVec2 realSize = m_vecRealSize; CVec2 newRealSize = realSize; switch(hitPos) { case eHTR_HIT_TOP_LEFT: if(anchor.x > 0.f) newRealSize.x = - x / anchor.x; if(anchor.y > 0.f) newRealSize.y = - y / anchor.y; break; case eHTR_HIT_TOP_CENTER: newRealSize.x = realSize.x; if(anchor.y > 0.f) newRealSize.y = - y / anchor.y; break; case eHTR_HIT_TOP_RIGHT: if(anchor.x < 1.f) newRealSize.x = x / (1 - anchor.x); if(anchor.y > 0.f) newRealSize.y = - y / anchor.y; break; case eHTR_HIT_LEFT_CENTER: if(anchor.x > 0.f) newRealSize.x = - x / anchor.x; newRealSize.y = realSize.y; break; case eHTR_HIT_RIGHT_CENTER: if(anchor.x < 1.f) newRealSize.x = x / (1 - anchor.x); newRealSize.y = realSize.y; break; case eHTR_HIT_BOTTOM_LEFT: if(anchor.x > 0.f) newRealSize.x = - x / anchor.x; if(anchor.y < 1.f) newRealSize.y = y / (1 - anchor.y); break; case eHTR_HIT_BOTTOM_CENTER: newRealSize.x = realSize.x; if(anchor.y < 1.f) newRealSize.y = y / (1 - anchor.y); break; case eHTR_HIT_BOTTOM_RIGHT: if(anchor.x < 1.f) newRealSize.x = x / (1 - anchor.x); if(anchor.y < 1.f) newRealSize.y = y / (1 - anchor.y); break; default: BEATS_ASSERT(false); } CVec2 newSize = newRealSize; CNode* pParent = GetParentNode(); if( pParent && pParent->GetType() == eNT_NodeGUI ) { CVec2 realSizePercentPart = m_vecRealSize - m_vec2Size; newSize = newRealSize - realSizePercentPart; } return newSize; }
void WITVolumeViz::updateActors() { if(!_vol) return; this->updateUserMatrices(); uint dim[4]; double voxSize[3]; _vol->getDimension(dim[0], dim[1], dim[2], dim[3]); _vol->getVoxelSize(voxSize[0], voxSize[1], voxSize[2]); VTK_SAFE_DELETE(_img); _img = vtkImageData::New(); _img->SetScalarTypeToFloat(); _img->SetNumberOfScalarComponents(dim[3]); _img->SetDimensions (dim[0], dim[1], dim[2]); _img->SetSpacing (1,1,1); if (dim[3] == 1) _img->SetScalarTypeToFloat(); else _img->SetScalarTypeToUnsignedChar(); _img->AllocateScalars(); vtkScalarsToColors *lut = _lutBW; if (dim[3] == 1) // more common case { // create the sagital actor vtkImageMapToColors *sagittalColors = vtkImageMapToColors::New(); sagittalColors->SetInput(_img); sagittalColors->SetLookupTable(lut); // create the axial actor vtkImageMapToColors *axialColors = vtkImageMapToColors::New(); axialColors->SetInput(_img); axialColors->SetLookupTable(lut); // create the coronal actor vtkImageMapToColors *coronalColors = vtkImageMapToColors::New(); coronalColors->SetInput(_img); coronalColors->SetLookupTable(lut); // Apply the color map to all registered actors this->setSliceActorsToColors(sagittalColors, axialColors, coronalColors); sagittalColors->Delete(); axialColors->Delete(); coronalColors->Delete(); } else { // Apply user matrix to each registered actor for(std::map<vtkRenderWindow*, ActorSet*>::iterator it = this->windowToActorSet.begin(); it != this->windowToActorSet.end(); it++) { ActorSet *as = it->second; as->sag->SetInput(_img); as->axial->SetInput(_img); as->cor->SetInput(_img); } } // Find the local pos based on world pos DTIVoxel lPos = DTIVoxel(3); WorldToLocal(_vol->getTransformMatrix(), _vPos, dim, lPos); sagExtent[0] = lPos[0]; sagExtent[1] = lPos[0]; sagExtent[2] = 0; sagExtent[3] = dim[1]-1; sagExtent[4] = 0; sagExtent[5] = dim[2] - 1; axialExtent[0] = 0; axialExtent[1] = dim[0] - 1; axialExtent[2] = 0; axialExtent[3] = dim[1]-1; axialExtent[4] = lPos[2]; axialExtent[5] = lPos[2]; corExtent[0] = 0; corExtent[1] = dim[0]-1; corExtent[2] = lPos[1]; corExtent[3] = lPos[1]; corExtent[4] = 0; corExtent[5] = dim[2] - 1; // set the extent to which the image should be mapped // Apply user matrix to each registered actor for(std::map<vtkRenderWindow*, ActorSet*>::iterator it = this->windowToActorSet.begin(); it != this->windowToActorSet.end(); it++) { ActorSet *as = it->second; as->sag->SetDisplayExtent(sagExtent); as->axial->SetDisplayExtent(axialExtent); as->cor->SetDisplayExtent(corExtent); as->sag->Modified(); as->cor->Modified(); as->axial->Modified(); // set the position in the as->text text actor as->text->GetTextProperty()->SetFontSize(16); as->text->GetTextProperty()->SetFontFamilyToArial(); as->text->GetTextProperty()->SetJustificationToLeft(); as->text->GetPositionCoordinate()->SetValue(2,0); //as->text->GetTextProperty()->BoldOn(); //as->text->GetTextProperty()->ItalicOn(); as->text->GetTextProperty()->SetColor(0,0,0); as->text->Modified(); } }
///Display border around the selected image plane void WITVolumeViz::DisplayBorder() { if(_nActiveImage>=0 && _nActiveImage<3) { // Position the slice double voxSize[3]; uint dim[4]; _vol->getVoxelSize (voxSize[0], voxSize[1], voxSize[2]); _vol->getDimension (dim[0], dim[1], dim[2], dim[3]); DTIVoxel lPos = DTIVoxel(3); WorldToLocal(_vol->getTransformMatrix(), _vPos, dim, lPos); double p[3]= {lPos[0], lPos[1], lPos[2]}, m[3] = {dim[0]-1, dim[1]-1, dim[2]-1}; vtkPoints *pts = _pdBorder->GetPoints(); // specify the 4 corners of the border depending on which image plane has been selected switch(_nActiveImage) { case DTI_ACTOR_SAGITTAL_TOMO: pts->SetPoint(0, p[0],0,0); pts->SetPoint(1, p[0],0,m[2]); pts->SetPoint(2, p[0],m[1],m[2]); pts->SetPoint(3, p[0],m[1],0); break; case DTI_ACTOR_AXIAL_TOMO: pts->SetPoint(0, 0,0,p[2]); pts->SetPoint(1, m[0],0,p[2]); pts->SetPoint(2, m[0],m[1],p[2]); pts->SetPoint(3, 0,m[1],p[2]); break; case DTI_ACTOR_CORONAL_TOMO: pts->SetPoint(0, 0,p[1],0); pts->SetPoint(1, m[0],p[1],0); pts->SetPoint(2, m[0],p[1],m[2]); pts->SetPoint(3, 0,p[1],m[2]); break; } _pdBorder->Modified(); for(std::map<vtkRenderWindow*, ActorSet*>::iterator it = this->windowToActorSet.begin(); it != this->windowToActorSet.end(); it++) { ActorSet *as = it->second; as->border->SetUserMatrix(as->cor->GetUserMatrix()); as->border->SetVisibility(true); as->border->Modified(); } } else { for(std::map<vtkRenderWindow*, ActorSet*>::iterator it = this->windowToActorSet.begin(); it != this->windowToActorSet.end(); it++) { ActorSet *as = it->second; as->border->SetUserMatrix(as->cor->GetUserMatrix()); as->border->SetVisibility(false); as->border->Modified(); } } }
void WITVolumeViz::GetCursorPosition(DTIVoxel &lPos) { uint dim[4]; _vol->getDimension(dim[0], dim[1], dim[2], dim[3]); WorldToLocal(_vol->getTransformMatrix(), _vPos, dim, lPos); }
void WITVolumeViz::ActiveImageExtents(double transPts[4][3], double transNormal[4]) { // get the active image extents double pts[4][3]; int displayExtent[6]; double planeNormal[4]= {0,0,0,0}; uint dim[4]; // get the image dimensions _vol->getDimension (dim[0], dim[1], dim[2], dim[3]); DTIVoxel lPos = DTIVoxel(3); // map position from ACPC to 3d world space WorldToLocal(_vol->getTransformMatrix(), _vPos, dim, lPos); memset(pts, 0, sizeof(double)*4*3); int i = ActiveImage(); GetDisplayExtent ((DTISceneActorID)i,displayExtent); for (int j = 0; j < 4; j++) pts[j][i] = lPos[i]; planeNormal[i] = 1; // get the 4 corners depending on which image plane is selected switch (ActiveImage()) { case DTI_ACTOR_SAGITTAL_TOMO: pts[1][1] = displayExtent[3]; pts[2][1] = displayExtent[3]; pts[2][2] = displayExtent[5]; pts[3][2] = displayExtent[5]; break; case DTI_ACTOR_CORONAL_TOMO: pts[1][0] = displayExtent[1]; pts[2][0] = displayExtent[1]; pts[2][2] = displayExtent[5]; pts[3][2] = displayExtent[5]; break; case DTI_ACTOR_AXIAL_TOMO: pts[1][0] = displayExtent[1]; pts[2][0] = displayExtent[1]; pts[2][1] = displayExtent[3]; pts[3][1] = displayExtent[3]; break; default: break; }; vtkMatrix4x4 *mx = GetUserMatrix(); // map the points from 3d world space to ACPC space for (int i = 0; i < 4; i++) { double fooIn[4] = {pts[i][0], pts[i][1], pts[i][2], 1}; double fooOut[4]; mx->MultiplyPoint (fooIn, fooOut); transPts[i][0] = fooOut[0]; transPts[i][1] = fooOut[1]; transPts[i][2] = fooOut[2]; } // inverse of transpose: vtkMatrix4x4 *invertedMx = vtkMatrix4x4::New(); vtkMatrix4x4 *transposedMx = vtkMatrix4x4::New(); mx->Invert (mx, invertedMx); mx->Transpose (invertedMx, transposedMx); mx->MultiplyPoint (planeNormal, transNormal); transposedMx->Delete(); invertedMx->Delete(); }
bool OBB::Intersects(const LineSegment &lineSegment, float *dNear, float *dFar) const { AABB aabb(float3(0,0,0), float3(Size())); LineSegment l = WorldToLocal() * lineSegment; return aabb.Intersects(lineSegment, dNear, dFar); }
bool OBB::Intersects(const Ray &ray, float &dNear, float &dFar) const { AABB aabb(POINT_VEC_SCALAR(0.f), Size()); Ray r = WorldToLocal() * ray; return aabb.Intersects(r, dNear, dFar); }
bool OBB::Intersects(const Triangle &triangle) const { AABB aabb(float3(0,0,0), float3(Size())); Triangle t = WorldToLocal() * triangle; return t.Intersects(aabb); }
void WITVolumeViz::SetPosition(Vector3d &v) { uint dim[4]; double voxSize[3]; _vol->getDimension(dim[0], dim[1], dim[2], dim[3]); _vol->getVoxelSize(voxSize[0], voxSize[1], voxSize[2]); DTIVoxel lPos = DTIVoxel(3); WorldToLocal(_vol->getTransformMatrix(), v, dim, lPos); sagExtent[0] = lPos[0]; sagExtent[1] = lPos[0]; sagExtent[2] = 0; sagExtent[3] = dim[1]-1; sagExtent[4] = 0; sagExtent[5] = dim[2] - 1; axialExtent[0] = 0; axialExtent[1] = dim[0] - 1; axialExtent[2] = 0; axialExtent[3] = dim[1]-1; axialExtent[4] = lPos[2]; axialExtent[5] = lPos[2]; corExtent[0] = 0; corExtent[1] = dim[0]-1; corExtent[2] = lPos[1]; corExtent[3] = lPos[1]; corExtent[4] = 0; corExtent[5] = dim[2] - 1; // do a lazy update on the image planes that are mapped to the image actors if(v[0] != _vPos[0]) { _vPos[0] = v[0]; for(std::map<vtkRenderWindow*, ActorSet*>::iterator it = this->windowToActorSet.begin(); it != this->windowToActorSet.end(); it++) { ActorSet *as = it->second; as->sag->SetDisplayExtent(sagExtent); as->sag->Modified(); } } if(v[1] != _vPos[1]) { _vPos[1] = v[1]; // Update Coronal position for(std::map<vtkRenderWindow*, ActorSet*>::iterator it = this->windowToActorSet.begin(); it != this->windowToActorSet.end(); it++) { ActorSet *as = it->second; as->cor->SetDisplayExtent(corExtent); as->cor->Modified(); } } if(v[2] != _vPos[2]) { _vPos[2] = v[2]; // Update Coronal position for(std::map<vtkRenderWindow*, ActorSet*>::iterator it = this->windowToActorSet.begin(); it != this->windowToActorSet.end(); it++) { ActorSet *as = it->second; as->axial->SetDisplayExtent(axialExtent); as->axial->Modified(); } } double flPos[3] = {lPos[0], lPos[1], lPos[2]}; for(int i=0; i<3; i++) { flPos[i]*=voxSize[i]; } // for(int i = 0; i < (int)_overlays.size(); i++) // _overlays[i]->SetPosition(_vPos, flPos); DisplayBorder(); // update the text of the position actor to show the new position in ACPC space char spos[100]; sprintf(spos, "Position: %.1f, %.1f, %.1f",_vPos[0],_vPos[1],_vPos[2]); for(std::map<vtkRenderWindow*, ActorSet*>::iterator it = this->windowToActorSet.begin(); it != this->windowToActorSet.end(); it++) { ActorSet *as = it->second; as->text->SetInput(spos); } //for(unsigned i = 0; i < _overlays.size(); i++) // _overlays[i]->SetPosition(v, lPos); }