11 changed files with 11202 additions and 2558 deletions
-
6pcbnew/import_gfx/dxf_import_plugin.cpp
-
3thirdparty/tinyspline_lib/CMakeLists.txt
-
6thirdparty/tinyspline_lib/LICENSE
-
2079thirdparty/tinyspline_lib/parson.c
-
234thirdparty/tinyspline_lib/parson.h
-
4476thirdparty/tinyspline_lib/tinyspline.c
-
3653thirdparty/tinyspline_lib/tinyspline.h
-
493thirdparty/tinyspline_lib/tinysplinecpp.cpp
-
143thirdparty/tinyspline_lib/tinysplinecpp.h
-
1707thirdparty/tinyspline_lib/tinysplinecxx.cxx
-
960thirdparty/tinyspline_lib/tinysplinecxx.h
2079
thirdparty/tinyspline_lib/parson.c
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,234 @@ |
|||
/* |
|||
Parson ( http://kgabis.github.com/parson/ ) |
|||
Copyright (c) 2012 - 2017 Krzysztof Gabis |
|||
|
|||
Permission is hereby granted, free of charge, to any person obtaining a copy |
|||
of this software and associated documentation files (the "Software"), to deal |
|||
in the Software without restriction, including without limitation the rights |
|||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|||
copies of the Software, and to permit persons to whom the Software is |
|||
furnished to do so, subject to the following conditions: |
|||
|
|||
The above copyright notice and this permission notice shall be included in |
|||
all copies or substantial portions of the Software. |
|||
|
|||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
|||
THE SOFTWARE. |
|||
*/ |
|||
|
|||
#ifndef parson_parson_h |
|||
#define parson_parson_h |
|||
|
|||
#ifdef __cplusplus |
|||
extern "C" |
|||
{ |
|||
#endif |
|||
|
|||
#include <stddef.h> /* size_t */ |
|||
|
|||
/* Types and enums */ |
|||
typedef struct json_object_t JSON_Object; |
|||
typedef struct json_array_t JSON_Array; |
|||
typedef struct json_value_t JSON_Value; |
|||
|
|||
enum json_value_type { |
|||
JSONError = -1, |
|||
JSONNull = 1, |
|||
JSONString = 2, |
|||
JSONNumber = 3, |
|||
JSONObject = 4, |
|||
JSONArray = 5, |
|||
JSONBoolean = 6 |
|||
}; |
|||
typedef int JSON_Value_Type; |
|||
|
|||
enum json_result_t { |
|||
JSONSuccess = 0, |
|||
JSONFailure = -1 |
|||
}; |
|||
typedef int JSON_Status; |
|||
|
|||
typedef void * (*JSON_Malloc_Function)(size_t); |
|||
typedef void (*JSON_Free_Function)(void *); |
|||
|
|||
/* Call only once, before calling any other function from parson API. If not called, malloc and free |
|||
from stdlib will be used for all allocations */ |
|||
void json_set_allocation_functions(JSON_Malloc_Function malloc_fun, JSON_Free_Function free_fun); |
|||
|
|||
/* Parses first JSON value in a file, returns NULL in case of error */ |
|||
JSON_Value * json_parse_file(const char *filename); |
|||
|
|||
/* Parses first JSON value in a file and ignores comments (/ * * / and //), |
|||
returns NULL in case of error */ |
|||
JSON_Value * json_parse_file_with_comments(const char *filename); |
|||
|
|||
/* Parses first JSON value in a string, returns NULL in case of error */ |
|||
JSON_Value * json_parse_string(const char *string); |
|||
|
|||
/* Parses first JSON value in a string and ignores comments (/ * * / and //), |
|||
returns NULL in case of error */ |
|||
JSON_Value * json_parse_string_with_comments(const char *string); |
|||
|
|||
/* Serialization */ |
|||
size_t json_serialization_size(const JSON_Value *value); /* returns 0 on fail */ |
|||
JSON_Status json_serialize_to_buffer(const JSON_Value *value, char *buf, size_t buf_size_in_bytes); |
|||
JSON_Status json_serialize_to_file(const JSON_Value *value, const char *filename); |
|||
char * json_serialize_to_string(const JSON_Value *value); |
|||
|
|||
/* Pretty serialization */ |
|||
size_t json_serialization_size_pretty(const JSON_Value *value); /* returns 0 on fail */ |
|||
JSON_Status json_serialize_to_buffer_pretty(const JSON_Value *value, char *buf, size_t buf_size_in_bytes); |
|||
JSON_Status json_serialize_to_file_pretty(const JSON_Value *value, const char *filename); |
|||
char * json_serialize_to_string_pretty(const JSON_Value *value); |
|||
|
|||
void json_free_serialized_string(char *string); /* frees string from json_serialize_to_string and json_serialize_to_string_pretty */ |
|||
|
|||
/* Comparing */ |
|||
int json_value_equals(const JSON_Value *a, const JSON_Value *b); |
|||
|
|||
/* Validation |
|||
This is *NOT* JSON Schema. It validates json by checking if object have identically |
|||
named fields with matching types. |
|||
For example schema {"name":"", "age":0} will validate |
|||
{"name":"Joe", "age":25} and {"name":"Joe", "age":25, "gender":"m"}, |
|||
but not {"name":"Joe"} or {"name":"Joe", "age":"Cucumber"}. |
|||
In case of arrays, only first value in schema is checked against all values in tested array. |
|||
Empty objects ({}) validate all objects, empty arrays ([]) validate all arrays, |
|||
null validates values of every type. |
|||
*/ |
|||
JSON_Status json_validate(const JSON_Value *schema, const JSON_Value *value); |
|||
|
|||
/* |
|||
* JSON Object |
|||
*/ |
|||
JSON_Value * json_object_get_value (const JSON_Object *object, const char *name); |
|||
const char * json_object_get_string (const JSON_Object *object, const char *name); |
|||
JSON_Object * json_object_get_object (const JSON_Object *object, const char *name); |
|||
JSON_Array * json_object_get_array (const JSON_Object *object, const char *name); |
|||
double json_object_get_number (const JSON_Object *object, const char *name); /* returns 0 on fail */ |
|||
int json_object_get_boolean(const JSON_Object *object, const char *name); /* returns -1 on fail */ |
|||
|
|||
/* dotget functions enable addressing values with dot notation in nested objects, |
|||
just like in structs or c++/java/c# objects (e.g. objectA.objectB.value). |
|||
Because valid names in JSON can contain dots, some values may be inaccessible |
|||
this way. */ |
|||
JSON_Value * json_object_dotget_value (const JSON_Object *object, const char *name); |
|||
const char * json_object_dotget_string (const JSON_Object *object, const char *name); |
|||
JSON_Object * json_object_dotget_object (const JSON_Object *object, const char *name); |
|||
JSON_Array * json_object_dotget_array (const JSON_Object *object, const char *name); |
|||
double json_object_dotget_number (const JSON_Object *object, const char *name); /* returns 0 on fail */ |
|||
int json_object_dotget_boolean(const JSON_Object *object, const char *name); /* returns -1 on fail */ |
|||
|
|||
/* Functions to get available names */ |
|||
size_t json_object_get_count (const JSON_Object *object); |
|||
const char * json_object_get_name (const JSON_Object *object, size_t index); |
|||
JSON_Value * json_object_get_value_at(const JSON_Object *object, size_t index); |
|||
JSON_Value * json_object_get_wrapping_value(const JSON_Object *object); |
|||
|
|||
/* Functions to check if object has a value with a specific name. Returned value is 1 if object has |
|||
* a value and 0 if it doesn't. dothas functions behave exactly like dotget functions. */ |
|||
int json_object_has_value (const JSON_Object *object, const char *name); |
|||
int json_object_has_value_of_type(const JSON_Object *object, const char *name, JSON_Value_Type type); |
|||
|
|||
int json_object_dothas_value (const JSON_Object *object, const char *name); |
|||
int json_object_dothas_value_of_type(const JSON_Object *object, const char *name, JSON_Value_Type type); |
|||
|
|||
/* Creates new name-value pair or frees and replaces old value with a new one. |
|||
* json_object_set_value does not copy passed value so it shouldn't be freed afterwards. */ |
|||
JSON_Status json_object_set_value(JSON_Object *object, const char *name, JSON_Value *value); |
|||
JSON_Status json_object_set_string(JSON_Object *object, const char *name, const char *string); |
|||
JSON_Status json_object_set_number(JSON_Object *object, const char *name, double number); |
|||
JSON_Status json_object_set_boolean(JSON_Object *object, const char *name, int boolean); |
|||
JSON_Status json_object_set_null(JSON_Object *object, const char *name); |
|||
|
|||
/* Works like dotget functions, but creates whole hierarchy if necessary. |
|||
* json_object_dotset_value does not copy passed value so it shouldn't be freed afterwards. */ |
|||
JSON_Status json_object_dotset_value(JSON_Object *object, const char *name, JSON_Value *value); |
|||
JSON_Status json_object_dotset_string(JSON_Object *object, const char *name, const char *string); |
|||
JSON_Status json_object_dotset_number(JSON_Object *object, const char *name, double number); |
|||
JSON_Status json_object_dotset_boolean(JSON_Object *object, const char *name, int boolean); |
|||
JSON_Status json_object_dotset_null(JSON_Object *object, const char *name); |
|||
|
|||
/* Frees and removes name-value pair */ |
|||
JSON_Status json_object_remove(JSON_Object *object, const char *name); |
|||
|
|||
/* Works like dotget function, but removes name-value pair only on exact match. */ |
|||
JSON_Status json_object_dotremove(JSON_Object *object, const char *key); |
|||
|
|||
/* Removes all name-value pairs in object */ |
|||
JSON_Status json_object_clear(JSON_Object *object); |
|||
|
|||
/* |
|||
*JSON Array |
|||
*/ |
|||
JSON_Value * json_array_get_value (const JSON_Array *array, size_t index); |
|||
const char * json_array_get_string (const JSON_Array *array, size_t index); |
|||
JSON_Object * json_array_get_object (const JSON_Array *array, size_t index); |
|||
JSON_Array * json_array_get_array (const JSON_Array *array, size_t index); |
|||
double json_array_get_number (const JSON_Array *array, size_t index); /* returns 0 on fail */ |
|||
int json_array_get_boolean(const JSON_Array *array, size_t index); /* returns -1 on fail */ |
|||
size_t json_array_get_count (const JSON_Array *array); |
|||
JSON_Value * json_array_get_wrapping_value(const JSON_Array *array); |
|||
|
|||
/* Frees and removes value at given index, does nothing and returns JSONFailure if index doesn't exist. |
|||
* Order of values in array may change during execution. */ |
|||
JSON_Status json_array_remove(JSON_Array *array, size_t i); |
|||
|
|||
/* Frees and removes from array value at given index and replaces it with given one. |
|||
* Does nothing and returns JSONFailure if index doesn't exist. |
|||
* json_array_replace_value does not copy passed value so it shouldn't be freed afterwards. */ |
|||
JSON_Status json_array_replace_value(JSON_Array *array, size_t i, JSON_Value *value); |
|||
JSON_Status json_array_replace_string(JSON_Array *array, size_t i, const char* string); |
|||
JSON_Status json_array_replace_number(JSON_Array *array, size_t i, double number); |
|||
JSON_Status json_array_replace_boolean(JSON_Array *array, size_t i, int boolean); |
|||
JSON_Status json_array_replace_null(JSON_Array *array, size_t i); |
|||
|
|||
/* Frees and removes all values from array */ |
|||
JSON_Status json_array_clear(JSON_Array *array); |
|||
|
|||
/* Appends new value at the end of array. |
|||
* json_array_append_value does not copy passed value so it shouldn't be freed afterwards. */ |
|||
JSON_Status json_array_append_value(JSON_Array *array, JSON_Value *value); |
|||
JSON_Status json_array_append_string(JSON_Array *array, const char *string); |
|||
JSON_Status json_array_append_number(JSON_Array *array, double number); |
|||
JSON_Status json_array_append_boolean(JSON_Array *array, int boolean); |
|||
JSON_Status json_array_append_null(JSON_Array *array); |
|||
|
|||
/* |
|||
*JSON Value |
|||
*/ |
|||
JSON_Value * json_value_init_object (void); |
|||
JSON_Value * json_value_init_array (void); |
|||
JSON_Value * json_value_init_string (const char *string); /* copies passed string */ |
|||
JSON_Value * json_value_init_number (double number); |
|||
JSON_Value * json_value_init_boolean(int boolean); |
|||
JSON_Value * json_value_init_null (void); |
|||
JSON_Value * json_value_deep_copy (const JSON_Value *value); |
|||
void json_value_free (JSON_Value *value); |
|||
|
|||
JSON_Value_Type json_value_get_type (const JSON_Value *value); |
|||
JSON_Object * json_value_get_object (const JSON_Value *value); |
|||
JSON_Array * json_value_get_array (const JSON_Value *value); |
|||
const char * json_value_get_string (const JSON_Value *value); |
|||
double json_value_get_number (const JSON_Value *value); |
|||
int json_value_get_boolean(const JSON_Value *value); |
|||
JSON_Value * json_value_get_parent (const JSON_Value *value); |
|||
|
|||
/* Same as above, but shorter */ |
|||
JSON_Value_Type json_type (const JSON_Value *value); |
|||
JSON_Object * json_object (const JSON_Value *value); |
|||
JSON_Array * json_array (const JSON_Value *value); |
|||
const char * json_string (const JSON_Value *value); |
|||
double json_number (const JSON_Value *value); |
|||
int json_boolean(const JSON_Value *value); |
|||
|
|||
#ifdef __cplusplus |
|||
} |
|||
#endif |
|||
|
|||
#endif |
|||
4476
thirdparty/tinyspline_lib/tinyspline.c
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
3653
thirdparty/tinyspline_lib/tinyspline.h
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -1,493 +0,0 @@ |
|||
/*
|
|||
* The MIT License (MIT) |
|||
* |
|||
* Copyright (c) 2016 Marcel Steinbeck |
|||
* |
|||
* Permission is hereby granted, free of charge, to any person obtaining a copy |
|||
* of this software and associated documentation files (the "Software"), to deal |
|||
* in the Software without restriction, including without limitation the rights |
|||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|||
* copies of the Software, and to permit persons to whom the Software is |
|||
* furnished to do so, subject to the following conditions: |
|||
* |
|||
* The above copyright notice and this permission notice shall be included in all |
|||
* copies or substantial portions of the Software. |
|||
* |
|||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
|||
* SOFTWARE. |
|||
*/ |
|||
|
|||
#include "tinysplinecpp.h"
|
|||
#include <stdexcept>
|
|||
|
|||
/********************************************************
|
|||
* * |
|||
* DeBoorNet * |
|||
* * |
|||
********************************************************/ |
|||
tinyspline::DeBoorNet::DeBoorNet() |
|||
{ |
|||
ts_deboornet_default( &deBoorNet ); |
|||
} |
|||
|
|||
|
|||
tinyspline::DeBoorNet::DeBoorNet( const tinyspline::DeBoorNet& other ) |
|||
{ |
|||
const tsError err = ts_deboornet_copy( &other.deBoorNet, &deBoorNet ); |
|||
|
|||
if( err < 0 ) |
|||
throw std::runtime_error( ts_enum_str( err ) ); |
|||
} |
|||
|
|||
|
|||
tinyspline::DeBoorNet::~DeBoorNet() |
|||
{ |
|||
ts_deboornet_free( &deBoorNet ); |
|||
} |
|||
|
|||
|
|||
tinyspline::DeBoorNet& tinyspline::DeBoorNet::operator=( const tinyspline::DeBoorNet& other ) |
|||
{ |
|||
if( &other != this ) |
|||
{ |
|||
const tsError err = ts_deboornet_copy( |
|||
&other.deBoorNet, &deBoorNet ); |
|||
|
|||
if( err < 0 ) |
|||
throw std::runtime_error( ts_enum_str( err ) ); |
|||
} |
|||
|
|||
return *this; |
|||
} |
|||
|
|||
|
|||
tinyspline::real tinyspline::DeBoorNet::u() const |
|||
{ |
|||
return deBoorNet.u; |
|||
} |
|||
|
|||
|
|||
size_t tinyspline::DeBoorNet::k() const |
|||
{ |
|||
return deBoorNet.k; |
|||
} |
|||
|
|||
|
|||
size_t tinyspline::DeBoorNet::s() const |
|||
{ |
|||
return deBoorNet.s; |
|||
} |
|||
|
|||
|
|||
size_t tinyspline::DeBoorNet::h() const |
|||
{ |
|||
return deBoorNet.h; |
|||
} |
|||
|
|||
|
|||
size_t tinyspline::DeBoorNet::dim() const |
|||
{ |
|||
return deBoorNet.dim; |
|||
} |
|||
|
|||
|
|||
size_t tinyspline::DeBoorNet::nPoints() const |
|||
{ |
|||
return deBoorNet.n_points; |
|||
} |
|||
|
|||
|
|||
std::vector<tinyspline::real> tinyspline::DeBoorNet::points() const |
|||
{ |
|||
const tinyspline::real* begin = deBoorNet.points; |
|||
const tinyspline::real* end = begin + deBoorNet.n_points * deBoorNet.dim; |
|||
|
|||
return std::vector<tinyspline::real>( begin, end ); |
|||
} |
|||
|
|||
|
|||
std::vector<tinyspline::real> tinyspline::DeBoorNet::result() const |
|||
{ |
|||
const tinyspline::real* begin = deBoorNet.result; |
|||
const tinyspline::real* end = begin + deBoorNet.dim; |
|||
|
|||
return std::vector<tinyspline::real>( begin, end ); |
|||
} |
|||
|
|||
|
|||
tsDeBoorNet* tinyspline::DeBoorNet::data() |
|||
{ |
|||
return &deBoorNet; |
|||
} |
|||
|
|||
|
|||
#ifndef TINYSPLINE_DISABLE_CXX11_FEATURES
|
|||
tinyspline::DeBoorNet::DeBoorNet( tinyspline::DeBoorNet&& other ) noexcept |
|||
{ |
|||
ts_deboornet_default( &deBoorNet ); |
|||
swap( other ); |
|||
} |
|||
|
|||
|
|||
tinyspline::DeBoorNet& tinyspline::DeBoorNet::operator=( tinyspline::DeBoorNet&& other ) noexcept |
|||
{ |
|||
if( &other != this ) |
|||
{ |
|||
ts_deboornet_free( &deBoorNet ); |
|||
swap( other ); |
|||
} |
|||
|
|||
return *this; |
|||
} |
|||
|
|||
|
|||
void tinyspline::DeBoorNet::swap( tinyspline::DeBoorNet& other ) |
|||
{ |
|||
if( &other != this ) |
|||
{ |
|||
std::swap( deBoorNet.u, other.deBoorNet.u ); |
|||
std::swap( deBoorNet.k, other.deBoorNet.k ); |
|||
std::swap( deBoorNet.s, other.deBoorNet.s ); |
|||
std::swap( deBoorNet.h, other.deBoorNet.h ); |
|||
std::swap( deBoorNet.dim, other.deBoorNet.dim ); |
|||
std::swap( deBoorNet.n_points, other.deBoorNet.n_points ); |
|||
std::swap( deBoorNet.points, other.deBoorNet.points ); |
|||
std::swap( deBoorNet.result, other.deBoorNet.result ); |
|||
} |
|||
} |
|||
|
|||
|
|||
#endif
|
|||
|
|||
|
|||
/********************************************************
|
|||
* * |
|||
* BSpline * |
|||
* * |
|||
********************************************************/ |
|||
tinyspline::BSpline::BSpline() |
|||
{ |
|||
ts_bspline_default( &bspline ); |
|||
} |
|||
|
|||
|
|||
tinyspline::BSpline::BSpline( const tinyspline::BSpline& other ) |
|||
{ |
|||
const tsError err = ts_bspline_copy( &other.bspline, &bspline ); |
|||
|
|||
if( err < 0 ) |
|||
throw std::runtime_error( ts_enum_str( err ) ); |
|||
} |
|||
|
|||
|
|||
tinyspline::BSpline::BSpline( const size_t nCtrlp, const size_t dim, |
|||
const size_t deg, const tinyspline::BSpline::type type ) |
|||
{ |
|||
const tsError err = ts_bspline_new( nCtrlp, dim, deg, type, &bspline ); |
|||
|
|||
if( err < 0 ) |
|||
throw std::runtime_error( ts_enum_str( err ) ); |
|||
} |
|||
|
|||
|
|||
tinyspline::BSpline::~BSpline() |
|||
{ |
|||
ts_bspline_free( &bspline ); |
|||
} |
|||
|
|||
|
|||
tinyspline::BSpline& tinyspline::BSpline::operator=( const tinyspline::BSpline& other ) |
|||
{ |
|||
if( &other != this ) |
|||
{ |
|||
const tsError err = ts_bspline_copy( &other.bspline, &bspline ); |
|||
|
|||
if( err < 0 ) |
|||
throw std::runtime_error( ts_enum_str( err ) ); |
|||
} |
|||
|
|||
return *this; |
|||
} |
|||
|
|||
|
|||
tinyspline::DeBoorNet tinyspline::BSpline::operator()( const tinyspline::real u ) const |
|||
{ |
|||
return evaluate( u ); |
|||
} |
|||
|
|||
|
|||
size_t tinyspline::BSpline::deg() const |
|||
{ |
|||
return bspline.deg; |
|||
} |
|||
|
|||
|
|||
size_t tinyspline::BSpline::order() const |
|||
{ |
|||
return bspline.order; |
|||
} |
|||
|
|||
|
|||
size_t tinyspline::BSpline::dim() const |
|||
{ |
|||
return bspline.dim; |
|||
} |
|||
|
|||
|
|||
size_t tinyspline::BSpline::nCtrlp() const |
|||
{ |
|||
return bspline.n_ctrlp; |
|||
} |
|||
|
|||
|
|||
size_t tinyspline::BSpline::nKnots() const |
|||
{ |
|||
return bspline.n_knots; |
|||
} |
|||
|
|||
|
|||
std::vector<tinyspline::real> tinyspline::BSpline::ctrlp() const |
|||
{ |
|||
const tinyspline::real* begin = bspline.ctrlp; |
|||
const tinyspline::real* end = begin + bspline.n_ctrlp * bspline.dim; |
|||
|
|||
return std::vector<tinyspline::real>( begin, end ); |
|||
} |
|||
|
|||
|
|||
std::vector<tinyspline::real> tinyspline::BSpline::knots() const |
|||
{ |
|||
const tinyspline::real* begin = bspline.knots; |
|||
const tinyspline::real* end = begin + bspline.n_knots; |
|||
|
|||
return std::vector<tinyspline::real>( begin, end ); |
|||
} |
|||
|
|||
|
|||
tsBSpline* tinyspline::BSpline::data() |
|||
{ |
|||
return &bspline; |
|||
} |
|||
|
|||
|
|||
tinyspline::DeBoorNet tinyspline::BSpline::evaluate( const tinyspline::real u ) const |
|||
{ |
|||
tinyspline::DeBoorNet deBoorNet; |
|||
const tsError err = ts_bspline_evaluate( &bspline, u, deBoorNet.data() ); |
|||
|
|||
if( err < 0 ) |
|||
throw std::runtime_error( ts_enum_str( err ) ); |
|||
|
|||
return deBoorNet; |
|||
} |
|||
|
|||
|
|||
void tinyspline::BSpline::setCtrlp( const std::vector<tinyspline::real>& ctrlp ) |
|||
{ |
|||
if( ctrlp.size() != nCtrlp() * dim() ) |
|||
{ |
|||
throw std::runtime_error( "The number of values must be equals" |
|||
"to the spline's number of control points multiplied" |
|||
"by the dimension of each control point." ); |
|||
} |
|||
|
|||
const tsError err = ts_bspline_set_ctrlp( |
|||
&bspline, ctrlp.data(), &bspline ); |
|||
|
|||
if( err < 0 ) |
|||
throw std::runtime_error( ts_enum_str( err ) ); |
|||
} |
|||
|
|||
|
|||
void tinyspline::BSpline::setKnots( const std::vector<tinyspline::real>& knots ) |
|||
{ |
|||
if( knots.size() != nKnots() ) |
|||
{ |
|||
throw std::runtime_error( "The number of values must be equals" |
|||
"to the spline's number of knots." ); |
|||
} |
|||
|
|||
const tsError err = ts_bspline_set_knots( |
|||
&bspline, knots.data(), &bspline ); |
|||
|
|||
if( err < 0 ) |
|||
throw std::runtime_error( ts_enum_str( err ) ); |
|||
} |
|||
|
|||
|
|||
tinyspline::BSpline tinyspline::BSpline::fillKnots( const tsBSplineType type, |
|||
const tinyspline::real min, |
|||
const tinyspline::real max ) const |
|||
{ |
|||
tinyspline::BSpline bs; |
|||
const tsError err = ts_bspline_fill_knots( |
|||
&bspline, type, min, max, &bs.bspline ); |
|||
|
|||
if( err < 0 ) |
|||
throw std::runtime_error( ts_enum_str( err ) ); |
|||
|
|||
return bs; |
|||
} |
|||
|
|||
|
|||
tinyspline::BSpline tinyspline::BSpline::insertKnot( const tinyspline::real u, |
|||
const size_t n ) const |
|||
{ |
|||
tinyspline::BSpline bs; |
|||
size_t k; |
|||
const tsError err = ts_bspline_insert_knot( |
|||
&bspline, u, n, &bs.bspline, &k ); |
|||
|
|||
if( err < 0 ) |
|||
throw std::runtime_error( ts_enum_str( err ) ); |
|||
|
|||
return bs; |
|||
} |
|||
|
|||
|
|||
tinyspline::BSpline tinyspline::BSpline::resize( const int n, const int back ) const |
|||
{ |
|||
tinyspline::BSpline bs; |
|||
const tsError err = ts_bspline_resize( &bspline, n, back, &bs.bspline ); |
|||
|
|||
if( err < 0 ) |
|||
throw std::runtime_error( ts_enum_str( err ) ); |
|||
|
|||
return bs; |
|||
} |
|||
|
|||
|
|||
tinyspline::BSpline tinyspline::BSpline::split( const tinyspline::real u ) const |
|||
{ |
|||
tinyspline::BSpline bs; |
|||
size_t k; |
|||
const tsError err = ts_bspline_split( &bspline, u, &bs.bspline, &k ); |
|||
|
|||
if( err < 0 ) |
|||
throw std::runtime_error( ts_enum_str( err ) ); |
|||
|
|||
return bs; |
|||
} |
|||
|
|||
|
|||
tinyspline::BSpline tinyspline::BSpline::buckle( const tinyspline::real b ) const |
|||
{ |
|||
tinyspline::BSpline bs; |
|||
const tsError err = ts_bspline_buckle( &bspline, b, &bs.bspline ); |
|||
|
|||
if( err < 0 ) |
|||
throw std::runtime_error( ts_enum_str( err ) ); |
|||
|
|||
return bs; |
|||
} |
|||
|
|||
|
|||
tinyspline::BSpline tinyspline::BSpline::toBeziers() const |
|||
{ |
|||
tinyspline::BSpline bs; |
|||
const tsError err = ts_bspline_to_beziers( &bspline, &bs.bspline ); |
|||
|
|||
if( err < 0 ) |
|||
throw std::runtime_error( ts_enum_str( err ) ); |
|||
|
|||
return bs; |
|||
} |
|||
|
|||
|
|||
tinyspline::BSpline tinyspline::BSpline::derive() const |
|||
{ |
|||
tinyspline::BSpline bs; |
|||
const tsError err = ts_bspline_derive( &bspline, &bs.bspline ); |
|||
|
|||
if( err < 0 ) |
|||
throw std::runtime_error( ts_enum_str( err ) ); |
|||
|
|||
return bs; |
|||
} |
|||
|
|||
|
|||
#ifndef TINYSPLINE_DISABLE_CXX11_FEATURES
|
|||
tinyspline::BSpline::BSpline( tinyspline::BSpline&& other ) noexcept |
|||
{ |
|||
ts_bspline_default( &bspline ); |
|||
swap( other ); |
|||
} |
|||
|
|||
|
|||
tinyspline::BSpline& tinyspline::BSpline::operator=( tinyspline::BSpline&& other ) noexcept |
|||
{ |
|||
if( &other != this ) |
|||
{ |
|||
ts_bspline_free( &bspline ); |
|||
swap( other ); |
|||
} |
|||
|
|||
return *this; |
|||
} |
|||
|
|||
|
|||
void tinyspline::BSpline::swap( tinyspline::BSpline& other ) |
|||
{ |
|||
if( &other != this ) |
|||
{ |
|||
std::swap( bspline.deg, other.bspline.deg ); |
|||
std::swap( bspline.order, other.bspline.order ); |
|||
std::swap( bspline.dim, other.bspline.dim ); |
|||
std::swap( bspline.n_ctrlp, other.bspline.n_ctrlp ); |
|||
std::swap( bspline.n_knots, other.bspline.n_knots ); |
|||
std::swap( bspline.ctrlp, other.bspline.ctrlp ); |
|||
std::swap( bspline.knots, other.bspline.knots ); |
|||
} |
|||
} |
|||
|
|||
|
|||
#endif
|
|||
|
|||
|
|||
/********************************************************
|
|||
* * |
|||
* Utils * |
|||
* * |
|||
********************************************************/ |
|||
tinyspline::BSpline tinyspline::Utils::interpolateCubic( |
|||
const std::vector<tinyspline::real>* points, |
|||
const size_t dim ) |
|||
{ |
|||
if( dim == 0 ) |
|||
throw std::runtime_error( ts_enum_str( TS_DIM_ZERO ) ); |
|||
|
|||
if( points->size() % dim != 0 ) |
|||
throw std::runtime_error( "#points % dim == 0 failed" ); |
|||
|
|||
tinyspline::BSpline bspline; |
|||
const tsError err = ts_bspline_interpolate_cubic( |
|||
points->data(), points->size() / dim, dim, bspline.data() ); |
|||
|
|||
if( err < 0 ) |
|||
throw std::runtime_error( ts_enum_str( err ) ); |
|||
|
|||
return bspline; |
|||
} |
|||
|
|||
|
|||
bool tinyspline::Utils::fequals( const tinyspline::real x, const tinyspline::real y ) |
|||
{ |
|||
return ts_fequals( x, y ) == 1; |
|||
} |
|||
|
|||
|
|||
std::string tinyspline::Utils::enum_str( const tsError err ) |
|||
{ |
|||
return std::string( ts_enum_str( err ) ); |
|||
} |
|||
|
|||
|
|||
tsError tinyspline::Utils::str_enum( const std::string str ) |
|||
{ |
|||
return ts_str_enum( str.c_str() ); |
|||
} |
|||
@ -1,143 +0,0 @@ |
|||
/* |
|||
* The MIT License (MIT) |
|||
* |
|||
* Copyright (c) 2016 Marcel Steinbeck |
|||
* |
|||
* Permission is hereby granted, free of charge, to any person obtaining a copy |
|||
* of this software and associated documentation files (the "Software"), to deal |
|||
* in the Software without restriction, including without limitation the rights |
|||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|||
* copies of the Software, and to permit persons to whom the Software is |
|||
* furnished to do so, subject to the following conditions: |
|||
* |
|||
* The above copyright notice and this permission notice shall be included in all |
|||
* copies or substantial portions of the Software. |
|||
* |
|||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
|||
* SOFTWARE. |
|||
*/ |
|||
|
|||
#include "tinyspline.h" |
|||
#include <vector> |
|||
#include <string> |
|||
|
|||
namespace tinyspline { |
|||
typedef tsReal real; |
|||
|
|||
class DeBoorNet |
|||
{ |
|||
public: |
|||
/* Constructors & Destructors */ |
|||
DeBoorNet(); |
|||
DeBoorNet( const DeBoorNet& other ); |
|||
~DeBoorNet(); |
|||
|
|||
/* Operators */ |
|||
DeBoorNet& operator=( const DeBoorNet& other ); |
|||
|
|||
/* Getter */ |
|||
real u() const; |
|||
size_t k() const; |
|||
size_t s() const; |
|||
size_t h() const; |
|||
size_t dim() const; |
|||
size_t nPoints() const; |
|||
|
|||
std::vector<real> points() const; |
|||
|
|||
std::vector<real> result() const; |
|||
tsDeBoorNet* data(); |
|||
|
|||
/* C++11 features */ |
|||
#ifndef TINYSPLINE_DISABLE_CXX11_FEATURES |
|||
DeBoorNet( DeBoorNet&& other ) noexcept; |
|||
DeBoorNet& operator=( DeBoorNet&& other ) noexcept; |
|||
void swap( DeBoorNet& other ); |
|||
|
|||
friend void swap( DeBoorNet& left, DeBoorNet& right ) |
|||
{ |
|||
left.swap( right ); |
|||
} |
|||
|
|||
#endif |
|||
|
|||
private: |
|||
tsDeBoorNet deBoorNet; |
|||
}; |
|||
|
|||
class BSpline |
|||
{ |
|||
public: |
|||
typedef tsBSplineType type; |
|||
|
|||
/* Constructors & Destructors */ |
|||
BSpline(); |
|||
BSpline( const BSpline& other ); |
|||
explicit BSpline( size_t nCtrlp, size_t dim = 2, size_t deg = 3, |
|||
tinyspline::BSpline::type type = TS_CLAMPED ); |
|||
~BSpline(); |
|||
|
|||
/* Operators */ |
|||
BSpline& operator=( const BSpline& other ); |
|||
DeBoorNet operator()( real u ) const; |
|||
|
|||
/* Getter */ |
|||
size_t deg() const; |
|||
size_t order() const; |
|||
size_t dim() const; |
|||
size_t nCtrlp() const; |
|||
size_t nKnots() const; |
|||
|
|||
std::vector<real> ctrlp() const; |
|||
|
|||
std::vector<real> knots() const; |
|||
tsBSpline* data(); |
|||
DeBoorNet evaluate( real u ) const; |
|||
|
|||
/* Modifications */ |
|||
void setCtrlp( const std::vector<real>& ctrlp ); |
|||
void setKnots( const std::vector<real>& knots ); |
|||
|
|||
/* Transformations */ |
|||
BSpline fillKnots( tsBSplineType type, real min, real max ) const; |
|||
BSpline insertKnot( real u, size_t n ) const; |
|||
BSpline resize( int n, int back ) const; |
|||
BSpline split( real u ) const; |
|||
BSpline buckle( real b ) const; |
|||
BSpline toBeziers() const; |
|||
BSpline derive() const; |
|||
|
|||
/* C++11 features */ |
|||
#ifndef TINYSPLINE_DISABLE_CXX11_FEATURES |
|||
BSpline( BSpline&& other ) noexcept; |
|||
BSpline& operator=( BSpline&& other ) noexcept; |
|||
void swap( BSpline& other ); |
|||
|
|||
friend void swap( BSpline& left, BSpline& right ) |
|||
{ |
|||
left.swap( right ); |
|||
} |
|||
|
|||
#endif |
|||
|
|||
private: |
|||
tsBSpline bspline; |
|||
}; |
|||
|
|||
class Utils |
|||
{ |
|||
public: |
|||
static BSpline interpolateCubic( const std::vector<real>* points, size_t dim ); |
|||
static bool fequals( real x, real y ); |
|||
static std::string enum_str( tsError err ); |
|||
static tsError str_enum( std::string str ); |
|||
|
|||
private: |
|||
Utils() {} |
|||
}; |
|||
} |
|||
1707
thirdparty/tinyspline_lib/tinysplinecxx.cxx
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,960 @@ |
|||
/** @file */ |
|||
|
|||
#pragma once |
|||
|
|||
#include "tinyspline.h" |
|||
#include <vector> |
|||
#include <string> |
|||
|
|||
#ifndef TINYSPLINECXX_API |
|||
#define TINYSPLINECXX_API TINYSPLINE_API |
|||
#endif |
|||
|
|||
|
|||
|
|||
/*! @name Emscripten Extensions |
|||
* |
|||
* Please see the following references for more details on how to use |
|||
* Emscripten with C++: |
|||
* |
|||
* https://emscripten.org/docs/porting/connecting_cpp_and_javascript/embind.html |
|||
* https://emscripten.org/docs/api_reference/bind.h.html |
|||
* |
|||
* @{ |
|||
*/ |
|||
#ifdef TINYSPLINE_EMSCRIPTEN |
|||
|
|||
// Additional includes and namespaces. |
|||
#include <stdexcept> |
|||
#include <emscripten/bind.h> |
|||
using namespace emscripten; |
|||
|
|||
/* Used by value_objects to guard read-only properties. */ |
|||
void inline |
|||
cannotWrite() |
|||
{ throw std::runtime_error("cannot write read-only property"); } |
|||
|
|||
/* Allow clients to read exception messages in the Javascript binding. */ |
|||
std::string |
|||
exceptionMessage(int ptr) |
|||
{ return std::string(reinterpret_cast<std::exception *>(ptr)->what()); } |
|||
|
|||
// Map: std::vector <--> JS array |
|||
// https://github.com/emscripten-core/emscripten/issues/11070#issuecomment-717675128 |
|||
namespace emscripten { |
|||
namespace internal { |
|||
template <typename T, typename Allocator> |
|||
struct BindingType<std::vector<T, Allocator>> { |
|||
using ValBinding = BindingType<val>; |
|||
using WireType = ValBinding::WireType; |
|||
|
|||
static WireType |
|||
toWireType(const std::vector<T, Allocator> &vec) |
|||
{ return ValBinding::toWireType(val::array(vec)); } |
|||
|
|||
static std::vector<T, Allocator> |
|||
fromWireType(WireType value) |
|||
{ return vecFromJSArray<T>(ValBinding::fromWireType(value)); } |
|||
}; |
|||
|
|||
template <typename T> |
|||
struct TypeID<T, // this is ridiculous... |
|||
typename std::enable_if_t<std::is_same< |
|||
typename Canonicalized<T>::type, |
|||
std::vector<typename Canonicalized<T>::type::value_type, |
|||
typename Canonicalized<T>::type::allocator_type>>::value>> { |
|||
static constexpr TYPEID |
|||
get() { return TypeID<val>::get(); } |
|||
}; |
|||
} // namespace internal |
|||
} // namespace emscripten |
|||
#endif |
|||
/*! @} */ |
|||
|
|||
|
|||
|
|||
namespace tinyspline { |
|||
|
|||
/*! @name API Configuration |
|||
* |
|||
* @{ |
|||
*/ |
|||
typedef tsReal real; |
|||
/*! @} */ |
|||
|
|||
|
|||
|
|||
/*! @name Swig Type Mapping |
|||
* |
|||
* Methods that do not return or set the value of a class attribute (let's call |
|||
* these methods `non-accessor methods') must return/take instances of |
|||
* std::vector as pointer. Otherwise, they aren't type mapped by Swig to the |
|||
* std::vector representation of the target language. |
|||
* |
|||
* @{ |
|||
*/ |
|||
#ifdef SWIG |
|||
using std_real_vector_in = std::vector<tinyspline::real> *; |
|||
using std_real_vector_out = std::vector<tinyspline::real> *; |
|||
#else |
|||
using std_real_vector_in = const std::vector<tinyspline::real> &; |
|||
using std_real_vector_out = std::vector<tinyspline::real>; |
|||
#endif |
|||
/*! @} */ |
|||
|
|||
|
|||
|
|||
/*! @name Vector Math |
|||
* |
|||
* Wrapper classes for TinySpline's vector math. |
|||
* |
|||
* @{ |
|||
*/ |
|||
class TINYSPLINECXX_API Vec2 { |
|||
public: |
|||
Vec2(); |
|||
Vec2(real x, real y); |
|||
|
|||
Vec2 operator+(const Vec2 &other); |
|||
Vec2 operator-(const Vec2 &other); |
|||
Vec2 operator*(real scalar); |
|||
|
|||
real x() const; |
|||
void setX(real val); |
|||
real y() const; |
|||
void setY(real val); |
|||
std::vector<real> values() const; |
|||
|
|||
Vec2 add(const Vec2 &other) const; |
|||
Vec2 subtract(const Vec2 &other) const; |
|||
Vec2 multiply(real scalar) const; |
|||
Vec2 normalize() const; |
|||
TS_DEPRECATED Vec2 norm() const; |
|||
real magnitude() const; |
|||
real dot(const Vec2 &other) const; |
|||
real angle(const Vec2 &other) const; |
|||
real distance(const Vec2 &other) const; |
|||
|
|||
std::string toString() const; |
|||
|
|||
private: |
|||
real m_vals[2]; |
|||
|
|||
#ifdef TINYSPLINE_EMSCRIPTEN |
|||
public: |
|||
void setValues(std::vector<real>) { cannotWrite(); } |
|||
#endif |
|||
}; |
|||
|
|||
class TINYSPLINECXX_API Vec3 { |
|||
public: |
|||
Vec3(); |
|||
Vec3(real x, real y, real z); |
|||
|
|||
Vec3 operator+(const Vec3 &other); |
|||
Vec3 operator-(const Vec3 &other); |
|||
Vec3 operator*(real scalar); |
|||
|
|||
real x() const; |
|||
void setX(real val); |
|||
real y() const; |
|||
void setY(real val); |
|||
real z() const; |
|||
void setZ(real val); |
|||
std::vector<real> values() const; |
|||
|
|||
Vec3 add(const Vec3 &other) const; |
|||
Vec3 subtract(const Vec3 &other) const; |
|||
Vec3 multiply(real scalar) const; |
|||
Vec3 cross(const Vec3 &other) const; |
|||
Vec3 normalize() const; |
|||
TS_DEPRECATED Vec3 norm() const; |
|||
real magnitude() const; |
|||
real dot(const Vec3 &other) const; |
|||
real angle(const Vec3 &other) const; |
|||
real distance(const Vec3 &other) const; |
|||
|
|||
std::string toString() const; |
|||
|
|||
private: |
|||
real m_vals[3]; |
|||
|
|||
#ifdef TINYSPLINE_EMSCRIPTEN |
|||
public: |
|||
void setValues(std::vector<real>) { cannotWrite(); } |
|||
#endif |
|||
}; |
|||
|
|||
class TINYSPLINECXX_API Vec4 { |
|||
public: |
|||
Vec4(); |
|||
Vec4(real x, real y, real z, real w); |
|||
|
|||
Vec4 operator+(const Vec4 &other); |
|||
Vec4 operator-(const Vec4 &other); |
|||
Vec4 operator*(real scalar); |
|||
|
|||
real x() const; |
|||
void setX(real val); |
|||
real y() const; |
|||
void setY(real val); |
|||
real z() const; |
|||
void setZ(real val); |
|||
real w() const; |
|||
void setW(real val); |
|||
std::vector<real> values() const; |
|||
|
|||
Vec4 add(const Vec4 &other) const; |
|||
Vec4 subtract(const Vec4 &other) const; |
|||
Vec4 multiply(real scalar) const; |
|||
Vec4 normalize() const; |
|||
TS_DEPRECATED Vec4 norm() const; |
|||
real magnitude() const; |
|||
real dot(const Vec4 &other) const; |
|||
real angle(const Vec4 &other) const; |
|||
real distance(const Vec4 &other) const; |
|||
|
|||
std::string toString() const; |
|||
|
|||
private: |
|||
real m_vals[4]; |
|||
|
|||
#ifdef TINYSPLINE_EMSCRIPTEN |
|||
public: |
|||
void setValues(std::vector<real>) { cannotWrite(); } |
|||
#endif |
|||
}; |
|||
|
|||
#ifdef TINYSPLINE_EMSCRIPTEN |
|||
class VecMath { |
|||
public: |
|||
/*! @name Add |
|||
* |
|||
* @{ |
|||
*/ |
|||
static Vec2 |
|||
add2(const Vec2 &a, const Vec2 &b) |
|||
{ return a.add(b); } |
|||
|
|||
static Vec3 |
|||
add3(const Vec3 &a, const Vec3 &b) |
|||
{ return a.add(b); } |
|||
|
|||
static Vec4 |
|||
add4(const Vec4 &a, const Vec4 &b) |
|||
{ return a.add(b); } |
|||
/*! @} */ |
|||
|
|||
/*! @name Subtract |
|||
* |
|||
* @{ |
|||
*/ |
|||
static Vec2 |
|||
subtract2(const Vec2 &a, const Vec2 &b) |
|||
{ return a.subtract(b); } |
|||
|
|||
static Vec3 |
|||
subtract3(const Vec3 &a, const Vec3 &b) |
|||
{ return a.subtract(b); } |
|||
|
|||
static Vec4 |
|||
subtract4(const Vec4 &a, const Vec4 &b) |
|||
{ return a.subtract(b); } |
|||
/*! @} */ |
|||
|
|||
/*! @name Multiply |
|||
* |
|||
* @{ |
|||
*/ |
|||
static Vec2 |
|||
multiply2(const Vec2 &vec, real scalar) |
|||
{ return vec.multiply(scalar); } |
|||
|
|||
static Vec3 |
|||
multiply3(const Vec3 &vec, real scalar) |
|||
{ return vec.multiply(scalar); } |
|||
|
|||
static Vec4 |
|||
multiply4(const Vec4 &vec, real scalar) |
|||
{ return vec.multiply(scalar); } |
|||
/*! @} */ |
|||
|
|||
/*! @name Cross |
|||
* |
|||
* @{ |
|||
*/ |
|||
static Vec3 |
|||
cross3(const Vec3 &a, Vec3 &b) |
|||
{ return a.cross(b); } |
|||
/*! @} */ |
|||
|
|||
/*! @name Normalize |
|||
* |
|||
* @{ |
|||
*/ |
|||
static Vec2 |
|||
normalize2(const Vec2 &vec) |
|||
{ return vec.normalize(); } |
|||
|
|||
static Vec3 |
|||
normalize3(const Vec3 &vec) |
|||
{ return vec.normalize(); } |
|||
|
|||
static Vec4 |
|||
normalize4(const Vec4 &vec) |
|||
{ return vec.normalize(); } |
|||
/*! @} */ |
|||
|
|||
/*! @name Magnitude |
|||
* |
|||
* @{ |
|||
*/ |
|||
static real |
|||
magnitude2(const Vec2 &vec) |
|||
{ return vec.magnitude(); } |
|||
|
|||
static real |
|||
magnitude3(const Vec3 &vec) |
|||
{ return vec.magnitude(); } |
|||
|
|||
static real |
|||
magnitude4(const Vec4 &vec) |
|||
{ return vec.magnitude(); } |
|||
/*! @} */ |
|||
|
|||
/*! @name Dot |
|||
* |
|||
* @{ |
|||
*/ |
|||
static real |
|||
dot2(const Vec2 &a, Vec2 &b) |
|||
{ return a.dot(b); } |
|||
|
|||
static real |
|||
dot3(const Vec3 &a, Vec3 &b) |
|||
{ return a.dot(b); } |
|||
|
|||
static real |
|||
dot4(const Vec4 &a, Vec4 &b) |
|||
{ return a.dot(b); } |
|||
/*! @} */ |
|||
|
|||
/*! @name Angle |
|||
* |
|||
* @{ |
|||
*/ |
|||
static real |
|||
angle2(const Vec2 &a, Vec2 &b) |
|||
{ return a.angle(b); } |
|||
|
|||
static real |
|||
angle3(const Vec3 &a, Vec3 &b) |
|||
{ return a.angle(b); } |
|||
|
|||
static real |
|||
angle4(const Vec4 &a, Vec4 &b) |
|||
{ return a.angle(b); } |
|||
/*! @} */ |
|||
|
|||
/*! @name Distance |
|||
* |
|||
* @{ |
|||
*/ |
|||
static real |
|||
distance2(const Vec2 &a, Vec2 &b) |
|||
{ return a.distance(b); } |
|||
|
|||
static real |
|||
distance3(const Vec3 &a, Vec3 &b) |
|||
{ return a.distance(b); } |
|||
|
|||
static real |
|||
distance4(const Vec4 &a, Vec4 &b) |
|||
{ return a.distance(b); } |
|||
/*! @} */ |
|||
}; |
|||
#endif |
|||
/*! @} */ |
|||
|
|||
|
|||
|
|||
/*! @name Spline Framing |
|||
* |
|||
* Object-oriented representation of ::tsFrame (::Frame) and sequences of |
|||
* ::tsFrame (::FrameSeq). Instances of ::FrameSeq are created by |
|||
* ::BSpline::computeRMF. |
|||
* |
|||
* @{ |
|||
*/ |
|||
class TINYSPLINECXX_API Frame { |
|||
public: |
|||
Frame(Vec3 &position, |
|||
Vec3 &tangent, |
|||
Vec3 &normal, |
|||
Vec3 &binormal); |
|||
|
|||
Vec3 position() const; |
|||
Vec3 tangent() const; |
|||
Vec3 normal() const; |
|||
Vec3 binormal() const; |
|||
|
|||
std::string toString() const; |
|||
|
|||
private: |
|||
Vec3 m_position, |
|||
m_tangent, |
|||
m_normal, |
|||
m_binormal; |
|||
|
|||
#ifdef TINYSPLINE_EMSCRIPTEN |
|||
public: |
|||
Frame() {} |
|||
void setPosition(Vec3) { cannotWrite(); } |
|||
void setTangent(Vec3) { cannotWrite(); } |
|||
void setNormal(Vec3) { cannotWrite(); } |
|||
void setBinormal(Vec3) { cannotWrite(); } |
|||
#endif |
|||
}; |
|||
|
|||
class TINYSPLINECXX_API FrameSeq { |
|||
public: |
|||
FrameSeq(); |
|||
FrameSeq(const FrameSeq &other); |
|||
FrameSeq(FrameSeq &&other); |
|||
virtual ~FrameSeq(); |
|||
|
|||
FrameSeq &operator=(const FrameSeq &other); |
|||
FrameSeq &operator=(FrameSeq &&other); |
|||
|
|||
size_t size() const; |
|||
Frame at(size_t idx) const; |
|||
|
|||
std::string toString() const; |
|||
|
|||
private: |
|||
tsFrame *m_frames; |
|||
size_t m_size; |
|||
FrameSeq(tsFrame *frames, |
|||
size_t len); |
|||
friend class BSpline; |
|||
}; |
|||
/*! @} */ |
|||
|
|||
|
|||
|
|||
/*! @name Utility Classes |
|||
* |
|||
* Little helper classes, such as value classes or classes with only static |
|||
* methods. These are primarily classes that do not really fit into another |
|||
* group or are too small to form their own group. |
|||
* |
|||
* @{ |
|||
*/ |
|||
class TINYSPLINECXX_API Domain { |
|||
public: |
|||
/* Constructors & Destructors */ |
|||
Domain(real min, real max); |
|||
|
|||
/* Accessors */ |
|||
real min() const; |
|||
real max() const; |
|||
|
|||
/* Debug */ |
|||
std::string toString() const; |
|||
|
|||
private: |
|||
real m_min, |
|||
m_max; |
|||
|
|||
#ifdef TINYSPLINE_EMSCRIPTEN |
|||
public: |
|||
Domain() |
|||
: Domain(TS_DOMAIN_DEFAULT_MIN, TS_DOMAIN_DEFAULT_MAX) |
|||
{} |
|||
void setMin(real) { cannotWrite(); } |
|||
void setMax(real) { cannotWrite(); } |
|||
#endif |
|||
}; |
|||
/*! @} */ |
|||
|
|||
|
|||
|
|||
class TINYSPLINECXX_API DeBoorNet { |
|||
public: |
|||
/* Constructors & Destructors */ |
|||
DeBoorNet(const DeBoorNet &other); |
|||
DeBoorNet(DeBoorNet &&other); |
|||
virtual ~DeBoorNet(); |
|||
|
|||
/* Operators */ |
|||
DeBoorNet & operator=(const DeBoorNet &other); |
|||
DeBoorNet & operator=(DeBoorNet &&other); |
|||
|
|||
/* Accessors */ |
|||
real knot() const; |
|||
size_t index() const; |
|||
size_t multiplicity() const; |
|||
size_t numInsertions() const; |
|||
size_t dimension() const; |
|||
std::vector<real> points() const; |
|||
std::vector<real> result() const; |
|||
|
|||
/** |
|||
* Returns the result at \p idx as ::Vec2. Note that, by design, \p idx |
|||
* cannot be greater than \c 1. It is safe to call this method even if |
|||
* ::dimension is less than \c 2. In this case, the missing components |
|||
* are set to \c 0. If ::dimension is greater than \c 2, the excess |
|||
* values are ignored. |
|||
* |
|||
* @return |
|||
* The result at \p idx as ::Vec2. |
|||
* @throws std::out_of_range |
|||
* If \p idx is greater than \c 1, or if \p idx is \c 1, but there |
|||
* is only one result. |
|||
*/ |
|||
Vec2 resultVec2(size_t idx = 0) const; |
|||
|
|||
/** |
|||
* Returns the result at \p idx as ::Vec3. Note that, by design, \p idx |
|||
* cannot be greater than \c 1. It is safe to call this method even if |
|||
* ::dimension is less than \c 3. In this case, the missing components |
|||
* are set to \c 0. If ::dimension is greater than \c 3, the excess |
|||
* values are ignored. |
|||
* |
|||
* @return |
|||
* The result at \p idx as ::Vec3. |
|||
* @throws std::out_of_range |
|||
* If \p idx is greater than \c 1, or if \p idx is \c 1, but there |
|||
* is only one result. |
|||
*/ |
|||
Vec3 resultVec3(size_t idx = 0) const; |
|||
|
|||
/** |
|||
* Returns the result at \p idx as ::Vec4. Note that, by design, \p idx |
|||
* cannot be greater than \c 1. It is safe to call this method even if |
|||
* ::dimension is less than \c 4. In this case, the missing components |
|||
* are set to \c 0. If ::dimension is greater than \c 4, the excess |
|||
* values are ignored. |
|||
* |
|||
* @return |
|||
* The result at \p idx as ::Vec4. |
|||
* @throws std::out_of_range |
|||
* If \p idx is greater than \c 1, or if \p idx is \c 1, but there |
|||
* is only one result. |
|||
*/ |
|||
Vec4 resultVec4(size_t idx = 0) const; |
|||
|
|||
/* Debug */ |
|||
std::string toString() const; |
|||
|
|||
private: |
|||
tsDeBoorNet net; |
|||
|
|||
/* Constructors & Destructors */ |
|||
explicit DeBoorNet(tsDeBoorNet &data); |
|||
|
|||
friend class BSpline; |
|||
|
|||
#ifdef TINYSPLINE_EMSCRIPTEN |
|||
public: |
|||
DeBoorNet() : net(ts_deboornet_init()) {} |
|||
void setKnot(real) { cannotWrite(); } |
|||
void setIndex(size_t) { cannotWrite(); } |
|||
void setMultiplicity(size_t) { cannotWrite(); } |
|||
void setNumInsertions(size_t) { cannotWrite(); } |
|||
void setDimension(size_t) { cannotWrite(); } |
|||
void setPoints(std::vector<real>) { cannotWrite(); } |
|||
void setResult(std::vector<real>) { cannotWrite(); } |
|||
#endif |
|||
}; |
|||
|
|||
|
|||
|
|||
class Morphism; |
|||
class ChordLengths; |
|||
class TINYSPLINECXX_API BSpline { |
|||
public: |
|||
enum Type { Opened, Clamped, Beziers }; |
|||
|
|||
/* Constructors & Destructors */ |
|||
BSpline(); |
|||
BSpline(const BSpline &other); |
|||
BSpline(BSpline &&other); |
|||
explicit BSpline(size_t numControlPoints, |
|||
size_t dimension = 2, |
|||
size_t degree = 3, |
|||
Type type = Type::Clamped); |
|||
virtual ~BSpline(); |
|||
|
|||
/* Create from static method */ |
|||
static BSpline interpolateCubicNatural(std_real_vector_in points, |
|||
size_t dimension); |
|||
static BSpline interpolateCatmullRom(std_real_vector_in points, |
|||
size_t dimension, |
|||
real alpha = (real) 0.5, |
|||
std::vector<real> *first = nullptr, |
|||
std::vector<real> *last = nullptr, |
|||
real epsilon = TS_POINT_EPSILON); |
|||
static BSpline parseJson(std::string json); |
|||
static BSpline load(std::string path); |
|||
|
|||
static bool knotsEqual(real x, real y); |
|||
|
|||
/* Operators */ |
|||
BSpline & operator=(const BSpline &other); |
|||
BSpline & operator=(BSpline &&other); |
|||
DeBoorNet operator()(real u) const; |
|||
|
|||
/* Accessors */ |
|||
size_t degree() const; |
|||
size_t order() const; |
|||
size_t dimension() const; |
|||
std::vector<real> controlPoints() const; |
|||
Vec2 controlPointVec2At(size_t idx) const; |
|||
Vec3 controlPointVec3At(size_t idx) const; |
|||
Vec4 controlPointVec4At(size_t idx) const; |
|||
std::vector<real> knots() const; |
|||
real knotAt(size_t index) const; |
|||
|
|||
/* Query */ |
|||
size_t numControlPoints() const; |
|||
DeBoorNet eval(real u) const; |
|||
std_real_vector_out evalAll(std_real_vector_in knots) const; |
|||
std_real_vector_out sample(size_t num = 0) const; |
|||
DeBoorNet bisect(real value, |
|||
real epsilon = (real) 0.0, |
|||
bool persnickety = false, |
|||
size_t index = 0, |
|||
bool ascending = true, |
|||
size_t maxIter = 50) const; |
|||
Domain domain() const; |
|||
bool isClosed(real epsilon = TS_POINT_EPSILON) const; |
|||
FrameSeq computeRMF(std_real_vector_in knots, |
|||
Vec3 *firstNormal = nullptr) const; |
|||
BSpline subSpline(real knot0, real knot1) const; |
|||
std_real_vector_out uniformKnotSeq(size_t num = 100) const; |
|||
std_real_vector_out equidistantKnotSeq(size_t num = 100, |
|||
size_t numSamples = 0) const; |
|||
ChordLengths chordLengths(std_real_vector_in knots) const; |
|||
ChordLengths chordLengths(size_t numSamples = 200) const; |
|||
|
|||
/* Serialization */ |
|||
std::string toJson() const; |
|||
void save(std::string path) const; |
|||
|
|||
/* Modifications */ |
|||
void setControlPoints(const std::vector<real> &ctrlp); |
|||
void setControlPointVec2At(size_t idx, Vec2 &cp); |
|||
void setControlPointVec3At(size_t idx, Vec3 &cp); |
|||
void setControlPointVec4At(size_t idx, Vec4 &cp); |
|||
void setKnots(const std::vector<real> &knots); |
|||
void setKnotAt(size_t index, real knot); |
|||
|
|||
/* Transformations */ |
|||
BSpline insertKnot(real u, size_t n) const; |
|||
BSpline split(real u) const; |
|||
BSpline tension(real tension) const; |
|||
BSpline toBeziers() const; |
|||
BSpline derive(size_t n = 1, |
|||
real epsilon = TS_POINT_EPSILON) const; |
|||
BSpline elevateDegree(size_t amount, |
|||
real epsilon = TS_POINT_EPSILON) const; |
|||
BSpline alignWith(const BSpline &other, BSpline &otherAligned, |
|||
real epsilon = TS_POINT_EPSILON) const; |
|||
Morphism morphTo(const BSpline &other, |
|||
real epsilon = TS_POINT_EPSILON) const; |
|||
|
|||
/* Debug */ |
|||
std::string toString() const; |
|||
|
|||
private: |
|||
tsBSpline spline; |
|||
|
|||
/* Constructors & Destructors */ |
|||
explicit BSpline(tsBSpline &data); |
|||
|
|||
/* Needs to access ::spline. */ |
|||
friend class Morphism; |
|||
|
|||
#ifdef TINYSPLINE_EMSCRIPTEN |
|||
public: |
|||
std_real_vector_out sample0() const { return sample(); } |
|||
std_real_vector_out sample1(size_t num) const { return sample(num); } |
|||
BSpline derive0() const { return derive(); } |
|||
BSpline derive1(size_t n) const { return derive(n); } |
|||
BSpline derive2(size_t n, real eps) const { return derive(n, eps); } |
|||
#endif |
|||
}; |
|||
|
|||
|
|||
|
|||
/*! @name Spline Morphing |
|||
* |
|||
* @{ |
|||
*/ |
|||
class TINYSPLINECXX_API Morphism { |
|||
public: |
|||
Morphism(const BSpline &origin, |
|||
const BSpline &target, |
|||
real epsilon = TS_POINT_EPSILON); |
|||
|
|||
BSpline origin() const; |
|||
BSpline target() const; |
|||
real epsilon() const; |
|||
|
|||
BSpline eval(real t); |
|||
BSpline operator()(real t); |
|||
|
|||
std::string toString() const; |
|||
private: |
|||
BSpline m_origin, m_target; |
|||
real m_epsilon; |
|||
BSpline m_originAligned, m_targetAligned; |
|||
BSpline m_buffer; |
|||
}; |
|||
/*! @} */ |
|||
|
|||
|
|||
|
|||
/*! @name Reparametrization by Arc Length |
|||
* @{ |
|||
*/ |
|||
class TINYSPLINECXX_API ChordLengths { |
|||
public: |
|||
ChordLengths(); |
|||
ChordLengths(const ChordLengths &other); |
|||
ChordLengths(ChordLengths &&other); |
|||
virtual ~ChordLengths(); |
|||
|
|||
ChordLengths &operator=(const ChordLengths &other); |
|||
ChordLengths &operator=(ChordLengths &&other); |
|||
|
|||
BSpline spline() const; |
|||
std::vector<real> knots() const; |
|||
std::vector<real> values() const; |
|||
size_t size() const; |
|||
|
|||
real arcLength() const; |
|||
real lengthToKnot(real len) const; |
|||
real tToKnot(real t) const; |
|||
|
|||
std::string toString() const; |
|||
private: |
|||
BSpline m_spline; |
|||
real *m_knots, *m_chordLengths; |
|||
size_t m_size; |
|||
ChordLengths(const BSpline &spline, |
|||
real *knots, |
|||
real *chordLengths, |
|||
size_t size); |
|||
friend class BSpline; |
|||
}; |
|||
/*! @} */ |
|||
|
|||
} |
|||
|
|||
|
|||
|
|||
#ifdef TINYSPLINE_EMSCRIPTEN |
|||
using namespace tinyspline; |
|||
EMSCRIPTEN_BINDINGS(tinyspline) { |
|||
function("exceptionMessage", &exceptionMessage); |
|||
|
|||
// Vector Math |
|||
value_object<Vec2>("Vec2") |
|||
.field("x", |
|||
&Vec2::x, |
|||
&Vec2::setX) |
|||
.field("y", |
|||
&Vec2::y, |
|||
&Vec2::setY) |
|||
.field("values", |
|||
&Vec2::values, |
|||
&Vec2::setValues) |
|||
; |
|||
value_object<Vec3>("Vec3") |
|||
.field("x", |
|||
&Vec3::x, |
|||
&Vec3::setX) |
|||
.field("y", |
|||
&Vec3::y, |
|||
&Vec3::setY) |
|||
.field("z", |
|||
&Vec3::z, |
|||
&Vec3::setZ) |
|||
.field("values", |
|||
&Vec3::values, |
|||
&Vec3::setValues) |
|||
; |
|||
value_object<Vec4>("Vec4") |
|||
.field("x", |
|||
&Vec4::x, |
|||
&Vec4::setX) |
|||
.field("y", |
|||
&Vec4::y, |
|||
&Vec4::setY) |
|||
.field("z", |
|||
&Vec4::z, |
|||
&Vec4::setZ) |
|||
.field("w", |
|||
&Vec4::w, |
|||
&Vec4::setW) |
|||
.field("values", |
|||
&Vec4::values, |
|||
&Vec4::setValues) |
|||
; |
|||
class_<VecMath>("VecMath") |
|||
.class_function("add", &VecMath::add2) |
|||
.class_function("add", &VecMath::add3) |
|||
.class_function("add", &VecMath::add4) |
|||
.class_function("subtract", &VecMath::subtract2) |
|||
.class_function("subtract", &VecMath::subtract3) |
|||
.class_function("subtract", &VecMath::subtract4) |
|||
.class_function("multiply", &VecMath::multiply2) |
|||
.class_function("multiply", &VecMath::multiply3) |
|||
.class_function("multiply", &VecMath::multiply4) |
|||
.class_function("cross", &VecMath::cross3) |
|||
.class_function("normalize", &VecMath::normalize2) |
|||
.class_function("normalize", &VecMath::normalize3) |
|||
.class_function("normalize", &VecMath::normalize4) |
|||
.class_function("magnitude", &VecMath::magnitude2) |
|||
.class_function("magnitude", &VecMath::magnitude3) |
|||
.class_function("magnitude", &VecMath::magnitude4) |
|||
.class_function("dot", &VecMath::dot2) |
|||
.class_function("dot", &VecMath::dot3) |
|||
.class_function("dot", &VecMath::dot4) |
|||
.class_function("angle", &VecMath::angle2) |
|||
.class_function("angle", &VecMath::angle3) |
|||
.class_function("angle", &VecMath::angle4) |
|||
.class_function("distance", &VecMath::distance2) |
|||
.class_function("distance", &VecMath::distance3) |
|||
.class_function("distance", &VecMath::distance4) |
|||
; |
|||
|
|||
// Spline Framing |
|||
value_object<Frame>("Frame") |
|||
.field("position", |
|||
&Frame::position, |
|||
&Frame::setPosition) |
|||
.field("tangent", |
|||
&Frame::tangent, |
|||
&Frame::setTangent) |
|||
.field("normal", |
|||
&Frame::normal, |
|||
&Frame::setNormal) |
|||
.field("binormal", |
|||
&Frame::normal, |
|||
&Frame::setNormal) |
|||
; |
|||
class_<FrameSeq>("FrameSeq") |
|||
.constructor<>() |
|||
.constructor<FrameSeq>() |
|||
.function("size", &FrameSeq::size) |
|||
.function("at", &FrameSeq::at) |
|||
.function("toString", &FrameSeq::toString) |
|||
; |
|||
|
|||
// Utility Classes |
|||
value_object<Domain>("Domain") |
|||
.field("min", |
|||
&Domain::min, |
|||
&Domain::setMin) |
|||
.field("max", |
|||
&Domain::max, |
|||
&Domain::setMax) |
|||
; |
|||
|
|||
value_object<DeBoorNet>("DeBoorNet") |
|||
.field("knot", |
|||
&DeBoorNet::knot, |
|||
&DeBoorNet::setKnot) |
|||
.field("index", |
|||
&DeBoorNet::index, |
|||
&DeBoorNet::setIndex) |
|||
.field("multiplicity", |
|||
&DeBoorNet::multiplicity, |
|||
&DeBoorNet::setMultiplicity) |
|||
.field("numInsertions", |
|||
&DeBoorNet::numInsertions, |
|||
&DeBoorNet::setNumInsertions) |
|||
.field("dimension", |
|||
&DeBoorNet::dimension, |
|||
&DeBoorNet::setDimension) |
|||
.field("points", |
|||
&DeBoorNet::points, |
|||
&DeBoorNet::setPoints) |
|||
.field("result", |
|||
&DeBoorNet::result, |
|||
&DeBoorNet::setResult) |
|||
; |
|||
|
|||
class_<BSpline>("BSpline") |
|||
.constructor<>() |
|||
//.constructor<BSpline>() |
|||
.constructor<size_t>() |
|||
.constructor<size_t, size_t>() |
|||
.constructor<size_t, size_t, size_t>() |
|||
.constructor<size_t, size_t, size_t, BSpline::Type>() |
|||
|
|||
.class_function("interpolateCubicNatural", |
|||
&BSpline::interpolateCubicNatural) |
|||
.class_function("interpolateCatmullRom", |
|||
&BSpline::interpolateCatmullRom, |
|||
allow_raw_pointers()) |
|||
.class_function("parseJson", &BSpline::parseJson) |
|||
|
|||
.property("degree", &BSpline::degree) |
|||
.property("order", &BSpline::order) |
|||
.property("dimension", &BSpline::dimension) |
|||
.property("controlPoints", &BSpline::controlPoints, |
|||
&BSpline::setControlPoints) |
|||
.property("knots", &BSpline::knots, &BSpline::setKnots) |
|||
.property("domain", &BSpline::domain) |
|||
|
|||
/* Property by index */ |
|||
.function("knotAt", &BSpline::knotAt) |
|||
.function("setKnotAt", &BSpline::setKnotAt) |
|||
|
|||
/* Query */ |
|||
.function("numControlPoints", &BSpline::numControlPoints) |
|||
.function("eval", &BSpline::eval) |
|||
.function("evalAll", &BSpline::evalAll) |
|||
.function("sample", |
|||
select_overload<std_real_vector_out() const> |
|||
(&BSpline::sample0)) |
|||
.function("sample", |
|||
select_overload<std_real_vector_out(size_t) const> |
|||
(&BSpline::sample1)) |
|||
.function("sample", &BSpline::sample) |
|||
.function("bisect", &BSpline::bisect) |
|||
.function("isClosed", &BSpline::isClosed) |
|||
|
|||
/* Serialization */ |
|||
.function("toJson", &BSpline::toJson) |
|||
|
|||
/* Transformations */ |
|||
.function("insertKnot", &BSpline::insertKnot) |
|||
.function("split", &BSpline::split) |
|||
.function("tension", &BSpline::tension) |
|||
.function("toBeziers", &BSpline::toBeziers) |
|||
.function("derive", |
|||
select_overload<BSpline() const> |
|||
(&BSpline::derive0)) |
|||
.function("derive", |
|||
select_overload<BSpline(size_t) const> |
|||
(&BSpline::derive1)) |
|||
.function("derive", |
|||
select_overload<BSpline(size_t, real) const> |
|||
(&BSpline::derive2)) |
|||
|
|||
/* Debug */ |
|||
.function("toString", &BSpline::toString) |
|||
; |
|||
|
|||
enum_<BSpline::Type>("BSplineType") |
|||
.value("Opened", BSpline::Type::Opened) |
|||
.value("Clamped", BSpline::Type::Clamped) |
|||
.value("Beziers", BSpline::Type::Beziers) |
|||
; |
|||
} |
|||
#endif |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue