Skip to content
Commits on Source (6)
......@@ -13,6 +13,6 @@ NamespaceIndentation: None
PointerBindsToType: true
SpacesInParentheses: false
BreakBeforeBraces: Attach
ColumnLimit: 100
ColumnLimit: 120
Cpp11BracedListStyle: false
SpacesBeforeTrailingComments: 1
---
Checks: '*,-cert-err58-cpp,-modernize-use-trailing-return-type,-cppcoreguidelines-avoid-magic-numbers,-readability-magic-numbers,-fuchsia-default-arguments-*'
WarningsAsErrors: '*'
HeaderFilterRegex: '.*\/include\/mapbox\/geometry\/wagyu\/.*'
AnalyzeTemporaryDtors: false
CheckOptions:
- key: google-readability-braces-around-statements.ShortStatementLines
value: '1'
- key: google-readability-function-size.StatementThreshold
value: '800'
- key: google-readability-namespace-comments.ShortNamespaceLines
value: '10'
- key: google-readability-namespace-comments.SpacesBeforeComments
value: '2'
- key: modernize-loop-convert.MaxCopySize
value: '16'
- key: modernize-loop-convert.MinConfidence
value: reasonable
- key: modernize-loop-convert.NamingStyle
value: CamelCase
- key: modernize-pass-by-value.IncludeStyle
value: llvm
- key: modernize-replace-auto-ptr.IncludeStyle
value: llvm
- key: modernize-use-nullptr.NullMacros
value: 'NULL'
...
......@@ -6,3 +6,7 @@ build
mason_packages
*.dSYM
tests/output-polyjson
cmake-build
.mason
local.env
.toolchain
......@@ -4,113 +4,79 @@ sudo: false
matrix:
include:
# clang-tidy/format specific job
- os: linux
env: CXX=g++-4.9
addons:
apt:
sources: [ 'ubuntu-toolchain-r-test' ]
packages: [ 'g++-4.9' ]
# override before_install to use apt installed compiler
# rather than mason installed clang++
before_install:
- which ${CXX}
- os: linux
env: CXX=g++-5
addons:
apt:
sources: [ 'ubuntu-toolchain-r-test' ]
packages: [ 'g++-5' ]
# override before_install to use apt installed compiler
# rather than mason installed clang++
before_install:
- which ${CXX}
- os: linux
env: CXX=g++-6
addons:
apt:
sources: [ 'ubuntu-toolchain-r-test' ]
packages: [ 'g++-6' ]
# override before_install to use apt installed compiler
# rather than mason installed clang++
before_install:
- which ${CXX}
- os: linux
env: CXX=clang++ CXXFLAGS="-flto"
addons:
apt:
sources: [ 'ubuntu-toolchain-r-test' ]
packages: [ 'libstdc++-5-dev' ]
- os: linux
env: CXX=clang++ LLVM_VERSION="4.0.0" CXXFLAGS="-flto"
sudo: false
env: CLANG_FORMAT
addons:
apt:
sources: [ 'ubuntu-toolchain-r-test' ]
packages: [ 'libstdc++-5-dev' ]
packages: [ 'libstdc++6', 'libstdc++-5-dev' ]
script:
- make format
- os: linux
env: CXX=clang++ CXXFLAGS="-flto -fsanitize=cfi -fvisibility=hidden"
sudo: false
env: CXX=g++-4.9
addons:
apt:
sources: [ 'ubuntu-toolchain-r-test' ]
packages: [ 'libstdc++-5-dev' ]
packages: [ 'g++-4.9' ]
- os: linux
env: CXX=clang++ CXXFLAGS="-fsanitize=address -fsanitize-address-use-after-scope -fno-omit-frame-pointer -fno-common"
sudo: false
env: CXX=g++-5
addons:
apt:
sources: [ 'ubuntu-toolchain-r-test' ]
packages: [ 'libstdc++-5-dev' ]
packages: [ 'g++-5' ]
- os: linux
env: CXX=clang++ CXXFLAGS="-fsanitize=undefined"
sudo: false
env: CXX=clang++
addons:
apt:
sources: [ 'ubuntu-toolchain-r-test' ]
packages: [ 'libstdc++-5-dev' ]
packages: [ 'libstdc++6', 'libstdc++-5-dev' ]
- os: linux
env: CXX=clang++ CXXFLAGS="-fsanitize=integer"
sudo: required # workaround https://github.com/mapbox/node-cpp-skel/issues/93
env: CXXFLAGS="-fsanitize=address,undefined,integer -fno-sanitize-recover=all"
addons:
apt:
sources: [ 'ubuntu-toolchain-r-test' ]
packages: [ 'libstdc++-5-dev' ]
# OS X / apple clang / xcode 7.x
- os: osx
osx_image: xcode7.3
env: CXX=clang++
# override before_install to use apple clang
before_install:
- which ${CXX}
# OS X / mason clang 4.0.0 / xcode 8.x
- os: osx
osx_image: xcode8.2
env: CXX=clang++ LLVM_VERSION="4.0.0"
packages: [ 'libstdc++6', 'libstdc++-5-dev' ]
# coverage build
- os: linux
env: CXX=clang++ COVERAGE=true CXXFLAGS="--coverage"
sudo: false
env: CXXFLAGS="--coverage" LDFLAGS="--coverage"
addons:
apt:
sources: [ 'ubuntu-toolchain-r-test' ]
packages: [ 'libstdc++-5-dev' ]
# override before_script to run coverage
before_script:
- make debug
- ./mason.sh install llvm-cov 3.9.1
- export PATH=$(./mason.sh prefix llvm-cov 3.9.1)/bin:${PATH}
- which llvm-cov
- curl -S -f https://codecov.io/bash -o codecov
- chmod +x codecov
- ./codecov -x "llvm-cov gcov" -Z
packages: [ 'libstdc++6', 'libstdc++-5-dev' ]
script:
- make debug
- make test
# MASON_LLVM_RELEASE comes from the setup.sh script
- mason install llvm-cov ${MASON_LLVM_RELEASE}
- mason link llvm-cov ${MASON_LLVM_RELEASE}
- curl -S -f https://codecov.io/bash -o codecov
- chmod +x codecov
- ./codecov -x "llvm-cov gcov -l" -Z
before_install:
- git submodule update --init
- export LLVM_VERSION="${LLVM_VERSION:-3.9.1}"
- |
if [[ ${CXX} == "clang++" ]]; then
./mason.sh install clang++ ${LLVM_VERSION}
export PATH=$(./mason.sh prefix clang++ ${LLVM_VERSION})/bin:${PATH}
./mason.sh install binutils 2.27
export PATH=$(./mason.sh prefix binutils 2.27)/bin:${PATH}
fi
- which ${CXX}
env:
global:
- CMAKE_VERSION="3.8.2"
before_script:
- make test
- make clean
- make debug
install:
# set up the environment by installing mason and clang++
- ./scripts/setup.sh --config local.env
# put mason and clang++ on PATH
- source local.env
- mason install cmake ${CMAKE_VERSION}
- mason link cmake ${CMAKE_VERSION}
- which cmake
script:
- make release
- make test
- make clean
- make debug
- make test
- make clean
......@@ -47,3 +47,7 @@
## 0.4.3
- Use `::llround()` instead of `std::llround()` for old libstdc++ compatibility.
## 0.5.0
- Fixed various issues associated with floating point data and comparisions of numbers. This in effect solves some weird intersection bugs and situations where the bounds are not properly sorted. This can result in a variety of different crashes and bad results in the final output in very rare situations.
cmake_minimum_required(VERSION 3.8)
project(hpp_skel LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED on)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/mason.cmake)
option(WERROR "Add -Werror flag to build (turns warnings into errors)" ON)
# configure optimization
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
set(OPTIMIZATION_FLAGS "-O0 -DDEBUG")
message("-- Configuring debug build")
else()
set(OPTIMIZATION_FLAGS "-O3 -DNDEBUG")
message("-- Configuring release build")
endif()
# Enable extra warnings to adhere to https://github.com/mapbox/cpp/issues/37
set(DESIRED_WARNINGS "-Wall -Wextra -Wconversion -Wunreachable-code -Wuninitialized -pedantic-errors -Wold-style-cast -Wno-error=unused-variable -Wshadow -Wfloat-equal -Weffc++")
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
set(DESIRED_WARNINGS "${DESIRED_WARNINGS} -Wmost")
endif()
# Note: -D_GLIBCXX_USE_CXX11_ABI=0 is needed to support mason packages that are precompiled libs
# Currently we only depend on a header only library, but this will help avoid issues when more libs are added via mason
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OPTIMIZATION_FLAGS} -D_GLIBCXX_USE_CXX11_ABI=0 ${DESIRED_WARNINGS}")
if (WERROR)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror")
endif()
# mason_use is a mason function within the mason.cmake file and provides ready-to-go vars, like "STATIC_LIBS" and "INCLUDE_DIRS"
mason_use(boost_libfilesystem VERSION 1.72.0)
mason_use(boost_libsystem VERSION 1.72.0)
mason_use(boost VERSION 1.72.0 HEADER_ONLY)
include_directories(SYSTEM ${MASON_PACKAGE_boost_INCLUDE_DIRS})
mason_use(rapidjson VERSION 1.1.0 HEADER_ONLY)
include_directories(SYSTEM ${MASON_PACKAGE_rapidjson_INCLUDE_DIRS})
mason_use(geometry VERSION 1.0.0 HEADER_ONLY)
include_directories(SYSTEM ${MASON_PACKAGE_geometry_INCLUDE_DIRS})
mason_use(catch VERSION 1.9.6 HEADER_ONLY)
include_directories(SYSTEM ${MASON_PACKAGE_catch_INCLUDE_DIRS})
mason_use(benchmark VERSION 1.4.1)
include_directories(SYSTEM ${MASON_PACKAGE_benchmark_INCLUDE_DIRS})
include_directories("${PROJECT_SOURCE_DIR}/include")
file(GLOB TEST_SOURCES tests/unit/*.cpp)
add_executable(unit-tests ${TEST_SOURCES})
file(GLOB TEST_SOURCES tests/fixtures/*.cpp)
add_executable(fixture-tests ${TEST_SOURCES})
file(GLOB FUZZER_SOURCES fuzzer/*.cpp)
add_executable(fuzzer-tests ${FUZZER_SOURCES})
# libbenchmark.a supports threads and therefore needs pthread support
find_package(Threads REQUIRED)
file(GLOB BENCH_SOURCES bench/*.cpp)
add_executable(bench-tests ${BENCH_SOURCES})
# link benchmark static library to the bench-tests binary so the bench tests know where to find the benchmark impl code
target_link_libraries(bench-tests ${MASON_PACKAGE_benchmark_STATIC_LIBS} ${MASON_PACKAGE_boost_libfilesystem_STATIC_LIBS} ${MASON_PACKAGE_boost_libsystem_STATIC_LIBS} ${CMAKE_THREAD_LIBS_INIT})
......@@ -7,12 +7,14 @@ Date : 2 July 2015
Website : http://www.angusj.com
Copyright for portions of the derived code in the Wagyu library are held
by Angus Johnson, 2010-2015. All other copyright for the Wagyu Library are held by
Mapbox, 2016. This code is published in accordance with, and retains the same license
as the Clipper Library by Angus Johnson.
by Angus Johnson, 2010-2015. Copyright for the "include/mapbox/geometry/wagyu/almost_equal.hpp"
file is held by Google Inc and its license is listed at the top of that file.
All other copyright for the Wagyu Library are held by Mapbox, 2016. This code
is published in accordance with, and retains the same license as the Clipper
Library by Angus Johnson.
Copyright (c) 2010-2015, Angus Johnson
Copyright (c) 2016, Mapbox
Copyright (c) 2016-2020, Mapbox
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
......
BOOST_VERSION=1.63.0
RAPIDJSON_VERSION=1.1.0
GEOMETRY_VERSION=0.9.0
CC := $(CC)
CXX := $(CXX)
CXXFLAGS := $(CXXFLAGS) -Iinclude -isystem mason_packages/headers/boost/$(BOOST_VERSION)/include -isystem mason_packages/headers/rapidjson/$(RAPIDJSON_VERSION)/include -isystem mason_packages/headers/geometry/$(GEOMETRY_VERSION)/include -std=c++11
RELEASE_FLAGS := -O3 -DNDEBUG
WARNING_FLAGS := -Wall -Wextra -Weffc++ -Werror -Wsign-compare -Wfloat-equal -Wshadow -Wconversion
DEBUG_FLAGS := -g -O0 -DDEBUG -fno-inline-functions -fno-omit-frame-pointer
CLIPPER_REVISION=ac8d6bf2517f46c05647b5c19cac113fb180ffb4
ANGUS_DEFINES := -D'CLIPPER_INTPOINT_IMPL=mapbox::geometry::point<cInt>' -D'CLIPPER_PATH_IMPL=mapbox::geometry::linear_ring<cInt>' -D'CLIPPER_PATHS_IMPL=mapbox::geometry::polygon<cInt>' -D'CLIPPER_IMPL_INCLUDE=<mapbox/geometry/polygon.hpp>'
# Whether to turn compiler warnings into errors
export WERROR ?= true
export BUILD_DIR ?= cmake-build
default: release
default: test
release:
mkdir -p ./$(BUILD_DIR) && cd ./$(BUILD_DIR) && cmake ../ -DCMAKE_BUILD_TYPE=Release -DWERROR=$(WERROR) && VERBOSE=1 cmake --build .
mason_packages/headers/boost/$(BOOST_VERSION)/include:
./mason.sh install --header-only boost $(BOOST_VERSION)
debug:
mkdir -p ./$(BUILD_DIR) && cd ./$(BUILD_DIR) && cmake ../ -DCMAKE_BUILD_TYPE=Debug -DWERROR=$(WERROR) && VERBOSE=1 cmake --build .
mason_packages/headers/rapidjson/$(RAPIDJSON_VERSION)/include:
./mason.sh install --header-only rapidjson $(RAPIDJSON_VERSION)
test:
@if [ -f ./$(BUILD_DIR)/unit-tests ]; then ./$(BUILD_DIR)/unit-tests; ./tests/run-geometry-tests.sh ./$(BUILD_DIR)/fixture-tests; else echo "Please run 'make release' or 'make debug' first" && exit 1; fi
mason_packages/headers/geometry/$(GEOMETRY_VERSION)/include:
./mason.sh install --header-only geometry $(GEOMETRY_VERSION)
bench:
@if [ -f ./$(BUILD_DIR)/bench-tests ]; then ./$(BUILD_DIR)/bench-tests; else echo "Please run 'make release' or 'make debug' first" && exit 1; fi
deps: mason_packages/headers/boost/$(BOOST_VERSION)/include mason_packages/headers/rapidjson/$(RAPIDJSON_VERSION)/include mason_packages/headers/geometry/$(GEOMETRY_VERSION)/include
tidy:
./scripts/clang-tidy.sh
build-test: tests/* include/mapbox/geometry/* deps Makefile
$(CXX) $(RELEASE_FLAGS) tests/test.cpp tests/unit/*.cpp $(WARNING_FLAGS) $(CXXFLAGS) -isystem ./tests -o test
build-debug: tests/* include/mapbox/geometry/* deps Makefile
$(CXX) $(DEBUG_FLAGS) tests/test.cpp tests/unit/*.cpp $(WARNING_FLAGS) $(CXXFLAGS) -isystem ./tests -o test
build-fixture-tester-r:
$(CXX) $(RELEASE_FLAGS) tests/fixture-tester.cpp $(WARNING_FLAGS) $(CXXFLAGS) -o fixture-tester
build-fixture-tester:
$(CXX) $(DEBUG_FLAGS) tests/fixture-tester.cpp $(WARNING_FLAGS) $(CXXFLAGS) -o fixture-tester
build-fuzzer-r:
$(CXX) $(RELEASE_FLAGS) tests/fuzzer.cpp $(WARNING_FLAGS) $(CXXFLAGS) -o fuzzer
build-fuzzer:
$(CXX) $(DEBUG_FLAGS) tests/fuzzer.cpp $(WARNING_FLAGS) $(CXXFLAGS) -o fuzzer
quick_clip_profile: tests/quick_clip_profile.cpp
$(CXX) $(DEBUG_FLAGS) tests/quick_clip_profile.cpp $(WARNING_FLAGS) $(CXXFLAGS) -o quick_clip_profile
# angus clipper for benchmark
./deps/clipper:
git clone https://github.com/mapnik/clipper.git -b r496-mapnik ./deps/clipper && cd ./deps/clipper && git checkout $(CLIPPER_REVISION) && ./cpp/fix_members.sh
build-benchmark: ./deps/clipper
$(CXX) -c $(RELEASE_FLAGS) deps/clipper/cpp/clipper.cpp $(ANGUS_DEFINES) $(CXXFLAGS) -isystem ./deps/clipper/cpp
$(CXX) -c $(RELEASE_FLAGS) tests/benchmark.cpp $(ANGUS_DEFINES) $(CXXFLAGS) -isystem ./deps/clipper/cpp
$(CXX) $(RELEASE_FLAGS) clipper.o benchmark.o $(CXXFLAGS) -o benchmark
build-benchmark-d: ./deps/clipper
$(CXX) -c $(DEBUG_FLAGS) deps/clipper/cpp/clipper.cpp $(ANGUS_DEFINES) $(CXXFLAGS) -isystem ./deps/clipper/cpp
$(CXX) -c $(DEBUG_FLAGS) tests/benchmark.cpp $(ANGUS_DEFINES) $(CXXFLAGS) -isystem ./deps/clipper/cpp
$(CXX) $(DEBUG_FLAGS) clipper.o benchmark.o $(CXXFLAGS) -o benchmark
benchmark: build-benchmark
./tests/run-benchmark-tests.sh ./benchmark
test: build-test build-fixture-tester-r
./test
./tests/run-geometry-tests.sh ./fixture-tester
debug: build-debug build-fixture-tester
./test
./tests/run-geometry-tests.sh ./fixture-tester
coverage: Makefile
coverage:
./scripts/coverage.sh
fuzzer: build-fuzzer
./fuzzer
# avoids tools from getting deleted by make when it fails or you ctrl-c process
.PRECIOUS: fuzzer benchmark fixture-tester test
clean:
rm -rf *dSYM
rm -rf deps/
rm -f *.o
rm -f benchmark
rm -f test
rm -f fuzzer
rm -f fixture-tester
rm -rf ./$(BUILD_DIR)
# remove remains from running 'make coverage'
rm -f *.profraw
rm -f *.profdata
@echo "run 'make distclean' to also clear mason_packages, .mason, and .toolchain directories"
distclean: clean
rm -rf ./mason_packages
rm -rf mason_packages
# remove remains from running './scripts/setup.sh'
rm -rf .mason
rm -rf .toolchain
rm -f local.env
format:
./scripts/format.sh
indent:
clang-format -i $(filter-out ./tests/catch.hpp, $(shell find . -path ./mason_packages -prune -o '(' -name '*.hpp' -o -name '*.cpp' ')' -type f -print))
.PHONY: test bench
......@@ -2,6 +2,7 @@
[![Build Status](https://travis-ci.org/mapbox/wagyu.svg?branch=master)](https://travis-ci.org/mapbox/wagyu)
[![codecov](https://codecov.io/gh/mapbox/wagyu/branch/master/graph/badge.svg)](https://codecov.io/gh/mapbox/wagyu)
[![badge](https://mapbox.s3.amazonaws.com/cpp-assets/hpp-skel-badge_blue.svg)](https://github.com/mapbox/hpp-skel)
Wagyu is a general library for the following basic geometric operations:
......
This diff is collapsed.
/*******************************************************************************
* *
* Author : Angus Johnson *
* Version : 6.4.0 *
* Date : 2 July 2015 *
* Website : http://www.angusj.com *
* Copyright : Angus Johnson 2010-2015 *
* *
* License: *
* Use, modification & distribution is subject to Boost Software License Ver 1. *
* http://www.boost.org/LICENSE_1_0.txt *
* *
* Attributions: *
* The code in this library is an extension of Bala Vatti's clipping algorithm: *
* "A generic solution to polygon clipping" *
* Communications of the ACM, Vol 35, Issue 7 (July 1992) pp 56-63. *
* http://portal.acm.org/citation.cfm?id=129906 *
* *
* Computer graphics and geometric modeling: implementation and algorithms *
* By Max K. Agoston *
* Springer; 1 edition (January 4, 2005) *
* http://books.google.com/books?q=vatti+clipping+agoston *
* *
* See also: *
* "Polygon Offsetting by Computing Winding Numbers" *
* Paper no. DETC2005-85513 pp. 565-575 *
* ASME 2005 International Design Engineering Technical Conferences *
* and Computers and Information in Engineering Conference (IDETC/CIE2005) *
* September 24-28, 2005 , Long Beach, California, USA *
* http://www.me.berkeley.edu/~mcmains/pubs/DAC05OffsetPolygon.pdf *
* *
*******************************************************************************/
#ifndef clipper_hpp
#define clipper_hpp
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpragmas"
#pragma GCC diagnostic ignored "-Wold-style-cast"
#pragma GCC diagnostic ignored "-Weffc++"
#define CLIPPER_INTPOINT_IMPL mapbox::geometry::point<cInt>
#define CLIPPER_PATH_IMPL mapbox::geometry::linear_ring<cInt>
#define CLIPPER_PATHS_IMPL mapbox::geometry::polygon<cInt>
#define CLIPPER_IMPL_INCLUDE "mapbox/geometry/polygon.hpp"
#define CLIPPER_VERSION "6.2.6"
// use_int32: When enabled 32bit ints are used instead of 64bit ints. This
// improve performance but coordinate values are limited to the range +/- 46340
//#define use_int32
// use_xyz: adds a Z member to IntPoint. Adds a minor cost to perfomance.
//#define use_xyz
// use_lines: Enables line clipping. Adds a very minor cost to performance.
//#define use_lines
// use_deprecated: Enables temporary support for the obsolete functions
//#define use_deprecated
#include <cstdlib>
#include <cstring>
#include <functional>
#include <list>
#include <ostream>
#include <queue>
#include <set>
#include <stdexcept>
#include <unordered_map>
#include <vector>
#if defined(CLIPPER_IMPL_INCLUDE)
#include CLIPPER_IMPL_INCLUDE
#endif
namespace ClipperLib {
enum ClipType { ctIntersection, ctUnion, ctDifference, ctXor };
enum PolyType { ptSubject, ptClip };
// By far the most widely used winding rules for polygon filling are
// EvenOdd & NonZero (GDI, GDI+, XLib, OpenGL, Cairo, AGG, Quartz, SVG, Gr32)
// Others rules include Positive, Negative and ABS_GTR_EQ_TWO (only in OpenGL)
// see http://glprogramming.com/red/chapter11.html
enum PolyFillType { pftEvenOdd, pftNonZero, pftPositive, pftNegative };
#ifdef use_int32
typedef int cInt;
static cInt const loRange = 0x7FFF;
static cInt const hiRange = 0x7FFF;
#else
typedef std::int64_t cInt;
static cInt const loRange = 0x3FFFFFFF;
static cInt const hiRange = 0x3FFFFFFFFFFFFFFFLL;
typedef signed long long long64; // used by Int128 class
typedef unsigned long long ulong64;
#endif
#if defined(CLIPPER_INTPOINT_IMPL)
typedef CLIPPER_INTPOINT_IMPL IntPoint;
#else
struct IntPoint {
cInt x;
cInt y;
#ifdef use_xyz
cInt Z;
IntPoint(cInt _x = 0, cInt _y = 0, cInt z = 0) : x(_x), y(_y), Z(z){};
#else
IntPoint(cInt _x = 0, cInt _y = 0) : x(_x), y(_y){};
#endif
friend inline bool operator==(const IntPoint& a, const IntPoint& b) {
return a.x == b.x && a.y == b.y;
}
friend inline bool operator!=(const IntPoint& a, const IntPoint& b) {
return a.x != b.x || a.y != b.y;
}
};
#endif
//------------------------------------------------------------------------------
#if defined(CLIPPER_PATH_IMPL)
typedef CLIPPER_PATH_IMPL Path;
#else
typedef std::vector<IntPoint> Path;
#endif
#if defined(CLIPPER_PATHS_IMPL)
typedef CLIPPER_PATHS_IMPL Paths;
#else
typedef std::vector<Path> Paths;
#endif
inline Path& operator<<(Path& poly, const IntPoint& p) {
poly.push_back(p);
return poly;
}
inline Paths& operator<<(Paths& polys, const Path& p) {
polys.push_back(p);
return polys;
}
std::ostream& operator<<(std::ostream& s, const IntPoint& p);
std::ostream& operator<<(std::ostream& s, const Path& p);
std::ostream& operator<<(std::ostream& s, const Paths& p);
struct DoublePoint {
double x;
double y;
DoublePoint(double _x = 0, double _y = 0) : x(_x), y(_y) {
}
DoublePoint(IntPoint ip) : x((double)ip.x), y((double)ip.y) {
}
};
//------------------------------------------------------------------------------
#ifdef use_xyz
typedef void (*ZFillCallback)(IntPoint& e1bot, IntPoint& e1top, IntPoint& e2bot, IntPoint& e2top, IntPoint& pt);
#endif
enum InitOptions { ioReverseSolution = 1, ioStrictlySimple = 2, ioPreserveCollinear = 4 };
enum JoinType { jtSquare, jtRound, jtMiter };
enum EndType { etClosedPolygon, etClosedLine, etOpenButt, etOpenSquare, etOpenRound };
class PolyNode;
typedef std::vector<PolyNode*> PolyNodes;
class PolyNode {
public:
PolyNode();
virtual ~PolyNode(){};
Path Contour;
PolyNodes Childs;
PolyNode* Parent;
PolyNode* GetNext() const;
bool IsHole() const;
bool IsOpen() const;
int ChildCount() const;
private:
unsigned Index; // node index in Parent.Childs
bool m_IsOpen;
JoinType m_jointype;
EndType m_endtype;
PolyNode* GetNextSiblingUp() const;
void AddChild(PolyNode& child);
friend class Clipper; // to access Index
friend class ClipperOffset;
};
class PolyTree : public PolyNode {
public:
~PolyTree() {
Clear();
};
PolyNode* GetFirst() const;
void Clear();
int Total() const;
private:
PolyNodes AllNodes;
friend class Clipper; // to access AllNodes
};
bool Orientation(const Path& poly);
double Area(const Path& poly);
int PointInPolygon(const IntPoint& pt, const Path& path);
void SimplifyPolygon(const Path& in_poly, Paths& out_polys, PolyFillType fillType = pftEvenOdd);
void SimplifyPolygons(const Paths& in_polys, Paths& out_polys, PolyFillType fillType = pftEvenOdd);
void SimplifyPolygons(Paths& polys, PolyFillType fillType = pftEvenOdd);
void CleanPolygon(const Path& in_poly, Path& out_poly, double distance = 1.415);
void CleanPolygon(Path& poly, double distance = 1.415);
void CleanPolygons(const Paths& in_polys, Paths& out_polys, double distance = 1.415);
void CleanPolygons(Paths& polys, double distance = 1.415);
void MinkowskiSum(const Path& pattern, const Path& path, Paths& solution, bool pathIsClosed);
void MinkowskiSum(const Path& pattern, const Paths& paths, Paths& solution, bool pathIsClosed);
void MinkowskiDiff(const Path& poly1, const Path& poly2, Paths& solution);
void PolyTreeToPaths(const PolyTree& polytree, Paths& paths);
void ClosedPathsFromPolyTree(const PolyTree& polytree, Paths& paths);
void OpenPathsFromPolyTree(PolyTree& polytree, Paths& paths);
void ReversePath(Path& p);
void ReversePaths(Paths& p);
struct IntRect {
cInt left;
cInt top;
cInt right;
cInt bottom;
};
// enums that are used internally ...
enum EdgeSide { esLeft = 1, esRight = 2 };
// forward declarations (for stuff used internally) ...
struct TEdge;
struct IntersectNode;
struct LocalMinimum;
struct OutPt;
struct OutRec;
struct Join;
struct OutPtIntersect;
typedef std::vector<OutRec*> PolyOutList;
typedef std::vector<TEdge*> EdgeList;
typedef std::vector<Join*> JoinList;
typedef std::vector<IntersectNode*> IntersectList;
//------------------------------------------------------------------------------
// ClipperBase is the ancestor to the Clipper class. It should not be
// instantiated directly. This class simply abstracts the conversion of sets of
// polygon coordinates into edge objects that are stored in a LocalMinima list.
class ClipperBase {
public:
ClipperBase();
virtual ~ClipperBase();
virtual bool AddPath(const Path& pg, PolyType PolyTyp, bool Closed);
bool AddPaths(const Paths& ppg, PolyType PolyTyp, bool Closed);
virtual void Clear();
IntRect GetBounds();
bool PreserveCollinear() {
return m_PreserveCollinear;
};
void PreserveCollinear(bool value) {
m_PreserveCollinear = value;
};
protected:
void DisposeLocalMinimaList();
TEdge* AddBoundsToLML(TEdge* e, bool IsClosed);
virtual void Reset();
TEdge* ProcessBound(TEdge* E, bool NextIsForward);
void InsertScanbeam(const cInt Y);
bool PopScanbeam(cInt& Y);
bool LocalMinimaPending();
bool PopLocalMinima(cInt Y, const LocalMinimum*& locMin);
OutRec* CreateOutRec();
void DisposeAllOutRecs();
void DisposeOutRec(PolyOutList::size_type index);
void SwapPositionsInAEL(TEdge* Edge1, TEdge* Edge2);
void DeleteFromAEL(TEdge* e);
void UpdateEdgeIntoAEL(TEdge*& e);
typedef std::vector<LocalMinimum> MinimaList;
MinimaList::iterator m_CurrentLM;
MinimaList m_MinimaList;
bool m_UseFullRange;
EdgeList m_edges;
bool m_PreserveCollinear{};
bool m_HasOpenPaths{};
PolyOutList m_PolyOuts;
TEdge* m_ActiveEdges{};
typedef std::priority_queue<cInt> ScanbeamList;
ScanbeamList m_Scanbeam;
};
//------------------------------------------------------------------------------
class Clipper : public virtual ClipperBase {
public:
Clipper(int initOptions = 0);
bool Execute(ClipType clipType, Paths& solution, PolyFillType fillType = pftEvenOdd);
bool Execute(ClipType clipType, Paths& solution, PolyFillType subjFillType, PolyFillType clipFillType);
bool Execute(ClipType clipType, PolyTree& polytree, PolyFillType fillType = pftEvenOdd);
bool Execute(ClipType clipType, PolyTree& polytree, PolyFillType subjFillType, PolyFillType clipFillType);
bool ReverseSolution() {
return m_ReverseOutput;
};
void ReverseSolution(bool value) {
m_ReverseOutput = value;
};
bool StrictlySimple() {
return m_StrictSimple;
};
void StrictlySimple(bool value) {
m_StrictSimple = value;
};
// set the callback function for z value filling on intersections (otherwise Z is 0)
#ifdef use_xyz
void ZFillFunction(ZFillCallback zFillFunc);
#endif
protected:
virtual bool ExecuteInternal();
private:
JoinList m_Joins;
JoinList m_GhostJoins;
IntersectList m_IntersectList;
ClipType m_ClipType;
typedef std::list<cInt> MaximaList;
MaximaList m_Maxima;
TEdge* m_SortedEdges{};
bool m_ExecuteLocked;
PolyFillType m_ClipFillType;
PolyFillType m_SubjFillType;
bool m_ReverseOutput;
bool m_UsingPolyTree{};
bool m_StrictSimple;
#ifdef use_xyz
ZFillCallback m_ZFill; // custom callback
#endif
void SetWindingCount(TEdge& edge);
bool IsEvenOddFillType(const TEdge& edge) const;
bool IsEvenOddAltFillType(const TEdge& edge) const;
void InsertLocalMinimaIntoAEL(const cInt botY);
void InsertEdgeIntoAEL(TEdge* edge, TEdge* startEdge);
void AddEdgeToSEL(TEdge* edge);
bool PopEdgeFromSEL(TEdge*& edge);
void CopyAELToSEL();
void DeleteFromSEL(TEdge* e);
void SwapPositionsInSEL(TEdge* Edge1, TEdge* Edge2);
bool IsContributing(const TEdge& edge) const;
bool IsTopHorz(const cInt XPos);
void DoMaxima(TEdge* e);
void ProcessHorizontals();
void ProcessHorizontal(TEdge* horzEdge);
void AddLocalMaxPoly(TEdge* e1, TEdge* e2, const IntPoint& Pt);
OutPt* AddLocalMinPoly(TEdge* e1, TEdge* e2, const IntPoint& Pt);
OutRec* GetOutRec(int Idx);
void AppendPolygon(TEdge* e1, TEdge* e2);
void IntersectEdges(TEdge* e1, TEdge* e2, IntPoint& Pt);
OutPt* AddOutPt(TEdge* e, const IntPoint& pt);
OutPt* GetLastOutPt(TEdge* e);
bool ProcessIntersections(const cInt topY);
void BuildIntersectList(const cInt topY);
void ProcessIntersectList();
void ProcessEdgesAtTopOfScanbeam(const cInt topY);
void BuildResult(Paths& polys);
void BuildResult2(PolyTree& polytree);
void SetHoleState(TEdge* e, OutRec* outrec);
void DisposeIntersectNodes();
bool FixupIntersectionOrder();
void FixupOutPolygon(OutRec& outrec);
void FixupOutPolyline(OutRec& outrec);
bool IsHole(TEdge* e);
bool FindOwnerFromSplitRecs(OutRec& outRec, OutRec*& currOrfl);
void FixHoleLinkage(OutRec& outrec);
void AddJoin(OutPt* op1, OutPt* op2, const IntPoint OffPt);
void ClearJoins();
void ClearGhostJoins();
void AddGhostJoin(OutPt* op, const IntPoint OffPt);
bool JoinPoints(Join* j, OutRec* outRec1, OutRec* outRec2);
void JoinCommonEdges();
void DoSimplePolygons();
bool FindIntersectLoop(std::unordered_multimap<int, OutPtIntersect>& dupeRec,
std::list<std::pair<int, OutPtIntersect>>& iList,
OutRec* outRec_parent,
int idx_origin,
int idx_search,
std::set<int>& visited,
OutPt* orig_pt,
OutPt* prev_pt);
bool FixIntersects(std::unordered_multimap<int, OutPtIntersect>& dupeRec,
OutPt* op_j,
OutPt* op_k,
OutRec* outRec_j,
OutRec* outRec_k);
void FixupFirstLefts1(OutRec* OldOutRec, OutRec* NewOutRec);
void FixupFirstLefts2(OutRec* InnerOutRec, OutRec* OuterOutRec);
void FixupFirstLefts3(OutRec* OldOutRec, OutRec* NewOutRec);
#ifdef use_xyz
void SetZ(IntPoint& pt, TEdge& e1, TEdge& e2);
#endif
};
//------------------------------------------------------------------------------
class ClipperOffset {
public:
ClipperOffset(double miterLimit = 2.0, double arcTolerance = 0.25);
~ClipperOffset();
void AddPath(const Path& path, JoinType joinType, EndType endType);
void AddPaths(const Paths& paths, JoinType joinType, EndType endType);
void Execute(Paths& solution, double delta);
void Execute(PolyTree& solution, double delta);
void Clear();
double MiterLimit;
double ArcTolerance;
private:
Paths m_destPolys;
Path m_srcPoly;
Path m_destPoly;
std::vector<DoublePoint> m_normals;
double m_delta{}, m_sinA{}, m_sin{}, m_cos{};
double m_miterLim{}, m_StepsPerRad{};
IntPoint m_lowest;
PolyNode m_polyNodes;
void FixOrientations();
void DoOffset(double delta);
void OffsetPoint(int j, int& k, JoinType jointype);
void DoSquare(int j, int k);
void DoMiter(int j, int k, double r);
void DoRound(int j, int k);
};
//------------------------------------------------------------------------------
class clipperException : public std::exception {
public:
clipperException(const char* description) : m_descr(description) {
}
virtual ~clipperException() throw() {
}
virtual const char* what() const throw() {
return m_descr.c_str();
}
private:
std::string m_descr;
};
//------------------------------------------------------------------------------
} // namespace ClipperLib
#pragma GCC diagnostic pop
#endif // clipper_hpp
#pragma once
#include "../tests/util/fixture_utils.hpp"
#include "angus.hpp"
#include <benchmark/benchmark.h>
#include <boost/filesystem.hpp>
#include <mapbox/geometry/wagyu/wagyu.hpp>
auto BM_wagyu_fixture_union = [](benchmark::State& state, std::string subject_filename, std::string clip_filename) {
auto poly_subject = fixture_file_to_polygon<std::int64_t>(subject_filename.c_str());
auto poly_clip = fixture_file_to_polygon<std::int64_t>(clip_filename.c_str());
while (state.KeepRunning()) {
mapbox::geometry::wagyu::wagyu<std::int64_t> clipper;
clipper.add_polygon(poly_subject, mapbox::geometry::wagyu::polygon_type_subject);
clipper.add_polygon(poly_clip, mapbox::geometry::wagyu::polygon_type_clip);
mapbox::geometry::multi_polygon<std::int64_t> solution;
clipper.execute(mapbox::geometry::wagyu::clip_type_union, solution, mapbox::geometry::wagyu::fill_type_even_odd,
mapbox::geometry::wagyu::fill_type_even_odd);
}
};
auto BM_wagyu_fixture_intersection =
[](benchmark::State& state, std::string subject_filename, std::string clip_filename) {
auto poly_subject = fixture_file_to_polygon<std::int64_t>(subject_filename.c_str());
auto poly_clip = fixture_file_to_polygon<std::int64_t>(clip_filename.c_str());
while (state.KeepRunning()) {
mapbox::geometry::wagyu::wagyu<std::int64_t> clipper;
clipper.add_polygon(poly_subject, mapbox::geometry::wagyu::polygon_type_subject);
clipper.add_polygon(poly_clip, mapbox::geometry::wagyu::polygon_type_clip);
mapbox::geometry::multi_polygon<std::int64_t> solution;
clipper.execute(mapbox::geometry::wagyu::clip_type_intersection, solution,
mapbox::geometry::wagyu::fill_type_even_odd, mapbox::geometry::wagyu::fill_type_even_odd);
}
};
auto BM_wagyu_fixture_difference =
[](benchmark::State& state, std::string subject_filename, std::string clip_filename) {
auto poly_subject = fixture_file_to_polygon<std::int64_t>(subject_filename.c_str());
auto poly_clip = fixture_file_to_polygon<std::int64_t>(clip_filename.c_str());
while (state.KeepRunning()) {
mapbox::geometry::wagyu::wagyu<std::int64_t> clipper;
clipper.add_polygon(poly_subject, mapbox::geometry::wagyu::polygon_type_subject);
clipper.add_polygon(poly_clip, mapbox::geometry::wagyu::polygon_type_clip);
mapbox::geometry::multi_polygon<std::int64_t> solution;
clipper.execute(mapbox::geometry::wagyu::clip_type_difference, solution,
mapbox::geometry::wagyu::fill_type_even_odd, mapbox::geometry::wagyu::fill_type_even_odd);
}
};
auto BM_wagyu_fixture_x_or = [](benchmark::State& state, std::string subject_filename, std::string clip_filename) {
auto poly_subject = fixture_file_to_polygon<std::int64_t>(subject_filename.c_str());
auto poly_clip = fixture_file_to_polygon<std::int64_t>(clip_filename.c_str());
while (state.KeepRunning()) {
mapbox::geometry::wagyu::wagyu<std::int64_t> clipper;
clipper.add_polygon(poly_subject, mapbox::geometry::wagyu::polygon_type_subject);
clipper.add_polygon(poly_clip, mapbox::geometry::wagyu::polygon_type_clip);
mapbox::geometry::multi_polygon<std::int64_t> solution;
clipper.execute(mapbox::geometry::wagyu::clip_type_x_or, solution, mapbox::geometry::wagyu::fill_type_even_odd,
mapbox::geometry::wagyu::fill_type_even_odd);
}
};
inline void process_polynode_branch(ClipperLib::PolyNode* polynode, mapbox::geometry::multi_polygon<std::int64_t>& mp) {
mapbox::geometry::polygon<std::int64_t> polygon;
polygon.push_back(std::move(polynode->Contour));
if (polygon.back().size() > 2) // Throw out invalid polygons
{
if (polygon.back().back() != polygon.back().front()) {
polygon.back().push_back(polygon.back().front());
}
double outer_area = ClipperLib::Area(polygon.back());
if (outer_area > 0) {
std::reverse(polygon.back().begin(), polygon.back().end());
}
// children of exterior ring are always interior rings
for (auto* ring : polynode->Childs) {
if (ring->Contour.size() < 3) {
continue; // Throw out invalid holes
}
double inner_area = ClipperLib::Area(ring->Contour);
if (inner_area < 0) {
std::reverse(ring->Contour.begin(), ring->Contour.end());
}
polygon.push_back(std::move(ring->Contour));
if (polygon.back().back() != polygon.back().front()) {
polygon.back().push_back(polygon.back().front());
}
}
mp.push_back(std::move(polygon));
}
for (auto* ring : polynode->Childs) {
for (auto* sub_ring : ring->Childs) {
process_polynode_branch(sub_ring, mp);
}
}
}
auto BM_angus_fixture_union = [](benchmark::State& state, std::string subject_filename, std::string clip_filename) {
auto poly_subject = fixture_file_to_polygon<std::int64_t>(subject_filename.c_str());
auto poly_clip = fixture_file_to_polygon<std::int64_t>(clip_filename.c_str());
while (state.KeepRunning()) {
ClipperLib::Clipper clipper;
clipper.StrictlySimple(true);
for (auto& r : poly_subject) {
// ClipperLib::CleanPolygon(r, 1.415);
clipper.AddPath(r, ClipperLib::ptSubject, true);
}
for (auto& r : poly_clip) {
clipper.AddPath(r, ClipperLib::ptClip, true);
}
ClipperLib::PolyTree polygons;
clipper.Execute(ClipperLib::ctUnion, polygons, ClipperLib::pftEvenOdd, ClipperLib::pftEvenOdd);
clipper.Clear();
mapbox::geometry::multi_polygon<std::int64_t> solution;
for (auto* polynode : polygons.Childs) {
process_polynode_branch(polynode, solution);
}
}
};
auto BM_angus_fixture_intersection =
[](benchmark::State& state, std::string subject_filename, std::string clip_filename) {
auto poly_subject = fixture_file_to_polygon<std::int64_t>(subject_filename.c_str());
auto poly_clip = fixture_file_to_polygon<std::int64_t>(clip_filename.c_str());
while (state.KeepRunning()) {
ClipperLib::Clipper clipper;
clipper.StrictlySimple(true);
for (auto& r : poly_subject) {
// ClipperLib::CleanPolygon(r, 1.415);
clipper.AddPath(r, ClipperLib::ptSubject, true);
}
for (auto& r : poly_clip) {
clipper.AddPath(r, ClipperLib::ptClip, true);
}
ClipperLib::PolyTree polygons;
clipper.Execute(ClipperLib::ctIntersection, polygons, ClipperLib::pftEvenOdd, ClipperLib::pftEvenOdd);
clipper.Clear();
mapbox::geometry::multi_polygon<std::int64_t> solution;
for (auto* polynode : polygons.Childs) {
process_polynode_branch(polynode, solution);
}
}
};
auto BM_angus_fixture_difference =
[](benchmark::State& state, std::string subject_filename, std::string clip_filename) {
auto poly_subject = fixture_file_to_polygon<std::int64_t>(subject_filename.c_str());
auto poly_clip = fixture_file_to_polygon<std::int64_t>(clip_filename.c_str());
while (state.KeepRunning()) {
ClipperLib::Clipper clipper;
clipper.StrictlySimple(true);
for (auto& r : poly_subject) {
// ClipperLib::CleanPolygon(r, 1.415);
clipper.AddPath(r, ClipperLib::ptSubject, true);
}
for (auto& r : poly_clip) {
clipper.AddPath(r, ClipperLib::ptClip, true);
}
ClipperLib::PolyTree polygons;
clipper.Execute(ClipperLib::ctDifference, polygons, ClipperLib::pftEvenOdd, ClipperLib::pftEvenOdd);
clipper.Clear();
mapbox::geometry::multi_polygon<std::int64_t> solution;
for (auto* polynode : polygons.Childs) {
process_polynode_branch(polynode, solution);
}
}
};
auto BM_angus_fixture_x_or = [](benchmark::State& state, std::string subject_filename, std::string clip_filename) {
auto poly_subject = fixture_file_to_polygon<std::int64_t>(subject_filename.c_str());
auto poly_clip = fixture_file_to_polygon<std::int64_t>(clip_filename.c_str());
while (state.KeepRunning()) {
ClipperLib::Clipper clipper;
clipper.StrictlySimple(true);
for (auto& r : poly_subject) {
// ClipperLib::CleanPolygon(r, 1.415);
clipper.AddPath(r, ClipperLib::ptSubject, true);
}
for (auto& r : poly_clip) {
clipper.AddPath(r, ClipperLib::ptClip, true);
}
ClipperLib::PolyTree polygons;
clipper.Execute(ClipperLib::ctXor, polygons, ClipperLib::pftEvenOdd, ClipperLib::pftEvenOdd);
clipper.Clear();
mapbox::geometry::multi_polygon<std::int64_t> solution;
for (auto* polynode : polygons.Childs) {
process_polynode_branch(polynode, solution);
}
}
};
inline void register_fixtures() {
boost::filesystem::path fixture_directory("./tests/output-polyjson");
boost::filesystem::path clip_file("./tests/fixtures/clip-clockwise-square.json");
for (auto subject : boost::filesystem::directory_iterator(fixture_directory)) {
if (!boost::filesystem::is_regular_file(subject)) {
continue;
}
std::string union_name = std::string("f/") + subject.path().filename().string() + std::string("/union/wagyu");
std::string union_name2 = std::string("f/") + subject.path().filename().string() + std::string("/union/angus");
std::string intersection_name =
std::string("f/") + subject.path().filename().string() + std::string("/intersection/wagyu");
std::string intersection_name2 =
std::string("f/") + subject.path().filename().string() + std::string("/intersection/angus");
std::string difference_name =
std::string("f/") + subject.path().filename().string() + std::string("/difference/wagyu");
std::string difference_name2 =
std::string("f/") + subject.path().filename().string() + std::string("/difference/angus");
std::string x_or_name = std::string("f/") + subject.path().filename().string() + std::string("/x_or/wagyu");
std::string x_or_name2 = std::string("f/") + subject.path().filename().string() + std::string("/x_or/angus");
benchmark::RegisterBenchmark(union_name.c_str(), BM_wagyu_fixture_union, subject.path().native(),
clip_file.native());
benchmark::RegisterBenchmark(union_name2.c_str(), BM_angus_fixture_union, subject.path().native(),
clip_file.native());
benchmark::RegisterBenchmark(intersection_name.c_str(), BM_wagyu_fixture_intersection, subject.path().native(),
clip_file.native());
benchmark::RegisterBenchmark(intersection_name2.c_str(), BM_angus_fixture_intersection, subject.path().native(),
clip_file.native());
benchmark::RegisterBenchmark(difference_name.c_str(), BM_wagyu_fixture_difference, subject.path().native(),
clip_file.native());
benchmark::RegisterBenchmark(difference_name2.c_str(), BM_angus_fixture_difference, subject.path().native(),
clip_file.native());
benchmark::RegisterBenchmark(x_or_name.c_str(), BM_wagyu_fixture_x_or, subject.path().native(),
clip_file.native());
benchmark::RegisterBenchmark(x_or_name2.c_str(), BM_angus_fixture_x_or, subject.path().native(),
clip_file.native());
}
}
#include "fixtures.hpp"
#include <benchmark/benchmark.h>
int main(int argc, char* argv[]) {
register_fixtures();
benchmark::Initialize(&argc, argv);
benchmark::RunSpecifiedBenchmarks();
return 0;
}
string(RANDOM LENGTH 16 MASON_INVOCATION)
# Directory where Mason packages are located; typically ends with mason_packages
if (NOT MASON_PACKAGE_DIR)
set(MASON_PACKAGE_DIR "${CMAKE_SOURCE_DIR}/mason_packages")
endif()
# URL prefix of where packages are located.
if (NOT MASON_REPOSITORY)
set(MASON_REPOSITORY "https://mason-binaries.s3.amazonaws.com")
endif()
# Path to Mason executable
if (NOT MASON_COMMAND)
set(MASON_COMMAND "${CMAKE_SOURCE_DIR}/.mason/mason")
endif()
# Determine platform
# we call uname -s manually here since
# CMAKE_HOST_SYSTEM_NAME will not be defined before the project() call
execute_process(
COMMAND uname -s
OUTPUT_VARIABLE UNAME_S
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT MASON_PLATFORM)
if (UNAME_S STREQUAL "Darwin")
set(MASON_PLATFORM "macos")
else()
set(MASON_PLATFORM "linux")
endif()
endif()
# Determine platform version string
if(MASON_PLATFORM STREQUAL "ios")
set(MASON_PLATFORM_VERSION "8.0") # Deployment target version
elseif(MASON_PLATFORM STREQUAL "android")
if (ANDROID_ABI STREQUAL "armeabi")
set(MASON_PLATFORM_VERSION "arm-v5-9")
elseif(ANDROID_ABI STREQUAL "arm64-v8a")
set(MASON_PLATFORM_VERSION "arm-v8-21")
elseif(ANDROID_ABI STREQUAL "x86")
set(MASON_PLATFORM_VERSION "x86-9")
elseif(ANDROID_ABI STREQUAL "x86_64")
set(MASON_PLATFORM_VERSION "x86-64-21")
elseif(ANDROID_ABI STREQUAL "mips")
set(MASON_PLATFORM_VERSION "mips-9")
elseif(ANDROID_ABI STREQUAL "mips64")
set(MASON_PLATFORM_VERSION "mips64-21")
else()
set(MASON_PLATFORM_VERSION "arm-v7-9")
endif()
elseif(NOT MASON_PLATFORM_VERSION)
execute_process(
COMMAND uname -m
OUTPUT_VARIABLE MASON_PLATFORM_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE)
endif()
if(MASON_PLATFORM STREQUAL "macos")
set(MASON_PLATFORM "osx")
endif()
set(ENV{MASON_PLATFORM} "${MASON_PLATFORM}")
set(ENV{MASON_PLATFORM_VERSION} "${MASON_PLATFORM_VERSION}")
include(CMakeParseArguments)
function(mason_use _PACKAGE)
if(NOT _PACKAGE)
message(FATAL_ERROR "[Mason] No package name given")
endif()
cmake_parse_arguments("" "HEADER_ONLY" "VERSION" "" ${ARGN})
if(_UNPARSED_ARGUMENTS)
message(FATAL_ERROR "[Mason] mason_use() called with unrecognized arguments: ${_UNPARSED_ARGUMENTS}")
endif()
if(NOT _VERSION)
message(FATAL_ERROR "[Mason] Specifying a version is required")
endif()
if(MASON_PACKAGE_${_PACKAGE}_INVOCATION STREQUAL "${MASON_INVOCATION}")
# Check that the previous invocation of mason_use didn't select another version of this package
if(NOT MASON_PACKAGE_${_PACKAGE}_VERSION STREQUAL ${_VERSION})
message(FATAL_ERROR "[Mason] Already using ${_PACKAGE} ${MASON_PACKAGE_${_PACKAGE}_VERSION}. Cannot select version ${_VERSION}.")
endif()
else()
if(_HEADER_ONLY)
set(_PLATFORM_ID "headers")
else()
set(_PLATFORM_ID "${MASON_PLATFORM}-${MASON_PLATFORM_VERSION}")
endif()
set(_SLUG "${_PLATFORM_ID}/${_PACKAGE}/${_VERSION}")
set(_INSTALL_PATH "${MASON_PACKAGE_DIR}/${_SLUG}")
file(RELATIVE_PATH _INSTALL_PATH_RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${_INSTALL_PATH}")
if(NOT EXISTS "${_INSTALL_PATH}")
set(_CACHE_PATH "${MASON_PACKAGE_DIR}/.binaries/${_SLUG}.tar.gz")
if (NOT EXISTS "${_CACHE_PATH}")
# Download the package
set(_URL "${MASON_REPOSITORY}/${_SLUG}.tar.gz")
message(STATUS "[Mason] Downloading package ${_URL}...")
set(_FAILED)
set(_ERROR)
# Note: some CMake versions are compiled without SSL support
get_filename_component(_CACHE_DIR "${_CACHE_PATH}" DIRECTORY)
file(MAKE_DIRECTORY "${_CACHE_DIR}")
execute_process(
COMMAND curl --retry 3 -s -f -S -L "${_URL}" -o "${_CACHE_PATH}.tmp"
RESULT_VARIABLE _FAILED
ERROR_VARIABLE _ERROR)
if(_FAILED)
message(FATAL_ERROR "[Mason] Failed to download ${_URL}: ${_ERROR}")
else()
# We downloaded to a temporary file to prevent half-finished downloads
file(RENAME "${_CACHE_PATH}.tmp" "${_CACHE_PATH}")
endif()
endif()
# Unpack the package
message(STATUS "[Mason] Unpacking package to ${_INSTALL_PATH_RELATIVE}...")
file(MAKE_DIRECTORY "${_INSTALL_PATH}")
execute_process(
COMMAND ${CMAKE_COMMAND} -E tar xzf "${_CACHE_PATH}"
WORKING_DIRECTORY "${_INSTALL_PATH}")
endif()
# Create a config file if it doesn't exist in the package
# TODO: remove this once all packages have a mason.ini file
if(NOT EXISTS "${_INSTALL_PATH}/mason.ini")
# Change pkg-config files
file(GLOB_RECURSE _PKGCONFIG_FILES "${_INSTALL_PATH}/*.pc")
foreach(_PKGCONFIG_FILE IN ITEMS ${_PKGCONFIG_FILES})
file(READ "${_PKGCONFIG_FILE}" _PKGCONFIG_FILE_CONTENT)
string(REGEX REPLACE "(^|\n)prefix=[^\n]*" "\\1prefix=${_INSTALL_PATH}" _PKGCONFIG_FILE_CONTENT "${_PKGCONFIG_FILE_CONTENT}")
file(WRITE "${_PKGCONFIG_FILE}" "${_PKGCONFIG_FILE_CONTENT}")
endforeach()
if(NOT EXISTS "${MASON_COMMAND}")
message(FATAL_ERROR "[Mason] Could not find Mason command at ${MASON_COMMAND}")
endif()
set(_FAILED)
set(_ERROR)
execute_process(
COMMAND ${MASON_COMMAND} config ${_PACKAGE} ${_VERSION}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_FILE "${_INSTALL_PATH}/mason.ini"
RESULT_VARIABLE _FAILED
ERROR_VARIABLE _ERROR)
if(_FAILED)
message(FATAL_ERROR "[Mason] Could not get configuration for package ${_PACKAGE} ${_VERSION}: ${_ERROR}")
endif()
endif()
set(MASON_PACKAGE_${_PACKAGE}_PREFIX "${_INSTALL_PATH}" CACHE STRING "${_PACKAGE} ${_INSTALL_PATH}" FORCE)
mark_as_advanced(MASON_PACKAGE_${_PACKAGE}_PREFIX)
# Load the configuration from the ini file
file(STRINGS "${_INSTALL_PATH}/mason.ini" _CONFIG_FILE)
foreach(_LINE IN LISTS _CONFIG_FILE)
string(REGEX MATCH "^([a-z_]+) *= *" _KEY "${_LINE}")
if (_KEY)
string(LENGTH "${_KEY}" _KEY_LENGTH)
string(SUBSTRING "${_LINE}" ${_KEY_LENGTH} -1 _VALUE)
string(REGEX REPLACE ";.*$" "" _VALUE "${_VALUE}") # Trim trailing commas
string(REPLACE "{prefix}" "${_INSTALL_PATH}" _VALUE "${_VALUE}")
string(STRIP "${_VALUE}" _VALUE)
string(REPLACE "=" "" _KEY "${_KEY}")
string(STRIP "${_KEY}" _KEY)
string(TOUPPER "${_KEY}" _KEY)
if(_KEY STREQUAL "INCLUDE_DIRS" OR _KEY STREQUAL "STATIC_LIBS" )
separate_arguments(_VALUE)
endif()
set(MASON_PACKAGE_${_PACKAGE}_${_KEY} "${_VALUE}" CACHE STRING "${_PACKAGE} ${_KEY}" FORCE)
mark_as_advanced(MASON_PACKAGE_${_PACKAGE}_${_KEY})
endif()
endforeach()
# Compare version in the package to catch errors early on
if(NOT _VERSION STREQUAL MASON_PACKAGE_${_PACKAGE}_VERSION)
message(FATAL_ERROR "[Mason] Package at ${_INSTALL_PATH_RELATIVE} has version '${MASON_PACKAGE_${_PACKAGE}_VERSION}', but required '${_VERSION}'")
endif()
if(NOT _PACKAGE STREQUAL MASON_PACKAGE_${_PACKAGE}_NAME)
message(FATAL_ERROR "[Mason] Package at ${_INSTALL_PATH_RELATIVE} has name '${MASON_PACKAGE_${_PACKAGE}_NAME}', but required '${_NAME}'")
endif()
if(NOT _HEADER_ONLY)
if(NOT MASON_PLATFORM STREQUAL MASON_PACKAGE_${_PACKAGE}_PLATFORM)
message(FATAL_ERROR "[Mason] Package at ${_INSTALL_PATH_RELATIVE} has platform '${MASON_PACKAGE_${_PACKAGE}_PLATFORM}', but required '${MASON_PLATFORM}'")
endif()
if(NOT MASON_PLATFORM_VERSION STREQUAL MASON_PACKAGE_${_PACKAGE}_PLATFORM_VERSION)
message(FATAL_ERROR "[Mason] Package at ${_INSTALL_PATH_RELATIVE} has platform version '${MASON_PACKAGE_${_PACKAGE}_PLATFORM_VERSION}', but required '${MASON_PLATFORM_VERSION}'")
endif()
endif()
# Concatenate the static libs and libraries
set(_LIBRARIES)
list(APPEND _LIBRARIES ${MASON_PACKAGE_${_PACKAGE}_STATIC_LIBS} ${MASON_PACKAGE_${_PACKAGE}_LDFLAGS})
set(MASON_PACKAGE_${_PACKAGE}_LIBRARIES "${_LIBRARIES}" CACHE STRING "${_PACKAGE} _LIBRARIES" FORCE)
mark_as_advanced(MASON_PACKAGE_${_PACKAGE}_LIBRARIES)
if(NOT _HEADER_ONLY)
string(REGEX MATCHALL "(^| +)-L *([^ ]+)" MASON_PACKAGE_${_PACKAGE}_LIBRARY_DIRS "${MASON_PACKAGE_${_PACKAGE}_LDFLAGS}")
string(REGEX REPLACE "(^| +)-L *" "\\1" MASON_PACKAGE_${_PACKAGE}_LIBRARY_DIRS "${MASON_PACKAGE_${_PACKAGE}_LIBRARY_DIRS}")
set(MASON_PACKAGE_${_PACKAGE}_LIBRARY_DIRS "${MASON_PACKAGE_${_PACKAGE}_LIBRARY_DIRS}" CACHE STRING "${_PACKAGE} ${MASON_PACKAGE_${_PACKAGE}_LIBRARY_DIRS}" FORCE)
mark_as_advanced(MASON_PACKAGE_${_PACKAGE}_LIBRARY_DIRS)
endif()
# Store invocation ID to prevent different versions of the same package in one invocation
set(MASON_PACKAGE_${_PACKAGE}_INVOCATION "${MASON_INVOCATION}" CACHE INTERNAL "${_PACKAGE} invocation ID" FORCE)
endif()
endfunction()
macro(target_add_mason_package _TARGET _VISIBILITY _PACKAGE)
if (NOT MASON_PACKAGE_${_PACKAGE}_INVOCATION)
message(FATAL_ERROR "[Mason] Package ${_PACKAGE} has not been initialized yet")
endif()
target_include_directories(${_TARGET} ${_VISIBILITY} "${MASON_PACKAGE_${_PACKAGE}_INCLUDE_DIRS}")
target_compile_definitions(${_TARGET} ${_VISIBILITY} "${MASON_PACKAGE_${_PACKAGE}_DEFINITIONS}")
target_compile_options(${_TARGET} ${_VISIBILITY} "${MASON_PACKAGE_${_PACKAGE}_OPTIONS}")
target_link_libraries(${_TARGET} ${_VISIBILITY} "${MASON_PACKAGE_${_PACKAGE}_LIBRARIES}")
endmacro()
ignore:
- "bench"
- "test"
- "fuzzer"
mapbox-wagyu (0.4.3-4) UNRELEASED; urgency=medium
mapbox-wagyu (0.5.0-1) unstable; urgency=medium
* New upstream release.
* Bump Standards-Version to 4.4.1, no changes.
* Update watch file to limit matches to archive path.
* Update gbp.conf to use --source-only-changes by default.
* Drop Name field from upstream metadata.
* Update copyright file.
* Override dh_auto_test & dh_auto_install targets too.
-- Bas Couwenberg <sebastic@debian.org> Sun, 05 Aug 2018 20:27:11 +0200
-- Bas Couwenberg <sebastic@debian.org> Thu, 16 Jan 2020 17:53:11 +0100
mapbox-wagyu (0.4.3-3) unstable; urgency=medium
......
......@@ -3,10 +3,7 @@ Section: libdevel
Priority: optional
Maintainer: Debian GIS Project <pkg-grass-devel@lists.alioth.debian.org>
Uploaders: Bas Couwenberg <sebastic@debian.org>
Build-Depends: debhelper (>= 9),
libboost-dev,
libmapbox-geometry-dev,
rapidjson-dev
Build-Depends: debhelper (>= 9)
Standards-Version: 4.4.1
Vcs-Browser: https://salsa.debian.org/debian-gis-team/mapbox-wagyu/
Vcs-Git: https://salsa.debian.org/debian-gis-team/mapbox-wagyu.git
......
......@@ -4,8 +4,8 @@ Upstream-Contact: Mapbox (https://github.com/mapbox/wagyu/issues)
Source: https://github.com/mapbox/wagyu
Files: *
Copyright: 2016, Mapbox
2010-2015, Angus Johnson
Copyright: 2016-2020, Mapbox
2010-2015, Angus Johnson
Comment: Parts of the code in the Wagyu Library are derived from the
version of the Clipper Library by Angus Johnson listed below.
.
......@@ -20,9 +20,9 @@ Comment: Parts of the code in the Wagyu Library are derived from the
retains the same license as the Clipper Library by Angus Johnson.
License: BSL-1.0
Files: tests/catch.hpp
Copyright: 2012, Two Blue Cubes Ltd.
License: BSL-1.0
Files: include/mapbox/geometry/wagyu/almost_equal.hpp
Copyright: 2005, Google Inc.
License: BSD-3-Clause
Files: debian/*
Copyright: 2016, Bas Couwenberg <sebastic@debian.org>
......@@ -53,6 +53,33 @@ License: BSL-1.0
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
License: BSD-3-Clause
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
.
1) Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
.
2) Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
.
3) Neither the name of the ORGANIZATION nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
License: GPL-3+
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......
Description: Disable mason, dependencies are packaged.
Author: Bas Couwenberg <sebastic@debian.org>
Forwarded: not-needed
--- a/Makefile
+++ b/Makefile
@@ -4,7 +4,7 @@ GEOMETRY_VERSION=0.9.0
CC := $(CC)
CXX := $(CXX)
-CXXFLAGS := $(CXXFLAGS) -Iinclude -isystem mason_packages/headers/boost/$(BOOST_VERSION)/include -isystem mason_packages/headers/rapidjson/$(RAPIDJSON_VERSION)/include -isystem mason_packages/headers/geometry/$(GEOMETRY_VERSION)/include -std=c++11
+CXXFLAGS := $(CXXFLAGS) -Iinclude -std=c++11
RELEASE_FLAGS := -O3 -DNDEBUG
WARNING_FLAGS := -Wall -Wextra -Weffc++ -Werror -Wsign-compare -Wfloat-equal -Wshadow -Wconversion
DEBUG_FLAGS := -g -O0 -DDEBUG -fno-inline-functions -fno-omit-frame-pointer
@@ -25,10 +25,10 @@ mason_packages/headers/geometry/$(GEOMET
deps: mason_packages/headers/boost/$(BOOST_VERSION)/include mason_packages/headers/rapidjson/$(RAPIDJSON_VERSION)/include mason_packages/headers/geometry/$(GEOMETRY_VERSION)/include
-build-test: tests/* include/mapbox/geometry/* deps Makefile
+build-test: tests/* include/mapbox/geometry/* Makefile
$(CXX) $(RELEASE_FLAGS) tests/test.cpp tests/unit/*.cpp $(WARNING_FLAGS) $(CXXFLAGS) -isystem ./tests -o test
-build-debug: tests/* include/mapbox/geometry/* deps Makefile
+build-debug: tests/* include/mapbox/geometry/* Makefile
$(CXX) $(DEBUG_FLAGS) tests/test.cpp tests/unit/*.cpp $(WARNING_FLAGS) $(CXXFLAGS) -isystem ./tests -o test
build-fixture-tester-r:
Description: Skip tests for missing test data.
Author: Bas Couwenberg <sebastic@debian.org>
Forwarded: not-needed
--- a/tests/run-geometry-tests.sh
+++ b/tests/run-geometry-tests.sh
@@ -13,6 +13,11 @@ elif [ ! -e "$TESTER" ]; then
exit 1
fi
+if [ ! -e "./tests/geometry-test-data/input-polyjson" ]; then
+ echo "No test data available, skipping tests."
+ exit 0
+fi
+
mkdir -p ./tests/output-polyjson