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 )
|
||||
{
|
||||
|
@ -1367,11 +1367,11 @@ void DXF_IMPORT_PLUGIN::insertSpline( double aWidth )
|
|||
tinyspline::BSpline dxfspline( m_curr_entity.m_SplineControlPointList.size(),
|
||||
/* coord dim */ 2, m_curr_entity.m_SplineDegree );
|
||||
|
||||
dxfspline.setCtrlp( ctrlp );
|
||||
dxfspline.setControlPoints( ctrlp );
|
||||
dxfspline.setKnots( m_curr_entity.m_SplineKnotsList );
|
||||
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
|
||||
{
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
set(TINYSPLINE_LIB_SRCS
|
||||
tinyspline.c
|
||||
tinysplinecpp.cpp
|
||||
tinysplinecxx.cxx
|
||||
parson.c
|
||||
)
|
||||
|
||||
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
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
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