Skip to content
Snippets Groups Projects
Commit 564a4633 authored by Léon Victor's avatar Léon Victor
Browse files

Implicit Annulus Widget: Introduce annulus implicit function

parent 94210e56
No related branches found
No related tags found
No related merge requests found
......@@ -10,6 +10,7 @@ set(classes
vtkAnimationScene
vtkAnnotation
vtkAnnotationLayers
vtkAnnulus
vtkArrayData
vtkAtom
vtkAttributesErrorMetric
......
// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
// SPDX-License-Identifier: BSD-3-Clause
#include "vtkAnnulus.h"
#include "vtkCylinder.h"
#include "vtkImplicitBoolean.h"
#include "vtkMath.h"
#include "vtkObjectFactory.h"
#include "vtkTransform.h"
#include "vtkVector.h"
#include <cmath>
#include <limits>
VTK_ABI_NAMESPACE_BEGIN
vtkStandardNewMacro(vtkAnnulus);
//------------------------------------------------------------------------------
vtkAnnulus::vtkAnnulus()
{
this->InnerCylinder->SetRadius(0.25);
this->OuterCylinder->SetRadius(0.5);
this->BooleanOp->AddFunction(this->OuterCylinder);
this->BooleanOp->AddFunction(this->InnerCylinder);
this->BooleanOp->SetOperationTypeToDifference();
}
//------------------------------------------------------------------------------
vtkAnnulus::~vtkAnnulus() = default;
//------------------------------------------------------------------------------
double vtkAnnulus::EvaluateFunction(double x[3])
{
return this->BooleanOp->EvaluateFunction(x);
}
//------------------------------------------------------------------------------
void vtkAnnulus::EvaluateGradient(double x[3], double g[3])
{
return this->BooleanOp->EvaluateGradient(x, g);
}
//------------------------------------------------------------------------------
void vtkAnnulus::SetCenter(double x, double y, double z)
{
this->SetCenter(vtkVector3d(x, y, z));
}
//------------------------------------------------------------------------------
void vtkAnnulus::SetCenter(const double xyz[3])
{
this->SetCenter(vtkVector3d(xyz));
}
//------------------------------------------------------------------------------
void vtkAnnulus::SetCenter(const vtkVector3d& xyz)
{
if (this->Center != xyz)
{
this->Center = xyz;
this->UpdateTransform();
}
}
//------------------------------------------------------------------------------
void vtkAnnulus::GetCenter(double& x, double& y, double& z)
{
x = this->Center[0];
y = this->Center[1];
z = this->Center[2];
}
//------------------------------------------------------------------------------
void vtkAnnulus::GetCenter(double xyz[3])
{
xyz[0] = this->Center[0];
xyz[1] = this->Center[1];
xyz[2] = this->Center[2];
}
//------------------------------------------------------------------------------
double* vtkAnnulus::GetCenter()
{
return this->Center.GetData();
}
//------------------------------------------------------------------------------
void vtkAnnulus::SetAxis(double x, double y, double z)
{
this->SetAxis(vtkVector3d(x, y, z));
}
//------------------------------------------------------------------------------
void vtkAnnulus::SetAxis(double axis[3])
{
this->SetAxis(vtkVector3d(axis));
}
//------------------------------------------------------------------------------
void vtkAnnulus::SetAxis(const vtkVector3d& axis)
{
vtkVector3d newAxis = axis;
// Normalize axis, reject if length == 0
if (newAxis.Normalize() < std::numeric_limits<double>::epsilon())
{
return;
}
if (this->Axis != newAxis)
{
this->Axis = newAxis;
this->UpdateTransform();
}
}
//------------------------------------------------------------------------------
void vtkAnnulus::GetAxis(double& x, double& y, double& z)
{
x = this->Axis[0];
y = this->Axis[1];
z = this->Axis[2];
}
//------------------------------------------------------------------------------
void vtkAnnulus::GetAxis(double xyz[3])
{
xyz[0] = this->Axis[0];
xyz[1] = this->Axis[1];
xyz[2] = this->Axis[2];
}
//------------------------------------------------------------------------------
double* vtkAnnulus::GetAxis()
{
return this->Axis.GetData();
}
//------------------------------------------------------------------------------
void vtkAnnulus::SetOuterRadius(double radius)
{
if (this->OuterCylinder->GetRadius() != radius)
{
this->OuterCylinder->SetRadius(radius);
this->Modified();
}
}
//------------------------------------------------------------------------------
double vtkAnnulus::GetOuterRadius() const
{
return this->OuterCylinder->GetRadius();
}
//------------------------------------------------------------------------------
void vtkAnnulus::SetInnerRadius(double radius)
{
if (this->InnerCylinder->GetRadius() != radius)
{
this->InnerCylinder->SetRadius(radius);
this->Modified();
}
}
//------------------------------------------------------------------------------
double vtkAnnulus::GetInnerRadius() const
{
return this->InnerCylinder->GetRadius();
}
//------------------------------------------------------------------------------
void vtkAnnulus::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os, indent);
os << indent << "Center: " << this->Center << std::endl;
os << indent << "Axis: " << this->Axis << std::endl;
os << indent << "Inner Radius: " << this->InnerCylinder->GetRadius() << std::endl;
os << indent << "Outer Radius: " << this->OuterCylinder->GetRadius() << std::endl;
}
//------------------------------------------------------------------------------
void vtkAnnulus::UpdateTransform()
{
const vtkVector3d yAxis(0., 1., 0.);
vtkVector3d cross = yAxis.Cross(this->Axis);
const double crossNorm = cross.Normalize();
const double dot = yAxis.Dot(this->Axis);
const double angle = vtkMath::DegreesFromRadians(std::atan2(crossNorm, dot));
vtkNew<vtkTransform> transform;
transform->Identity();
transform->Translate(this->Center.GetData());
transform->RotateWXYZ(angle, cross.GetData());
transform->Inverse();
this->SetTransform(transform.GetPointer());
this->Modified();
}
VTK_ABI_NAMESPACE_END
// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
// SPDX-License-Identifier: BSD-3-Clause
/**
* @class vtkAnnulus
* @brief implicit function for a annulus
*
* vtkAnnulus computes the implicit function and function gradient
* for an annulus composed of two co-axial cylinders. vtkAnnulus is a concrete
* implementation of vtkImplicitFunction. By default the Annulus is
* centered at the origin and the axis of rotation is along the
* y-axis. You can redefine the center and axis of rotation by setting
* the Center and Axis data members. (Note that it is also possible to
* use the superclass' vtkImplicitFunction transformation matrix if
* necessary to reposition by using FunctionValue() and
* FunctionGradient().)
*
* @warning
* The annulus is infinite in extent. To truncate the annulus in
* modeling operations use the vtkImplicitBoolean in combination with
* clipping planes.
*
*/
#ifndef vtkAnnulus_h
#define vtkAnnulus_h
#include "vtkCommonDataModelModule.h" // For export macro
#include "vtkImplicitFunction.h"
#include "vtkNew.h" // For vtkNew
#include "vtkVector.h" // For vtkVector3d
VTK_ABI_NAMESPACE_BEGIN
class vtkCylinder;
class vtkImplicitBoolean;
class VTKCOMMONDATAMODEL_EXPORT vtkAnnulus : public vtkImplicitFunction
{
public:
static vtkAnnulus* New();
vtkTypeMacro(vtkAnnulus, vtkImplicitFunction);
void PrintSelf(ostream& os, vtkIndent indent) override;
///@{
/**
* Evaluate annulus equation.
*/
using vtkImplicitFunction::EvaluateFunction;
double EvaluateFunction(double x[3]) override;
///@}
/**
* Evaluate annulus function gradient.
*/
void EvaluateGradient(double x[3], double g[3]) override;
///@{
/**
* Set/Get the inner annulus radius. Default is 0.25.
*/
void SetInnerRadius(double radius);
double GetInnerRadius() const;
///@}
///@{
/**
* Set/Get the outer annulus radius. Default is 0.5.
*/
void SetOuterRadius(double radius);
double GetOuterRadius() const;
///@}
///@{
/**
* Set/Get the annulus center. Default is (0, 0, 0).
*/
void SetCenter(double x, double y, double z);
void SetCenter(const double xyz[3]);
void SetCenter(const vtkVector3d& xyz);
void GetCenter(double& x, double& y, double& z);
void GetCenter(double xyz[3]);
double* GetCenter() VTK_SIZEHINT(3);
///@}
///@{
/**
* Set/Get the axis of the annulus. If the axis is not specified as
* a unit vector, it will be normalized. If zero-length axis vector
* is used as input to this method, it will be ignored.
* Default is the Y-axis (0, 1, 0)
*/
void SetAxis(double x, double y, double z);
void SetAxis(double axis[3]);
void SetAxis(const vtkVector3d& axis);
void GetAxis(double& x, double& y, double& z);
void GetAxis(double xyz[3]);
double* GetAxis() VTK_SIZEHINT(3);
///@}
protected:
vtkAnnulus();
~vtkAnnulus() override;
private:
vtkAnnulus(const vtkAnnulus&) = delete;
void operator=(const vtkAnnulus&) = delete;
void UpdateTransform();
vtkVector3d Center = { 0.0, 0.0, 0.0 };
vtkVector3d Axis = { 0.0, 1.0, 0.0 };
vtkNew<vtkCylinder> InnerCylinder;
vtkNew<vtkCylinder> OuterCylinder;
vtkNew<vtkImplicitBoolean> BooleanOp;
};
VTK_ABI_NAMESPACE_END
#endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment