Update tinysplice to latest
A few years worth of bug fixes
This commit is contained in:
parent
61119fbf64
commit
24ca892afb
|
@ -1316,7 +1316,7 @@ void DXF_IMPORT_PLUGIN::insertArc( const VECTOR2D& aSegStart, const VECTOR2D& aS
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#include "tinysplinecpp.h"
|
#include "tinysplinecxx.h"
|
||||||
|
|
||||||
void DXF_IMPORT_PLUGIN::insertSpline( double aWidth )
|
void DXF_IMPORT_PLUGIN::insertSpline( double aWidth )
|
||||||
{
|
{
|
||||||
|
@ -1367,11 +1367,11 @@ void DXF_IMPORT_PLUGIN::insertSpline( double aWidth )
|
||||||
tinyspline::BSpline dxfspline( m_curr_entity.m_SplineControlPointList.size(),
|
tinyspline::BSpline dxfspline( m_curr_entity.m_SplineControlPointList.size(),
|
||||||
/* coord dim */ 2, m_curr_entity.m_SplineDegree );
|
/* coord dim */ 2, m_curr_entity.m_SplineDegree );
|
||||||
|
|
||||||
dxfspline.setCtrlp( ctrlp );
|
dxfspline.setControlPoints( ctrlp );
|
||||||
dxfspline.setKnots( m_curr_entity.m_SplineKnotsList );
|
dxfspline.setKnots( m_curr_entity.m_SplineKnotsList );
|
||||||
tinyspline::BSpline beziers( dxfspline.toBeziers() );
|
tinyspline::BSpline beziers( dxfspline.toBeziers() );
|
||||||
|
|
||||||
coords = beziers.ctrlp();
|
coords = beziers.controlPoints();
|
||||||
}
|
}
|
||||||
catch( const std::runtime_error& ) //tinyspline throws everything including data validation as runtime errors
|
catch( const std::runtime_error& ) //tinyspline throws everything including data validation as runtime errors
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
set(TINYSPLINE_LIB_SRCS
|
set(TINYSPLINE_LIB_SRCS
|
||||||
tinyspline.c
|
tinyspline.c
|
||||||
tinysplinecpp.cpp
|
tinysplinecxx.cxx
|
||||||
|
parson.c
|
||||||
)
|
)
|
||||||
|
|
||||||
add_library(tinyspline_lib STATIC ${TINYSPLINE_LIB_SRCS})
|
add_library(tinyspline_lib STATIC ${TINYSPLINE_LIB_SRCS})
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2016 Marcel Steinbeck
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
in the Software without restriction, including without limitation the rights
|
in the Software without restriction, including without limitation the rights
|
||||||
|
@ -14,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
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
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
SOFTWARE.
|
SOFTWARE.
|
File diff suppressed because it is too large
Load Diff
|
@ -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
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -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() {}
|
|
||||||
};
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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
|
Loading…
Reference in New Issue