//---------------------------------------------------------------------------- void CIsoSurface::GetZMaxEdges (int iX, int iY, int iZ, int iType, VETable& rkTable) { int iFaceType = 0; if ( iType & EB_XMIN_ZMAX ) iFaceType |= 0x01; if ( iType & EB_XMAX_ZMAX ) iFaceType |= 0x02; if ( iType & EB_YMIN_ZMAX ) iFaceType |= 0x04; if ( iType & EB_YMAX_ZMAX ) iFaceType |= 0x08; switch ( iFaceType ) { case 0: return; case 3: rkTable.Insert(EI_XMIN_ZMAX,EI_XMAX_ZMAX); break; case 5: rkTable.Insert(EI_XMIN_ZMAX,EI_YMIN_ZMAX); break; case 6: rkTable.Insert(EI_XMAX_ZMAX,EI_YMIN_ZMAX); break; case 9: rkTable.Insert(EI_XMIN_ZMAX,EI_YMAX_ZMAX); break; case 10: rkTable.Insert(EI_XMAX_ZMAX,EI_YMAX_ZMAX); break; case 12: rkTable.Insert(EI_YMIN_ZMAX,EI_YMAX_ZMAX); break; case 15: { // four vertices, one per edge, need to disambiguate int i = iX + m_iXBound*(iY + m_iYBound*(iZ+1)); int iF00 = m_aiData[i]; // F(x,y,z) i++; int iF10 = m_aiData[i]; // F(x+1,y,z) i += m_iXBound; int iF11 = m_aiData[i]; // F(x+1,y+1,z) i--; int iF01 = m_aiData[i]; // F(x,y+1,z) int iDet = iF00*iF11 - iF01*iF10; if ( iDet > 0 ) { // disjoint hyperbolic segments, pair <P0,P2>, <P1,P3> rkTable.Insert(EI_XMIN_ZMAX,EI_YMIN_ZMAX); rkTable.Insert(EI_XMAX_ZMAX,EI_YMAX_ZMAX); } else if ( iDet < 0 ) { // disjoint hyperbolic segments, pair <P0,P3>, <P1,P2> rkTable.Insert(EI_XMIN_ZMAX,EI_YMAX_ZMAX); rkTable.Insert(EI_XMAX_ZMAX,EI_YMIN_ZMAX); } else { // plus-sign configuration, add branch point to tessellation rkTable.Insert(FI_ZMAX,TVector3D(rkTable.GetX(EI_YMIN_ZMAX), rkTable.GetY(EI_XMIN_ZMAX),rkTable.GetZ(EI_XMIN_ZMAX))); // add edges sharing the branch point rkTable.Insert(EI_XMIN_ZMAX,FI_ZMAX); rkTable.Insert(EI_XMAX_ZMAX,FI_ZMAX); rkTable.Insert(EI_YMIN_ZMAX,FI_ZMAX); rkTable.Insert(EI_YMAX_ZMAX,FI_ZMAX); } break; } default: assert( false ); } }
//---------------------------------------------------------------------------- int CIsoSurface::GetVertices (float fLevel, int iX, int iY, int iZ, VETable& rkTable) { int iType = 0; // get image values at corners of voxel int i000 = iX + m_iXBound*(iY + m_iYBound*iZ); int i100 = i000 + 1; int i010 = i000 + m_iXBound; int i110 = i010 + 1; int i001 = i000 + m_iXYBound; int i101 = i001 + 1; int i011 = i001 + m_iXBound; int i111 = i011 + 1; float fF000 = (float)m_aiData[i000]; float fF100 = (float)m_aiData[i100]; float fF010 = (float)m_aiData[i010]; float fF110 = (float)m_aiData[i110]; float fF001 = (float)m_aiData[i001]; float fF101 = (float)m_aiData[i101]; float fF011 = (float)m_aiData[i011]; float fF111 = (float)m_aiData[i111]; float fX0 = (float)iX, fY0 = (float)iY, fZ0 = (float)iZ; float fX1 = fX0+1.0f, fY1 = fY0+1.0f, fZ1 = fZ0+1.0f; // xmin-ymin edge float fDiff0 = fLevel - fF000; float fDiff1 = fLevel - fF001; if ( fDiff0*fDiff1 < 0.0f ) { iType |= EB_XMIN_YMIN; rkTable.Insert(EI_XMIN_YMIN, TVector3D(fX0,fY0,fZ0+fDiff0/(fF001-fF000))); } // xmin-ymax edge fDiff0 = fLevel - fF010; fDiff1 = fLevel - fF011; if ( fDiff0*fDiff1 < 0.0f ) { iType |= EB_XMIN_YMAX; rkTable.Insert(EI_XMIN_YMAX, TVector3D(fX0,fY1,fZ0+fDiff0/(fF011-fF010))); } // xmax-ymin edge fDiff0 = fLevel - fF100; fDiff1 = fLevel - fF101; if ( fDiff0*fDiff1 < 0.0f ) { iType |= EB_XMAX_YMIN; rkTable.Insert(EI_XMAX_YMIN, TVector3D(fX1,fY0,fZ0+fDiff0/(fF101-fF100))); } // xmax-ymax edge fDiff0 = fLevel - fF110; fDiff1 = fLevel - fF111; if ( fDiff0*fDiff1 < 0.0f ) { iType |= EB_XMAX_YMAX; rkTable.Insert(EI_XMAX_YMAX, TVector3D(fX1,fY1,fZ0+fDiff0/(fF111-fF110))); } // xmin-zmin edge fDiff0 = fLevel - fF000; fDiff1 = fLevel - fF010; if ( fDiff0*fDiff1 < 0.0f ) { iType |= EB_XMIN_ZMIN; rkTable.Insert(EI_XMIN_ZMIN, TVector3D(fX0,fY0+fDiff0/(fF010-fF000),fZ0)); } // xmin-zmax edge fDiff0 = fLevel - fF001; fDiff1 = fLevel - fF011; if ( fDiff0*fDiff1 < 0.0f ) { iType |= EB_XMIN_ZMAX; rkTable.Insert(EI_XMIN_ZMAX, TVector3D(fX0,fY0+fDiff0/(fF011-fF001),fZ1)); } // xmax-zmin edge fDiff0 = fLevel - fF100; fDiff1 = fLevel - fF110; if ( fDiff0*fDiff1 < 0.0f ) { iType |= EB_XMAX_ZMIN; rkTable.Insert(EI_XMAX_ZMIN, TVector3D(fX1,fY0+fDiff0/(fF110-fF100),fZ0)); } // xmax-zmax edge fDiff0 = fLevel - fF101; fDiff1 = fLevel - fF111; if ( fDiff0*fDiff1 < 0.0f ) { iType |= EB_XMAX_ZMAX; rkTable.Insert(EI_XMAX_ZMAX, TVector3D(fX1,fY0+fDiff0/(fF111-fF101),fZ1)); } // ymin-zmin edge fDiff0 = fLevel - fF000; fDiff1 = fLevel - fF100; if ( fDiff0*fDiff1 < 0.0f ) { iType |= EB_YMIN_ZMIN; rkTable.Insert(EI_YMIN_ZMIN, TVector3D(fX0+fDiff0/(fF100-fF000),fY0,fZ0)); } // ymin-zmax edge fDiff0 = fLevel - fF001; fDiff1 = fLevel - fF101; if ( fDiff0*fDiff1 < 0.0f ) { iType |= EB_YMIN_ZMAX; rkTable.Insert(EI_YMIN_ZMAX, TVector3D(fX0+fDiff0/(fF101-fF001),fY0,fZ1)); } // ymax-zmin edge fDiff0 = fLevel - fF010; fDiff1 = fLevel - fF110; if ( fDiff0*fDiff1 < 0.0f ) { iType |= EB_YMAX_ZMIN; rkTable.Insert(EI_YMAX_ZMIN, TVector3D(fX0+fDiff0/(fF110-fF010),fY1,fZ0)); } // ymax-zmax edge fDiff0 = fLevel - fF011; fDiff1 = fLevel - fF111; if ( fDiff0*fDiff1 < 0.0f ) { iType |= EB_YMAX_ZMAX; rkTable.Insert(EI_YMAX_ZMAX, TVector3D(fX0+fDiff0/(fF111-fF011),fY1,fZ1)); } return iType; }
/*! Returns the 3D vector form of this 4D vector, dividing the x, y, and z coordinates by the w coordinate. Returns a null vector if w is zero. \sa toVector3D(), toVector2DAffine(), toPoint() */ TVector3D TVector4D::toVector3DAffine() const { if (qIsNull(wp)) return TVector3D(); return TVector3D(xp / wp, yp / wp, zp / wp, 1); }
/*! Returns the 3D form of this 2D vector, with the z coordinate set to zero. \sa toVector4D(), toPoint() */ TVector3D TVector2D::toVector3D() const { return TVector3D(xp, yp, 0.0f, 1); }
/*! Returns the 3D vector form of this 4D vector, dropping the w coordinate. \sa toVector3DAffine(), toVector2D(), toPoint() */ TVector3D TVector4D::toVector3D() const { return TVector3D(xp, yp, zp, 1); }