// Copyright 2021 The Manifold Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #pragma once #include <limits> #include <vector> #ifdef MANIFOLD_DEBUG #include <chrono> #endif #include "manifold/linalg.h" namespace manifold { /** @addtogroup Math * @ingroup Core * @brief Simple math operations. * */ /** @addtogroup LinAlg * @{ */ la; vec2; vec3; vec4; bvec4; mat2; mat3x2; mat4x2; mat2x3; mat3; mat4x3; mat3x4; mat4; ivec2; ivec3; ivec4; quat; /** @} */ /** @addtogroup Scalar * @ingroup Math * @brief Simple scalar operations. * @{ */ constexpr double kPi = …; constexpr double kTwoPi = …; constexpr double kHalfPi = …; /** * Convert degrees to radians. * * @param a Angle in degrees. */ constexpr double radians(double a) { … } /** * Convert radians to degrees. * * @param a Angle in radians. */ constexpr double degrees(double a) { … } /** * Performs smooth Hermite interpolation between 0 and 1 when edge0 < x < edge1. * * @param edge0 Specifies the value of the lower edge of the Hermite function. * @param edge1 Specifies the value of the upper edge of the Hermite function. * @param a Specifies the source value for interpolation. */ constexpr double smoothstep(double edge0, double edge1, double a) { … } /** * Sine function where multiples of 90 degrees come out exact. * * @param x Angle in degrees. */ inline double sind(double x) { … } /** * Cosine function where multiples of 90 degrees come out exact. * * @param x Angle in degrees. */ inline double cosd(double x) { … } /** @} */ /** @addtogroup Structs * @ingroup Core * @brief Miscellaneous data structures for interfacing with this library. * @{ */ /** * @brief Single polygon contour, wound CCW. First and last point are implicitly * connected. Should ensure all input is * [ε-valid](https://github.com/elalish/manifold/wiki/Manifold-Library#definition-of-%CE%B5-valid). */ SimplePolygon; /** * @brief Set of polygons with holes. Order of contours is arbitrary. Can * contain any depth of nested holes and any number of separate polygons. Should * ensure all input is * [ε-valid](https://github.com/elalish/manifold/wiki/Manifold-Library#definition-of-%CE%B5-valid). */ Polygons; /** * @brief Defines which edges to sharpen and how much for the Manifold.Smooth() * constructor. */ struct Smoothness { … }; /** * @brief Axis-aligned 3D box, primarily for bounding. */ struct Box { … }; /** * @brief Axis-aligned 2D box, primarily for bounding. */ struct Rect { … }; /** * @brief Boolean operation type: Add (Union), Subtract (Difference), and * Intersect. */ enum class OpType { … }; constexpr int DEFAULT_SEGMENTS = …; constexpr double DEFAULT_ANGLE = …; constexpr double DEFAULT_LENGTH = …; /** * @brief These static properties control how circular shapes are quantized by * default on construction. * * If circularSegments is specified, it takes * precedence. If it is zero, then instead the minimum is used of the segments * calculated based on edge length and angle, rounded up to the nearest * multiple of four. To get numbers not divisible by four, circularSegments * must be specified. */ class Quality { … }; /** @} */ /** @addtogroup Debug * @ingroup Optional * @{ */ /** * @brief Global parameters that control debugging output. Only has an * effect when compiled with the MANIFOLD_DEBUG flag. */ struct ExecutionParams { … }; /** @} */ #ifdef MANIFOLD_DEBUG inline std::ostream& operator<<(std::ostream& stream, const Box& box) { return stream << "min: " << box.min << ", " << "max: " << box.max; } inline std::ostream& operator<<(std::ostream& stream, const Rect& box) { return stream << "min: " << box.min << ", " << "max: " << box.max; } /** * Print the contents of this vector to standard output. Only exists if compiled * with MANIFOLD_DEBUG flag. */ template <typename T> void Dump(const std::vector<T>& vec) { std::cout << "Vec = " << std::endl; for (size_t i = 0; i < vec.size(); ++i) { std::cout << i << ", " << vec[i] << ", " << std::endl; } std::cout << std::endl; } template <typename T> void Diff(const std::vector<T>& a, const std::vector<T>& b) { std::cout << "Diff = " << std::endl; if (a.size() != b.size()) { std::cout << "a and b must have the same length, aborting Diff" << std::endl; return; } for (size_t i = 0; i < a.size(); ++i) { if (a[i] != b[i]) std::cout << i << ": " << a[i] << ", " << b[i] << std::endl; } std::cout << std::endl; } struct Timer { std::chrono::high_resolution_clock::time_point start, end; void Start() { start = std::chrono::high_resolution_clock::now(); } void Stop() { end = std::chrono::high_resolution_clock::now(); } float Elapsed() { return std::chrono::duration_cast<std::chrono::milliseconds>(end - start) .count(); } void Print(std::string message) { std::cout << "----------- " << std::round(Elapsed()) << " ms for " << message << std::endl; } }; #endif } // namespace manifold