From 47d28f4cfef3e2f6f136967b1f74acf298a3d0fe Mon Sep 17 00:00:00 2001 From: SonSang Date: Mon, 2 Nov 2020 21:20:08 +0900 Subject: [PATCH] Added extrusion surface --- Surface/ExtrusionSurface3d.cpp | 62 +++++++++++++++++++++++++++++++++ Surface/ExtrusionSurface3d.h | 43 +++++++++++++++++++++++ Surface/RevolutionSurface3d.cpp | 2 +- 3 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 Surface/ExtrusionSurface3d.cpp create mode 100644 Surface/ExtrusionSurface3d.h diff --git a/Surface/ExtrusionSurface3d.cpp b/Surface/ExtrusionSurface3d.cpp new file mode 100644 index 0000000..79c25b3 --- /dev/null +++ b/Surface/ExtrusionSurface3d.cpp @@ -0,0 +1,62 @@ +#include "ExtrusionSurface3d.h" + +namespace MN { + ExtrusionSurface3d ExtrusionSurface3d::create(const std::vector& profile) { + ExtrusionSurface3d surface; + surface.profile = profile; + return surface; + } + ExtrusionSurface3d::Ptr ExtrusionSurface3d::createPtr(const std::vector& profile) { + return std::make_shared(create(profile)); + } + + const std::vector& ExtrusionSurface3d::getProfile() const { + return profile; + } + void ExtrusionSurface3d::setProfile(const std::vector& profile) { + this->profile = profile; + } + + // u : Parameter for profile curve evaluation + // v : Parameter for extrusion along Z axis + Vec3 ExtrusionSurface3d::evaluate(int curveID, Real u, Real v) const { + Vec2 pt = profile[curveID]->evaluate(u); + return { pt[0], pt[1], v }; + } + Vec3 ExtrusionSurface3d::differentiate(int curveID, Real u, Real v, int uOrder, int vOrder) const { + if (uOrder == 0 && vOrder == 0) + return evaluate(curveID, u, v); + else if (uOrder == 1 && vOrder == 0) { + auto curveDeriv = profile[curveID]->differentiate(u, 1); + return { curveDeriv[0], curveDeriv[1], 0 }; + } + else if (uOrder == 0 && vOrder == 1) { + return { 0, 0, 1 }; + } + else if (uOrder == 2 && vOrder == 0) { + auto curveDeriv = profile[curveID]->differentiate(u, 2); + return { curveDeriv[0], curveDeriv[1], 0 }; + } + else if (uOrder == 1 && vOrder == 1) { + return { 0, 0, 0 }; + } + else if (uOrder == 0 && vOrder == 2) { + return { 0, 0, 0 }; + } + else if (uOrder == 3 && vOrder == 0) { + auto curveDeriv = profile[curveID]->differentiate(u, 3); + return { curveDeriv[0], curveDeriv[1], 0 }; + } + else if (uOrder == 2 && vOrder == 1) { + return { 0, 0, 0 }; + } + else if (uOrder == 1 && vOrder == 2) { + return { 0, 0, 0 }; + } + else if (uOrder == 0 && vOrder == 3) { + return { 0, 0, 0 }; + } + else + throw(std::runtime_error("Extrusion surface differentiation is only allowed up to 2nd derivatives")); + } +} \ No newline at end of file diff --git a/Surface/ExtrusionSurface3d.h b/Surface/ExtrusionSurface3d.h new file mode 100644 index 0000000..ccaae4a --- /dev/null +++ b/Surface/ExtrusionSurface3d.h @@ -0,0 +1,43 @@ +/* + ******************************************************************************************* + * Author : Sang Hyun Son + * Email : shh1295@gmail.com + * Github : github.com/SonSang + ******************************************************************************************* + */ + +#ifndef __MN_EXTRUSION_SURFACE_3D_H__ +#define __MN_EXTRUSION_SURFACE_3D_H__ + +#ifdef _MSC_VER +#pragma once +#endif + +#include "../Freeform.h" +#include "../Curve/BsplineCurve2d.h" +#include + +namespace MN { + class ExtrusionSurface3d : public Freeform3ds { + private: + ExtrusionSurface3d() = default; + + // Profile curve on XY plane that is extruded along Z axis + std::vector profile; + public: + using Ptr = std::shared_ptr; + + static ExtrusionSurface3d create(const std::vector& profile); + static Ptr createPtr(const std::vector& profile); + + const std::vector& getProfile() const; + void setProfile(const std::vector& profile); + + // u : Parameter for profile curve evaluation + // v : Parameter for extrusion along Z axis + virtual Vec3 evaluate(int curveID, Real u, Real v) const; + virtual Vec3 differentiate(int curveID, Real u, Real v, int uOrder, int vOrder) const; + }; +} + +#endif \ No newline at end of file diff --git a/Surface/RevolutionSurface3d.cpp b/Surface/RevolutionSurface3d.cpp index 3a94c08..727c107 100644 --- a/Surface/RevolutionSurface3d.cpp +++ b/Surface/RevolutionSurface3d.cpp @@ -66,6 +66,6 @@ namespace MN { return { curvePoint[0] * sin(v), 0, curvePoint[0] * -cos(v) }; } else - throw(std::runtime_error("Bezier surface differentiation is only allowed up to 2nd derivatives")); + throw(std::runtime_error("Revolution surface differentiation is only allowed up to 2nd derivatives")); } } \ No newline at end of file