//============================================================================ // Copyright (c) Kitware, Inc. // All rights reserved. // See LICENSE.txt 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. // // Copyright 2017 Sandia Corporation. // Copyright 2017 UT-Battelle, LLC. // Copyright 2017 Los Alamos National Security. // // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. // // Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National // Laboratory (LANL), the U.S. Government retains certain rights in // this software. //============================================================================ #ifndef vtk_m_cont_ImplicitFunction_h #define vtk_m_cont_ImplicitFunction_h #include #include #include namespace vtkm { namespace cont { class VTKM_CONT_EXPORT ImplicitFunction { public: virtual ~ImplicitFunction(); template vtkm::exec::ImplicitFunction PrepareForExecution(DeviceAdapter device) const { if (!this->Cache->GetValid()) { this->SetDefaultDevices(); } return this->Cache->GetVirtualObject(device); } void Modified() { this->Cache->SetRefreshFlag(true); } protected: using CacheType = vtkm::cont::VirtualObjectCache; ImplicitFunction() : Cache(new CacheType) { } ImplicitFunction(ImplicitFunction &&other) : Cache(std::move(other.Cache)) { } ImplicitFunction& operator=(ImplicitFunction &&other) { if (this != &other) { this->Cache = std::move(other.Cache); } return *this; } virtual void SetDefaultDevices() const = 0; std::unique_ptr Cache; }; template class VTKM_ALWAYS_EXPORT ImplicitFunctionImpl : public ImplicitFunction { public: template void ResetDevices(DeviceAdapterList devices) { this->Cache->Bind(static_cast(this), devices); } protected: ImplicitFunctionImpl() = default; ImplicitFunctionImpl(const ImplicitFunctionImpl &) : ImplicitFunction() { } // Cannot default due to a bug in VS2013 ImplicitFunctionImpl(ImplicitFunctionImpl &&other) : ImplicitFunction(std::move(other)) { } ImplicitFunctionImpl& operator=(const ImplicitFunctionImpl &) { return *this; } // Cannot default due to a bug in VS2013 ImplicitFunctionImpl& operator=(ImplicitFunctionImpl &&other) { ImplicitFunction::operator=(std::move(other)); return *this; } void SetDefaultDevices() const override { this->Cache->Bind(static_cast(this)); } }; //============================================================================ // ImplicitFunctions: //============================================================================ /// \brief Implicit function for a box class VTKM_ALWAYS_EXPORT Box : public ImplicitFunctionImpl { public: Box() : MinPoint(vtkm::Vec(FloatDefault(0), FloatDefault(0), FloatDefault(0))), MaxPoint(vtkm::Vec(FloatDefault(1), FloatDefault(1), FloatDefault(1))) { } Box(vtkm::Vec minPoint, vtkm::Vec maxPoint) : MinPoint(minPoint), MaxPoint(maxPoint) { } Box(FloatDefault xmin, FloatDefault xmax, FloatDefault ymin, FloatDefault ymax, FloatDefault zmin, FloatDefault zmax) { MinPoint[0] = xmin; MaxPoint[0] = xmax; MinPoint[1] = ymin; MaxPoint[1] = ymax; MinPoint[2] = zmin; MaxPoint[2] = zmax; } void SetMinPoint(const vtkm::Vec &point) { this->MinPoint = point; this->Modified(); } void SetMaxPoint(const vtkm::Vec &point) { this->MaxPoint = point; this->Modified(); } const vtkm::Vec& GetMinPoint() const { return this->MinPoint; } const vtkm::Vec& GetMaxPoint() const { return this->MaxPoint; } VTKM_EXEC_CONT FloatDefault Value(const vtkm::Vec &x) const; VTKM_EXEC_CONT FloatDefault Value(FloatDefault x, FloatDefault y, FloatDefault z) const { return this->Value(vtkm::Vec(x, y, z)); } VTKM_EXEC_CONT vtkm::Vec Gradient(const vtkm::Vec &x) const; VTKM_EXEC_CONT vtkm::Vec Gradient(FloatDefault x, FloatDefault y, FloatDefault z) const { return this->Gradient(vtkm::Vec(x, y, z)); } private: vtkm::Vec MinPoint; vtkm::Vec MaxPoint; }; //============================================================================ /// \brief Implicit function for a plane class VTKM_ALWAYS_EXPORT Plane : public ImplicitFunctionImpl { public: Plane() : Origin(FloatDefault(0)), Normal(FloatDefault(0), FloatDefault(0), FloatDefault(1)) { } explicit Plane(const vtkm::Vec &normal) : Origin(FloatDefault(0)), Normal(normal) { } Plane(const vtkm::Vec &origin, const vtkm::Vec &normal) : Origin(origin), Normal(normal) { } void SetOrigin(const vtkm::Vec &origin) { this->Origin = origin; this->Modified(); } void SetNormal(const vtkm::Vec &normal) { this->Normal = normal; this->Modified(); } const vtkm::Vec& GetOrigin() const { return this->Origin; } const vtkm::Vec& GetNormal() const { return this->Normal; } VTKM_EXEC_CONT FloatDefault Value(FloatDefault x, FloatDefault y, FloatDefault z) const { return ((x - this->Origin[0]) * this->Normal[0]) + ((y - this->Origin[1]) * this->Normal[1]) + ((z - this->Origin[2]) * this->Normal[2]); } VTKM_EXEC_CONT FloatDefault Value(const vtkm::Vec &x) const { return this->Value(x[0], x[1], x[2]); } VTKM_EXEC_CONT vtkm::Vec Gradient(FloatDefault, FloatDefault, FloatDefault) const { return this->Normal; } VTKM_EXEC_CONT vtkm::Vec Gradient(const vtkm::Vec&) const { return this->Normal; } private: vtkm::Vec Origin; vtkm::Vec Normal; }; //============================================================================ /// \brief Implicit function for a sphere class VTKM_ALWAYS_EXPORT Sphere : public ImplicitFunctionImpl { public: Sphere() : Radius(FloatDefault(0.2)), Center(FloatDefault(0)) { } explicit Sphere(FloatDefault radius) : Radius(radius), Center(FloatDefault(0)) { } Sphere(vtkm::Vec center, FloatDefault radius) : Radius(radius), Center(center) { } void SetRadius(FloatDefault radius) { this->Radius = radius; this->Modified(); } void SetCenter(const vtkm::Vec ¢er) { this->Center = center; this->Modified(); } FloatDefault GetRadius() const { return this->Radius; } const vtkm::Vec& GetCenter() const { return this->Center; } VTKM_EXEC_CONT FloatDefault Value(FloatDefault x, FloatDefault y, FloatDefault z) const { return ((x - this->Center[0]) * (x - this->Center[0]) + (y - this->Center[1]) * (y - this->Center[1]) + (z - this->Center[2]) * (z - this->Center[2])) - (this->Radius * this->Radius); } VTKM_EXEC_CONT FloatDefault Value(const vtkm::Vec &x) const { return this->Value(x[0], x[1], x[2]); } VTKM_EXEC_CONT vtkm::Vec Gradient(FloatDefault x, FloatDefault y, FloatDefault z) const { return this->Gradient(vtkm::Vec(x, y, z)); } VTKM_EXEC_CONT vtkm::Vec Gradient(const vtkm::Vec &x) const { return FloatDefault(2) * (x - this->Center); } private: FloatDefault Radius; vtkm::Vec Center; }; } } // vtkm::cont #include #endif // vtk_m_cont_ImplicitFunction_h