Example #1
0
int cv::viz::vtkXYZReader::RequestData(vtkInformation*, vtkInformationVector**, vtkInformationVector* outputVector)
{
    // Make sure we have a file to read.
    if(!this->FileName)
    {
        vtkErrorMacro("A FileName must be specified.");
        return 0;
    }

    // Open the input file.
    ifstream fin(this->FileName);
    if(!fin)
    {
        vtkErrorMacro("Error opening file " << this->FileName);
        return 0;
    }

    // Allocate objects to hold points and vertex cells.
    vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
    vtkSmartPointer<vtkCellArray> verts = vtkSmartPointer<vtkCellArray>::New();

    // Read points from the file.
    vtkDebugMacro("Reading points from file " << this->FileName);
    double x[3];
    while(fin >> x[0] >> x[1] >> x[2])
    {
        vtkIdType id = points->InsertNextPoint(x);
        verts->InsertNextCell(1, &id);
    }
    vtkDebugMacro("Read " << points->GetNumberOfPoints() << " points.");

    // Store the points and cells in the output data object.
    vtkPolyData* output = vtkPolyData::GetData(outputVector);
    output->SetPoints(points);
    output->SetVerts(verts);

    return 1;
}
//------------------------------------------------------------------------------
void vtkSlicerCollisionWarningLogic::OnMRMLSceneNodeRemoved( vtkMRMLNode* node )
{
  if ( node == NULL || this->GetMRMLScene() == NULL )
  {
    vtkWarningMacro( "OnMRMLSceneNodeRemoved: Invalid MRML scene or node" );
    return;
  }

  if ( node->IsA( "vtkMRMLCollisionWarningNode" ) )
  {
    vtkDebugMacro( "OnMRMLSceneNodeRemoved" );
    vtkUnObserveMRMLNodeMacro( node );
    for (std::deque< vtkWeakPointer< vtkMRMLCollisionWarningNode > >::iterator it=this->WarningSoundPlayingNodes.begin(); it!=this->WarningSoundPlayingNodes.end(); ++it)
    {
      if (it->GetPointer()==node)
      {
        this->WarningSoundPlayingNodes.erase(it);
        break;
      }
    }
    this->SetWarningSoundPlaying(!this->WarningSoundPlayingNodes.empty());
  }
}
//------------------------------------------------------------------------------
void vtkSlicerCollisionWarningLogic::OnMRMLSceneNodeAdded( vtkMRMLNode* node )
{
  if ( node == NULL || this->GetMRMLScene() == NULL )
  {
    vtkWarningMacro( "OnMRMLSceneNodeAdded: Invalid MRML scene or node" );
    return;
  }

  vtkMRMLCollisionWarningNode* bwNode = vtkMRMLCollisionWarningNode::SafeDownCast(node);
  if ( bwNode )
  {
    vtkDebugMacro( "OnMRMLSceneNodeAdded: Module node added." );
    vtkUnObserveMRMLNodeMacro( bwNode ); // Remove previous observers.
    vtkNew<vtkIntArray> events;
    events->InsertNextValue( vtkCommand::ModifiedEvent );
    events->InsertNextValue( vtkMRMLCollisionWarningNode::InputDataModifiedEvent );
    vtkObserveMRMLNodeEventsMacro( bwNode, events.GetPointer() );
    if(bwNode->GetPlayWarningSound() && bwNode->IsToolTipInsideModel())
    {
      // Add to list of playing nodes (if not there already)
      std::deque< vtkWeakPointer< vtkMRMLCollisionWarningNode > >::iterator foundPlayingNodeIt = this->WarningSoundPlayingNodes.begin();    
      for (; foundPlayingNodeIt!=this->WarningSoundPlayingNodes.end(); ++foundPlayingNodeIt)
      {
        if (foundPlayingNodeIt->GetPointer()==bwNode)
        {
          // found, current bw node is already in the playing list
          break;
        }
      }
      if (foundPlayingNodeIt==this->WarningSoundPlayingNodes.end())
      {
        this->WarningSoundPlayingNodes.push_back(bwNode);
      }
      this->SetWarningSoundPlaying(true);
    }
  }
}
Example #4
0
//----------------------------------------------------------------------------
int ShapefileReader::RequestData(
                                 vtkInformation* vtkNotUsed( request ),
                                 vtkInformationVector** vtkNotUsed(inputVector),
                                 vtkInformationVector* outputVector)
{
  vtkInformation* outInfo = outputVector->GetInformationObject(0);
  vtkPolyData* polydata = vtkPolyData::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT()));

  if (illegalFileName()){
    return 0;
  }

  if (incompleteSrcFiles()){
    return 0;
  }

  SHPHandle shpHandle = SHPOpen(this->FileName, "rb");
  int fileType = 0;

  if (shpHandle == NULL){
    vtkErrorMacro("shp file read failed.");
    return 0;
  }

  vtkDebugMacro("file type: " << shpHandle->nShapeType);

  switch (shpHandle->nShapeType) {
    case SHPT_NULL:
      vtkErrorMacro("NULL Object type." << this->FileName);
      SHPClose(shpHandle);
      return 0;
      break;
    case SHPT_POINT:
    case SHPT_POINTZ:
    case SHPT_POINTM:
    case SHPT_MULTIPOINT:
    case SHPT_MULTIPOINTZ:
    case SHPT_MULTIPOINTM:
      fileType = POINTOBJ;
      break;
    case SHPT_ARC:
    case SHPT_ARCZ:
    case SHPT_ARCM:
      fileType = LINEOBJ;
      break;
    case SHPT_POLYGON:
    case SHPT_POLYGONZ:
    case SHPT_POLYGONM:
      fileType = FACEOBJ;
      break;
    case SHPT_MULTIPATCH:
      fileType = MESHOBJ;
      break;
    default:
      vtkErrorMacro("Unknown Object type." << this->FileName);
      SHPClose(shpHandle);
      return 0;
  }

  int pCount=0, pStart=0, pEnd=0;
  int vTracker = 0, pid=0;
  SHPObject* shpObj;

  vtkSmartPointer<vtkPoints> pts = vtkSmartPointer<vtkPoints>::New();
  vtkSmartPointer<vtkCellArray> polys = vtkSmartPointer<vtkCellArray>::New();
  vtkSmartPointer<vtkCellArray> strips = vtkSmartPointer<vtkCellArray>::New();
  vtkSmartPointer<vtkCellArray> pLines = vtkSmartPointer<vtkCellArray>::New();
  vtkSmartPointer<vtkCellArray> verts = vtkSmartPointer<vtkCellArray>::New();
  vtkSmartPointer<vtkTriangleFilter> tFilter = vtkSmartPointer<vtkTriangleFilter>::New();
  vtkSmartPointer<vtkStripper> stripper = vtkSmartPointer<vtkStripper>::New();
  vtkSmartPointer<vtkPolyData> pdRaw = vtkSmartPointer<vtkPolyData>::New();
  vtkSmartPointer<vtkPolyData> pdRefined = vtkSmartPointer<vtkPolyData>::New();

  //looping through all records in file
  for (int rIndex = 0; rIndex < shpHandle->nRecords; rIndex++){
    
    shpObj = SHPReadObject(shpHandle, rIndex);

    //making sure shp object type is consistent with file type
    if (shpObj->nSHPType != shpHandle->nShapeType){
      vtkErrorMacro("Inconsistent shape type of record: " << rIndex 
        << " in file " << this->FileName);
      continue;
    }

    pCount = shpObj->nParts;
    
    switch (fileType){
    case POINTOBJ:{

      vtkIdType *ids = new vtkIdType[shpObj->nVertices];

      for (int vIndex = 0; vIndex < shpObj->nVertices; vIndex++){
        pts->InsertPoint(pid,shpObj->padfX[vIndex],
                             shpObj->padfY[vIndex],
                             shpObj->padfZ[vIndex]);
        ids[vIndex] = pid++;
      }
      verts->InsertNextCell(shpObj->nVertices, ids);
      delete ids;
      ids = NULL;
      break;

    }
    case LINEOBJ:{
      
      for (int pIndex = 0; pIndex < pCount; pIndex++){
        pStart = shpObj->panPartStart[pIndex];

        if (pIndex == (pCount-1)){
          pEnd = shpObj->nVertices;
        }else{
          pEnd = shpObj->panPartStart[pIndex+1];
        }

        vtkSmartPointer<vtkPolyLine> pLine = vtkSmartPointer<vtkPolyLine>::New();
        pLine->GetPointIds()->SetNumberOfIds(pEnd-pStart); 

        for (int vIndex = pStart; vIndex < pEnd; vIndex++){
          pts->InsertNextPoint(shpObj->padfX[vIndex],
                               shpObj->padfY[vIndex],
                               shpObj->padfZ[vIndex]);
          pLine->GetPointIds()->SetId(vIndex-pStart, vTracker+vIndex-pStart);
        }
        pLines->InsertNextCell(pLine);
        vTracker += pEnd-pStart;
      }
      break;

    }
    case FACEOBJ:{

      for (int pIndex = 0; pIndex < pCount; pIndex++){
        pStart = shpObj->panPartStart[pIndex];

        if (pIndex == (pCount-1)){
          pEnd = shpObj->nVertices;
        }else{
          pEnd = shpObj->panPartStart[pIndex+1];
        }
        vtkSmartPointer<vtkPolygon> poly = vtkSmartPointer<vtkPolygon>::New();
        vtkSmartPointer<vtkPolyLine> pLine = vtkSmartPointer<vtkPolyLine>::New();
        poly->GetPointIds()->SetNumberOfIds(pEnd-pStart); 
        pLine->GetPointIds()->SetNumberOfIds(pEnd-pStart); 

        for (int vIndex = pStart; vIndex < pEnd; vIndex++){
          pts->InsertNextPoint(shpObj->padfX[vIndex],
                               shpObj->padfY[vIndex],
                               shpObj->padfZ[vIndex]);
          poly->GetPointIds()->SetId(vIndex-pStart, vTracker+vIndex-pStart);
          pLine->GetPointIds()->SetId(vIndex-pStart, vTracker+vIndex-pStart);
        }

        polys->InsertNextCell(poly);
        pLines->InsertNextCell(pLine);
        vTracker += pEnd-pStart;
      }
      break;

    }
    case MESHOBJ:{

      switch (*(shpObj->panPartType)){

      case SHPP_TRISTRIP:{
        for (int pIndex = 0; pIndex < pCount; pIndex++){
          pStart = shpObj->panPartStart[pIndex];

          if (pIndex == (pCount-1)){
            pEnd = shpObj->nVertices;
          }else{
            pEnd = shpObj->panPartStart[pIndex+1];
          }

          vtkSmartPointer<vtkTriangleStrip> strip = vtkSmartPointer<vtkTriangleStrip>::New();
          strip->GetPointIds()->SetNumberOfIds(pEnd-pStart);

          for (int vIndex = pStart; vIndex < pEnd; vIndex++){
            pts->InsertNextPoint(shpObj->padfX[vIndex],
                                 shpObj->padfY[vIndex],
                                 shpObj->padfZ[vIndex]);
            strip->GetPointIds()->SetId(vIndex-pStart, vTracker+vIndex-pStart);
          }

          strips->InsertNextCell(strip);
          vTracker += pEnd-pStart;
        }
        break;
      }//SHPP_TRISTRIP
      case SHPP_TRIFAN:{
        for (int pIndex = 0; pIndex < pCount; pIndex++){
          pStart = shpObj->panPartStart[pIndex];

          if (pIndex == (pCount-1)){
            pEnd = shpObj->nVertices;
          }else{
            pEnd = shpObj->panPartStart[pIndex+1];
          }

          vtkSmartPointer<vtkTriangleStrip> strip = vtkSmartPointer<vtkTriangleStrip>::New();
          strip->GetPointIds()->SetNumberOfIds(pEnd-pStart);

          for (int vIndex = pStart; vIndex < pEnd; vIndex++){
            pts->InsertNextPoint(shpObj->padfX[vIndex],
                                 shpObj->padfY[vIndex],
                                 shpObj->padfZ[vIndex]);
            strip->GetPointIds()->SetId(vIndex-pStart, vTracker+vIndex-pStart);
          }

          strips->InsertNextCell(strip);
          vTracker += pEnd-pStart;
        }
        break;
      }//SHPP_TRIFAN
      case SHPP_OUTERRING:
      case SHPP_INNERRING:
      case SHPP_FIRSTRING:
      case SHPP_RING:{
        for (int pIndex = 0; pIndex < pCount; pIndex++){
        pStart = shpObj->panPartStart[pIndex];

        if (pIndex == (pCount-1)){
          pEnd = shpObj->nVertices;
        }else{
          pEnd = shpObj->panPartStart[pIndex+1];
        }
        vtkSmartPointer<vtkPolygon> poly = vtkSmartPointer<vtkPolygon>::New();
        vtkSmartPointer<vtkPolyLine> pLine = vtkSmartPointer<vtkPolyLine>::New();
        poly->GetPointIds()->SetNumberOfIds(pEnd-pStart); 
        pLine->GetPointIds()->SetNumberOfIds(pEnd-pStart); 

        for (int vIndex = pStart; vIndex < pEnd; vIndex++){
          pts->InsertNextPoint(shpObj->padfX[vIndex],
                               shpObj->padfY[vIndex],
                               shpObj->padfZ[vIndex]);
          poly->GetPointIds()->SetId(vIndex-pStart, vTracker+vIndex-pStart);
          pLine->GetPointIds()->SetId(vIndex-pStart, vTracker+vIndex-pStart);
        }

        polys->InsertNextCell(poly);
        pLines->InsertNextCell(pLine);
        vTracker += pEnd-pStart;
      }
      break;
      }//rings
      }//panPartType
      break;
    
    }//MESHOBJ
    }//fileType

    SHPDestroyObject(shpObj);
  }// rIndex
  SHPClose(shpHandle);
  
  DBFHandle dbfHandle = DBFOpen(this->FileName, "rb");
  int fieldCount = DBFGetFieldCount(dbfHandle);
  
  for (int fieldIndex = 0; fieldIndex < fieldCount; fieldIndex++){
    
    DBFFieldType fieldType;
    const char *typeName;
    char nativeFieldType;
    char pszFieldName[12];
    int pnWidth=0, pnDecimals=0, recordCount=0;

    nativeFieldType = DBFGetNativeFieldType(dbfHandle, fieldIndex);
    fieldType = DBFGetFieldInfo(dbfHandle, fieldIndex, pszFieldName, &pnWidth, &pnDecimals);
    recordCount = DBFGetRecordCount(dbfHandle);

    vtkDebugMacro("record count: " << recordCount);

    switch (fieldType){
    case FTString:{

      vtkSmartPointer<vtkStringArray> cellData = vtkSmartPointer<vtkStringArray>::New();

      cellData->SetName(pszFieldName);
      
      for (int recordIndex = 0; recordIndex < recordCount; recordIndex++){
        if (DBFIsAttributeNULL(dbfHandle, recordIndex, fieldIndex)){
          cellData->InsertNextValue("NULL");
        }else{
          cellData->InsertNextValue(DBFReadStringAttribute(dbfHandle, recordIndex, fieldIndex));
        }
      }
      
      polydata->GetCellData()->AddArray(cellData);

      break;
    }
    case FTInteger:{

      vtkSmartPointer<vtkIntArray> cellData = vtkSmartPointer<vtkIntArray>::New();

      cellData->SetName(pszFieldName);
      
      for (int recordIndex = 0; recordIndex < recordCount; recordIndex++){
        if (DBFIsAttributeNULL(dbfHandle, recordIndex, fieldIndex)){
          cellData->InsertNextValue(0);
        }else{
          cellData->InsertNextValue(DBFReadIntegerAttribute(dbfHandle, recordIndex, fieldIndex));
        }
      }
      
      polydata->GetCellData()->AddArray(cellData);

      break;
    }
    case FTDouble:{

      vtkSmartPointer<vtkDoubleArray> cellData = vtkSmartPointer<vtkDoubleArray>::New();

      cellData->SetName(pszFieldName);
      
      for (int recordIndex = 0; recordIndex < recordCount; recordIndex++){
        if (DBFIsAttributeNULL(dbfHandle, recordIndex, fieldIndex)){
          cellData->InsertNextValue(0.0);
        }else{
          cellData->InsertNextValue(DBFReadDoubleAttribute(dbfHandle, recordIndex, fieldIndex));
        }
      }
      
      polydata->GetCellData()->AddArray(cellData);

      break;
    }
    case FTLogical:{
      //what is this? lack of sample data!
      break;
    }
    case FTInvalid:{
      vtkErrorMacro("Invalid DBF field type");
      break;
    }    
    }
  }

  DBFClose(dbfHandle);

  
  //pdRaw->SetPoints(pts);
  //pdRaw->SetPolys(polys);
  //pdRaw->SetLines(pLines);
  //pdRaw->SetVerts(verts);

  //tFilter->SetInput(pdRaw);
  //tFilter->Update();
  //pdRefined = tFilter->GetOutput();

  //polydata->SetPoints(pdRefined->GetPoints());
  //polydata->SetPolys(pdRefined->GetPolys());
  //polydata->SetLines(pdRefined->GetLines());
  //polydata->SetVerts(pdRefined->GetVerts());
  
  
  polydata->SetPoints(pts);
  polydata->SetLines(pLines);
  polydata->SetVerts(verts);
  polydata->SetStrips(strips);

  return 1;
}
int StreamTracer::CheckInputs(vtkAbstractInterpolatedVelocityField*& func,
                              int* maxCellSize)
{
    if (!this->InputData)
    {
        return VTK_ERROR;
    }

    vtkCompositeDataIterator* iter = this->InputData->NewIterator();
    vtkSmartPointer<vtkCompositeDataIterator> iterP(iter);
    iter->Delete();

    iterP->GoToFirstItem();
    if (iterP->IsDoneWithTraversal())
    {
        return VTK_ERROR;
    }

    // Set the function set to be integrated
    if ( !this->InterpolatorPrototype )
    {
        func = vtkInterpolatedVelocityField::New();

        // turn on the following segment, in place of the above line, if an
        // interpolator equipped with a cell locator is dedired as the default
        //
        // func = vtkCellLocatorInterpolatedVelocityField::New();
        // vtkSmartPointer< vtkModifiedBSPTree > locator =
        // vtkSmartPointer< vtkModifiedBSPTree >::New();
        // vtkCellLocatorInterpolatedVelocityField::SafeDownCast( func )
        //   ->SetCellLocatorPrototype( locator.GetPointer() );
    }
    else
    {
        func = this->InterpolatorPrototype->NewInstance();
        func->CopyParameters(this->InterpolatorPrototype);
    }
    vtkDataArray *vectors = this->GetInputArrayToProcess(
                                0,iterP->GetCurrentDataObject());
    if (!vectors)
    {
        return VTK_ERROR;
    }
    const char *vecName = vectors->GetName();
    func->SelectVectors(vecName);

    // Add all the inputs ( except source, of course ) which
    // have the appropriate vectors and compute the maximum
    // cell size.
    int numInputs = 0;
    iterP->GoToFirstItem();
    while (!iterP->IsDoneWithTraversal())
    {
        vtkDataSet* inp = vtkDataSet::SafeDownCast(iterP->GetCurrentDataObject());
        if (inp)
        {
            if (!inp->GetPointData()->GetVectors(vecName))
            {
                vtkDebugMacro("One of the input blocks does not contain a "
                              "velocity vector.");
                iterP->GoToNextItem();
                continue;
            }
            int cellSize = inp->GetMaxCellSize();
            if ( cellSize > *maxCellSize )
            {
                *maxCellSize = cellSize;
            }
            func->AddDataSet(inp);
            numInputs++;
        }
        iterP->GoToNextItem();
    }
    if ( numInputs == 0 )
    {
        vtkDebugMacro("No appropriate inputs have been found. Can not execute.");
        return VTK_ERROR;
    }
    return VTK_OK;
}
int StreamTracer::RequestData(
    vtkInformation *vtkNotUsed(request),
    vtkInformationVector **inputVector,
    vtkInformationVector *outputVector)
{
    vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
    vtkInformation *outInfo = outputVector->GetInformationObject(0);

    if (!this->SetupOutput(inInfo, outInfo))
    {
        return 0;
    }

    vtkInformation *sourceInfo = inputVector[1]->GetInformationObject(0);
    vtkDataSet *source = 0;
    if (sourceInfo)
    {
        source = vtkDataSet::SafeDownCast(
                     sourceInfo->Get(vtkDataObject::DATA_OBJECT()));
    }
    vtkPolyData *output = vtkPolyData::SafeDownCast(
                              outInfo->Get(vtkDataObject::DATA_OBJECT()));

    vtkDataArray* seeds = 0;
    vtkIdList* seedIds = 0;
    vtkIntArray* integrationDirections = 0;

    this->InitializeSeeds(seeds, seedIds, integrationDirections, source);

    if (seeds)
    {
        double lastPoint[3];
        vtkAbstractInterpolatedVelocityField * func;
        int maxCellSize = 0;
        if (this->CheckInputs(func, &maxCellSize) != VTK_OK)
        {
            vtkDebugMacro("No appropriate inputs have been found. Can not execute.");
            func->Delete();
            seeds->Delete();
            integrationDirections->Delete();
            seedIds->Delete();
            this->InputData->UnRegister(this);
            return 1;
        }

        vtkCompositeDataIterator* iter = this->InputData->NewIterator();
        vtkSmartPointer<vtkCompositeDataIterator> iterP(iter);
        iter->Delete();

        iterP->GoToFirstItem();
        vtkDataSet* input0 = 0;
        if (!iterP->IsDoneWithTraversal())
        {
            input0 = vtkDataSet::SafeDownCast(iterP->GetCurrentDataObject());
        }
        vtkDataArray *vectors = this->GetInputArrayToProcess(0,input0);
        if (vectors)
        {
            const char *vecName = vectors->GetName();
            double propagation = 0;
            vtkIdType numSteps = 0;
            this->Integrate(input0, output,
                            seeds, seedIds,
                            integrationDirections,
                            lastPoint, func,
                            maxCellSize, vecName,
                            propagation, numSteps);
        }
        func->Delete();
        seeds->Delete();
    }

    integrationDirections->Delete();
    seedIds->Delete();

    this->InputData->UnRegister(this);
    return 1;
}
Example #7
0
int vtkEllipsoidSource::RequestData(
  vtkInformation *vtkNotUsed(request),
  vtkInformationVector **vtkNotUsed(inputVector),
  vtkInformationVector *outputVector)
{
  
  // get the info object
  vtkInformation *outInfo = outputVector->GetInformationObject(0);
  
  // get the ouptut
  vtkPolyData *output = vtkPolyData::SafeDownCast(
    outInfo->Get(vtkDataObject::DATA_OBJECT()));
  
  //save the center info
  double originalCenter[3];
  originalCenter[0] = this->Center[0];
  originalCenter[1] = this->Center[1];
  originalCenter[2] = this->Center[2];
  
  double unitRadius = 1.0;
  
  //for now set the center to (0,0,0) so the scaling is around the origin
  this->Center[0] = 0.0;
  this->Center[1] = 0.0;
  this->Center[2] = 0.0;
  
  int i, j;
  int jStart, jEnd, numOffset;
  int numPts, numPolys;
  
  double x[3], n[3], deltaPhi, deltaTheta, phi, theta, radius, norm;
  double startTheta, endTheta, startPhi, endPhi;
  int base, numPoles=0, thetaResolution, phiResolution;
  vtkIdType pts[4];
  int piece =
    outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER());
  int numPieces =
    outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_PIECES());
  
  if (numPieces > this->ThetaResolution)
    {
    numPieces = this->ThetaResolution;
    }
    
  if (piece >= numPieces)
    {
    // Although the super class should take care of this,
    // it cannot hurt to check here.
    return 1;
    }
  
  // I want to modify the ivars resoultion start theta and end theta,
  // so I will make local copies of them.  THese might be able to be merged
  // with the other copies of them, ...
  int localThetaResolution = this->ThetaResolution;
  double localStartTheta = this->StartTheta;
  double localEndTheta = this->EndTheta;
  
  while (localEndTheta < localStartTheta) //here
    {
    localEndTheta += 360.0;
    }
    
  deltaTheta = (localEndTheta - localStartTheta) / localThetaResolution;
  
  // Change the ivars based on pieces.
  int start, end;
  start = piece * localThetaResolution / numPieces;
  end = (piece+1) * localThetaResolution / numPieces;
  localEndTheta = localStartTheta + (double)(end) * deltaTheta;
  localStartTheta = localStartTheta + (double)(start) * deltaTheta;
  localThetaResolution = end - start;
  
  // Set things up; allocate memory
  //
  vtkDebugMacro("SphereSource Executing piece index " << piece
		  << " of " << numPieces << " pieces.");
  
  numPts = this->PhiResolution * localThetaResolution + 2;
  // creating triangles
  numPolys = this->PhiResolution * 2 * localThetaResolution;
  
  vtkSmartPointer<vtkPoints> newPoints = 
      vtkSmartPointer<vtkPoints>::New();
  newPoints->Allocate(numPts);
  vtkSmartPointer<vtkFloatArray> newNormals = 
      vtkSmartPointer<vtkFloatArray>::New();
  newNormals->SetNumberOfComponents(3);
  newNormals->Allocate(3*numPts);
  newNormals->SetName("Normals");
  
  vtkSmartPointer<vtkCellArray> newPolys = 
      vtkSmartPointer<vtkCellArray>::New();
  newPolys->Allocate(newPolys->EstimateSize(numPolys, 3));
  
  // Create sphere
  //
  // Create north pole if needed
  if ( this->StartPhi <= 0.0 )
    {
    x[0] = this->Center[0];
    x[1] = this->Center[1];
    x[2] = this->Center[2] + unitRadius;
    newPoints->InsertPoint(numPoles,x);
  
    x[0] = x[1] = 0.0; x[2] = 1.0;
    newNormals->InsertTuple(numPoles,x);
    numPoles++;
    }
  
  // Create south pole if needed
  if ( this->EndPhi >= 180.0 )
    {
    x[0] = this->Center[0];
    x[1] = this->Center[1];
    x[2] = this->Center[2] - unitRadius;
    newPoints->InsertPoint(numPoles,x);
  
    x[0] = x[1] = 0.0; x[2] = -1.0;
    newNormals->InsertTuple(numPoles,x);
    numPoles++;
    }
  
  // Check data, determine increments, and convert to radians
  startTheta = (localStartTheta < localEndTheta ? localStartTheta : localEndTheta);
  startTheta *= vtkMath::Pi() / 180.0;
  endTheta = (localEndTheta > localStartTheta ? localEndTheta : localStartTheta);
  endTheta *= vtkMath::Pi() / 180.0;
  
  startPhi = (this->StartPhi < this->EndPhi ? this->StartPhi : this->EndPhi);
  startPhi *= vtkMath::Pi() / 180.0;
  endPhi = (this->EndPhi > this->StartPhi ? this->EndPhi : this->StartPhi);
  endPhi *= vtkMath::Pi() / 180.0;
  
  phiResolution = this->PhiResolution - numPoles;
  deltaPhi = (endPhi - startPhi) / (this->PhiResolution - 1);
  thetaResolution = localThetaResolution;
  if (fabs(localStartTheta - localEndTheta) < 360.0)
    {
    ++localThetaResolution;
    }
    
  deltaTheta = (endTheta - startTheta) / thetaResolution;
  
  jStart = (this->StartPhi <= 0.0 ? 1 : 0);
  jEnd = (this->EndPhi >= 180.0 ? this->PhiResolution - 1
  : this->PhiResolution);
  
  this->UpdateProgress(0.1);
  
  // Create intermediate points
  for (i=0; i < localThetaResolution; i++)
    {
    theta = localStartTheta * vtkMath::Pi() / 180.0 + i*deltaTheta;
  
    for (j=jStart; j<jEnd; j++)
      {
      phi = startPhi + j*deltaPhi;
      radius = unitRadius * sin((double)phi);
      n[0] = radius * cos((double)theta);
      n[1] = radius * sin((double)theta);
      n[2] = unitRadius * cos((double)phi);
      x[0] = n[0] + this->Center[0];
      x[1] = n[1] + this->Center[1];
      x[2] = n[2] + this->Center[2];
      newPoints->InsertNextPoint(x);

      if ( (norm = vtkMath::Norm(n)) == 0.0 )
        {
          norm = 1.0;
        }
      n[0] /= norm; n[1] /= norm; n[2] /= norm;
      newNormals->InsertNextTuple(n);
      }
    this->UpdateProgress (0.10 + 0.50*i/static_cast<float>(localThetaResolution));
    }
  
  // Generate mesh connectivity
  base = phiResolution * localThetaResolution;
  
  if (fabs(localStartTheta - localEndTheta) < 360.0)
    {
    --localThetaResolution;
    }
  
  if ( this->StartPhi <= 0.0 )  // around north pole
    {
    for (i=0; i < localThetaResolution; i++)
      {
      pts[0] = phiResolution*i + numPoles;
      pts[1] = (phiResolution*(i+1) % base) + numPoles;
      pts[2] = 0;
      newPolys->InsertNextCell(3, pts);
      }
    }
  
  if ( this->EndPhi >= 180.0 ) // around south pole
    {
    numOffset = phiResolution - 1 + numPoles;
  
    for (i=0; i < localThetaResolution; i++)
      {
      pts[0] = phiResolution*i + numOffset;
      pts[2] = ((phiResolution*(i+1)) % base) + numOffset;
      pts[1] = numPoles - 1;
      newPolys->InsertNextCell(3, pts);
      }
	}
    
  this->UpdateProgress (0.70);
  
  // bands in-between poles
  for (i=0; i < localThetaResolution; i++)
    {
    for (j=0; j < (phiResolution-1); j++)
      {
      pts[0] = phiResolution*i + j + numPoles;
      pts[1] = pts[0] + 1;
      pts[2] = ((phiResolution*(i+1)+j) % base) + numPoles + 1;
      if ( !this->LatLongTessellation )
        {
        newPolys->InsertNextCell(3, pts);
        pts[1] = pts[2];
        pts[2] = pts[1] - 1;
        newPolys->InsertNextCell(3, pts);
        }
      else
        {
        pts[3] = pts[2] - 1;
        newPolys->InsertNextCell(4, pts);
        }
      }
    this->UpdateProgress (0.70 + 0.30*i/static_cast<double>(localThetaResolution));
    }
  
  // Update ourselves and release memeory
  //
  
  vtkSmartPointer<vtkPolyData> spherePolyData = 
      vtkSmartPointer<vtkPolyData>::New();
  
  newPoints->Squeeze();
  spherePolyData->SetPoints(newPoints);
  
  newNormals->Squeeze();
  spherePolyData->GetPointData()->SetNormals(newNormals);
  
  newPolys->Squeeze();
  spherePolyData->SetPolys(newPolys);
  
  //reset the center
  this->Center[0] = originalCenter[0];
  this->Center[1] = originalCenter[1];
  this->Center[2] = originalCenter[2];
  
  //this ellipsoid assumes that its major axis is aligned with the Z axis
  
  //create the transform
  this->EllipsoidTransform->Scale(this->XRadius, 
                                  this->YRadius, 
                                  this->ZRadius);
  
  //compute the ZAxis (orthogonal to XAxis and YAxis)
  vtkMath::Cross(this->XAxis, this->YAxis, this->ZAxis);
  
  //align the major axis
  vtkSmartPointer<vtkTransform> alignmentTransform = 
        vtkSmartPointer<vtkTransform>::New();
  AlignFrame(this->XAxis, this->YAxis, this->ZAxis, alignmentTransform);
  
  this->EllipsoidTransform->Concatenate(alignmentTransform);
  
  //translate to the correct center
  this->EllipsoidTransform->Translate(this->Center[0], 
                                      this->Center[1], 
                                      this->Center[2]);
  
  //apply the transform
  vtkSmartPointer<vtkTransformPolyDataFilter> transformFilter = 
      vtkSmartPointer<vtkTransformPolyDataFilter>::New();
  
  transformFilter->SetInputData(spherePolyData);
  transformFilter->SetTransform(this->EllipsoidTransform);
  transformFilter->Update();
  
  output->ShallowCopy(transformFilter->GetOutput());
  
  return 1;
}
double fwVtkCellPicker::IntersectWithLine(double p1[3], double p2[3], double tol,
                                       vtkAssemblyPath *path,
                                       vtkProp3D *prop3D,
                                       vtkAbstractMapper3D *m)
{
    vtkIdType numCells, cellId, minCellId;
    int i, minSubId, subId;
    double x[3], tMin, t, pcoords[3], minXYZ[3], minPcoords[3];
    vtkDataSet *input;
    vtkMapper *mapper;
    vtkAbstractVolumeMapper *volumeMapper;

    // Get the underlying dataset
    if ( (mapper=vtkMapper::SafeDownCast(m)) != NULL )
    {
        input = mapper->GetInput();
    }
    else if ( (volumeMapper=vtkAbstractVolumeMapper::SafeDownCast(m)) != NULL )
    {
        input = volumeMapper->GetDataSetInput();
    }
    else
    {
        return VTK_DOUBLE_MAX;
    }

    if ( (numCells = input->GetNumberOfCells()) < 1 )
    {
        return 2.0;
    }

    // Intersect each cell with ray.  Keep track of one closest to
    // the eye (within the tolerance tol) and within the clipping range).
    // Note that we fudge the "closest to" (tMin+this->Tolerance) a little and
    // keep track of the cell with the best pick based on parametric
    // coordinate (pick the minimum, maximum parametric distance). This
    // breaks ties in a reasonable way when cells are the same distance
    // from the eye (like cells lying on a 2D plane).
    //
    minCellId = -1;
    minSubId = -1;
    pcoords[0] = pcoords[1] = pcoords[2] = 0;
    double pDistMin=VTK_DOUBLE_MAX, pDist;
    for (tMin=VTK_DOUBLE_MAX,cellId=0; cellId<numCells; cellId++)
    {
        input->GetCell(cellId, this->Cell);

        if ( this->Cell->IntersectWithLine(p1, p2, tol, t, x, pcoords, subId)
                && t <= (tMin+this->Tolerance) )
        {
            pDist = this->Cell->GetParametricDistance(pcoords);
            if ( pDist < pDistMin || (pDist == pDistMin && t < tMin) )
            {
                minCellId = cellId;
                minSubId = subId;
                for (i=0; i<3; i++)
                {
                    minXYZ[i] = x[i];
                    minPcoords[i] = pcoords[i];
                }
                tMin = t;
                pDistMin = pDist;
            }//if minimum, maximum
        }//if a close cell
    }//for all cells

    //  Now compare this against other actors.
    if ( minCellId>(-1) && tMin < this->GlobalTMin )
    {
        this->MarkPicked(path, prop3D, m, tMin, minXYZ);
        this->CellId = minCellId;
        this->SubId = minSubId;
        for (i=0; i<3; i++)
        {
            this->PCoords[i] = minPcoords[i];
        }
        vtkDebugMacro("Picked cell id= " << minCellId);
    }
    return tMin;
}