openNURBS C++ Toolkit

repository·8.x·Indexed 20 days ago

https://github.com/mcneel/opennurbs

A C++ toolkit for reading and writing .3dm files, the 3D model format used by Rhinoceros®. openNURBS provides NURBS evaluation tools, geometric manipulation tools, and 3D view utilities.

Tokens
4K
Snippets
7
Records
22
Agent score
65%

What's inside openNURBS

  1. Get started with openNURBS

    8.x

    To use openNURBS in your C++ application, follow these steps:

    1. Clone the repository to your local machine.
    2. Build the library: Open opennurbs_public.sln in your IDE (e.g., Visual Studio), select your desired platform and configuration, and rebuild the solution.
    3. Integrate into your project: Create a new C++ project and configure your header files to include the openNURBS public interface.

    For detailed information on supported compilers and specific build instructions, refer to the official Getting Started guide.

    // 1. Clone the repository
    // 2. Open opennurbs_public.sln and rebuild
    // 3. Configure your project headers
  2. Build and run the OpenNURBS FileIO example test

    8.x

    The example_test project is a basic test suite for verifying OpenNURBS FileIO functionality. To build and run it, ensure you have the prerequisites met and follow the CMake workflow from the src4/opennurbs/example_test directory.

    Prerequisites

    • Operating System: Linux, macOS, or Windows.
    • C++ Compiler: Must support at least C++14 (tests are configured for C++17).
      • macOS: Apple Clang (via Xcode).
      • Windows: MSVC (via Visual Studio).
      • Linux: GCC.
    • Build Tools: CMake (version 3.16 or higher) and a compatible build tool (Make, Ninja, or MSBuild).
    # 1. Configure the project
    cmake -S . -B build
    
    # 2. Build the project
    cmake --build build
    
    # 3. Run the executable (Linux/macOS)
    cd build && ./example_test -r ../../example_files
    
    # 3. Run the executable (Windows)
    cd build/Debug && ./example_test -r ../../example_files
  3. Configure openNURBS in your C++ project

    8.x

    To include openNURBS in your C++ project, you must define the installation directory and include the public header. It is recommended to do this in your stdafx.h file.

    Use the OPENNURBS_PUBLIC_INSTALL_DIR macro to enable automatic linking via pragmas. Replace <MY_INSTALLPATH> with the absolute path to your openNURBS installation, ensuring you use forward slashes (/) as directory separators even on Windows.

    If you intend to use openNURBS as a Dynamic Link Library (DLL), uncomment the OPENNURBS_IMPORTS definition.

    // defining OPENNURBS_PUBLIC_INSTALL_DIR enables automatic linking using pragmas
    #define OPENNURBS_PUBLIC_INSTALL_DIR "C:/PATH/TO/YOUR/INSTALLATION"
    
    // uncomment the next line if you want to use opennurbs as a DLL
    //#define OPENNURBS_IMPORTS
    
    #include "C:/PATH/TO/YOUR/INSTALLATION/opennurbs_public.h"
  4. Overview of gxvalid (TrueType GX validator)

    8.x

    gxvalid is a module designed to validate TrueType GX tables, which are additional tables used by Apple Advanced Typography (AAT) and QuickDraw GX Text. It also validates extended kern tables used for AAT.

    Usage Patterns

    • Library Integration: You can link gxvalid with your own program to validate a font file before running your layout engine. This allows you to remove error-checking code from your engine, as gxvalid handles the validation upfront.
    • Stand-alone Validator: It can be used as a standalone font validator. The ftvalid test program (included in the ft2demo bundle) calls gxvalid internally, making it useful for font developers.

    gxvalid uses the FreeType 2 validator framework (ftvalid).

  5. Use the FreeType PCF driver for bitmap fonts

    8.x

    The PCF (Portable Compiled Format) driver allows FreeType to load binary bitmap fonts commonly used in X environments. Glyph images are loaded into memory on demand to maintain a small memory footprint.

    To use PCF fonts, you can compile existing BDF bitmap fonts into the PCF format using the bdftopcf utility (often found in XFree86 source trees).

  6. Use the ftrandom tool to fuzz FreeType fonts

    8.x

    The ftrandom program is a fuzzing tool designed to test FreeType's robustness. It works by taking a set of directories containing 'good' (valid) fonts and a set of font extensions to target. The tool randomly selects a font, creates a copy, introduces errors (either a specific count of single-byte errors or a fraction of the file size), and then runs a tester process against the corrupted font.

    Testing Workflow:

    1. The tool forks a new tester process for each erroneous font.
    2. The tester initializes the library and attempts to open the font.
    3. The tester loads each glyph (optionally decomposing outlines or rasterizing).
    4. Success/Failure Criteria:
      • If the tester crashes (exits with a signal) or hangs (takes longer than 20 seconds), ftrandom saves the corrupted font file for debugging.
      • If the tester exits normally or with a standard error, the corrupted file is removed.
  7. Validation limitations of gxvalid

    8.x

    gxvalid checks if layout data conforms to the TrueType GX format specified by Apple, but it has specific functional limitations:

    State Machine Validation

    gxvalid can check for 'expression' errors in the StateTable (the state transition diagram), such as:

    • Transitions to undefined states.
    • Existence of glyph IDs the State Machine cannot handle.
    • Inability to compute layout information from the diagram.

    It cannot check:

    • States that the State Machine never actually transits to.
    • Whether the State Machine reaches the end of text state.
    • Potential stack underflow/overflow (the State Machine can store up to 16 glyphs on its stack).
    • temporary glyph IDs used in chained State Machines (e.g., in mort and morx tables), as these are intended for intermediate use by the next component State Machine rather than the renderer.

    Relationship Validation

    gxvalid does not validate the relationship between multiple layout features. It cannot detect if conflicting typographic rules are activated simultaneously (e.g., setting both Text Spacing=Monospace and Ideographic Spacing=Proportional).

  8. Understand kern table dialects and versioning

    8.x

    gxvalid includes a specialized validator for kern tables to handle different versions and platform-specific dialects.

    Versions

    • Classic (16-bit): Identified by a version number of 0x0000. The number of subtables is a 16-bit value. The subtable header does not include a tupleIndex.
    • New (32-bit): Identified by a version number of 0x00010000. The number of subtables is a 32-bit value. The subtable header includes a 16-bit tupleIndex.

    Dialects

    Because bit interpretations of the coverage field differ between vendors, gxvalid must distinguish between three dialects:

    1. New Apple dialect: 32-bit version.
    2. Classic Apple dialect: 16-bit version; uses specific bit masks (e.g., 0x8000 for horizontal/vertical) that differ from Microsoft.
    3. Classic Microsoft dialect: 16-bit version; uses different bit interpretations (e.g., bit 8-15 for coverage).

    gxvalid uses an auto-detection algorithm: it first attempts to decode using the Classic Apple dialect; if reserved bits are set or subtable formats are incompatible, it retries using the Classic Microsoft dialect.

  9. Use ftmutator.cc for multi-file font fuzzing

    8.x

    Since libFuzzer typically only mutates a single input file, ftmutator.cc implements a custom mutator that uses an uncompressed tar file archive as the input.

    How it works:

    • The first file within the tarball is opened by FreeType as the primary font file.
    • All subsequent files in the tarball are treated as auxiliary input for FT_Attach_Stream (used for loading files like AFM files for PostScript Type 1 fonts).

    Compilation requirements are identical to ftfuzzer.cc.

  10. Configure gxvalid error handling levels

    8.x

    gxvalid is designed to be permissive, continuing validation even when errors are found, similar to how Apple's rendering engines behave. The behavior depends on the selected validation level:

    • FT_VALIDATE_DEFAULT: Warns about errors and continues. For example, it will warn about invalid feature numbers but continue validation.
    • FT_VALIDATE_TIGHT: More strict. It may ignore certain broken segments (like broken LookupTable format 2) or abort on specific errors like invalid feature numbers (case 'a') while continuing on others (case 'b').
    • FT_VALIDATE_PARANOID: The strictest level. It will abort on most specification violations, including too-short LookupTable format 0, broken prop bracketing, or invalid feature numbers.
  11. Handle anti-aliased BDF bitmaps

    8.x

    The driver supports an extension to the BDF format (used by Mark Leisher's xmbdfed and Microsoft's SBIT tool) that allows for anti-aliased bitmaps. This is indicated by a fourth field in the SIZE keyword specifying the bits per pixel (bpp).

    Supported bpp values and driver behavior:

    • 1: Default (returns a 1-bit per pixel bitmap).
    • 2: Four gray levels (returns an 8-bit per pixel pixmap).
    • 4: 16 gray levels (returns an 8-bit per pixel pixmap).
    • 8: 256 gray levels (returns an 8-bit per pixel pixmap).
  12. Build and use ftfuzzer for FreeType fuzzing

    8.x

    The ftfuzzer.cc file provides a target function for fuzzing FreeType using libFuzzer or similar tools. To build it, you must compile both libfreetype.a and ftfuzzer.cc using a recent clang compiler with specific sanitization flags for coverage and bug detection. You also require header files from the libarchive library to handle tar files.

    Build Steps:

    1. Compile libfreetype.a and ftfuzzer.cc with clang using -fsanitize-coverage=edge,8bit-counters and -fsanitize=address,signed-integer-overflow,shift.
    2. Link the resulting objects with libFuzzer (which provides the main function) and libarchive.
    3. Execute the fuzzer against a test corpus.
    # Recommended clang flags for building
    # For fuzzer coverage feedback:
    -fsanitize-coverage=edge,8bit-counters
    
    # For bug checking:
    -fsanitize=address,signed-integer-overflow,shift