File indexing completed on 2024-05-12 03:52:09

0001 /*******************************************************************************
0002 * Author    :  Angus Johnson                                                   *
0003 * Date      :  24 September 2023                                               *
0004 * Website   :  http://www.angusj.com                                           *
0005 * Copyright :  Angus Johnson 2010-2023                                         *
0006 * Purpose   :  Path Offset (Inflate/Shrink)                                    *
0007 * License   :  http://www.boost.org/LICENSE_1_0.txt                            *
0008 *******************************************************************************/
0009 
0010 #ifndef CLIPPER_OFFSET_H_
0011 #define CLIPPER_OFFSET_H_
0012 
0013 #include "clipper.core.h"
0014 #include "clipper.engine.h"
0015 
0016 namespace Clipper2Lib {
0017 
0018 enum class JoinType { Square, Bevel, Round, Miter };
0019 //Square : Joins are 'squared' at exactly the offset distance (more complex code)
0020 //Bevel  : Similar to Square, but the offset distance varies with angle (simple code & faster)
0021 
0022 enum class EndType {Polygon, Joined, Butt, Square, Round};
0023 //Butt   : offsets both sides of a path, with square blunt ends
0024 //Square : offsets both sides of a path, with square extended ends
0025 //Round  : offsets both sides of a path, with round extended ends
0026 //Joined : offsets both sides of a path, with joined ends
0027 //Polygon: offsets only one side of a closed path
0028 
0029 typedef std::function<double(const Path64& path, const PathD& path_normals, size_t curr_idx, size_t prev_idx)> DeltaCallback64;
0030 
0031 class ClipperOffset {
0032 private:
0033 
0034     class Group {
0035     public:
0036         Paths64 paths_in;
0037         Paths64 paths_out;
0038         Path64 path;
0039         bool is_reversed = false;
0040         JoinType join_type;
0041         EndType end_type;
0042         Group(const Paths64& _paths, JoinType _join_type, EndType _end_type) :
0043             paths_in(_paths), join_type(_join_type), end_type(_end_type) {}
0044     };
0045 
0046     int   error_code_ = 0;
0047     double delta_ = 0.0;
0048     double group_delta_ = 0.0;
0049     double temp_lim_ = 0.0;
0050     double steps_per_rad_ = 0.0;
0051     double step_sin_ = 0.0;
0052     double step_cos_ = 0.0;
0053     PathD norms;
0054     Paths64 solution;
0055     std::vector<Group> groups_;
0056     JoinType join_type_ = JoinType::Bevel;
0057     EndType end_type_ = EndType::Polygon;
0058 
0059     double miter_limit_ = 0.0;
0060     double arc_tolerance_ = 0.0;
0061     bool preserve_collinear_ = false;
0062     bool reverse_solution_ = false;
0063 
0064 #ifdef USINGZ
0065     ZCallback64 zCallback64_ = nullptr;
0066 #endif
0067     DeltaCallback64 deltaCallback64_ = nullptr;
0068 
0069     void DoBevel(Group& group, const Path64& path, size_t j, size_t k);
0070     void DoSquare(Group& group, const Path64& path, size_t j, size_t k);
0071     void DoMiter(Group& group, const Path64& path, size_t j, size_t k, double cos_a);
0072     void DoRound(Group& group, const Path64& path, size_t j, size_t k, double angle);
0073     void BuildNormals(const Path64& path);
0074     void OffsetPolygon(Group& group, Path64& path);
0075     void OffsetOpenJoined(Group& group, Path64& path);
0076     void OffsetOpenPath(Group& group, Path64& path);
0077     void OffsetPoint(Group& group, Path64& path, size_t j, size_t k);
0078     void DoGroupOffset(Group &group);
0079     void ExecuteInternal(double delta);
0080 public:
0081     explicit ClipperOffset(double miter_limit = 2.0,
0082         double arc_tolerance = 0.0,
0083         bool preserve_collinear = false, 
0084         bool reverse_solution = false) :
0085         miter_limit_(miter_limit), arc_tolerance_(arc_tolerance),
0086         preserve_collinear_(preserve_collinear),
0087         reverse_solution_(reverse_solution) { };
0088 
0089     ~ClipperOffset() { Clear(); };
0090 
0091     int ErrorCode() { return error_code_; };
0092     void AddPath(const Path64& path, JoinType jt_, EndType et_);
0093     void AddPaths(const Paths64& paths, JoinType jt_, EndType et_);
0094     void Clear() { groups_.clear(); norms.clear(); };
0095     
0096     void Execute(double delta, Paths64& paths);
0097     void Execute(double delta, PolyTree64& polytree);
0098     void Execute(DeltaCallback64 delta_cb, Paths64& paths);
0099 
0100     double MiterLimit() const { return miter_limit_; }
0101     void MiterLimit(double miter_limit) { miter_limit_ = miter_limit; }
0102 
0103     //ArcTolerance: needed for rounded offsets (See offset_triginometry2.svg)
0104     double ArcTolerance() const { return arc_tolerance_; }
0105     void ArcTolerance(double arc_tolerance) { arc_tolerance_ = arc_tolerance; }
0106 
0107     bool PreserveCollinear() const { return preserve_collinear_; }
0108     void PreserveCollinear(bool preserve_collinear){preserve_collinear_ = preserve_collinear;}
0109     
0110     bool ReverseSolution() const { return reverse_solution_; }
0111     void ReverseSolution(bool reverse_solution) {reverse_solution_ = reverse_solution;}
0112 
0113 #ifdef USINGZ
0114     void SetZCallback(ZCallback64 cb) { zCallback64_ = cb; }
0115 #endif
0116     void SetDeltaCallback(DeltaCallback64 cb) { deltaCallback64_ = cb; }
0117 
0118 };
0119 
0120 }
0121 #endif /* CLIPPER_OFFSET_H_ */