void mitk::VectorImageMapper2D::Paint( mitk::BaseRenderer * renderer ) { //std::cout << "2d vector mapping..." << std::endl; bool visible = true; GetDataNode()->GetVisibility(visible, renderer, "visible"); if ( !visible ) return ; mitk::Image::Pointer input = const_cast<mitk::Image*>( this->GetInput() ); if ( input.IsNull() ) return ; mitk::PlaneGeometry::Pointer worldPlaneGeometry2D = dynamic_cast< mitk::PlaneGeometry*>( const_cast<mitk::Geometry2D*>( renderer->GetCurrentWorldGeometry2D() ) ); assert( worldPlaneGeometry2D.IsNotNull() ); vtkImageData* vtkImage = input->GetVtkImageData( this->GetCurrentTimeStep( input, renderer ) ); // // set up the cutter orientation according to the current geometry of // the renderers plane // Point3D point; Vector3D normal; Geometry2D::ConstPointer worldGeometry = renderer->GetCurrentWorldGeometry2D(); PlaneGeometry::ConstPointer worldPlaneGeometry = dynamic_cast<const PlaneGeometry*>( worldGeometry.GetPointer() ); if ( worldPlaneGeometry.IsNotNull() ) { // set up vtkPlane according to worldGeometry point = worldPlaneGeometry->GetOrigin(); normal = worldPlaneGeometry->GetNormal(); normal.Normalize(); m_Plane->SetTransform( (vtkAbstractTransform*)NULL ); } else { itkWarningMacro( << "worldPlaneGeometry is NULL!" ); return ; } double vp[ 3 ], vp_slice[ 3 ], vnormal[ 3 ]; vnl2vtk( point.GetVnlVector(), vp ); vnl2vtk( normal.GetVnlVector(), vnormal ); //std::cout << "Origin: " << vp[0] <<" "<< vp[1] <<" "<< vp[2] << std::endl; //std::cout << "Normal: " << vnormal[0] <<" "<< vnormal[1] <<" "<< vnormal[2] << std::endl; //normally, we would need to transform the surface and cut the transformed surface with the cutter. //This might be quite slow. Thus, the idea is, to perform an inverse transform of the plane instead. //@todo It probably does not work for scaling operations yet:scaling operations have to be //dealed with after the cut is performed by scaling the contour. vtkLinearTransform * vtktransform = GetDataNode() ->GetVtkTransform(); vtkTransform* world2vtk = vtkTransform::New(); world2vtk->Identity(); world2vtk->Concatenate(vtktransform->GetLinearInverse()); double myscale[3]; world2vtk->GetScale(myscale); world2vtk->PostMultiply(); world2vtk->Scale(1/myscale[0],1/myscale[1],1/myscale[2]); world2vtk->TransformPoint( vp, vp ); world2vtk->TransformNormalAtPoint( vp, vnormal, vnormal ); world2vtk->Delete(); // vtk works in axis align coords // thus the normal also must be axis align, since // we do not allow arbitrary cutting through volume // // vnormal should already be axis align, but in order // to get rid of precision effects, we set the two smaller // components to zero here int dims[3]; vtkImage->GetDimensions(dims); double spac[3]; vtkImage->GetSpacing(spac); vp_slice[0] = vp[0]; vp_slice[1] = vp[1]; vp_slice[2] = vp[2]; if(fabs(vnormal[0]) > fabs(vnormal[1]) && fabs(vnormal[0]) > fabs(vnormal[2]) ) { if(fabs(vp_slice[0]/spac[0]) < 0.4) vp_slice[0] = 0.4*spac[0]; if(fabs(vp_slice[0]/spac[0]) > (dims[0]-1)-0.4) vp_slice[0] = ((dims[0]-1)-0.4)*spac[0]; vnormal[1] = 0; vnormal[2] = 0; } if(fabs(vnormal[1]) > fabs(vnormal[0]) && fabs(vnormal[1]) > fabs(vnormal[2]) ) { if(fabs(vp_slice[1]/spac[1]) < 0.4) vp_slice[1] = 0.4*spac[1]; if(fabs(vp_slice[1]/spac[1]) > (dims[1]-1)-0.4) vp_slice[1] = ((dims[1]-1)-0.4)*spac[1]; vnormal[0] = 0; vnormal[2] = 0; } if(fabs(vnormal[2]) > fabs(vnormal[1]) && fabs(vnormal[2]) > fabs(vnormal[0]) ) { if(fabs(vp_slice[2]/spac[2]) < 0.4) vp_slice[2] = 0.4*spac[2]; if(fabs(vp_slice[2]/spac[2]) > (dims[2]-1)-0.4) vp_slice[2] = ((dims[2]-1)-0.4)*spac[2]; vnormal[0] = 0; vnormal[1] = 0; } m_Plane->SetOrigin( vp_slice ); m_Plane->SetNormal( vnormal ); vtkPolyData* cuttedPlane; if(!( (dims[0] == 1 && vnormal[0] != 0) || (dims[1] == 1 && vnormal[1] != 0) || (dims[2] == 1 && vnormal[2] != 0) )) { m_Cutter->SetCutFunction( m_Plane ); m_Cutter->SetInputData( vtkImage ); m_Cutter->GenerateCutScalarsOff();//! m_Cutter->Update(); cuttedPlane = m_Cutter->GetOutput(); } else { // cutting of a 2D-Volume does not work, // so we have to build up our own polydata object cuttedPlane = vtkPolyData::New(); vtkPoints* points = vtkPoints::New(); points->SetNumberOfPoints(vtkImage->GetNumberOfPoints()); for(int i=0; i<vtkImage->GetNumberOfPoints(); i++) points->SetPoint(i, vtkImage->GetPoint(i)); cuttedPlane->SetPoints(points); vtkFloatArray* pointdata = vtkFloatArray::New(); int comps = vtkImage->GetPointData()->GetScalars()->GetNumberOfComponents(); pointdata->SetNumberOfComponents(comps); int tuples = vtkImage->GetPointData()->GetScalars()->GetNumberOfTuples(); pointdata->SetNumberOfTuples(tuples); for(int i=0; i<tuples; i++) pointdata->SetTuple(i,vtkImage->GetPointData()->GetScalars()->GetTuple(i)); pointdata->SetName( "vector" ); cuttedPlane->GetPointData()->AddArray(pointdata); } if ( cuttedPlane->GetNumberOfPoints() != 0) { // // make sure, that we have point data with more than 1 component (as vectors) // vtkPointData * pointData = cuttedPlane->GetPointData(); if ( pointData == NULL ) { itkWarningMacro( << "no point data associated with cutters result!" ); return ; }
void mitk::UnstructuredGridMapper2D::Paint( mitk::BaseRenderer* renderer ) { if ( IsVisible( renderer ) == false ) return ; vtkLinearTransform * vtktransform = GetDataNode()->GetVtkTransform(); vtkLinearTransform * inversetransform = vtktransform->GetLinearInverse(); Geometry2D::ConstPointer worldGeometry = renderer->GetCurrentWorldGeometry2D(); PlaneGeometry::ConstPointer worldPlaneGeometry = dynamic_cast<const PlaneGeometry*>( worldGeometry.GetPointer() ); Point3D point; Vector3D normal; if(worldPlaneGeometry.IsNotNull()) { // set up vtkPlane according to worldGeometry point=worldPlaneGeometry->GetOrigin(); normal=worldPlaneGeometry->GetNormal(); normal.Normalize(); m_Plane->SetTransform((vtkAbstractTransform*)NULL); } else { //@FIXME: does not work correctly. Does m_Plane->SetTransform really transforms a "plane plane" into a "curved plane"? return; AbstractTransformGeometry::ConstPointer worldAbstractGeometry = dynamic_cast<const AbstractTransformGeometry*>(renderer->GetCurrentWorldGeometry2D()); if(worldAbstractGeometry.IsNotNull()) { // set up vtkPlane according to worldGeometry point=const_cast<mitk::BoundingBox*>(worldAbstractGeometry->GetParametricBoundingBox())->GetMinimum(); FillVector3D(normal, 0, 0, 1); m_Plane->SetTransform(worldAbstractGeometry->GetVtkAbstractTransform()->GetInverse()); } else return; } vtkFloatingPointType vp[ 3 ], vnormal[ 3 ]; vnl2vtk(point.Get_vnl_vector(), vp); vnl2vtk(normal.Get_vnl_vector(), vnormal); //normally, we would need to transform the surface and cut the transformed surface with the cutter. //This might be quite slow. Thus, the idea is, to perform an inverse transform of the plane instead. //@todo It probably does not work for scaling operations yet:scaling operations have to be //dealed with after the cut is performed by scaling the contour. inversetransform->TransformPoint( vp, vp ); inversetransform->TransformNormalAtPoint( vp, vnormal, vnormal ); m_Plane->SetOrigin( vp ); m_Plane->SetNormal( vnormal ); // set data into cutter m_Slicer->SetInput( m_VtkPointSet ); // m_Cutter->GenerateCutScalarsOff(); // m_Cutter->SetSortByToSortByCell(); // calculate the cut m_Slicer->Update(); // fetch geometry mitk::DisplayGeometry::Pointer displayGeometry = renderer->GetDisplayGeometry(); assert( displayGeometry ); // float toGL=displayGeometry->GetSizeInDisplayUnits()[1]; //apply color and opacity read from the PropertyList ApplyProperties( renderer ); // traverse the cut contour vtkPolyData * contour = m_Slicer->GetOutput(); vtkPoints *vpoints = contour->GetPoints(); vtkCellArray *vlines = contour->GetLines(); vtkCellArray *vpolys = contour->GetPolys(); vtkPointData *vpointdata = contour->GetPointData(); vtkDataArray* vscalars = vpointdata->GetScalars(); vtkCellData *vcelldata = contour->GetCellData(); vtkDataArray* vcellscalars = vcelldata->GetScalars(); const int numberOfLines = contour->GetNumberOfLines(); const int numberOfPolys = contour->GetNumberOfPolys(); const bool useCellData = m_ScalarMode->GetVtkScalarMode() == VTK_SCALAR_MODE_DEFAULT || m_ScalarMode->GetVtkScalarMode() == VTK_SCALAR_MODE_USE_CELL_DATA; const bool usePointData = m_ScalarMode->GetVtkScalarMode() == VTK_SCALAR_MODE_USE_POINT_DATA; Point3D p; Point2D p2d; vlines->InitTraversal(); vpolys->InitTraversal(); mitk::Color outlineColor = m_Color->GetColor(); glLineWidth((float)m_LineWidth->GetValue()); for (int i = 0;i < numberOfLines;++i ) { vtkIdType *cell(0); vtkIdType cellSize(0); vlines->GetNextCell( cellSize, cell ); float rgba[4] = {outlineColor[0], outlineColor[1], outlineColor[2], 1.0f}; if (m_ScalarVisibility->GetValue() && vcellscalars) { if ( useCellData ) { // color each cell according to cell data double scalar = vcellscalars->GetComponent( i, 0 ); double rgb[3] = { 1.0f, 1.0f, 1.0f }; m_ScalarsToColors->GetColor(scalar, rgb); rgba[0] = (float)rgb[0]; rgba[1] = (float)rgb[1]; rgba[2] = (float)rgb[2]; rgba[3] = (float)m_ScalarsToOpacity->GetValue(scalar); } else if ( usePointData ) { double scalar = vscalars->GetComponent( i, 0 ); double rgb[3] = { 1.0f, 1.0f, 1.0f }; m_ScalarsToColors->GetColor(scalar, rgb); rgba[0] = (float)rgb[0]; rgba[1] = (float)rgb[1]; rgba[2] = (float)rgb[2]; rgba[3] = (float)m_ScalarsToOpacity->GetValue(scalar); } } glColor4fv( rgba ); glBegin ( GL_LINE_LOOP ); for ( int j = 0;j < cellSize;++j ) { vpoints->GetPoint( cell[ j ], vp ); //take transformation via vtktransform into account vtktransform->TransformPoint( vp, vp ); vtk2itk( vp, p ); //convert 3D point (in mm) to 2D point on slice (also in mm) worldGeometry->Map( p, p2d ); //convert point (until now mm and in worldcoordinates) to display coordinates (units ) displayGeometry->WorldToDisplay( p2d, p2d ); //convert display coordinates ( (0,0) is top-left ) in GL coordinates ( (0,0) is bottom-left ) //p2d[1]=toGL-p2d[1]; //add the current vertex to the line glVertex2f( p2d[0], p2d[1] ); } glEnd (); } bool polyOutline = m_Outline->GetValue(); bool scalarVisibility = m_ScalarVisibility->GetValue(); // only draw polygons if there are cell scalars // or the outline property is set to true if ((scalarVisibility && vcellscalars) || polyOutline) { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); // cache the transformed points // a fixed size array is way faster than 'new' // slices through 3d cells usually do not generated // polygons with more than 6 vertices Point2D cachedPoints[10]; for (int i = 0;i < numberOfPolys;++i ) { vtkIdType *cell(0); vtkIdType cellSize(0); vpolys->GetNextCell( cellSize, cell ); float rgba[4] = {1.0f, 1.0f, 1.0f, 0}; if (scalarVisibility && vcellscalars) { if ( useCellData ) { // color each cell according to cell data double scalar = vcellscalars->GetComponent( i, 0 ); double rgb[3] = { 1.0f, 1.0f, 1.0f }; m_ScalarsToColors->GetColor(scalar, rgb); rgba[0] = (float)rgb[0]; rgba[1] = (float)rgb[1]; rgba[2] = (float)rgb[2]; rgba[3] = (float)m_ScalarsToOpacity->GetValue(scalar); } else if ( usePointData ) { double scalar = vscalars->GetComponent( i, 0 ); double rgb[3] = { 1.0f, 1.0f, 1.0f }; m_ScalarsToColors->GetColor(scalar, rgb); rgba[0] = (float)rgb[0]; rgba[1] = (float)rgb[1]; rgba[2] = (float)rgb[2]; rgba[3] = (float)m_ScalarsToOpacity->GetValue(scalar); } } glColor4fv( rgba ); glBegin( GL_POLYGON ); for (int j = 0; j < cellSize; ++j) { vpoints->GetPoint( cell[ j ], vp ); //take transformation via vtktransform into account vtktransform->TransformPoint( vp, vp ); vtk2itk( vp, p ); //convert 3D point (in mm) to 2D point on slice (also in mm) worldGeometry->Map( p, p2d ); //convert point (until now mm and in worldcoordinates) to display coordinates (units ) displayGeometry->WorldToDisplay( p2d, p2d ); //convert display coordinates ( (0,0) is top-left ) in GL coordinates ( (0,0) is bottom-left ) //p2d[1]=toGL-p2d[1]; cachedPoints[j][0] = p2d[0]; cachedPoints[j][1] = p2d[1]; //add the current vertex to the line glVertex2f( p2d[0], p2d[1] ); } glEnd(); if (polyOutline) { glColor4f(outlineColor[0], outlineColor[1], outlineColor[2], 1.0f); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glBegin( GL_POLYGON ); //glPolygonOffset(1.0, 1.0); for (int j = 0; j < cellSize; ++j) { //add the current vertex to the line glVertex2f( cachedPoints[j][0], cachedPoints[j][1] ); } glEnd(); } } glDisable(GL_BLEND); } }
void mitk::SurfaceGLMapper2D::Paint(mitk::BaseRenderer * renderer) { bool visible = true; GetDataNode()->GetVisibility(visible, renderer, "visible"); if(!visible) return; Surface::Pointer input = const_cast<Surface*>(this->GetInput()); if(input.IsNull()) return; // // get the TimeGeometry of the input object // const TimeGeometry* inputTimeGeometry = input->GetTimeGeometry(); if(( inputTimeGeometry == NULL ) || ( inputTimeGeometry->CountTimeSteps() == 0 ) ) return; m_LineWidth = 1; GetDataNode()->GetIntProperty("line width", m_LineWidth, renderer); // // get the world time // ScalarType time =renderer->GetTime(); int timestep=0; if( time > itk::NumericTraits<mitk::ScalarType>::NonpositiveMin() ) timestep = inputTimeGeometry->TimePointToTimeStep( time ); // int timestep = this->GetTimestep(); if( inputTimeGeometry->IsValidTimeStep( timestep ) == false ) return; vtkPolyData * vtkpolydata = input->GetVtkPolyData( timestep ); if((vtkpolydata==NULL) || (vtkpolydata->GetNumberOfPoints() < 1 )) return; //apply color and opacity read from the PropertyList this->ApplyAllProperties(renderer); if (m_DrawNormals) { m_PointLocator->SetDataSet( vtkpolydata ); m_PointLocator->BuildLocatorFromPoints( vtkpolydata->GetPoints() ); } if(vtkpolydata!=NULL) { Point3D point; Vector3D normal; //Check if Lookup-Table is already given, else use standard one. double* scalarLimits = m_LUT->GetTableRange(); double scalarsMin = scalarLimits[0], scalarsMax = scalarLimits[1]; vtkLookupTable *lut; LookupTableProperty::Pointer lookupTableProp; this->GetDataNode()->GetProperty(lookupTableProp, "LookupTable", renderer); if (lookupTableProp.IsNotNull() ) { lut = lookupTableProp->GetLookupTable()->GetVtkLookupTable(); GetDataNode()->GetDoubleProperty("ScalarsRangeMinimum", scalarsMin, renderer); GetDataNode()->GetDoubleProperty("ScalarsRangeMaximum", scalarsMax, renderer); // check if the scalar range has been changed, e.g. manually, for the data tree node, and rebuild the LUT if necessary. double* oldRange = lut->GetTableRange(); if( oldRange[0] != scalarsMin || oldRange[1] != scalarsMax ) { lut->SetTableRange(scalarsMin, scalarsMax); lut->Build(); } } else { lut = m_LUT; } vtkLinearTransform * vtktransform = GetDataNode()->GetVtkTransform(timestep); PlaneGeometry::ConstPointer worldGeometry = renderer->GetCurrentWorldPlaneGeometry(); assert( worldGeometry.IsNotNull() ); if (worldGeometry.IsNotNull()) { // set up vtkPlane according to worldGeometry point=worldGeometry->GetOrigin(); normal=worldGeometry->GetNormal(); normal.Normalize(); m_Plane->SetTransform((vtkAbstractTransform*)NULL); } else { AbstractTransformGeometry::ConstPointer worldAbstractGeometry = dynamic_cast<const AbstractTransformGeometry*>(renderer->GetCurrentWorldPlaneGeometry()); if(worldAbstractGeometry.IsNotNull()) { AbstractTransformGeometry::ConstPointer surfaceAbstractGeometry = dynamic_cast<const AbstractTransformGeometry*>(input->GetTimeGeometry()->GetGeometryForTimeStep(0).GetPointer()); if(surfaceAbstractGeometry.IsNotNull()) //@todo substitude by operator== after implementation, see bug id 28 { PaintCells(renderer, vtkpolydata, worldGeometry, renderer->GetDisplayGeometry(), vtktransform, lut); return; } else { //@FIXME: does not work correctly. Does m_Plane->SetTransform really transforms a "flat plane" into a "curved plane"? return; // set up vtkPlane according to worldGeometry point=const_cast<BoundingBox*>(worldAbstractGeometry->GetParametricBoundingBox())->GetMinimum(); FillVector3D(normal, 0, 0, 1); m_Plane->SetTransform(worldAbstractGeometry->GetVtkAbstractTransform()->GetInverse()); } } else return; } double vp[3], vnormal[3]; vnl2vtk(point.GetVnlVector(), vp); vnl2vtk(normal.GetVnlVector(), vnormal); //normally, we would need to transform the surface and cut the transformed surface with the cutter. //This might be quite slow. Thus, the idea is, to perform an inverse transform of the plane instead. //@todo It probably does not work for scaling operations yet:scaling operations have to be //dealed with after the cut is performed by scaling the contour. vtkLinearTransform * inversetransform = vtktransform->GetLinearInverse(); inversetransform->TransformPoint(vp, vp); inversetransform->TransformNormalAtPoint(vp, vnormal, vnormal); m_Plane->SetOrigin(vp); m_Plane->SetNormal(vnormal); //set data into cutter m_Cutter->SetInputData(vtkpolydata); m_Cutter->Update(); // m_Cutter->GenerateCutScalarsOff(); // m_Cutter->SetSortByToSortByCell(); if (m_DrawNormals) { m_Stripper->SetInputData( m_Cutter->GetOutput() ); // calculate the cut m_Stripper->Update(); PaintCells(renderer, m_Stripper->GetOutput(), worldGeometry, renderer->GetDisplayGeometry(), vtktransform, lut, vtkpolydata); } else { PaintCells(renderer, m_Cutter->GetOutput(), worldGeometry, renderer->GetDisplayGeometry(), vtktransform, lut, vtkpolydata); } } }
void mitk::ExtrudedContour::BuildGeometry() { if(m_Contour.IsNull()) return; // Initialize(1); Vector3D nullvector; nullvector.Fill(0.0); float xProj[3]; unsigned int i; unsigned int numPts = 20; //m_Contour->GetNumberOfPoints(); mitk::Contour::PathPointer path = m_Contour->GetContourPath(); mitk::Contour::PathType::InputType cstart = path->StartOfInput(); mitk::Contour::PathType::InputType cend = path->EndOfInput(); mitk::Contour::PathType::InputType cstep = (cend-cstart)/numPts; mitk::Contour::PathType::InputType ccur; // Part I: guarantee/calculate legal vectors m_Vector.Normalize(); itk2vtk(m_Vector, m_Normal); // check m_Vector if(mitk::Equal(m_Vector, nullvector) || m_AutomaticVectorGeneration) { if ( m_AutomaticVectorGeneration == false) itkWarningMacro("Extrusion vector is 0 ("<< m_Vector << "); trying to use normal of polygon"); vtkPoints *loopPoints = vtkPoints::New(); //mitk::Contour::PointsContainerIterator pointsIt = m_Contour->GetPoints()->Begin(); double vtkpoint[3]; unsigned int i=0; for(i=0, ccur=cstart; i<numPts; ++i, ccur+=cstep) { itk2vtk(path->Evaluate(ccur), vtkpoint); loopPoints->InsertNextPoint(vtkpoint); } // Make sure points define a loop with a m_Normal vtkPolygon::ComputeNormal(loopPoints, m_Normal); loopPoints->Delete(); vtk2itk(m_Normal, m_Vector); if(mitk::Equal(m_Vector, nullvector)) { itkExceptionMacro("Cannot calculate normal of polygon"); } } // check m_RightVector if((mitk::Equal(m_RightVector, nullvector)) || (mitk::Equal(m_RightVector*m_Vector, 0.0)==false)) { if(mitk::Equal(m_RightVector, nullvector)) { itkDebugMacro("Right vector is 0. Calculating."); } else { itkWarningMacro("Right vector ("<<m_RightVector<<") not perpendicular to extrusion vector "<<m_Vector<<": "<<m_RightVector*m_Vector); } // calculate a legal m_RightVector if( mitk::Equal( m_Vector[1], 0.0f ) == false ) { FillVector3D( m_RightVector, 1.0f, -m_Vector[0]/m_Vector[1], 0.0f ); m_RightVector.Normalize(); } else { FillVector3D( m_RightVector, 0.0f, 1.0f, 0.0f ); } } // calculate down-vector VnlVector rightDV = m_RightVector.GetVnlVector(); rightDV.normalize(); vnl2vtk(rightDV, m_Right); VnlVector downDV = vnl_cross_3d( m_Vector.GetVnlVector(), rightDV ); downDV.normalize(); vnl2vtk(downDV, m_Down); // Part II: calculate plane as base for extrusion, project the contour // on this plane and store as polygon for IsInside test and BoundingBox calculation // initialize m_ProjectionPlane, yet with origin at 0 m_ProjectionPlane->InitializeStandardPlane(rightDV, downDV); // create vtkPolygon from contour and simultaneously determine 2D bounds of // contour projected on m_ProjectionPlane //mitk::Contour::PointsContainerIterator pointsIt = m_Contour->GetPoints()->Begin(); m_Polygon->Points->Reset(); m_Polygon->Points->SetNumberOfPoints(numPts); m_Polygon->PointIds->Reset(); m_Polygon->PointIds->SetNumberOfIds(numPts); mitk::Point2D pt2d; mitk::Point3D pt3d; mitk::Point2D min, max; min.Fill(ScalarTypeNumericTraits::max()); max.Fill(ScalarTypeNumericTraits::min()); xProj[2]=0.0; for(i=0, ccur=cstart; i<numPts; ++i, ccur+=cstep) { pt3d.CastFrom(path->Evaluate(ccur)); m_ProjectionPlane->Map(pt3d, pt2d); xProj[0]=pt2d[0]; if(pt2d[0]<min[0]) min[0]=pt2d[0]; if(pt2d[0]>max[0]) max[0]=pt2d[0]; xProj[1]=pt2d[1]; if(pt2d[1]<min[1]) min[1]=pt2d[1]; if(pt2d[1]>max[1]) max[1]=pt2d[1]; m_Polygon->Points->SetPoint(i, xProj); m_Polygon->PointIds->SetId(i, i); } // shift parametric origin to (0,0) for(i=0; i<numPts; ++i) { double * pt = this->m_Polygon->Points->GetPoint(i); pt[0]-=min[0]; pt[1]-=min[1]; itkDebugMacro( << i << ": (" << pt[0] << "," << pt[1] << "," << pt[2] << ")" ); } this->m_Polygon->GetBounds(m_ProjectedContourBounds); //m_ProjectedContourBounds[4]=-1.0; m_ProjectedContourBounds[5]=1.0; // calculate origin (except translation along the normal) and bounds // of m_ProjectionPlane: // origin is composed of the minimum x-/y-coordinates of the polygon, // bounds from the extent of the polygon, both after projecting on the plane mitk::Point3D origin; m_ProjectionPlane->Map(min, origin); ScalarType bounds[6]={0, max[0]-min[0], 0, max[1]-min[1], 0, 1}; m_ProjectionPlane->SetBounds(bounds); m_ProjectionPlane->SetOrigin(origin); // Part III: initialize geometry if(m_ClippingGeometry.IsNotNull()) { ScalarType min_dist=ScalarTypeNumericTraits::max(), max_dist=ScalarTypeNumericTraits::min(), dist; unsigned char i; for(i=0; i<8; ++i) { dist = m_ProjectionPlane->SignedDistance( m_ClippingGeometry->GetCornerPoint(i) ); if(dist<min_dist) min_dist=dist; if(dist>max_dist) max_dist=dist; } //incorporate translation along the normal into origin origin = origin+m_Vector*min_dist; m_ProjectionPlane->SetOrigin(origin); bounds[5]=max_dist-min_dist; } else bounds[5]=20; itk2vtk(origin, m_Origin); mitk::Geometry3D::Pointer g3d = GetGeometry( 0 ); assert( g3d.IsNotNull() ); g3d->SetBounds(bounds); g3d->SetIndexToWorldTransform(m_ProjectionPlane->GetIndexToWorldTransform()); g3d->TransferItkToVtkTransform(); ProportionalTimeGeometry::Pointer timeGeometry = ProportionalTimeGeometry::New(); timeGeometry->Initialize(g3d,1); SetTimeGeometry(timeGeometry); }
void mitk::PolyDataGLMapper2D::Paint( mitk::BaseRenderer * renderer ) { if ( IsVisible( renderer ) == false ) return ; // ok, das ist aus GenerateData kopiert mitk::BaseData::Pointer input = const_cast<mitk::BaseData*>( GetData() ); assert( input ); input->Update(); vtkPolyData * vtkpolydata = this->GetVtkPolyData(); assert( vtkpolydata ); vtkLinearTransform * vtktransform = GetDataNode() ->GetVtkTransform(); if (vtktransform) { vtkLinearTransform * inversetransform = vtktransform->GetLinearInverse(); Geometry2D::ConstPointer worldGeometry = renderer->GetCurrentWorldGeometry2D(); PlaneGeometry::ConstPointer worldPlaneGeometry = dynamic_cast<const PlaneGeometry*>( worldGeometry.GetPointer() ); if ( vtkpolydata != NULL ) { Point3D point; Vector3D normal; if(worldPlaneGeometry.IsNotNull()) { // set up vtkPlane according to worldGeometry point=worldPlaneGeometry->GetOrigin(); normal=worldPlaneGeometry->GetNormal(); normal.Normalize(); m_Plane->SetTransform((vtkAbstractTransform*)NULL); } else { //@FIXME: does not work correctly. Does m_Plane->SetTransform really transforms a "plane plane" into a "curved plane"? return; AbstractTransformGeometry::ConstPointer worldAbstractGeometry = dynamic_cast<const AbstractTransformGeometry*>(renderer->GetCurrentWorldGeometry2D()); if(worldAbstractGeometry.IsNotNull()) { // set up vtkPlane according to worldGeometry point=const_cast<mitk::BoundingBox*>(worldAbstractGeometry->GetParametricBoundingBox())->GetMinimum(); FillVector3D(normal, 0, 0, 1); m_Plane->SetTransform(worldAbstractGeometry->GetVtkAbstractTransform()->GetInverse()); } else return; } vtkFloatingPointType vp[ 3 ], vnormal[ 3 ]; vnl2vtk(point.Get_vnl_vector(), vp); vnl2vtk(normal.Get_vnl_vector(), vnormal); //normally, we would need to transform the surface and cut the transformed surface with the cutter. //This might be quite slow. Thus, the idea is, to perform an inverse transform of the plane instead. //@todo It probably does not work for scaling operations yet:scaling operations have to be //dealed with after the cut is performed by scaling the contour. inversetransform->TransformPoint( vp, vp ); inversetransform->TransformNormalAtPoint( vp, vnormal, vnormal ); m_Plane->SetOrigin( vp ); m_Plane->SetNormal( vnormal ); // set data into cutter m_Cutter->SetInput( vtkpolydata ); // m_Cutter->GenerateCutScalarsOff(); // m_Cutter->SetSortByToSortByCell(); // calculate the cut m_Cutter->Update(); // fetch geometry mitk::DisplayGeometry::Pointer displayGeometry = renderer->GetDisplayGeometry(); assert( displayGeometry ); // float toGL=displayGeometry->GetSizeInDisplayUnits()[1]; //apply color and opacity read from the PropertyList ApplyProperties( renderer ); // traverse the cut contour vtkPolyData * contour = m_Cutter->GetOutput(); vtkPoints *vpoints = contour->GetPoints(); vtkCellArray *vpolys = contour->GetLines(); vtkPointData *vpointdata = contour->GetPointData(); vtkDataArray* vscalars = vpointdata->GetScalars(); vtkCellData *vcelldata = contour->GetCellData(); vtkDataArray* vcellscalars = vcelldata->GetScalars(); int i, numberOfCells = vpolys->GetNumberOfCells(); Point3D p; Point2D p2d, last, first; vpolys->InitTraversal(); vtkScalarsToColors* lut = GetVtkLUT(); assert ( lut != NULL ); for ( i = 0;i < numberOfCells;++i ) { vtkIdType *cell(NULL); vtkIdType cellSize(0); vpolys->GetNextCell( cellSize, cell ); if ( m_ColorByCellData ) { // color each cell according to cell data vtkFloatingPointType* color = lut->GetColor( vcellscalars->GetComponent( i, 0 ) ); glColor3f( color[ 0 ], color[ 1 ], color[ 2 ] ); } if ( m_ColorByPointData ) { vtkFloatingPointType* color = lut->GetColor( vscalars->GetComponent( cell[0], 0 ) ); glColor3f( color[ 0 ], color[ 1 ], color[ 2 ] ); } glBegin ( GL_LINE_LOOP ); for ( int j = 0;j < cellSize;++j ) { vpoints->GetPoint( cell[ j ], vp ); //take transformation via vtktransform into account vtktransform->TransformPoint( vp, vp ); vtk2itk( vp, p ); //convert 3D point (in mm) to 2D point on slice (also in mm) worldGeometry->Map( p, p2d ); //convert point (until now mm and in worldcoordinates) to display coordinates (units ) displayGeometry->WorldToDisplay( p2d, p2d ); //convert display coordinates ( (0,0) is top-left ) in GL coordinates ( (0,0) is bottom-left ) //p2d[1]=toGL-p2d[1]; //add the current vertex to the line glVertex2f( p2d[0], p2d[1] ); } glEnd (); } } } }