1 // Copyright 2016-2021 Doug Moen 2 // Licensed under the Apache License, version 2.0 3 // See accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0 4 5 #ifndef LIBCURV_SHAPE_H 6 #define LIBCURV_SHAPE_H 7 8 #include <libcurv/frame.h> 9 #include <libcurv/sc_compiler.h> 10 #include <libcurv/location.h> 11 #include <libcurv/vec.h> 12 #include <cmath> 13 14 namespace curv { 15 16 struct Function; 17 struct Context; 18 struct System; 19 struct Program; 20 struct Phrase; 21 struct Render_Opts; 22 23 struct Viewed_Shape; 24 25 // axis aligned bounding box 26 struct BBox 27 { 28 double xmin, ymin, zmin; 29 double xmax, ymax, zmax; empty2BBox30 bool empty2() const { 31 return (xmin >= xmax || ymin >= ymax); 32 } empty3BBox33 bool empty3() const { 34 return (xmin >= xmax || ymin >= ymax || zmin >= zmax); 35 } infinite2BBox36 bool infinite2() const { 37 return (xmin == -INFINITY || ymin == -INFINITY || 38 xmax == +INFINITY || ymax == +INFINITY); 39 } infinite3BBox40 bool infinite3() const { 41 return (xmin == -INFINITY || ymin == -INFINITY || zmin == -INFINITY || 42 xmax == +INFINITY || ymax == +INFINITY || zmax == +INFINITY); 43 } size2BBox44 glm::dvec2 size2() const { 45 return glm::dvec2(xmax - xmin, ymax - ymin); 46 } size3BBox47 glm::dvec3 size3() const { 48 return glm::dvec3(xmax - xmin, ymax - ymin, zmax - zmin); 49 } 50 static BBox from_value(Value, const Context&); 51 }; 52 53 struct Shape 54 { 55 bool is_2d_; 56 bool is_3d_; 57 BBox bbox_; 58 virtual double dist(double x, double y, double z, double t) = 0; 59 virtual Vec3 colour(double x, double y, double z, double t) = 0; 60 }; 61 62 struct Shape_Program final : public Shape 63 { 64 // is_shape is initially false, becomes true after recognize() succeeds. is_shapefinal65 bool is_shape() const { return is_2d_ || is_3d_; } 66 67 // implement PROGRAM api for use with At_Program 68 Source_State& sstate_; 69 Shared<const Phrase> nub_; // source code of shape expression systemfinal70 System& system() const { return sstate_.system_; } syntaxfinal71 const Phrase& syntax() const { return *nub_; } 72 73 // shape fields, filled in by recognize() 74 Shared<Record> record_; 75 Shared<const Function> dist_fun_; 76 Shared<const Function> colour_fun_; 77 std::unique_ptr<Frame> dist_frame_; 78 std::unique_ptr<Frame> colour_frame_; 79 80 Viewed_Shape* viewed_shape_ = nullptr; 81 82 Shape_Program(Program&); 83 Shape_Programfinal84 Shape_Program(Source_State& sstate, Shared<const Phrase> nub) 85 : sstate_(sstate), nub_(move(nub)) 86 {} 87 88 // If the value is a shape, fill in the shape fields and return true. 89 // The Render_Opts argument is modified using data from shape.render, 90 // if the recognized shape has a render field. 91 // Used with the first constructor. 92 bool recognize(Value, Render_Opts*); 93 94 // This is called from the Viewed_Shape constructor, after a 95 // parametric shape has been recognized. We construct a Shape_Program 96 // that describes a parametric shape. 97 Shape_Program(const Shape_Program&, Shared<Record>, Viewed_Shape*); 98 99 // Invoke the shape's `dist` function. 100 double dist(double x, double y, double z, double t); 101 102 // Invoke the shape's `colour` function. 103 Vec3 colour(double x, double y, double z, double t); 104 }; 105 106 } // namespace 107 #endif // header guard 108