### Install C and C++ interfaces Source: https://github.com/msteinbeck/tinyspline/blob/master/BUILD.md Install the compiled libraries and configuration scripts to the system. ```bash cmake --build . --target install ``` -------------------------------- ### Install tinyspline with Go Source: https://github.com/msteinbeck/tinyspline/blob/master/README.md Get the tinyspline Go package using the go get command. ```bash go get github.com/tinyspline/go@v0.6.0 ``` -------------------------------- ### Install tinyspline with PyPI (Python) Source: https://github.com/msteinbeck/tinyspline/blob/master/README.md Install the tinyspline Python package using pip. ```bash python -m pip install tinyspline ``` -------------------------------- ### Install tinyspline with Luarocks (Lua) Source: https://github.com/msteinbeck/tinyspline/blob/master/README.md Install the tinyspline Lua package from the specified server using luarocks. ```bash luarocks install --server=https://tinyspline.github.io/lua tinyspline ``` -------------------------------- ### Install tinyspline with RubyGems (Ruby) Source: https://github.com/msteinbeck/tinyspline/blob/master/README.md Install the tinyspline Ruby gem using the gem install command. ```bash gem install tinyspline ``` -------------------------------- ### Python Example: Interpolate, Evaluate, and Visualize Spline Source: https://github.com/msteinbeck/tinyspline/blob/master/README.md This Python example demonstrates interpolating a cubic natural spline, evaluating points and tangents, and visualizing the spline with matplotlib. Ensure matplotlib is installed. ```python from tinyspline import * import matplotlib.pyplot as plt spline = BSpline.interpolate_cubic_natural( [ 100, -100, # P1 -100, 200, # P2 100, 400, # P3 400, 300, # P4 700, 500 # P5 ], 2) # <- dimensionality of the points # Draw spline as polyline. points = spline.sample(100) x = points[0::2] y = points[1::2] plt.plot(x, y) # Draw point at knot 0.3. vec2 = spline.eval(0.3).result_vec2() plt.plot(vec2.x, vec2.y, 'ro') # Draw tangent at knot 0.7. pos = spline(0.7).result_vec2() # operator () -> eval der = spline.derive()(0.7).result_vec2().normalize() * 200 s = pos - der t = pos + der plt.plot([s.x, t.x], [s.y, t.y]) # Draw 15 normals with equidistant distribution. knots = spline.equidistant_knot_seq(15) frames = spline.compute_rmf(knots) for i in range(frames.size()): pos = frames.at(i).position nor = pos + frames.at(i).normal * 20 # You can also fetch the tangent and binormal: # frames.at(i).tangent # frames.at(i).binormal plt.plot([pos.x, nor.x], [pos.y, nor.y], 'g') plt.show() ``` -------------------------------- ### Install TinySpline C++ Library Source: https://github.com/msteinbeck/tinyspline/blob/master/src/CMakeLists.txt Configures the installation of the TinySpline C++ library targets, headers, and CMake configuration files. ```cmake target_include_directories( tinysplinecxx PUBLIC $ $ ) install( TARGETS tinysplinecxx EXPORT tinysplinecxx RUNTIME DESTINATION ${TINYSPLINE_INSTALL_BINARY_DIR} LIBRARY DESTINATION ${TINYSPLINE_INSTALL_LIBRARY_DIR} ARCHIVE DESTINATION ${TINYSPLINE_INSTALL_LIBRARY_DIR} PUBLIC_HEADER DESTINATION ${TINYSPLINE_INSTALL_INCLUDE_DIR} ) install( EXPORT tinysplinecxx DESTINATION "${TINYSPLINE_CXX_INSTALL_CMAKE_CONFIG_DIR}" NAMESPACE "tinysplinecxx::" FILE "${TINYSPLINE_CXX_LIBRARY_OUTPUT_NAME}-targets.cmake" ) ``` ```cmake configure_package_config_file( "pkg/tinysplinecxx-config.cmake.in" "${TINYSPLINE_BINARY_DIR}/${TINYSPLINE_CXX_LIBRARY_OUTPUT_NAME}-config.cmake" INSTALL_DESTINATION "${TINYSPLINE_CXX_INSTALL_CMAKE_CONFIG_DIR}" PATH_VARS TINYSPLINE_INSTALL_INCLUDE_DIR TINYSPLINE_INSTALL_LIBRARY_DIR TINYSPLINE_INSTALL_BINARY_DIR ) write_basic_package_version_file( "${TINYSPLINE_BINARY_DIR}/${TINYSPLINE_CXX_LIBRARY_OUTPUT_NAME}-config-version.cmake" VERSION ${TINYSPLINE_VERSION} COMPATIBILITY ExactVersion ) install( FILES "${TINYSPLINE_BINARY_DIR}/${TINYSPLINE_CXX_LIBRARY_OUTPUT_NAME}-config.cmake" "${TINYSPLINE_BINARY_DIR}/${TINYSPLINE_CXX_LIBRARY_OUTPUT_NAME}-config-version.cmake" DESTINATION "${TINYSPLINE_CXX_INSTALL_CMAKE_CONFIG_DIR}" ) ``` ```cmake list(APPEND TINYSPLINE_PKGCONFIG_CXX_LINK_LIBRARIES "${TINYSPLINE_CXX_LIBRARY_OUTPUT_NAME}" ) if(NOT BUILD_SHARED_LIBS) list(APPEND TINYSPLINE_PKGCONFIG_CXX_LINK_LIBRARIES "${TINYSPLINE_CXX_LINK_LIBRARIES}" ) endif() list(JOIN TINYSPLINE_PKGCONFIG_CXX_LINK_LIBRARIES " -l" TINYSPLINE_PKGCONFIG_CXX_LINK_LIBRARIES ) set(TINYSPLINE_PKGCONFIG_CXX_LINK_LIBRARIES "-l${TINYSPLINE_PKGCONFIG_CXX_LINK_LIBRARIES}" ) configure_file( "pkg/tinysplinecxx.pc.in" "${TINYSPLINE_BINARY_DIR}/${TINYSPLINE_CXX_LIBRARY_OUTPUT_NAME}.pc" @ONLY ) install( FILES "${TINYSPLINE_BINARY_DIR}/${TINYSPLINE_CXX_LIBRARY_OUTPUT_NAME}.pc" DESTINATION "${TINYSPLINE_INSTALL_PKGCONFIG_PATH}" ) ``` -------------------------------- ### StrUtil.c Implementation Source: https://github.com/msteinbeck/tinyspline/blob/master/test/cutest/README.txt Example implementation of a string utility function and its corresponding test case using CuTest. ```c #include "CuTest.h" char* StrToUpper(char* str) { return str; } void TestStrToUpper(CuTest *tc) { char* input = strdup("hello world"); char* actual = StrToUpper(input); char* expected = "HELLO WORLD"; CuAssertStrEquals(tc, expected, actual); } CuSuite* StrUtilGetSuite() { CuSuite* suite = CuSuiteNew(); SUITE_ADD_TEST(suite, TestStrToUpper); return suite; } ``` -------------------------------- ### Install tinyspline with NuGet (C#) Source: https://github.com/msteinbeck/tinyspline/blob/master/README.md Add the tinyspline package to your C# project using NuGet. ```xml ``` -------------------------------- ### Install tinyspline with Maven (Java) Source: https://github.com/msteinbeck/tinyspline/blob/master/README.md Add the tinyspline dependency to your Java project using Maven. ```xml org.tinyspline tinyspline 0.6.0-1 ``` -------------------------------- ### Link Executable using CMake Targets Source: https://github.com/msteinbeck/tinyspline/blob/master/test/pkg/CMakeLists.txt Examples of creating C and C++ executable targets and linking them against TinySpline using CMake's target-based linking. ```cmake # Check if libraries can be linked using CMake targets. add_executable(testc_target test.c) target_link_libraries(testc_target tinyspline::tinyspline) add_executable(testcxx_target test.cxx) target_link_libraries(testcxx_target tinysplinecxx::tinysplinecxx) ``` -------------------------------- ### Setup Control Points for a Spline Source: https://context7.com/msteinbeck/tinyspline/llms.txt Set the control points for a spline by directly assigning to the `control_points` attribute. Ensure the control points are provided as a flat list of coordinates. ```python ctrlp = spline.control_points ctrlp[0], ctrlp[1] = 100, -100 # P1 ctrlp[2], ctrlp[3] = -100, 200 # P2 ctrlp[4], ctrlp[5] = 100, 400 # P3 ctrlp[6], ctrlp[7] = 400, 300 # P4 ctrlp[8], ctrlp[9] = 700, 500 # P5 ctrlp[10], ctrlp[11] = 600, 200 # P6 ctrlp[12], ctrlp[13] = 500, 100 # P7 spline.control_points = ctrlp ``` -------------------------------- ### Clone and enter the repository Source: https://github.com/msteinbeck/tinyspline/blob/master/BUILD.md Initial steps to download the source code and navigate to the project directory. ```bash git clone https://github.com/msteinbeck/tinyspline.git tinyspline cd tinyspline ``` -------------------------------- ### Create and enter build directory Source: https://github.com/msteinbeck/tinyspline/blob/master/BUILD.md Standard practice to perform out-of-source builds using CMake. ```bash mkdir build cd build ``` -------------------------------- ### Run CMake and build the project Source: https://github.com/msteinbeck/tinyspline/blob/master/BUILD.md Standard commands to configure the build system and compile the project. ```bash cmake .. cmake --build . ``` -------------------------------- ### Enable all interfaces Source: https://github.com/msteinbeck/tinyspline/blob/master/BUILD.md Build all supported language bindings simultaneously. ```bash cmake -DTINYSPLINE_ENABLE_ALL_INTERFACES=True .. cmake --build . ``` -------------------------------- ### Compile and Run Tests with StrUtil Source: https://github.com/msteinbeck/tinyspline/blob/master/test/cutest/README.txt Compile the test suite including StrUtil.c and run the tests. Replace gcc with your preferred compiler. ```bash gcc AllTests.c CuTest.c StrUtil.c ``` -------------------------------- ### Release Docker Image Source: https://github.com/msteinbeck/tinyspline/blob/master/tools/ci/README.md Logs into Docker, tags an existing image, and pushes it to the Docker Hub repository 'tinyspline/build-deps'. Replace and with your credentials and the image ID. ```shell docker login -u tinyspline -p docker tag tinyspline/build-deps:latest docker push tinyspline/build-deps ``` -------------------------------- ### Evaluate Spline at Specific Knot Source: https://context7.com/msteinbeck/tinyspline/llms.txt Evaluate the spline at a specific knot value (u) to get the corresponding point. The `result_vec2()` method returns the 2D coordinates. ```python # Evaluate at specific knot result = spline_interp.eval(0.5).result_vec2() plt.plot(result.x, result.y, 'ro', label='u=0.5') ``` -------------------------------- ### Compile and Run AllTests Source: https://github.com/msteinbeck/tinyspline/blob/master/test/cutest/README.txt Compile and run all unit tests for CuTest. Replace cl.exe with your preferred compiler. ```bash cl.exe AllTests.c CuTest.c CuTestTest.c AllTests.exe ``` -------------------------------- ### Morphing Between Splines in Python Source: https://context7.com/msteinbeck/tinyspline/llms.txt Create a morphing spline that smoothly interpolates between two existing splines. The `morph_to` method automatically aligns the splines. Evaluate the morphed spline at different time points to get intermediate shapes. ```python from tinyspline import * # Create start spline start = BSpline(7, 2, 3) ctrlp = start.control_points ctrlp[0], ctrlp[1] = 120, 100 ctrlp[2], ctrlp[3] = 270, 40 ctrlp[4], ctrlp[5] = 370, 490 ctrlp[6], ctrlp[7] = 590, 40 ctrlp[8], ctrlp[9] = 570, 490 ctrlp[10], ctrlp[11] = 420, 480 ctrlp[12], ctrlp[13] = 220, 500 start.control_points = ctrlp # Create end spline (different degree and control points) end = BSpline(5, 2, 4) ctrlp = end.control_points ctrlp[0], ctrlp[1] = 60, 150 ctrlp[2], ctrlp[3] = 200, 300 ctrlp[4], ctrlp[5] = 370, 490 ctrlp[6], ctrlp[7] = 590, 40 ctrlp[8], ctrlp[9] = 570, 490 end.control_points = ctrlp # Create morphism (automatically aligns splines) morph = start.morph_to(end) # Evaluate at different time points for t in [0.0, 0.25, 0.5, 0.75, 1.0]: intermediate = morph.eval(t) points = intermediate.sample(50) print(f"t={t}: {len(points)//2} points sampled") # At t=0, result equals start; at t=1, result equals end ``` -------------------------------- ### Build Test Utilities Source: https://github.com/msteinbeck/tinyspline/blob/master/test/CMakeLists.txt Creates a static library for test utilities and links it against cutest and tinyspline. ```cmake add_library(testutils STATIC "testutils.c") target_include_directories(testutils PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}") target_link_libraries(testutils PUBLIC cutest tinyspline) ``` -------------------------------- ### Set CMake Policy CMP0122 to NEW for CMake >= 3.21 Source: https://github.com/msteinbeck/tinyspline/blob/master/src/CMakeLists.txt Enables new behavior for SWIG library generation starting with CMake 3.21. This policy ensures compatibility with newer CMake versions and their default naming conventions for SWIG-generated libraries. ```cmake if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.21.0") cmake_policy(SET CMP0122 NEW) endif() ``` -------------------------------- ### Initialize Spline (Python) Source: https://context7.com/msteinbeck/tinyspline/llms.txt Basic initialization of a cubic spline using the Python bindings. ```python from tinyspline import * import matplotlib.pyplot as plt # Create a cubic spline with 7 control points in 2D spline = BSpline(7, 2, 3, BSpline.Clamped) ``` -------------------------------- ### Link Executable using CMake Variables Source: https://github.com/msteinbeck/tinyspline/blob/master/test/pkg/CMakeLists.txt Demonstrates creating C and C++ executable targets and linking them against TinySpline using CMake variables for libraries. ```cmake # Check if libraries can be linked using CMake variables. add_executable(testc_variable test.c) target_link_libraries(testc_variable ${TINYSPLINE_LIBRARIES}) add_executable(testcxx_variable test.cxx) target_link_libraries(testcxx_variable ${TINYSPLINECXX_LIBRARIES}) ``` -------------------------------- ### Extract Go package Source: https://github.com/msteinbeck/tinyspline/blob/master/tools/release/README.md Unzip the Go package archive into the designated directory. ```shell unzip -d go -o tinyspline/tinyspline-go.zip ``` -------------------------------- ### Build Docker Image Source: https://github.com/msteinbeck/tinyspline/blob/master/tools/ci/README.md Builds a Docker image tagged 'tinyspline/build-deps:latest' using the Dockerfile in the current directory. ```shell docker build -t tinyspline/build-deps:latest -f Dockerfile . ``` -------------------------------- ### Build FLTK UI Wrapper and Executable Source: https://github.com/msteinbeck/tinyspline/blob/master/examples/cxx/fltk/CMakeLists.txt Finds FLTK and OpenGL, includes necessary directories, wraps the UI definition, and links libraries for a demo executable. This snippet is conditional on FLTK and OpenGL being found. ```cmake find_package(FLTK) if(FLTK_FOUND AND OPENGL_FOUND) include_directories(${FLTK_INCLUDE_DIR}) include_directories(${CMAKE_CURRENT_SOURCE_DIR}) fltk_wrap_ui(demo-ui demo.fl) add_library(demo-ui ${demo-ui_FLTK_UI_SRCS}) if(${TINYSPLINE_PLATFORM_IS_WINDOWS}) target_compile_definitions(demo-ui PUBLIC WIN32) endif() target_link_libraries( demo-ui PUBLIC ${FLTK_LIBRARIES} ${OPENGL_LIBRARIES} tinysplinecxx ) add_executable(demo main.cxx eval.h sample.h frames.h) add_dependencies(demo demo-ui) target_link_libraries(demo PUBLIC demo-ui) endif() ``` -------------------------------- ### Generate Luarocks manifest Source: https://github.com/msteinbeck/tinyspline/blob/master/tools/release/README.md Create a manifest file for Luarocks after copying binary rocks into the repository root. ```shell luarocks-admin make-manifest . ``` -------------------------------- ### Upload PyPI packages Source: https://github.com/msteinbeck/tinyspline/blob/master/tools/release/README.md Use twine to upload built packages to the PyPI repository. ```shell python -m twine upload pypi/* ``` -------------------------------- ### Enable C++ Linkage Support Source: https://github.com/msteinbeck/tinyspline/blob/master/test/cutest/CHANGES.txt Wraps CuTest header declarations in extern "C" blocks to ensure compatibility when linking with C++ binaries. ```c #ifdef __cplusplus extern "C" { #endif #define CUTEST_VERSION "CuTest 1.5" /* CuString */ ... void CuSuiteRun(CuSuite* testSuite); void CuSuiteSummary(CuSuite* testSuite, CuString* summary); void CuSuiteDetails(CuSuite* testSuite, CuString* details); #ifdef __cplusplus } #endif ``` -------------------------------- ### Create and Configure B-Spline in C Source: https://context7.com/msteinbeck/tinyspline/llms.txt Demonstrates creating a cubic B-Spline with specified control points, dimension, and knot vector type. Control points and spline properties can be accessed and modified after creation. ```c #include "tinyspline.h" #include #include int main() { tsBSpline spline; tsReal *ctrlp; // Create a cubic spline with 7 control points in 2D using a clamped knot vector ts_bspline_new( 7, // number of control points 2, // dimension (2D) 3, // degree (cubic) TS_CLAMPED, // clamped knot vector &spline, NULL ); // Get and set control points ts_bspline_control_points(&spline, &ctrlp, NULL); ctrlp[0] = -1.75; ctrlp[1] = -1.0; // P0 ctrlp[2] = -1.5; ctrlp[3] = -0.5; // P1 ctrlp[4] = -1.5; ctrlp[5] = 0.0; // P2 ctrlp[6] = -1.25; ctrlp[7] = 0.5; // P3 ctrlp[8] = -0.75; ctrlp[9] = 0.75; // P4 ctrlp[10] = 0.0; ctrlp[11] = 0.5; // P5 ctrlp[12] = 0.5; ctrlp[13] = 0.0; // P6 ts_bspline_set_control_points(&spline, ctrlp, NULL); printf("Degree: %zu\n", ts_bspline_degree(&spline)); // Output: 3 printf("Dimension: %zu\n", ts_bspline_dimension(&spline)); // Output: 2 printf("Control Points: %zu\n", ts_bspline_num_control_points(&spline)); // Output: 7 printf("Knots: %zu\n", ts_bspline_num_knots(&spline)); // Output: 11 free(ctrlp); ts_bspline_free(&spline); return 0; } ``` -------------------------------- ### Build CuTest Library Source: https://github.com/msteinbeck/tinyspline/blob/master/test/CMakeLists.txt Compiles the CuTest static library and configures include directories, with specific handling for MSVC compiler warnings. ```cmake add_library(cutest STATIC "cutest/CuTest.c") target_include_directories(cutest PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/cutest") if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") # Disable warnings regarding sprintf. target_compile_definitions(cutest PRIVATE _CRT_SECURE_NO_WARNINGS) endif() ``` -------------------------------- ### Perform Vector Math Operations Source: https://context7.com/msteinbeck/tinyspline/llms.txt Demonstrates common vector operations including addition, subtraction, dot product, cross product, normalization, and distance calculation. ```c #include "tinyspline.h" #include int main() { tsReal v1[3] = {1.0, 0.0, 0.0}; tsReal v2[3] = {0.0, 1.0, 0.0}; tsReal result[3]; // Vector addition ts_vec_add(v1, v2, 3, result); printf("v1 + v2 = (%f, %f, %f)\n", result[0], result[1], result[2]); // Vector subtraction ts_vec_sub(v1, v2, 3, result); printf("v1 - v2 = (%f, %f, %f)\n", result[0], result[1], result[2]); // Dot product tsReal dot = ts_vec_dot(v1, v2, 3); printf("v1 . v2 = %f\n", dot); // Cross product (3D only) ts_vec3_cross(v1, v2, result); printf("v1 x v2 = (%f, %f, %f)\n", result[0], result[1], result[2]); // Magnitude (length) tsReal mag = ts_vec_mag(v1, 3); printf("|v1| = %f\n", mag); // Normalize ts_vec_norm(v1, 3, result); printf("normalize(v1) = (%f, %f, %f)\n", result[0], result[1], result[2]); // Scalar multiplication ts_vec_mul(v1, 3, 2.0, result); printf("v1 * 2 = (%f, %f, %f)\n", result[0], result[1], result[2]); // Angle between vectors (in degrees) tsReal buf[6]; // buffer for normalization tsReal angle = ts_vec_angle(v1, v2, buf, 3); printf("angle(v1, v2) = %f degrees\n", angle); // Distance between points tsReal p1[2] = {0.0, 0.0}; tsReal p2[2] = {3.0, 4.0}; tsReal dist = ts_distance(p1, p2, 2); printf("distance = %f\n", dist); // Output: 5.0 return 0; } ``` -------------------------------- ### C++ BSpline Initialization and Control Points Source: https://context7.com/msteinbeck/tinyspline/llms.txt Create a cubic spline with a specified number of control points and dimension using the C++ API. Control points are set using a vector of real numbers. ```cpp #include "tinysplinecxx.h" #include #include int main() { using namespace tinyspline; // Create a cubic spline with 7 control points in 2D BSpline spline(7, 2, 3, BSpline::Clamped); // Set control points std::vector ctrlp = { -1.75, -1.0, // P0 -1.5, -0.5, // P1 -1.5, 0.0, // P2 -1.25, 0.5, // P3 -0.75, 0.75, // P4 0.0, 0.5, // P5 0.5, 0.0 // P6 }; spline.setControlPoints(ctrlp); // Interpolate from points std::vector points = {100, 100, 200, 300, 400, 200, 500, 400}; BSpline interp = BSpline::interpolateCubicNatural(points, 2); // Evaluate at u = 0.5 DeBoorNet net = spline.eval(0.5); Vec2 result = net.resultVec2(); std::cout << "Point at u=0.5: (" << result.x() << ", " << result.y() << ")\n"; // Alternative: use operator() Vec2 point = spline(0.3).resultVec2(); // Sample the curve std::vector samples = spline.sample(100); std::cout << "Sampled " << samples.size() / 2 << " points\n"; // Derive and convert to Beziers BSpline derivative = spline.derive(); BSpline beziers = spline.toBeziers(); // Check if closed if (spline.isClosed()) { std::cout << "Spline is closed\n"; } // Get domain Domain dom = spline.domain(); std::cout << "Domain: [" << dom.min() << ", " << dom.max() << "]\n"; // Serialize to JSON std::string json = spline.toJson(); BSpline loaded = BSpline::parseJson(json); // Save and load from file spline.save("curve.json"); BSpline fromFile = BSpline::load("curve.json"); return 0; } ``` -------------------------------- ### Create Code Coverage Report with CMake Source: https://github.com/msteinbeck/tinyspline/blob/master/test/c/CMakeLists.txt Sets up the build for code coverage analysis. It creates a separate executable for coverage, links required libraries and flags, and defines a custom target 'tinyspline_coverage' to run lcov and genhtml. ```cmake if(TINYSPLINE_COVERAGE_AVAILABLE) add_executable( tinyspline_tests_coverage EXCLUDE_FROM_ALL ${TINYSPLINE_TESTS_SOURCE_FILES} ${TINYSPLINE_C_SOURCE_FILES} ) target_include_directories( tinyspline_tests_coverage PRIVATE ${TINYSPLINE_C_INCLUDE_DIR} ) set_target_properties( tinyspline_tests_coverage PROPERTIES COMPILE_FLAGS ${TINYSPLINE_COVERAGE_C_FLAGS} ) target_link_libraries( tinyspline_tests_coverage PRIVATE testutils ${TINYSPLINE_COVERAGE_C_LIBRARIES} ${TINYSPLINE_C_LINK_LIBRARIES} ) set(TINYSPLINE_COVERAGE_INFO_FILE coverage.info) add_custom_target( tinyspline_coverage COMMAND ${TINYSPLINE_LCOV} --directory . --zerocounters COMMAND tinyspline_tests_coverage COMMAND ${TINYSPLINE_LCOV} --rc lcov_branch_coverage=1 --directory . --capture --output-file ${TINYSPLINE_COVERAGE_INFO_FILE} COMMAND ${TINYSPLINE_LCOV} --rc lcov_branch_coverage=1 --extract ${TINYSPLINE_COVERAGE_INFO_FILE} '*tinyspline.c' --output-file ${TINYSPLINE_COVERAGE_INFO_FILE} COMMAND ${TINYSPLINE_GENHTML} --rc genhtml_branch_coverage=1 -o ${TINYSPLINE_COVERAGE_OUTPUT_DIRECTORY}/c ${TINYSPLINE_COVERAGE_INFO_FILE} COMMAND ${CMAKE_COMMAND} -E remove ${TINYSPLINE_COVERAGE_INFO_FILE} DEPENDS tinyspline_tests_coverage ) endif() ``` -------------------------------- ### Configure Compiler Standards Source: https://github.com/msteinbeck/tinyspline/blob/master/test/CMakeLists.txt Sets the C++ standard to 11 and enforces it for the build. ```cmake set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) ``` -------------------------------- ### Serialize and Deserialize Splines (C) Source: https://context7.com/msteinbeck/tinyspline/llms.txt Demonstrates converting splines to JSON strings or files and loading them back into memory. Remember to free the allocated JSON string and spline objects. ```c #include "tinyspline.h" #include #include int main() { tsBSpline original, loaded; char *json; // Create and setup a spline tsReal points[15] = { 1, -1, 0, -1, 2, 0, 1, 4, 0, 4, 3, 0, 7, 5, 0 }; ts_bspline_interpolate_cubic_natural(points, 5, 3, &original, NULL); // Serialize to JSON string ts_bspline_to_json(&original, &json, NULL); printf("JSON:\n%s\n", json); // Parse JSON back to spline ts_bspline_parse_json(json, &loaded, NULL); printf("\nLoaded spline: degree=%zu, control_points=%zu\n", ts_bspline_degree(&loaded), ts_bspline_num_control_points(&loaded)); // Save to file ts_bspline_save(&original, "spline.json", NULL); // Load from file tsBSpline from_file; ts_bspline_load("spline.json", &from_file, NULL); free(json); ts_bspline_free(&original); ts_bspline_free(&loaded); ts_bspline_free(&from_file); return 0; } ``` -------------------------------- ### Configure CMake Tests and Environment Variables Source: https://github.com/msteinbeck/tinyspline/blob/master/test/pkg/CMakeLists.txt Enables testing and registers test executables. On Windows, it sets the PATH environment variable to include binary directories for library resolution. ```cmake enable_testing() add_test(testc_target testc_target) add_test(testcxx_target testcxx_target) add_test(testc_variable testc_variable) add_test(testcxx_variable testcxx_variable) if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows") set_tests_properties( testc_target PROPERTIES ENVIRONMENT "PATH=${TINYSPLINE_BINARY_DIRS};$ENV{PATH}" ) set_tests_properties( testcxx_target PROPERTIES ENVIRONMENT "PATH=${TINYSPLINECXX_BINARY_DIRS};$ENV{PATH}" ) set_tests_properties( testc_variable PROPERTIES ENVIRONMENT "PATH=${TINYSPLINE_BINARY_DIRS};$ENV{PATH}" ) set_tests_properties( testcxx_variable PROPERTIES ENVIRONMENT "PATH=${TINYSPLINECXX_BINARY_DIRS};$ENV{PATH}" ) endif() ``` -------------------------------- ### Build a specific language interface Source: https://github.com/msteinbeck/tinyspline/blob/master/BUILD.md Use the TINYSPLINE_ENABLE_ flag to selectively build language bindings. ```bash cmake -DTINYSPLINE_ENABLE_PYTHON=True .. cmake --build . tinysplinepython ``` -------------------------------- ### Run Compiled Tests Source: https://github.com/msteinbeck/tinyspline/blob/master/test/cutest/README.txt Execute the compiled test program. ```bash a.out ``` -------------------------------- ### Define Custom Build Targets Source: https://github.com/msteinbeck/tinyspline/blob/master/test/CMakeLists.txt Creates custom targets for running tests and generating coverage reports. ```cmake add_custom_target( tests DEPENDS tinyspline_tests tinysplinecxx_tests COMMAND tinyspline_tests COMMAND tinysplinecxx_tests ) add_custom_target(coverage DEPENDS tinyspline_coverage tinysplinecxx_coverage) ``` -------------------------------- ### Configure Coverage Output and Flags Source: https://github.com/msteinbeck/tinyspline/blob/master/test/CMakeLists.txt Sets the output directory for coverage reports and defines the necessary compiler flags and libraries. ```cmake set(TINYSPLINE_COVERAGE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/coverage) set_directory_properties( PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${TINYSPLINE_COVERAGE_OUTPUT_DIRECTORY}" ) # TINYSPLINE_COVERAGE_C_FLAGS TINYSPLINE_COVERAGE_CXX_FLAGS set(TINYSPLINE_COVERAGE_C_FLAGS "-g -O0 -fprofile-arcs -ftest-coverage") set(TINYSPLINE_COVERAGE_CXX_FLAGS "-g -O0 -fprofile-arcs -ftest-coverage") # TINYSPLINE_COVERAGE_C_LIBRARIES TINYSPLINE_COVERAGE_CXX_LIBRARIES set(TINYSPLINE_COVERAGE_C_LIBRARIES "-lgcov") set(TINYSPLINE_COVERAGE_CXX_LIBRARIES "-lgcov") ``` -------------------------------- ### Configure SWIG bindings for C# and D Source: https://github.com/msteinbeck/tinyspline/blob/master/src/CMakeLists.txt Main execution block that validates platform requirements and invokes the binding generation for C# and D languages. ```cmake if(${TINYSPLINE_BINDING_REQUESTED}) if(${TINYSPLINE_PLATFORM_NAME} STREQUAL "undefined") message(FATAL_ERROR "Cannot build bindings for undefined platform name") endif() if(${TINYSPLINE_PLATFORM_ARCH} STREQUAL "unknown") message( FATAL_ERROR "Cannot build bindings for unknown platform architecture" ) endif() find_package(SWIG 4.0.2 REQUIRED) include(${SWIG_USE_FILE}) include_directories(${CMAKE_CURRENT_SOURCE_DIR}) # C# if(${TINYSPLINE_ENABLE_CSHARP}) tinyspline_add_swig_library( TARGET ${TINYSPLINE_CSHARP_CMAKE_TARGET} LANG csharp OUTPUT ${TINYSPLINE_CSHARP_SOURCE_DIRECTORY} SWIG_ARGS -namespace TinySpline ) # DLL find_package(CSharp) if(CSHARP_FOUND) if(${CSHARP_TYPE} STREQUAL ".NET") string(SUBSTRING ${CSHARP_DOTNET_VERSION} 1 3 TINYSPLINE_CSHARP_FRAMEWORK_VERSION ) # csc does not support '/' in 'recursive'. add_custom_command( TARGET ${TINYSPLINE_CSHARP_CMAKE_TARGET} POST_BUILD COMMAND ${CSHARP_COMPILER} /target:library /out:"${TINYSPLINE_CSHARP_INTERFACE_FILE}" /recurse:"${TINYSPLINE_CSHARP_SOURCE_DIRECTORY}\\*.cs" ) else() set(TINYSPLINE_CSHARP_FRAMEWORK_VERSION "4.5") add_custom_command( TARGET ${TINYSPLINE_CSHARP_CMAKE_TARGET} POST_BUILD COMMAND ${CSHARP_COMPILER} -sdk:4.5 -target:library -out:"${TINYSPLINE_CSHARP_INTERFACE_FILE}" -recurse:"${TINYSPLINE_CSHARP_SOURCE_DIRECTORY}/*.cs" ) endif() endif() endif() # D if(${TINYSPLINE_ENABLE_DLANG}) tinyspline_add_swig_library( TARGET ${TINYSPLINE_DLANG_CMAKE_TARGET} LANG d OUTPUT ${TINYSPLINE_DLANG_SOURCE_DIRECTORY} SWIG_ARGS -d2 -wrapperlibrary ${TINYSPLINE_DLANG_CMAKE_TARGET} -module ${TINYSPLINE_PACKAGE_NAME} ) add_custom_command( TARGET ${TINYSPLINE_DLANG_CMAKE_TARGET} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy "${TINYSPLINE_DLANG_SOURCE_DIRECTORY}/${TINYSPLINE_PACKAGE_NAME}.d" "${TINYSPLINE_DLANG_INTERFACE_FILE}" ``` -------------------------------- ### Configure Multi-Config Builds in CMake Source: https://github.com/msteinbeck/tinyspline/blob/master/src/CMakeLists.txt This CMake script iterates through `CMAKE_CONFIGURATION_TYPES` to set runtime, library, and archive output directories for each configuration, ensuring consistent output locations. ```cmake foreach(TINYSPLINE_CONFIG ${CMAKE_CONFIGURATION_TYPES}) string(TOUPPER ${TINYSPLINE_CONFIG} TINYSPLINE_CONFIG) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${TINYSPLINE_CONFIG}_BACKUP ${CMAKE_RUNTIME_OUTPUT_DIRECTORY_${TINYSPLINE_CONFIG}} ) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_${TINYSPLINE_CONFIG}_BACKUP ${CMAKE_LIBRARY_OUTPUT_DIRECTORY_${TINYSPLINE_CONFIG}} ) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${TINYSPLINE_CONFIG}_BACKUP ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${TINYSPLINE_CONFIG}} ) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${TINYSPLINE_CONFIG} ${TINYSPLINE_OUTPUT_DIRECTORY} ) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_${TINYSPLINE_CONFIG} ${TINYSPLINE_OUTPUT_DIRECTORY} ) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${TINYSPLINE_CONFIG} ${TINYSPLINE_OUTPUT_DIRECTORY} ) endforeach() ``` -------------------------------- ### Create Unit Tests with CMake Source: https://github.com/msteinbeck/tinyspline/blob/master/test/c/CMakeLists.txt Defines the unit tests for the tinyspline library. It finds all C source files, creates an executable, and links necessary libraries. Conditional logic is included for Emscripten and Windows environments. ```cmake file(GLOB_RECURSE TINYSPLINE_TESTS_SOURCE_FILES "*.c") add_executable(tinyspline_tests ${TINYSPLINE_TESTS_SOURCE_FILES}) target_link_libraries(tinyspline_tests PRIVATE testutils) if(EMSCRIPTEN) add_test(NAME tinyspline_tests COMMAND $ENV{EMSDK_NODE} tinyspline_tests) else() add_test(tinyspline_tests tinyspline_tests) endif() if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows") set_tests_properties( tinyspline_tests PROPERTIES ENVIRONMENT "PATH=${TINYSPLINE_OUTPUT_DIRECTORY};$ENV{PATH}" ) endif() ``` -------------------------------- ### Define SWIG library creation function Source: https://github.com/msteinbeck/tinyspline/blob/master/src/CMakeLists.txt A reusable CMake function that parses arguments, configures SWIG library properties, and handles platform-specific library naming and stripping. ```cmake function(tinyspline_add_swig_library) cmake_parse_arguments( ARGS "" "TARGET;TYPE;LANG;OUTPUT;NAME" "SWIG_ARGS;FLAGS;LIBS" ${ARGN} ) set_source_files_properties("swig/${ARGS_TARGET}.i" PROPERTIES CPLUSPLUS ON) if(NOT DEFINED ARGS_TYPE) set(ARGS_TYPE MODULE) endif() list(APPEND CMAKE_SWIG_FLAGS ${ARGS_SWIG_ARGS}) list(APPEND CMAKE_SWIG_FLAGS -O) # enable optimization if(TINYSPLINE_FLOAT_PRECISION) list(APPEND CMAKE_SWIG_FLAGS -DTINYSPLINE_FLOAT_PRECISION) endif() swig_add_library( ${ARGS_TARGET} TYPE ${ARGS_TYPE} LANGUAGE ${ARGS_LANG} OUTPUT_DIR ${ARGS_OUTPUT} SOURCES "swig/${ARGS_TARGET}.i" ${TINYSPLINE_CXX_SOURCE_FILES} ) # On Linux and macOS, we can (and for the sake of portability should) omit # linking libraries. if(NOT ${TINYSPLINE_PLATFORM_NAME} STREQUAL "linux" AND NOT ${TINYSPLINE_PLATFORM_NAME} STREQUAL "macosx" ) swig_link_libraries( ${ARGS_TARGET} ${ARGS_LIBS} ${TINYSPLINE_BINDING_LINK_LIBRARIES} ) endif() set_target_properties( ${ARGS_TARGET} PROPERTIES FOLDER ${TINYSPLINE_BINDINGS_FOLDER_NAME} COMPILE_FLAGS "${TINYSPLINE_BINDING_CXX_FLAGS} ${ARGS_FLAGS}" LINK_FLAGS "${TINYSPLINE_BINDING_LINKER_FLAGS}" ) target_compile_definitions( ${ARGS_TARGET} PUBLIC ${TINYSPLINE_BINDING_CXX_DEFINITIONS} ) # Fix library prefix for C#. if(${ARGS_LANG} STREQUAL "csharp") set_property( TARGET ${ARGS_TARGET} APPEND PROPERTY PREFIX "lib" ) endif() # Fix library prefix for Go. if(${ARGS_LANG} STREQUAL "go") set_property( TARGET ${ARGS_TARGET} APPEND PROPERTY PREFIX "lib" ) endif() # Fix library prefix for non-windows platforms. if(NOT ${TINYSPLINE_PLATFORM_IS_WINDOWS}) if(${ARGS_LANG} STREQUAL "d") set_property( TARGET ${ARGS_TARGET} APPEND PROPERTY PREFIX "lib" ) endif() endif() # Fix library suffix for Ruby on Windows. if(${ARGS_LANG} STREQUAL "ruby" AND ${TINYSPLINE_PLATFORM_IS_WINDOWS}) set_property( TARGET ${ARGS_TARGET} APPEND PROPERTY SUFFIX ".so" ) endif() if(NOT ${ARGS_NAME} STREQUAL "") set_property( TARGET ${ARGS_TARGET} APPEND PROPERTY OUTPUT_NAME "${ARGS_NAME}" ) endif() if(CMAKE_STRIP AND NOT TINYSPLINE_MACOSX_TO_MACOSX) add_custom_command( TARGET ${ARGS_TARGET} POST_BUILD COMMAND ${CMAKE_COMMAND} -E echo "Stripping $" COMMAND "${CMAKE_STRIP}" --strip-unneeded "$" WORKING_DIRECTORY "${TINYSPLINE_OUTPUT_DIRECTORY}" ) endif() endfunction() ``` -------------------------------- ### Define and Check Directories Function Source: https://github.com/msteinbeck/tinyspline/blob/master/test/pkg/CMakeLists.txt A CMake function to verify if provided paths exist and are directories. It reports errors if paths are invalid. ```cmake cmake_minimum_required(VERSION 3.12) project(test) find_package(tinyspline REQUIRED) find_package(tinysplinecxx REQUIRED) # Checks for each path listed in ${list_of_dirs} whether it exists and is a # directory. Errors are reported with message(SEND_ERROR ...). function(check_directories list_of_dirs) foreach(dir ${list_of_dirs}) if(NOT EXISTS ${dir}) message(SEND_ERROR "'${dir}' does not exist") return() endif() if(NOT IS_DIRECTORY ${dir}) message(SEND_ERROR "'${dir}' is not a directory") endif() endforeach() endfunction() ``` -------------------------------- ### Push RubyGems package Source: https://github.com/msteinbeck/tinyspline/blob/master/tools/release/README.md Upload a specific gem file to the RubyGems repository. ```shell gem push tinyspline/.gem ``` -------------------------------- ### Add Test Subdirectories Source: https://github.com/msteinbeck/tinyspline/blob/master/test/CMakeLists.txt Includes subdirectories for C and C++ unit tests. ```cmake add_subdirectory(c) add_subdirectory(cxx) ``` -------------------------------- ### Generate NPM package.json Source: https://github.com/msteinbeck/tinyspline/blob/master/src/CMakeLists.txt Configures a package.json file for Emscripten builds to include JS and WASM library outputs. ```cmake file(REMOVE "${TINYSPLINE_BINARY_DIR}/package.json") if(${EMSCRIPTEN}) set(TINYSPLINE_NPM_FILES "\"${TINYSPLINE_LIB_DIR}/${TINYSPLINE_JS_LIBRARY_OUTPUT_NAME}.js\",\ \"${TINYSPLINE_LIB_DIR}/${TINYSPLINE_JS_LIBRARY_OUTPUT_NAME}.wasm\"" ) configure_file( "pkg/package.json.in" "${TINYSPLINE_BINARY_DIR}/package.json" @ONLY ) endif() ``` -------------------------------- ### Set C++ Standard Globally Source: https://github.com/msteinbeck/tinyspline/blob/master/src/CMakeLists.txt Configures the C++ standard for the project. Uses C++17 for Emscripten builds and C++11 otherwise. Ensures the C++ standard is required and disables C++ extensions. ```cmake if(EMSCRIPTEN) set(CMAKE_CXX_STANDARD 17) else() set(CMAKE_CXX_STANDARD 11) endif() set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) ``` -------------------------------- ### Implement Error Handling with C Macros Source: https://context7.com/msteinbeck/tinyspline/llms.txt Uses TS_TRY, TS_CALL, TS_CATCH, and TS_FINALLY macros to manage resource cleanup and error reporting in C applications. ```c #include "tinyspline.h" #include #include int main() { tsStatus status; tsBSpline spline = ts_bspline_init(); tsBSpline beziers = ts_bspline_init(); tsDeBoorNet net = ts_deboornet_init(); tsReal *ctrlp = NULL; tsReal *result = NULL; TS_TRY(try, status.code, &status) // Create spline - may fail with TS_MALLOC or invalid parameters TS_CALL(try, status.code, ts_bspline_new( 7, 2, 3, TS_CLAMPED, &spline, &status)) // Get control points - may fail with TS_MALLOC TS_CALL(try, status.code, ts_bspline_control_points( &spline, &ctrlp, &status)) // Setup control points ctrlp[0] = -1.75; ctrlp[1] = -1.0; ctrlp[2] = -1.5; ctrlp[3] = -0.5; // ... more points ... TS_CALL(try, status.code, ts_bspline_set_control_points( &spline, ctrlp, &status)) // Evaluate - may fail with TS_U_UNDEFINED if knot out of domain TS_CALL(try, status.code, ts_bspline_eval( &spline, 0.5, &net, &status)) TS_CALL(try, status.code, ts_deboornet_result( &net, &result, &status)) printf("Success: Point at u=0.5 is (%f, %f)\n", result[0], result[1]); TS_CATCH(status.code) // Handle error printf("Error %d: %s\n", status.code, status.message); TS_FINALLY // Clean up resources - always executed ts_bspline_free(&spline); ts_bspline_free(&beziers); ts_deboornet_free(&net); if (ctrlp) free(ctrlp); if (result) free(result); TS_END_TRY return status.code ? 1 : 0; } ``` -------------------------------- ### Define Host and Platform Constants in CMake Source: https://github.com/msteinbeck/tinyspline/blob/master/src/CMakeLists.txt Sets internal cache variables to determine if the host system is Windows, and defines platform-specific constants like `TINYSPLINE_PLATFORM_NAME`, `TINYSPLINE_PLATFORM_IS_WINDOWS`, `TINYSPLINE_PLATFORM_ARCH`, `TINYSPLINE_PLATFORM`, and `TINYSPLINE_MACOSX_TO_MACOSX`. ```cmake # Host if(${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Windows") set(TINYSPLINE_HOST_IS_WINDOWS True CACHE INTERNAL "" ) elseif(${CMAKE_HOST_SYSTEM_NAME} STREQUAL "WindowsStore") set(TINYSPLINE_HOST_IS_WINDOWS True CACHE INTERNAL "" ) else() set(TINYSPLINE_HOST_IS_WINDOWS False CACHE INTERNAL "" ) endif() ``` -------------------------------- ### Define TINYSPLINE_BINDINGS_FOLDER_NAME Source: https://github.com/msteinbeck/tinyspline/blob/master/src/CMakeLists.txt Sets the folder name for generated bindings. This variable specifies the directory where language bindings will be placed. ```cmake set(TINYSPLINE_BINDINGS_FOLDER_NAME "bindings") ``` -------------------------------- ### Force Python version for bindings Source: https://github.com/msteinbeck/tinyspline/blob/master/BUILD.md Specify the Python version for Swig binding generation when multiple versions are present. ```bash cmake -DTINYSPLINE_PYTHON_VERSION=2 .. ```