An update will be applied December 9th, between 12PM and 1:00PM EST (UTC -5:00). The site may be slow during that time.

Commit 6a3b1257 authored by Mathieu Westphal's avatar Mathieu Westphal
Browse files

Adding an vtkEllipseArcSource

the current vtkArcSource is not sufficient for some usage
this commit adds a vtkEllipseArcSource filter, controlled by
a center, a normal, a major radius vector, start and segment angle,
resolution, ratio, and output precision
parent 0ed90343
......@@ -6,6 +6,7 @@ set(Module_SRCS
vtkCubeSource.cxx
vtkCylinderSource.cxx
vtkDiskSource.cxx
vtkEllipseArcSource.cxx
vtkEllipticalButtonSource.cxx
vtkFrustumSource.cxx
vtkGlyphSource2D.cxx
......
......@@ -5,6 +5,7 @@ vtk_add_test_cxx(${vtk-module}CxxTests tests
TestCylinderSource.cxx,NO_VALID
TestDiskSource.cxx,NO_VALID
TestEllipticalButtonSource.cxx,NO_VALID
TestEllipseArcSource.cxx
TestFrustumSource.cxx,NO_VALID
TestGlyphSource2D.cxx,NO_VALID
TestLineSource.cxx,NO_VALID
......@@ -25,4 +26,5 @@ vtk_add_test_cxx(${vtk-module}CxxTests tests
TestTexturedSphereSource.cxx,NO_VALID
TestGlyphSource2DResolution.cxx,
)
vtk_test_cxx_executable(${vtk-module}CxxTests tests)
vtk_test_cxx_executable(${vtk-module}CxxTests tests
RENDERING_FACTORY)
/*=========================================================================
Program: Visualization Toolkit
Module: TestEllipseArcSource.cxx
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 <vtkEllipseArcSource.h>
#include <vtkPolyData.h>
#include <vtkNew.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
int TestEllipseArcSource(int vtkNotUsed(argc), char * vtkNotUsed(argv)[])
{
vtkNew<vtkEllipseArcSource> source;
source->SetCenter(0.0, 0.0, 0.0);
source->SetRatio(0.25);
source->SetNormal(0., 0., 1.);
source->SetMajorRadiusVector(10, 0., 0.);
source->SetStartAngle(20);
source->SetSegmentAngle(250);
source->SetResolution(80);
vtkNew<vtkPolyDataMapper> mapper;
mapper->SetInputConnection(source->GetOutputPort());
vtkNew<vtkActor> actor;
actor->SetMapper(mapper.Get());
vtkNew<vtkRenderer> renderer;
vtkNew<vtkRenderWindow> renderWindow;
renderWindow->AddRenderer(renderer.Get());
vtkNew<vtkRenderWindowInteractor> renderWindowInteractor;
renderWindowInteractor->SetRenderWindow(renderWindow.Get());
renderer->AddActor(actor.Get());
renderer->SetBackground(.3, .6, .3);
renderWindow->SetMultiSamples(0);
renderWindow->Render();
renderWindowInteractor->Start();
return EXIT_SUCCESS;
}
/*=========================================================================
Program: Visualization Toolkit
Module: vtkEllipseArcSource.cxx
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 "vtkEllipseArcSource.h"
#include "vtkCellArray.h"
#include "vtkFloatArray.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkMath.h"
#include "vtkMathUtilities.h"
#include "vtkNew.h"
#include "vtkObjectFactory.h"
#include "vtkPoints.h"
#include "vtkPointData.h"
#include "vtkPolyData.h"
#include "vtkStreamingDemandDrivenPipeline.h"
vtkStandardNewMacro(vtkEllipseArcSource);
// --------------------------------------------------------------------------
vtkEllipseArcSource::vtkEllipseArcSource()
{
// Default center is origin
this->Center[0] = 0.0;
this->Center[1] = 0.0;
this->Center[2] = 0.0;
// Default normal vector is unit in Oz direction
this->Normal[0] = 0.0;
this->Normal[1] = 0.0;
this->Normal[2] = 1.0;
this->MajorRadiusVector[0] = 1.0;
this->MajorRadiusVector[1] = 0.0;
this->MajorRadiusVector[2] = 0.0;
// Default arc is a quarter-circle
this->StartAngle = 0.0;
this->SegmentAngle = 90.;
// Default resolution
this->Resolution = 100;
this->OutputPointsPrecision = SINGLE_PRECISION;
// Default Ratio
this->Ratio = 1.0;
// This is a source
this->SetNumberOfInputPorts(0);
}
// --------------------------------------------------------------------------
int vtkEllipseArcSource::RequestData(vtkInformation* vtkNotUsed(request),
vtkInformationVector** vtkNotUsed(inputVector),
vtkInformationVector* outputVector)
{
int numLines = this->Resolution;
int numPts = this->Resolution + 1;
double tc[3] = { 0.0, 0.0, 0.0 };
// get the info object
vtkInformation* outInfo = outputVector->GetInformationObject(0);
// get the ouptut
vtkPolyData* output =
vtkPolyData::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT()));
double a = 1.0, b = 1.0;
double majorRadiusVect[3];
double orthogonalVect[3];
double startAngleRad = 0.0, segmentAngleRad, angleIncRad;
// make sure the normal vector is normalized
vtkMath::Normalize(this->Normal);
// get orthonal vector between user-defined major radius and this->Normal
vtkMath::Cross(this->Normal, this->MajorRadiusVector, orthogonalVect);
if (vtkMathUtilities::FuzzyCompare(vtkMath::Norm(orthogonalVect), 0.0))
{
vtkErrorMacro(<< "Ellipse normal vector and major radius axis are collinear");
return 0;
}
vtkMath::Normalize(orthogonalVect);
// get major Radius Vector adjusted to be on the plane defined by this->Normal
vtkMath::Cross(orthogonalVect, this->Normal, majorRadiusVect);
vtkMath::Normalize(majorRadiusVect);
// set the major and minor Radius values
a = vtkMath::Norm(this->MajorRadiusVector);
b = a * this->Ratio;
// user-defined angles (positive only)
startAngleRad = vtkMath::RadiansFromDegrees(this->StartAngle);
if (startAngleRad < 0)
{
startAngleRad += 2.0 * vtkMath::Pi();
}
segmentAngleRad = vtkMath::RadiansFromDegrees(this->SegmentAngle);
// Calcute angle increment
angleIncRad = segmentAngleRad / this->Resolution;
// Now create arc points and segments
vtkNew<vtkPoints> newPoints;
// Set the desired precision for the points in the output.
if (this->OutputPointsPrecision == vtkAlgorithm::DOUBLE_PRECISION)
{
newPoints->SetDataType(VTK_DOUBLE);
}
else
{
newPoints->SetDataType(VTK_FLOAT);
}
newPoints->Allocate(numPts);
vtkNew<vtkFloatArray> newTCoords;
newTCoords->SetNumberOfComponents(2);
newTCoords->Allocate(2 * numPts);
newTCoords->SetName("Texture Coordinates");
vtkNew<vtkCellArray> newLines;
newLines->Allocate(newLines->EstimateSize(numLines, 2));
double theta = startAngleRad;
double thetaEllipse;
// Iterate over angle increments
for (int i = 0; i <= this->Resolution; ++i, theta += angleIncRad)
{
// convert section angle to an angle applied to ellipse equation.
// the result point with the ellipse angle, will be located on section angle
int quotient = (int)(theta / (2.0 * vtkMath::Pi()));
theta = theta - quotient * 2.0 * vtkMath::Pi();
// result range: -pi/2, pi/2
thetaEllipse = atan(tan(theta) / this->Ratio);
//theta range: 0, 2 * pi
if (theta > vtkMath::Pi() / 2 && theta <= vtkMath::Pi())
{
thetaEllipse += vtkMath::Pi();
}
else if (theta > vtkMath::Pi() && theta <= 1.5 * vtkMath::Pi())
{
thetaEllipse -= vtkMath::Pi();
}
const double cosTheta = cos(thetaEllipse);
const double sinTheta = sin(thetaEllipse);
double p[3] =
{
this->Center[0] + a * cosTheta * majorRadiusVect[0] + b * sinTheta * orthogonalVect[0],
this->Center[1] + a * cosTheta * majorRadiusVect[1] + b * sinTheta * orthogonalVect[1],
this->Center[2] + a * cosTheta * majorRadiusVect[2] + b * sinTheta * orthogonalVect[2]
};
tc[0] = static_cast<double>(i) / this->Resolution;
newPoints->InsertPoint(i , p);
newTCoords->InsertTuple(i, tc);
}
newLines->InsertNextCell(numPts);
for (int k = 0; k < numPts; ++ k)
{
newLines->InsertCellPoint(k);
}
output->SetPoints(newPoints.Get());
output->GetPointData()->SetTCoords(newTCoords.Get());
output->SetLines(newLines.Get());
return 1;
}
// --------------------------------------------------------------------------
void vtkEllipseArcSource::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os, indent);
os << indent << "Resolution: " << this->Resolution << "\n";
os << indent << "Center: (" << this->Center[0] << ", "
<< this->Center[1] << ", "
<< this->Center[2] << ")\n";
os << indent << "Normal: (" << this->Normal[0] << ", "
<< this->Normal[1] << ", "
<< this->Normal[2] << ")\n";
os << indent << "Major Radius Vector: (" << this->MajorRadiusVector[0] << ", "
<< this->MajorRadiusVector[1] << ", "
<< this->MajorRadiusVector[2] << ")\n";
os << indent << "StartAngle: " << this->StartAngle << "\n";
os << indent << "SegmentAngle: " << this->SegmentAngle << "\n";
os << indent << "Resolution: " << this->Resolution << "\n";
os << indent << "Ratio: " << this->Ratio << "\n";
os << indent << "Output Points Precision: " << this->OutputPointsPrecision << "\n";
}
/*=========================================================================
Program: Visualization Toolkit
Module: vtkEllipseArcSource.h
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.
=========================================================================*/
// .NAME vtkEllipseArcSource - create an elliptical arc
// .SECTION Description
// vtkEllipseArcSource is a source object that creates an elliptical arc
// defined by a normal, a center and the major radius vector.
// You can define an angle to draw only a section of the ellipse. The number of
// segments composing the polyline is controlled by setting the object
// resolution.
#ifndef vtkEllipseArcSource_h
#define vtkEllipseArcSource_h
#include "vtkFiltersSourcesModule.h" // For export macro
#include "vtkPolyDataAlgorithm.h"
class VTKFILTERSSOURCES_EXPORT vtkEllipseArcSource : public vtkPolyDataAlgorithm
{
public:
static vtkEllipseArcSource *New();
vtkTypeMacro(vtkEllipseArcSource, vtkPolyDataAlgorithm);
void PrintSelf(ostream& os, vtkIndent indent);
// Description:
// Set position of the center of the ellipse that define the arc.
// Default is 0, 0, 0.
vtkSetVector3Macro(Center, double);
vtkGetVectorMacro(Center, double, 3);
// Description:
// Set normal vector. Represents the plane in which the ellipse will be drawn.
// Default 0, 0, 1.
vtkSetVector3Macro(Normal, double);
vtkGetVectorMacro(Normal, double, 3);
// Description:
// Set Major Radius Vector. It defines the origin of polar angle and the major
// radius size.
// Default is 1, 0, 0.
vtkSetVector3Macro(MajorRadiusVector, double);
vtkGetVectorMacro(MajorRadiusVector, double, 3);
// Description:
// Set the start angle. The angle where the plot begins.
// Default is 0.
vtkSetClampMacro(StartAngle, double, -360.0, 360.0);
vtkGetMacro(StartAngle, double);
// Description:
// Angular sector occupied by the arc, beginning at Start Angle
// Default is 90.
vtkSetClampMacro(SegmentAngle, double, 0.0, 360.0);
vtkGetMacro(SegmentAngle, double);
// Description:
// Divide line into resolution number of pieces.
// Note: if Resolution is set to 1 the arc is a
// straight line. Default is 100.
vtkSetClampMacro(Resolution, int, 1, VTK_INT_MAX);
vtkGetMacro(Resolution, int);
// Description:
// Set/get the desired precision for the output points.
// vtkAlgorithm::SINGLE_PRECISION - Output single-precision floating point,
// This is the default.
// vtkAlgorithm::DOUBLE_PRECISION - Output double-precision floating point.
vtkSetMacro(OutputPointsPrecision, int);
vtkGetMacro(OutputPointsPrecision, int);
// Description:
// Set the ratio of the ellipse, i.e. the ratio b/a _ b: minor radius;
// a: major radius
// default is 1.
vtkSetClampMacro(Ratio, double, 0.001, 100.0);
vtkGetMacro(Ratio, double);
protected:
vtkEllipseArcSource();
~vtkEllipseArcSource() {}
int RequestData(vtkInformation *, vtkInformationVector **,
vtkInformationVector *);
double Center[3];
double Normal[3];
double MajorRadiusVector[3];
double StartAngle;
double SegmentAngle;
int Resolution;
double Ratio;
int OutputPointsPrecision;
private:
vtkEllipseArcSource(const vtkEllipseArcSource&); // Not implemented.
void operator=(const vtkEllipseArcSource&); // Not implemented.
};
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment