Cloned library of VTK-5.0.0 with extra build files for internal package management.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

330 lines
8.9 KiB

2 years ago
/*=========================================================================
Program: Visualization Toolkit
Module: $RCSfile: vtkConeSource.cxx,v $
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
#include "vtkConeSource.h"
#include "vtkFloatArray.h"
#include "vtkMath.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkStreamingDemandDrivenPipeline.h"
#include "vtkPolyData.h"
#include "vtkTransform.h"
#include "vtkCellArray.h"
#include <math.h>
vtkCxxRevisionMacro(vtkConeSource, "$Revision: 1.73 $");
vtkStandardNewMacro(vtkConeSource);
//----------------------------------------------------------------------------
// Construct with default resolution 6, height 1.0, radius 0.5, and capping
// on.
vtkConeSource::vtkConeSource(int res)
{
res = (res < 0 ? 0 : res);
this->Resolution = res;
this->Height = 1.0;
this->Radius = 0.5;
this->Capping = 1;
this->Center[0] = 0.0;
this->Center[1] = 0.0;
this->Center[2] = 0.0;
this->Direction[0] = 1.0;
this->Direction[1] = 0.0;
this->Direction[2] = 0.0;
this->SetNumberOfInputPorts(0);
}
//----------------------------------------------------------------------------
int vtkConeSource::RequestData(
vtkInformation *vtkNotUsed(request),
vtkInformationVector **vtkNotUsed(inputVector),
vtkInformationVector *outputVector)
{
// get the info objects
vtkInformation *outInfo = outputVector->GetInformationObject(0);
double angle;
int numLines, numPolys, numPts;
double x[3], xbot;
int i;
vtkIdType pts[VTK_CELL_SIZE];
vtkPoints *newPoints;
vtkCellArray *newLines=0;
vtkCellArray *newPolys=0;
vtkPolyData *output = vtkPolyData::SafeDownCast(
outInfo->Get(vtkDataObject::DATA_OBJECT()));
// for streaming
int piece;
int numPieces;
int maxPieces;
int start, end;
int createBottom;
piece = output->GetUpdatePiece();
if (piece >= this->Resolution && !(piece == 0 && this->Resolution == 0))
{
return 1;
}
numPieces = output->GetUpdateNumberOfPieces();
maxPieces = this->Resolution != 0 ? this->Resolution : 1;
if (numPieces > maxPieces)
{
numPieces = maxPieces;
}
if (piece >= maxPieces)
{
// Super class should do this for us,
// but I put this condition in any way.
return 1;
}
start = maxPieces * piece / numPieces;
end = (maxPieces * (piece+1) / numPieces) - 1;
createBottom = (this->Capping && (start == 0));
vtkDebugMacro("ConeSource Executing");
if ( this->Resolution )
{
angle = 2.0*3.141592654/this->Resolution;
}
else
{
angle = 0.0;
}
// Set things up; allocate memory
//
switch ( this->Resolution )
{
case 0:
numPts = 2;
numLines = 1;
newLines = vtkCellArray::New();
newLines->Allocate(newLines->EstimateSize(numLines,numPts));
break;
case 1: case 2:
numPts = 2*this->Resolution + 1;
numPolys = this->Resolution;
newPolys = vtkCellArray::New();
newPolys->Allocate(newPolys->EstimateSize(numPolys,3));
break;
default:
if (createBottom)
{
// piece 0 has cap.
numPts = this->Resolution + 1;
numPolys = end - start + 2;
}
else
{
numPts = end - start + 3;
numPolys = end - start + 2;
}
newPolys = vtkCellArray::New();
newPolys->Allocate(newPolys->EstimateSize(numPolys,this->Resolution));
break;
}
newPoints = vtkPoints::New();
newPoints->SetDataTypeToFloat(); //used later during transformation
newPoints->Allocate(numPts);
// Create cone
//
x[0] = this->Height / 2.0; // zero-centered
x[1] = 0.0;
x[2] = 0.0;
pts[0] = newPoints->InsertNextPoint(x);
xbot = -this->Height / 2.0;
switch (this->Resolution)
{
case 0:
x[0] = xbot;
x[1] = 0.0;
x[2] = 0.0;
pts[1] = newPoints->InsertNextPoint(x);
newLines->InsertNextCell(2,pts);
break;
case 2: // fall through this case to use the code in case 1
x[0] = xbot;
x[1] = 0.0;
x[2] = -this->Radius;
pts[1] = newPoints->InsertNextPoint(x);
x[0] = xbot;
x[1] = 0.0;
x[2] = this->Radius;
pts[2] = newPoints->InsertNextPoint(x);
newPolys->InsertNextCell(3,pts);
case 1:
x[0] = xbot;
x[1] = -this->Radius;
x[2] = 0.0;
pts[1] = newPoints->InsertNextPoint(x);
x[0] = xbot;
x[1] = this->Radius;
x[2] = 0.0;
pts[2] = newPoints->InsertNextPoint(x);
newPolys->InsertNextCell(3,pts);
break;
default: // General case: create Resolution triangles and single cap
// create the bottom.
if ( createBottom )
{
for (i=0; i < this->Resolution; i++)
{
x[0] = xbot;
x[1] = this->Radius * cos ((double)i*angle);
x[2] = this->Radius * sin ((double)i*angle);
// Reverse the order
pts[this->Resolution - i - 1] = newPoints->InsertNextPoint(x);
}
newPolys->InsertNextCell(this->Resolution,pts);
}
pts[0] = 0;
if ( ! createBottom)
{
// we need to create the points also
x[0] = xbot;
x[1] = this->Radius * cos ((double)start*angle);
x[2] = this->Radius * sin ((double)start*angle);
pts[1] = newPoints->InsertNextPoint(x);
for (i = start; i <= end; ++i)
{
x[1] = this->Radius * cos ((double)(i+1)*angle);
x[2] = this->Radius * sin ((double)(i+1)*angle);
pts[2] = newPoints->InsertNextPoint(x);
newPolys->InsertNextCell(3,pts);
pts[1] = pts[2];
}
}
else
{
// bottom and points have already been created.
for (i=start; i <= end; i++)
{
pts[1] = i+1;
pts[2] = i+2;
if (pts[2] > this->Resolution)
{
pts[2] = 1;
}
newPolys->InsertNextCell(3,pts);
}
} // createBottom
} //switch
// A non-default origin and/or direction requires transformation
//
if ( this->Center[0] != 0.0 || this->Center[1] != 0.0 ||
this->Center[2] != 0.0 || this->Direction[0] != 1.0 ||
this->Direction[1] != 0.0 || this->Direction[2] != 0.0 )
{
vtkTransform *t = vtkTransform::New();
t->Translate(this->Center[0], this->Center[1], this->Center[2]);
double vMag = vtkMath::Norm(this->Direction);
if ( this->Direction[0] < 0.0 &&
this->Direction[1] == 0.0 &&
this->Direction[2] == 0.0 )
{
// just flip x
t->RotateWXYZ(180.0,0,1,0);
}
else
{
t->RotateWXYZ((double)180.0, (this->Direction[0]+vMag)/2.0,
this->Direction[1]/2.0, this->Direction[2]/2.0);
}
float *ipts = ((vtkFloatArray *)newPoints->GetData())->GetPointer(0);
for (i=0; i<numPts; i++, ipts+=3)
{
t->TransformPoint(ipts,ipts);
}
t->Delete();
}
// Update ourselves
//
output->SetPoints(newPoints);
newPoints->Delete();
if ( newPolys )
{
newPolys->Squeeze(); // we may have estimated size; reclaim some space
output->SetPolys(newPolys);
newPolys->Delete();
}
else
{
output->SetLines(newLines);
newLines->Delete();
}
return 1;
}
//----------------------------------------------------------------------------
int vtkConeSource::RequestInformation(
vtkInformation *vtkNotUsed(request),
vtkInformationVector **vtkNotUsed(inputVector),
vtkInformationVector *outputVector)
{
vtkInformation *outInfo = outputVector->GetInformationObject(0);
outInfo->Set(vtkStreamingDemandDrivenPipeline::MAXIMUM_NUMBER_OF_PIECES(),
-1);
return 1;
}
//----------------------------------------------------------------------------
void vtkConeSource::SetAngle(double angle)
{
this->SetRadius (this->Height * tan ((double) angle*vtkMath::DegreesToRadians()));
}
//----------------------------------------------------------------------------
double vtkConeSource::GetAngle()
{
return atan2 (this->Radius, this->Height) / vtkMath::DegreesToRadians();
}
//----------------------------------------------------------------------------
void vtkConeSource::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os,indent);
os << indent << "Resolution: " << this->Resolution << "\n";
os << indent << "Height: " << this->Height << "\n";
os << indent << "Radius: " << this->Radius << "\n";
os << indent << "Capping: " << (this->Capping ? "On\n" : "Off\n");
os << indent << "Center: (" << this->Center[0] << ", "
<< this->Center[1] << ", " << this->Center[2] << ")\n";
os << indent << "Direction: (" << this->Direction[0] << ", "
<< this->Direction[1] << ", " << this->Direction[2] << ")\n";
}